Merge "composer: add getDisplayPhysicalOrientation"
diff --git a/atrace/1.0/default/android.hardware.atrace@1.0-service.rc b/atrace/1.0/default/android.hardware.atrace@1.0-service.rc
index 7110b45..31459b4 100644
--- a/atrace/1.0/default/android.hardware.atrace@1.0-service.rc
+++ b/atrace/1.0/default/android.hardware.atrace@1.0-service.rc
@@ -14,4 +14,4 @@
     interface android.hardware.atrace@1.0::IAtraceDevice default
     class early_hal
     user system
-    group system
+    group system readtracefs
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/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
index f8df6e6..970d044 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
@@ -154,7 +154,7 @@
         return toInt(result.error());
     }
 
-    void onSetValues(const std::vector<SetValueResult> results) {
+    void onSetValues(std::vector<SetValueResult> results) {
         for (auto& result : results) {
             mSetValueResults.push_back(result);
         }
@@ -162,7 +162,7 @@
 
     const std::vector<SetValueResult>& getSetValueResults() { return mSetValueResults; }
 
-    void onGetValues(const std::vector<GetValueResult> results) {
+    void onGetValues(std::vector<GetValueResult> results) {
         for (auto& result : results) {
             mGetValueResults.push_back(result);
         }
@@ -170,7 +170,7 @@
 
     const std::vector<GetValueResult>& getGetValueResults() { return mGetValueResults; }
 
-    void onPropertyChangeEvent(const std::vector<VehiclePropValue>& values) {
+    void onPropertyChangeEvent(std::vector<VehiclePropValue> values) {
         for (auto& value : values) {
             mChangedProperties.push_back(value);
         }
diff --git a/automotive/vehicle/aidl/impl/vhal/Android.bp b/automotive/vehicle/aidl/impl/vhal/Android.bp
index 454fea5..a54ab4b 100644
--- a/automotive/vehicle/aidl/impl/vhal/Android.bp
+++ b/automotive/vehicle/aidl/impl/vhal/Android.bp
@@ -56,6 +56,7 @@
     srcs: [
         "src/ConnectedClient.cpp",
         "src/DefaultVehicleHal.cpp",
+        "src/PendingRequestPool.cpp",
     ],
     static_libs: [
         "VehicleHalUtils",
diff --git a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
index 4ee3ee9..f6f7d80 100644
--- a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
+++ b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
@@ -88,12 +88,17 @@
             GetSetValuesClient<::aidl::android::hardware::automotive::vehicle::SetValueResult,
                                ::aidl::android::hardware::automotive::vehicle::SetValueResults>;
 
+    // The default timeout of get or set value requests is 30s.
+    // TODO(b/214605968): define TIMEOUT_IN_NANO in IVehicle and allow getValues/setValues/subscribe
+    // to specify custom timeouts.
+    static constexpr int64_t TIMEOUT_IN_NANO = 30'000'000'000;
     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;
+    // Only modified in constructor, so thread-safe.
     std::unique_ptr<::ndk::ScopedFileDescriptor> mConfigFile;
 
     std::mutex mLock;
diff --git a/automotive/vehicle/aidl/impl/vhal/include/ParcelableUtils.h b/automotive/vehicle/aidl/impl/vhal/include/ParcelableUtils.h
index dcb15b9..4b7c2f3 100644
--- a/automotive/vehicle/aidl/impl/vhal/include/ParcelableUtils.h
+++ b/automotive/vehicle/aidl/impl/vhal/include/ParcelableUtils.h
@@ -31,19 +31,18 @@
 
 template <class T1, class T2>
 ::ndk::ScopedAStatus vectorToStableLargeParcelable(std::vector<T1>&& values, T2* output) {
+    output->payloads = std::move(values);
     auto result = ::android::automotive::car_binder_lib::LargeParcelableBase::
-            parcelableVectorToStableLargeParcelable(values);
+            parcelableToStableLargeParcelable(*output);
     if (!result.ok()) {
         return toScopedAStatus(
                 result, ::aidl::android::hardware::automotive::vehicle::StatusCode::INTERNAL_ERROR);
     }
     auto& fd = result.value();
-    if (fd == nullptr) {
-        // If we no longer needs values, move it inside the payloads to avoid copying.
-        output->payloads = std::move(values);
-    } else {
+    if (fd != nullptr) {
         // Move the returned ScopedFileDescriptor pointer to ScopedFileDescriptor value in
         // 'sharedMemoryFd' field.
+        output->payloads.clear();
         output->sharedMemoryFd = std::move(*fd);
     }
     return ::ndk::ScopedAStatus::ok();
@@ -57,12 +56,13 @@
     return vectorToStableLargeParcelable(std::move(valuesCopy), output);
 }
 
-template <class T1, class T2>
-::android::base::expected<std::vector<T1>, ::ndk::ScopedAStatus> stableLargeParcelableToVector(
-        const T2& largeParcelable) {
-    ::android::base::Result<std::optional<std::vector<T1>>> result =
-            ::android::automotive::car_binder_lib::LargeParcelableBase::
-                    stableLargeParcelableToParcelableVector<T1>(largeParcelable.sharedMemoryFd);
+template <class T>
+::android::base::expected<
+        ::android::automotive::car_binder_lib::LargeParcelableBase::BorrowedOwnedObject<T>,
+        ::ndk::ScopedAStatus>
+fromStableLargeParcelable(const T& largeParcelable) {
+    auto result = ::android::automotive::car_binder_lib::LargeParcelableBase::
+            stableLargeParcelableToParcelable(largeParcelable);
 
     if (!result.ok()) {
         return ::android::base::unexpected(toScopedAStatus(
@@ -70,15 +70,7 @@
                 "failed to parse large parcelable"));
     }
 
-    if (!result.value().has_value()) {
-        return ::android::base::unexpected(
-                ::ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
-                        toInt(::aidl::android::hardware::automotive::vehicle::StatusCode::
-                                      INVALID_ARG),
-                        "empty request"));
-    }
-
-    return std::move(result.value().value());
+    return std::move(result.value());
 }
 
 }  // namespace vehicle
diff --git a/automotive/vehicle/aidl/impl/vhal/include/PendingRequestPool.h b/automotive/vehicle/aidl/impl/vhal/include/PendingRequestPool.h
new file mode 100644
index 0000000..6dcfaff
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/vhal/include/PendingRequestPool.h
@@ -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.
+ */
+
+#ifndef android_hardware_automotive_vehicle_aidl_impl_vhal_include_PendingRequestPool_H_
+#define android_hardware_automotive_vehicle_aidl_impl_vhal_include_PendingRequestPool_H_
+
+#include <android-base/result.h>
+#include <android-base/thread_annotations.h>
+
+#include <atomic>
+#include <list>
+#include <mutex>
+#include <thread>
+#include <unordered_map>
+#include <unordered_set>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+// A thread-safe pending request pool that tracks whether each request has timed-out.
+class PendingRequestPool final {
+  public:
+    using TimeoutCallbackFunc = std::function<void(const std::unordered_set<int64_t>&)>;
+
+    explicit PendingRequestPool(int64_t timeoutInSec);
+
+    ~PendingRequestPool();
+
+    // Adds a list of requests to the request pool.
+    // The clientId is the key for all the requests. It could be a number or an address to a data
+    // structure that represents a client. The caller must maintain this data structure.
+    // All the request IDs must be unique for one client, if any of the requestIds is duplicate with
+    // any pending request IDs for the client, this function returns error and no requests would be
+    // added. Otherwise, they would be added to the request pool.
+    // The callback would be called if requests are not finished within {@code mTimeoutInNano}
+    // seconds.
+    android::base::Result<void> addRequests(const void* clientId,
+                                            const std::unordered_set<int64_t>& requestIds,
+                                            std::shared_ptr<TimeoutCallbackFunc> callback);
+
+    // Checks whether the request is currently pending.
+    bool isRequestPending(const void* clientId, int64_t requestId) const;
+
+    // Tries to mark the requests as finished and remove them from the pool if the request is
+    // currently pending. Returns the list of request that is pending and has been finished
+    // successfully. This function would try to finish any valid requestIds even though some of the
+    // requestIds are not valid.
+    std::unordered_set<int64_t> tryFinishRequests(const void* clientId,
+                                                  const std::unordered_set<int64_t>& requestIds);
+
+    // Returns how many pending requests in the pool, for testing purpose.
+    size_t countPendingRequests(const void* clientId) const;
+
+  private:
+    // The maximum number of pending requests allowed per client. If exceeds this number, adding
+    // more requests would fail. This is to prevent spamming from client.
+    static constexpr size_t MAX_PENDING_REQUEST_PER_CLIENT = 10000;
+
+    struct PendingRequest {
+        std::unordered_set<int64_t> requestIds;
+        int64_t timeoutTimestamp;
+        std::shared_ptr<TimeoutCallbackFunc> callback;
+    };
+
+    int64_t mTimeoutInNano;
+    mutable std::mutex mLock;
+    std::unordered_map<const void*, std::list<PendingRequest>> mPendingRequestsByClient
+            GUARDED_BY(mLock);
+    std::thread mThread;
+    std::atomic<bool> mThreadStop = false;
+    std::condition_variable mCv;
+    std::mutex mCvLock;
+
+    bool isRequestPendingLocked(const void* clientId, int64_t requestId) const REQUIRES(mLock);
+
+    // Checks whether the requests in the pool has timed-out, run periodically in a separate thread.
+    void checkTimeout();
+};
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_automotive_vehicle_aidl_impl_vhal_include_PendingRequestPool_H_
diff --git a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
index e98f021..7f09a59 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
@@ -57,7 +57,9 @@
     for (auto& config : configs) {
         mConfigsByPropId[config.prop] = config;
     }
-    auto result = LargeParcelableBase::parcelableVectorToStableLargeParcelable(configs);
+    VehiclePropConfigs vehiclePropConfigs;
+    vehiclePropConfigs.payloads = std::move(configs);
+    auto result = LargeParcelableBase::parcelableToStableLargeParcelable(vehiclePropConfigs);
     if (!result.ok()) {
         ALOGE("failed to convert configs to shared memory file, error: %s, code: %d",
               getErrorMsg(result).c_str(), getIntErrorCode(result));
@@ -71,6 +73,7 @@
 
 ScopedAStatus DefaultVehicleHal::getAllPropConfigs(VehiclePropConfigs* output) {
     if (mConfigFile != nullptr) {
+        output->payloads.clear();
         output->sharedMemoryFd.set(dup(mConfigFile->get()));
         return ScopedAStatus::ok();
     }
@@ -131,20 +134,14 @@
                                            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();
+    expected<LargeParcelableBase::BorrowedOwnedObject<GetValueRequests>, ScopedAStatus>
+            deserializedResults = fromStableLargeParcelable(requests);
+    if (!deserializedResults.ok()) {
+        ALOGE("getValues: failed to parse getValues requests");
+        return std::move(deserializedResults.error());
     }
+    const std::vector<GetValueRequest>& getValueRequests =
+            deserializedResults.value().getObject()->payloads;
 
     std::shared_ptr<GetValuesClient> client;
     {
@@ -153,7 +150,7 @@
     }
 
     if (StatusCode status =
-                mVehicleHardware->getValues(client->getResultCallback(), *getValueRequests);
+                mVehicleHardware->getValues(client->getResultCallback(), getValueRequests);
         status != StatusCode::OK) {
         return ScopedAStatus::fromServiceSpecificErrorWithMessage(
                 toInt(status), "failed to get value from VehicleHardware");
@@ -166,27 +163,21 @@
                                            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();
+    expected<LargeParcelableBase::BorrowedOwnedObject<SetValueRequests>, ScopedAStatus>
+            deserializedResults = fromStableLargeParcelable(requests);
+    if (!deserializedResults.ok()) {
+        ALOGE("setValues: failed to parse setValues requests");
+        return std::move(deserializedResults.error());
     }
+    const std::vector<SetValueRequest>& setValueRequests =
+            deserializedResults.value().getObject()->payloads;
 
     // 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) {
+    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());
diff --git a/automotive/vehicle/aidl/impl/vhal/src/PendingRequestPool.cpp b/automotive/vehicle/aidl/impl/vhal/src/PendingRequestPool.cpp
new file mode 100644
index 0000000..c2d6f89
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/vhal/src/PendingRequestPool.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 "PendingRequestPool.h"
+
+#include <VehicleHalTypes.h>
+#include <VehicleUtils.h>
+
+#include <utils/Log.h>
+#include <utils/SystemClock.h>
+
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+namespace {
+
+using ::aidl::android::hardware::automotive::vehicle::StatusCode;
+using ::android::base::Error;
+using ::android::base::Result;
+
+// At least check every 1s.
+constexpr int64_t CHECK_TIME_IN_NANO = 1000000000;
+
+}  // namespace
+
+PendingRequestPool::PendingRequestPool(int64_t timeoutInNano)
+    : mTimeoutInNano(timeoutInNano), mThread([this] {
+          // [this] must be alive within this thread because destructor would wait for this thread
+          // to exit.
+          int64_t sleepTime = std::min(mTimeoutInNano, static_cast<int64_t>(CHECK_TIME_IN_NANO));
+          std::unique_lock<std::mutex> lk(mCvLock);
+          while (!mCv.wait_for(lk, std::chrono::nanoseconds(sleepTime),
+                               [this] { return mThreadStop.load(); })) {
+              checkTimeout();
+          }
+      }) {}
+
+PendingRequestPool::~PendingRequestPool() {
+    mThreadStop = true;
+    mCv.notify_all();
+    if (mThread.joinable()) {
+        mThread.join();
+    }
+
+    // If this pool is being destructed, send out all pending requests as timeout.
+    {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+
+        for (auto& [_, pendingRequests] : mPendingRequestsByClient) {
+            for (const auto& request : pendingRequests) {
+                (*request.callback)(request.requestIds);
+            }
+        }
+        mPendingRequestsByClient.clear();
+    }
+}
+
+Result<void> PendingRequestPool::addRequests(const void* clientId,
+                                             const std::unordered_set<int64_t>& requestIds,
+                                             std::shared_ptr<TimeoutCallbackFunc> callback) {
+    std::scoped_lock<std::mutex> lockGuard(mLock);
+    std::list<PendingRequest>* pendingRequests;
+    size_t pendingRequestCount = 0;
+    if (mPendingRequestsByClient.find(clientId) != mPendingRequestsByClient.end()) {
+        pendingRequests = &mPendingRequestsByClient[clientId];
+        for (const auto& pendingRequest : *pendingRequests) {
+            const auto& pendingRequestIds = pendingRequest.requestIds;
+            for (int64_t requestId : requestIds) {
+                if (pendingRequestIds.find(requestId) != pendingRequestIds.end()) {
+                    return Error(toInt(StatusCode::INVALID_ARG))
+                           << "duplicate request ID: " << requestId;
+                }
+            }
+            pendingRequestCount += pendingRequestIds.size();
+        }
+    } else {
+        // Create a new empty list for this client.
+        pendingRequests = &mPendingRequestsByClient[clientId];
+    }
+
+    if (requestIds.size() > MAX_PENDING_REQUEST_PER_CLIENT - pendingRequestCount) {
+        return Error(toInt(StatusCode::TRY_AGAIN)) << "too many pending requests";
+    }
+
+    int64_t currentTime = elapsedRealtimeNano();
+    int64_t timeoutTimestamp = currentTime + mTimeoutInNano;
+
+    pendingRequests->push_back({
+            .requestIds = std::unordered_set<int64_t>(requestIds.begin(), requestIds.end()),
+            .timeoutTimestamp = timeoutTimestamp,
+            .callback = callback,
+    });
+
+    return {};
+}
+
+bool PendingRequestPool::isRequestPending(const void* clientId, int64_t requestId) const {
+    std::scoped_lock<std::mutex> lockGuard(mLock);
+
+    return isRequestPendingLocked(clientId, requestId);
+}
+
+size_t PendingRequestPool::countPendingRequests(const void* clientId) const {
+    std::scoped_lock<std::mutex> lockGuard(mLock);
+
+    auto it = mPendingRequestsByClient.find(clientId);
+    if (it == mPendingRequestsByClient.end()) {
+        return 0;
+    }
+
+    size_t count = 0;
+    for (const auto& pendingRequest : it->second) {
+        count += pendingRequest.requestIds.size();
+    }
+
+    return count;
+}
+
+bool PendingRequestPool::isRequestPendingLocked(const void* clientId, int64_t requestId) const {
+    auto it = mPendingRequestsByClient.find(clientId);
+    if (it == mPendingRequestsByClient.end()) {
+        return false;
+    }
+    for (const auto& pendingRequest : it->second) {
+        const auto& requestIds = pendingRequest.requestIds;
+        if (requestIds.find(requestId) != requestIds.end()) {
+            return true;
+        }
+    }
+    return false;
+}
+
+void PendingRequestPool::checkTimeout() {
+    std::vector<PendingRequest> timeoutRequests;
+    {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+
+        int64_t currentTime = elapsedRealtimeNano();
+
+        std::vector<const void*> clientsWithEmptyRequests;
+
+        for (auto& [clientId, pendingRequests] : mPendingRequestsByClient) {
+            auto it = pendingRequests.begin();
+            while (it != pendingRequests.end()) {
+                if (it->timeoutTimestamp >= currentTime) {
+                    break;
+                }
+                timeoutRequests.push_back(std::move(*it));
+                it = pendingRequests.erase(it);
+            }
+
+            if (pendingRequests.empty()) {
+                clientsWithEmptyRequests.push_back(clientId);
+            }
+        }
+
+        for (const void* clientId : clientsWithEmptyRequests) {
+            mPendingRequestsByClient.erase(clientId);
+        }
+    }
+
+    // Call the callback outside the lock.
+    for (const auto& request : timeoutRequests) {
+        (*request.callback)(request.requestIds);
+    }
+}
+
+std::unordered_set<int64_t> PendingRequestPool::tryFinishRequests(
+        const void* clientId, const std::unordered_set<int64_t>& requestIds) {
+    std::scoped_lock<std::mutex> lockGuard(mLock);
+
+    std::unordered_set<int64_t> foundIds;
+
+    if (mPendingRequestsByClient.find(clientId) == mPendingRequestsByClient.end()) {
+        return foundIds;
+    }
+
+    auto& pendingRequests = mPendingRequestsByClient[clientId];
+    auto it = pendingRequests.begin();
+    while (it != pendingRequests.end()) {
+        auto& pendingRequestIds = it->requestIds;
+        for (int64_t requestId : requestIds) {
+            auto idIt = pendingRequestIds.find(requestId);
+            if (idIt == pendingRequestIds.end()) {
+                continue;
+            }
+            pendingRequestIds.erase(idIt);
+            foundIds.insert(requestId);
+        }
+        if (pendingRequestIds.empty()) {
+            it = pendingRequests.erase(it);
+            continue;
+        }
+        it++;
+    }
+
+    return foundIds;
+}
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
index 8934a7b..ffc08a7 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
@@ -389,15 +389,14 @@
             });
         }
 
-        auto result = LargeParcelableBase::parcelableVectorToStableLargeParcelable(
-                expectedHardwareRequests);
+        requests.payloads = expectedHardwareRequests;
+        auto result = LargeParcelableBase::parcelableToStableLargeParcelable(requests);
         if (!result.ok()) {
             return result.error();
         }
-        if (result.value() == nullptr) {
-            requests.payloads = expectedHardwareRequests;
-        } else {
+        if (result.value() != nullptr) {
             requests.sharedMemoryFd = std::move(*result.value());
+            requests.payloads.clear();
         }
         return {};
     }
@@ -423,14 +422,13 @@
             });
         }
 
-        auto result = LargeParcelableBase::parcelableVectorToStableLargeParcelable(
-                expectedHardwareRequests);
+        requests.payloads = expectedHardwareRequests;
+        auto result = LargeParcelableBase::parcelableToStableLargeParcelable(requests);
         if (!result.ok()) {
             return result.error();
         }
-        if (result.value() == nullptr) {
-            requests.payloads = expectedHardwareRequests;
-        } else {
+        if (result.value() != nullptr) {
+            requests.payloads.clear();
             requests.sharedMemoryFd = std::move(*result.value());
         }
         return {};
@@ -490,13 +488,10 @@
 
     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);
+    auto result = LargeParcelableBase::stableLargeParcelableToParcelable(output);
     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);
+    ASSERT_EQ(result.value().getObject()->payloads, testConfigs);
 }
 
 TEST_F(DefaultVehicleHalTest, testGetValuesSmall) {
@@ -544,11 +539,9 @@
     ASSERT_TRUE(getValueResults.payloads.empty())
             << "payload should be empty, shared memory file should be used";
 
-    auto result = LargeParcelableBase::stableLargeParcelableToParcelableVector<GetValueResult>(
-            getValueResults.sharedMemoryFd);
+    auto result = LargeParcelableBase::stableLargeParcelableToParcelable(getValueResults);
     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";
+    ASSERT_EQ(result.value().getObject()->payloads, expectedResults) << "results mismatch";
     EXPECT_EQ(countClients(), static_cast<size_t>(1));
 }
 
@@ -621,11 +614,9 @@
     ASSERT_TRUE(setValueResults.payloads.empty())
             << "payload should be empty, shared memory file should be used";
 
-    auto result = LargeParcelableBase::stableLargeParcelableToParcelableVector<SetValueResult>(
-            setValueResults.sharedMemoryFd);
+    auto result = LargeParcelableBase::stableLargeParcelableToParcelable(setValueResults);
     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";
+    ASSERT_EQ(result.value().getObject()->payloads, expectedResults) << "results mismatch";
     EXPECT_EQ(countClients(), static_cast<size_t>(1));
 }
 
diff --git a/automotive/vehicle/aidl/impl/vhal/test/PendingRequestPoolTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/PendingRequestPoolTest.cpp
new file mode 100644
index 0000000..03d795b
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/vhal/test/PendingRequestPoolTest.cpp
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "PendingRequestPool.h"
+
+#include <VehicleHalTypes.h>
+#include <VehicleUtils.h>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <unordered_set>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+using ::aidl::android::hardware::automotive::vehicle::StatusCode;
+
+using ::testing::ElementsAre;
+using ::testing::UnorderedElementsAre;
+using ::testing::WhenSorted;
+
+class PendingRequestPoolTest : public ::testing::Test {
+  public:
+    void SetUp() override { mPool = std::make_unique<PendingRequestPool>(TEST_TIMEOUT); }
+
+    void TearDown() override {
+        if (mPool != nullptr) {
+            ASSERT_EQ(mPool->countPendingRequests(getTestClientId()), static_cast<size_t>(0))
+                    << "at least one pending request still exists in the pool when finish";
+        }
+    }
+
+    PendingRequestPool* getPool() { return mPool.get(); }
+
+    void destroyPool() { mPool.reset(); }
+
+    int64_t getTimeout() { return TEST_TIMEOUT; }
+
+    void* getTestClientId() { return reinterpret_cast<void*>(0); }
+
+  private:
+    // Test timeout is 0.1s.
+    static const int64_t TEST_TIMEOUT = 100000000;
+
+    std::unique_ptr<PendingRequestPool> mPool;
+};
+
+TEST_F(PendingRequestPoolTest, testFinishAllRequests) {
+    std::mutex lock;
+    std::vector<int64_t> timeoutRequestIds;
+
+    std::unordered_set<int64_t> requestIds;
+    for (int64_t i = 0; i < 10; i++) {
+        requestIds.insert(i);
+    }
+
+    auto callback = std::make_shared<PendingRequestPool::TimeoutCallbackFunc>(
+            [&lock, &timeoutRequestIds](const std::unordered_set<int64_t>& requests) {
+                std::scoped_lock<std::mutex> lockGuard(lock);
+                for (int64_t request : requests) {
+                    timeoutRequestIds.push_back(request);
+                }
+            });
+
+    ASSERT_RESULT_OK(getPool()->addRequests(getTestClientId(), requestIds, callback));
+
+    for (int64_t i = 0; i < 10; i++) {
+        ASSERT_TRUE(getPool()->isRequestPending(getTestClientId(), i));
+    }
+
+    for (int64_t i = 0; i < 10; i++) {
+        ASSERT_THAT(getPool()->tryFinishRequests(getTestClientId(), {i}), UnorderedElementsAre(i));
+    }
+
+    for (int64_t i = 0; i < 10; i++) {
+        ASSERT_FALSE(getPool()->isRequestPending(getTestClientId(), i));
+    }
+}
+
+TEST_F(PendingRequestPoolTest, testFinishHalfOfRequest) {
+    int64_t timeout = getTimeout();
+    std::mutex lock;
+    std::vector<int64_t> timeoutRequestIds;
+
+    std::unordered_set<int64_t> requestIds;
+    for (int64_t i = 0; i < 10; i++) {
+        requestIds.insert(i);
+    }
+
+    auto callback = std::make_shared<PendingRequestPool::TimeoutCallbackFunc>(
+            [&lock, &timeoutRequestIds](const std::unordered_set<int64_t>& requests) {
+                std::scoped_lock<std::mutex> lockGuard(lock);
+                for (int64_t request : requests) {
+                    timeoutRequestIds.push_back(request);
+                }
+            });
+
+    ASSERT_RESULT_OK(getPool()->addRequests(getTestClientId(), requestIds, callback));
+
+    for (int64_t i = 0; i < 10; i++) {
+        ASSERT_TRUE(getPool()->isRequestPending(getTestClientId(), i));
+    }
+
+    // Finish half of the requests.
+    requestIds.clear();
+    for (int64_t i = 0; i < 5; i++) {
+        requestIds.insert(i);
+    }
+
+    ASSERT_EQ(getPool()->tryFinishRequests(getTestClientId(), requestIds), requestIds);
+
+    for (int64_t i = 0; i < 5; i++) {
+        ASSERT_FALSE(getPool()->isRequestPending(getTestClientId(), i));
+    }
+    for (int64_t i = 5; i < 10; i++) {
+        ASSERT_TRUE(getPool()->isRequestPending(getTestClientId(), i));
+    }
+
+    // Wait until the unfinished requests timeout. The check interval is timeout, so at max we
+    // would wait an additional interval, which is 2 * timeout until the callback is called.
+    std::this_thread::sleep_for(2 * std::chrono::nanoseconds(timeout));
+
+    ASSERT_THAT(timeoutRequestIds, WhenSorted(ElementsAre(5, 6, 7, 8, 9)));
+}
+
+TEST_F(PendingRequestPoolTest, testFinishRequestTwice) {
+    std::mutex lock;
+    std::vector<int64_t> timeoutRequestIds;
+
+    auto callback = std::make_shared<PendingRequestPool::TimeoutCallbackFunc>(
+            [&lock, &timeoutRequestIds](const std::unordered_set<int64_t>& requests) {
+                std::scoped_lock<std::mutex> lockGuard(lock);
+                for (int64_t request : requests) {
+                    timeoutRequestIds.push_back(request);
+                }
+            });
+
+    ASSERT_RESULT_OK(getPool()->addRequests(getTestClientId(), {0}, callback));
+
+    ASSERT_THAT(getPool()->tryFinishRequests(getTestClientId(), {0}), UnorderedElementsAre(0))
+            << "failed to finish an added request";
+    ASSERT_TRUE(getPool()->tryFinishRequests(getTestClientId(), {0}).empty())
+            << "finish a request second time must return empty result";
+}
+
+TEST_F(PendingRequestPoolTest, testFinishRequestNonExistingId) {
+    std::mutex lock;
+    std::vector<int64_t> timeoutRequestIds;
+
+    auto callback = std::make_shared<PendingRequestPool::TimeoutCallbackFunc>(
+            [&lock, &timeoutRequestIds](const std::unordered_set<int64_t>& requests) {
+                std::scoped_lock<std::mutex> lockGuard(lock);
+                for (int64_t request : requests) {
+                    timeoutRequestIds.push_back(request);
+                }
+            });
+
+    ASSERT_RESULT_OK(getPool()->addRequests(getTestClientId(), {0, 1, 2}, callback));
+
+    ASSERT_THAT(getPool()->tryFinishRequests(getTestClientId(), {0, 1, 2, 3}),
+                UnorderedElementsAre(0, 1, 2))
+            << "finished request IDs must not contain non-existing request ID";
+    // Even though one of the request to finish does not exist, the rest of the requests should be
+    // finished.
+    ASSERT_EQ(getPool()->countPendingRequests(getTestClientId()), static_cast<size_t>(0))
+            << "requests not being finished correctly";
+}
+
+TEST_F(PendingRequestPoolTest, testFinishAfterTimeout) {
+    std::mutex lock;
+    std::vector<int64_t> timeoutRequestIds;
+
+    auto callback = std::make_shared<PendingRequestPool::TimeoutCallbackFunc>(
+            [&lock, &timeoutRequestIds](const std::unordered_set<int64_t>& requests) {
+                std::scoped_lock<std::mutex> lockGuard(lock);
+                for (int64_t request : requests) {
+                    timeoutRequestIds.push_back(request);
+                }
+            });
+
+    ASSERT_RESULT_OK(getPool()->addRequests(getTestClientId(), {0}, callback));
+
+    std::this_thread::sleep_for(2 * std::chrono::nanoseconds(getTimeout()));
+
+    ASSERT_TRUE(getPool()->tryFinishRequests(getTestClientId(), {0}).empty())
+            << "finish a request after timeout must do nothing";
+}
+
+TEST_F(PendingRequestPoolTest, testDestroyWithPendingRequests) {
+    std::mutex lock;
+    std::vector<int64_t> timeoutRequestIds;
+
+    auto callback = std::make_shared<PendingRequestPool::TimeoutCallbackFunc>(
+            [&lock, &timeoutRequestIds](const std::unordered_set<int64_t>& requests) {
+                std::scoped_lock<std::mutex> lockGuard(lock);
+                for (int64_t request : requests) {
+                    timeoutRequestIds.push_back(request);
+                }
+            });
+
+    ASSERT_RESULT_OK(getPool()->addRequests(getTestClientId(), {0}, callback));
+
+    destroyPool();
+
+    // Before the pool is destroyed, the pending requests should be notified as timeout.
+    ASSERT_THAT(timeoutRequestIds, UnorderedElementsAre(0))
+            << "timeout not triggered when the pool is destroyed";
+}
+
+TEST_F(PendingRequestPoolTest, testDuplicateRequestId) {
+    auto callback = std::make_shared<PendingRequestPool::TimeoutCallbackFunc>(
+            [](std::unordered_set<int64_t>) {});
+
+    ASSERT_RESULT_OK(getPool()->addRequests(getTestClientId(), {0}, callback));
+    ASSERT_FALSE(getPool()->addRequests(getTestClientId(), {1, 2, 0}, callback).ok())
+            << "adding duplicate request IDs must fail";
+
+    ASSERT_THAT(getPool()->tryFinishRequests(getTestClientId(), {0}), UnorderedElementsAre(0));
+}
+
+TEST_F(PendingRequestPoolTest, testSameRequestIdForDifferentClient) {
+    auto callback = std::make_shared<PendingRequestPool::TimeoutCallbackFunc>(
+            [](std::unordered_set<int64_t>) {});
+
+    ASSERT_RESULT_OK(getPool()->addRequests(reinterpret_cast<void*>(0), {0}, callback));
+    ASSERT_RESULT_OK(getPool()->addRequests(reinterpret_cast<void*>(1), {1, 2, 0}, callback));
+
+    ASSERT_THAT(getPool()->tryFinishRequests(reinterpret_cast<void*>(0), {0}),
+                UnorderedElementsAre(0));
+    ASSERT_THAT(getPool()->tryFinishRequests(reinterpret_cast<void*>(1), {1, 2, 0}),
+                UnorderedElementsAre(0, 1, 2));
+}
+
+TEST_F(PendingRequestPoolTest, testPendingRequestCountLimit) {
+    auto callback = std::make_shared<PendingRequestPool::TimeoutCallbackFunc>(
+            [](std::unordered_set<int64_t>) {});
+
+    std::unordered_set<int64_t> requests;
+
+    // MAX_PENDING_REQUEST_PER_CLIENT = 10000
+    for (size_t i = 0; i < 10000; i++) {
+        requests.insert(static_cast<int64_t>(i));
+    }
+    ASSERT_RESULT_OK(getPool()->addRequests(reinterpret_cast<void*>(0), requests, callback));
+
+    auto result = getPool()->addRequests(reinterpret_cast<void*>(0), {static_cast<int64_t>(10000)},
+                                         callback);
+    ASSERT_FALSE(result.ok()) << "adding more pending requests than limit must fail";
+    ASSERT_EQ(result.error().code(), toInt(StatusCode::TRY_AGAIN));
+
+    getPool()->tryFinishRequests(reinterpret_cast<void*>(0), requests);
+}
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl
index 295fde9..3a6461e 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.biometrics.common;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+parcelable OperationContext {
+  int id = 0;
+  android.hardware.biometrics.common.OperationReason reason = android.hardware.biometrics.common.OperationReason.UNKNOWN;
+  boolean isAoD = false;
+  boolean isCrypto = false;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationReason.aidl
similarity index 88%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationReason.aidl
index 295fde9..3da3a6a 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationReason.aidl
@@ -31,12 +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.biometrics.fingerprint;
-@VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+package android.hardware.biometrics.common;
+@Backing(type="byte") @VintfStability
+enum OperationReason {
+  UNKNOWN = 0,
+  BIOMETRIC_PROMPT = 1,
+  KEYGUARD = 2,
 }
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl
new file mode 100644
index 0000000..390e698
--- /dev/null
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.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.biometrics.common;
+
+import android.hardware.biometrics.common.OperationReason;
+
+/**
+ * Additional context associated with an operation.
+ */
+@VintfStability
+parcelable OperationContext {
+    /**
+     * An identifier for the logical action that the user is engaged in. These identifiers are
+     * not guaranteed to be unique. However, the framework will not reuse identifiers within
+     * short periods of time so they can be made unique, if needed, by appending a timestamp.
+     *
+     * Zero if the reason is OperationReason.UNKNOWN.
+     */
+    int id = 0;
+
+    /**
+     * A logical reason for this operation.
+     *
+     * This should be interpreted as a hint to enable optimizations or tracing. The
+     * framework may choose to use OperationReason.UNKNOWN at any time based on the device's
+     * policy.
+     */
+    OperationReason reason = OperationReason.UNKNOWN;
+
+    /* Flag indicating that the display is in AoD mode. */
+    boolean isAoD = false;
+
+    /** Flag indicating that crypto was requested. */
+    boolean isCrypto = false;
+}
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/OperationReason.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/OperationReason.aidl
new file mode 100644
index 0000000..abc25ed
--- /dev/null
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/OperationReason.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.biometrics.common;
+
+@VintfStability
+@Backing(type="byte")
+enum OperationReason {
+    /**
+     * A normal operation without an explicit reason.
+     */
+    UNKNOWN,
+
+    /**
+     * An operation associated with biometric prompt. This may be due to either application or
+     * system use, but it is not related to KEYGUARD device entry.
+     */
+    BIOMETRIC_PROMPT,
+
+    /**
+     * An operation associated with device entry.
+     */
+    KEYGUARD,
+}
diff --git a/biometrics/face/aidl/Android.bp b/biometrics/face/aidl/Android.bp
index 3f53fc8..fff2c1d 100644
--- a/biometrics/face/aidl/Android.bp
+++ b/biometrics/face/aidl/Android.bp
@@ -16,7 +16,7 @@
     imports: [
         "android.hardware.biometrics.common",
         "android.hardware.common-V2",
-        "android.hardware.keymaster",
+        "android.hardware.keymaster-V3",
     ],
     stability: "vintf",
     backend: {
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
index 7817864..4b51bb1 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
@@ -48,4 +48,7 @@
   void invalidateAuthenticatorId();
   void resetLockout(in android.hardware.keymaster.HardwareAuthToken hat);
   void close();
+  android.hardware.biometrics.common.ICancellationSignal authenticateWithContext(in long operationId, in android.hardware.biometrics.common.OperationContext context);
+  android.hardware.biometrics.common.ICancellationSignal enrollWithContext(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in @nullable android.hardware.common.NativeHandle previewSurface, in android.hardware.biometrics.common.OperationContext context);
+  android.hardware.biometrics.common.ICancellationSignal detectInteractionWithContext(in android.hardware.biometrics.common.OperationContext context);
 }
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
index 5f06b40..bbe3632 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
@@ -17,6 +17,7 @@
 package android.hardware.biometrics.face;
 
 import android.hardware.biometrics.common.ICancellationSignal;
+import android.hardware.biometrics.common.OperationContext;
 import android.hardware.biometrics.face.EnrollmentStageConfig;
 import android.hardware.biometrics.face.EnrollmentType;
 import android.hardware.biometrics.face.Feature;
@@ -441,4 +442,23 @@
      *   - ISessionCallback#onSessionClosed
      */
     void close();
+
+    /**
+     * These are alternative methods for some operations to allow the HAL to make optional
+     * optimizations during execution.
+     *
+     * HALs may ignore the additional context and treat all *WithContext methods the same as
+     * the original methods.
+     */
+
+    /* See ISession#authenticateWithContext(long) */
+    ICancellationSignal authenticateWithContext(in long operationId, in OperationContext context);
+
+    /* See ISession#enroll(HardwareAuthToken, EnrollmentType, Feature[], NativeHandle) */
+    ICancellationSignal enrollWithContext(in HardwareAuthToken hat, in EnrollmentType type,
+            in Feature[] features, in @nullable NativeHandle previewSurface,
+            in OperationContext context);
+
+    /* See ISession#detectInteraction() */
+    ICancellationSignal detectInteractionWithContext(in OperationContext context);
 }
diff --git a/biometrics/face/aidl/default/Android.bp b/biometrics/face/aidl/default/Android.bp
index 5092318..7f66eca 100644
--- a/biometrics/face/aidl/default/Android.bp
+++ b/biometrics/face/aidl/default/Android.bp
@@ -16,8 +16,8 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.biometrics.face-V1-ndk",
-        "android.hardware.biometrics.common-V1-ndk",
+        "android.hardware.biometrics.face-V2-ndk",
+        "android.hardware.biometrics.common-V2-ndk",
     ],
     srcs: [
         "main.cpp",
diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp
index 01cb620..9e753e5 100644
--- a/biometrics/face/aidl/default/Session.cpp
+++ b/biometrics/face/aidl/default/Session.cpp
@@ -151,4 +151,25 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus Session::authenticateWithContext(
+        int64_t operationId, const common::OperationContext& /*context*/,
+        std::shared_ptr<common::ICancellationSignal>* out) {
+    return authenticate(operationId, out);
+}
+
+ndk::ScopedAStatus Session::enrollWithContext(const keymaster::HardwareAuthToken& hat,
+                                              EnrollmentType enrollmentType,
+                                              const std::vector<Feature>& features,
+                                              const std::optional<NativeHandle>& previewSurface,
+                                              const common::OperationContext& /*context*/,
+                                              std::shared_ptr<common::ICancellationSignal>* out) {
+    return enroll(hat, enrollmentType, features, previewSurface, out);
+}
+
+ndk::ScopedAStatus Session::detectInteractionWithContext(
+        const common::OperationContext& /*context*/,
+        std::shared_ptr<common::ICancellationSignal>* out) {
+    return detectInteraction(out);
+}
+
 }  // namespace aidl::android::hardware::biometrics::face
diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h
index 4152909..0ce9e20 100644
--- a/biometrics/face/aidl/default/Session.h
+++ b/biometrics/face/aidl/default/Session.h
@@ -68,6 +68,20 @@
 
     ndk::ScopedAStatus close() override;
 
+    ndk::ScopedAStatus authenticateWithContext(
+            int64_t operationId, const common::OperationContext& context,
+            std::shared_ptr<common::ICancellationSignal>* out) override;
+
+    ndk::ScopedAStatus enrollWithContext(
+            const keymaster::HardwareAuthToken& hat, EnrollmentType enrollmentType,
+            const std::vector<Feature>& features, const std::optional<NativeHandle>& previewSurface,
+            const common::OperationContext& context,
+            std::shared_ptr<common::ICancellationSignal>* out) override;
+
+    ndk::ScopedAStatus detectInteractionWithContext(
+            const common::OperationContext& context,
+            std::shared_ptr<common::ICancellationSignal>* out) override;
+
   private:
     std::shared_ptr<ISessionCallback> cb_;
     std::mt19937 mRandom;
diff --git a/biometrics/face/aidl/default/face-default.xml b/biometrics/face/aidl/default/face-default.xml
index 6915ad0..e6ef842 100644
--- a/biometrics/face/aidl/default/face-default.xml
+++ b/biometrics/face/aidl/default/face-default.xml
@@ -1,6 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.biometrics.face</name>
+        <version>2</version>
         <fqname>IFace/default</fqname>
     </hal>
 </manifest>
diff --git a/biometrics/face/aidl/vts/Android.bp b/biometrics/face/aidl/vts/Android.bp
index 09ec4d0..4171ac3 100644
--- a/biometrics/face/aidl/vts/Android.bp
+++ b/biometrics/face/aidl/vts/Android.bp
@@ -15,8 +15,8 @@
     ],
     srcs: ["VtsHalBiometricsFaceTargetTest.cpp"],
     static_libs: [
-        "android.hardware.biometrics.common-V1-ndk",
-        "android.hardware.biometrics.face-V1-ndk",
+        "android.hardware.biometrics.common-V2-ndk",
+        "android.hardware.biometrics.face-V2-ndk",
         "android.hardware.common-V2-ndk",
         "android.hardware.keymaster-V3-ndk",
     ],
diff --git a/biometrics/fingerprint/aidl/Android.bp b/biometrics/fingerprint/aidl/Android.bp
index c46150e..c3a056c 100644
--- a/biometrics/fingerprint/aidl/Android.bp
+++ b/biometrics/fingerprint/aidl/Android.bp
@@ -15,7 +15,7 @@
     ],
     imports: [
         "android.hardware.biometrics.common",
-        "android.hardware.keymaster",
+        "android.hardware.keymaster-V3",
     ],
     stability: "vintf",
     backend: {
@@ -26,8 +26,5 @@
             enabled: false,
         },
     },
-    versions: [
-        "1",
-        "2",
-    ],
+    versions: ["1"],
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/.hash b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/.hash
deleted file mode 100644
index 411cb75..0000000
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/.hash
+++ /dev/null
@@ -1 +0,0 @@
-762eb38ce93ea3c7d39a680949cbdbd2371b3f06
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/ISession.aidl
deleted file mode 100644
index 9934a76..0000000
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/ISession.aidl
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.biometrics.fingerprint;
-@VintfStability
-interface ISession {
-  void generateChallenge();
-  void revokeChallenge(in long challenge);
-  android.hardware.biometrics.common.ICancellationSignal enroll(in android.hardware.keymaster.HardwareAuthToken hat);
-  android.hardware.biometrics.common.ICancellationSignal authenticate(in long operationId);
-  android.hardware.biometrics.common.ICancellationSignal detectInteraction();
-  void enumerateEnrollments();
-  void removeEnrollments(in int[] enrollmentIds);
-  void getAuthenticatorId();
-  void invalidateAuthenticatorId();
-  void resetLockout(in android.hardware.keymaster.HardwareAuthToken hat);
-  void close();
-  void onPointerDown(in int pointerId, in int x, in int y, in float minor, in float major);
-  void onPointerUp(in int pointerId);
-  void onUiReady();
-}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
deleted file mode 100644
index 3c40ad6..0000000
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.biometrics.fingerprint;
-@VintfStability
-interface ISessionCallback {
-  void onChallengeGenerated(in long challenge);
-  void onChallengeRevoked(in long challenge);
-  void onAcquired(in android.hardware.biometrics.fingerprint.AcquiredInfo info, in int vendorCode);
-  void onError(in android.hardware.biometrics.fingerprint.Error error, in int vendorCode);
-  void onEnrollmentProgress(in int enrollmentId, int remaining);
-  void onAuthenticationSucceeded(in int enrollmentId, in android.hardware.keymaster.HardwareAuthToken hat);
-  void onAuthenticationFailed();
-  void onLockoutTimed(in long durationMillis);
-  void onLockoutPermanent();
-  void onLockoutCleared();
-  void onInteractionDetected();
-  void onEnrollmentsEnumerated(in int[] enrollmentIds);
-  void onEnrollmentsRemoved(in int[] enrollmentIds);
-  void onAuthenticatorIdRetrieved(in long authenticatorId);
-  void onAuthenticatorIdInvalidated(in long newAuthenticatorId);
-  void onSessionClosed();
-}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
index 9934a76..4e7b3b4 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
@@ -48,4 +48,9 @@
   void onPointerDown(in int pointerId, in int x, in int y, in float minor, in float major);
   void onPointerUp(in int pointerId);
   void onUiReady();
+  android.hardware.biometrics.common.ICancellationSignal authenticateWithContext(in long operationId, in android.hardware.biometrics.common.OperationContext context);
+  android.hardware.biometrics.common.ICancellationSignal enrollWithContext(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.common.OperationContext context);
+  android.hardware.biometrics.common.ICancellationSignal detectInteractionWithContext(in android.hardware.biometrics.common.OperationContext context);
+  void onPointerDownWithContext(in android.hardware.biometrics.fingerprint.PointerContext context);
+  void onPointerUpWithContext(in android.hardware.biometrics.fingerprint.PointerContext context);
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/PointerContext.aidl
similarity index 91%
rename from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
rename to biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/PointerContext.aidl
index 295fde9..e383330 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/PointerContext.aidl
@@ -33,10 +33,11 @@
 
 package android.hardware.biometrics.fingerprint;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+parcelable PointerContext {
+  int pointerId = 0;
+  int x = 0;
+  int y = 0;
+  float minor = 0.000000f;
+  float major = 0.000000f;
+  boolean isAoD = false;
 }
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
index f1d96d3..ea8c6aa 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
@@ -17,6 +17,8 @@
 package android.hardware.biometrics.fingerprint;
 
 import android.hardware.biometrics.common.ICancellationSignal;
+import android.hardware.biometrics.common.OperationContext;
+import android.hardware.biometrics.fingerprint.PointerContext;
 import android.hardware.keymaster.HardwareAuthToken;
 
 /**
@@ -140,7 +142,7 @@
      *
      * @param hat See above documentation.
      * @return ICancellationSignal An object that can be used by the framework to cancel this
-     * operation.
+     *                             operation.
      */
     ICancellationSignal enroll(in HardwareAuthToken hat);
 
@@ -234,7 +236,7 @@
      *   - ISessionCallback#onAcquired
      *
      * @return ICancellationSignal An object that can be used by the framework to cancel this
-     * operation.
+     *                             operation.
      */
     ICancellationSignal detectInteraction();
 
@@ -448,4 +450,27 @@
      * HAL, the framework will invoke this operation to notify when the illumination is showing.
      */
     void onUiReady();
+
+    /**
+     * These are alternative methods for some operations to allow the HAL to make optional
+     * optimizations during execution.
+     *
+     * HALs may ignore the additional context and treat all *WithContext methods the same as
+     * the original methods.
+     */
+
+    /** See ISession#authenticate(long) */
+    ICancellationSignal authenticateWithContext(in long operationId, in OperationContext context);
+
+    /** See ISession#enroll(HardwareAuthToken) */
+    ICancellationSignal enrollWithContext(in HardwareAuthToken hat, in OperationContext context);
+
+    /** See ISession#detectInteraction() */
+    ICancellationSignal detectInteractionWithContext(in OperationContext context);
+
+    /** See ISession#onPointerDown(int, int, int, float, float) */
+    void onPointerDownWithContext(in PointerContext context);
+
+    /** See ISession#onPointerUp(int) */
+    void onPointerUpWithContext(in PointerContext context);
 }
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/PointerContext.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/PointerContext.aidl
new file mode 100644
index 0000000..4975175
--- /dev/null
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/PointerContext.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.biometrics.fingerprint;
+
+/**
+ * Additional context associated with a pointer event.
+ */
+@VintfStability
+parcelable PointerContext {
+    /* See android.view.MotionEvent#getPointerId. */
+    int pointerId = 0;
+
+    /* The distance in pixels from the left edge of the display. */
+    int x = 0;
+
+    /* The distance in pixels from the top edge of the display. */
+    int y = 0;
+
+    /* See android.view.MotionEvent#getTouchMinor. */
+    float minor = 0f;
+
+    /* See android.view.MotionEvent#getTouchMajor. */
+    float major = 0f;
+
+    /* Flag indicating that the display is in AoD mode. */
+    boolean isAoD = false;
+}
diff --git a/biometrics/fingerprint/aidl/default/Android.bp b/biometrics/fingerprint/aidl/default/Android.bp
index d4194a3..430bf3c 100644
--- a/biometrics/fingerprint/aidl/default/Android.bp
+++ b/biometrics/fingerprint/aidl/default/Android.bp
@@ -25,7 +25,7 @@
         "libbase",
         "libbinder_ndk",
         "android.hardware.biometrics.fingerprint-V2-ndk",
-        "android.hardware.biometrics.common-V1-ndk",
+        "android.hardware.biometrics.common-V2-ndk",
     ],
 }
 
diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp
index ca481e7..8cbcfc7 100644
--- a/biometrics/fingerprint/aidl/default/Session.cpp
+++ b/biometrics/fingerprint/aidl/default/Session.cpp
@@ -244,4 +244,30 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus Session::authenticateWithContext(
+        int64_t operationId, const common::OperationContext& /*context*/,
+        std::shared_ptr<common::ICancellationSignal>* out) {
+    return authenticate(operationId, out);
+}
+
+ndk::ScopedAStatus Session::enrollWithContext(const keymaster::HardwareAuthToken& hat,
+                                              const common::OperationContext& /*context*/,
+                                              std::shared_ptr<common::ICancellationSignal>* out) {
+    return enroll(hat, out);
+}
+
+ndk::ScopedAStatus Session::detectInteractionWithContext(
+        const common::OperationContext& /*context*/,
+        std::shared_ptr<common::ICancellationSignal>* out) {
+    return detectInteraction(out);
+}
+
+ndk::ScopedAStatus Session::onPointerDownWithContext(const PointerContext& context) {
+    return onPointerDown(context.pointerId, context.x, context.y, context.minor, context.major);
+}
+
+ndk::ScopedAStatus Session::onPointerUpWithContext(const PointerContext& context) {
+    return onPointerUp(context.pointerId);
+}
+
 }  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/include/Session.h b/biometrics/fingerprint/aidl/default/include/Session.h
index 9e46422..584cb27 100644
--- a/biometrics/fingerprint/aidl/default/include/Session.h
+++ b/biometrics/fingerprint/aidl/default/include/Session.h
@@ -79,6 +79,22 @@
 
     ndk::ScopedAStatus onUiReady() override;
 
+    ndk::ScopedAStatus authenticateWithContext(
+            int64_t operationId, const common::OperationContext& context,
+            std::shared_ptr<common::ICancellationSignal>* out) override;
+
+    ndk::ScopedAStatus enrollWithContext(
+            const keymaster::HardwareAuthToken& hat, const common::OperationContext& context,
+            std::shared_ptr<common::ICancellationSignal>* out) override;
+
+    ndk::ScopedAStatus detectInteractionWithContext(
+            const common::OperationContext& context,
+            std::shared_ptr<common::ICancellationSignal>* out) override;
+
+    ndk::ScopedAStatus onPointerDownWithContext(const PointerContext& context) override;
+
+    ndk::ScopedAStatus onPointerUpWithContext(const PointerContext& context) override;
+
     bool isClosed();
 
   private:
diff --git a/bluetooth/audio/aidl/Android.bp b/bluetooth/audio/aidl/Android.bp
index 12eed55..5107240 100644
--- a/bluetooth/audio/aidl/Android.bp
+++ b/bluetooth/audio/aidl/Android.bp
@@ -43,6 +43,10 @@
             vndk: {
                 enabled: true,
             },
+            apex_available: [
+                "//apex_available:platform",
+                "com.android.bluetooth",
+            ],
         },
     },
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl
index ad44c26..899b8ca 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl
@@ -34,9 +34,9 @@
 package android.hardware.bluetooth.audio;
 @VintfStability
 parcelable AacCapabilities {
-  android.hardware.bluetooth.audio.AacObjectType objectType;
+  android.hardware.bluetooth.audio.AacObjectType[] objectType;
   int[] sampleRateHz;
-  android.hardware.bluetooth.audio.ChannelMode channelMode;
+  android.hardware.bluetooth.audio.ChannelMode[] channelMode;
   boolean variableBitRateSupported;
   byte[] bitsPerSample;
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl
index c129c66..2148244 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl
@@ -34,8 +34,8 @@
 package android.hardware.bluetooth.audio;
 @Backing(type="byte") @VintfStability
 enum AacObjectType {
-  MPEG2_LC = 1,
-  MPEG4_LC = 2,
-  MPEG4_LTP = 4,
-  MPEG4_SCALABLE = 8,
+  MPEG2_LC = 0,
+  MPEG4_LC = 1,
+  MPEG4_LTP = 2,
+  MPEG4_SCALABLE = 3,
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxCapabilities.aidl
index 4767b69..08a38e2 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxCapabilities.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxCapabilities.aidl
@@ -35,6 +35,6 @@
 @VintfStability
 parcelable AptxCapabilities {
   int[] sampleRateHz;
-  android.hardware.bluetooth.audio.ChannelMode channelMode;
+  android.hardware.bluetooth.audio.ChannelMode[] channelMode;
   byte[] bitsPerSample;
 }
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/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 83%
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 a7224ca..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;
+    @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/ChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl
index 3ca93c3..c3bc741 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl
@@ -34,7 +34,7 @@
 package android.hardware.bluetooth.audio;
 @Backing(type="byte") @VintfStability
 enum ChannelMode {
-  UNKNOWN = 1,
-  MONO = 2,
-  STEREO = 4,
+  UNKNOWN = 0,
+  MONO = 1,
+  STEREO = 2,
 }
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 e5e79cb..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
@@ -38,4 +38,5 @@
   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/LdacCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacCapabilities.aidl
index 19e041a..aa4e4c8 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacCapabilities.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacCapabilities.aidl
@@ -35,7 +35,7 @@
 @VintfStability
 parcelable LdacCapabilities {
   int[] sampleRateHz;
-  android.hardware.bluetooth.audio.LdacChannelMode channelMode;
-  android.hardware.bluetooth.audio.LdacQualityIndex qualityIndex;
+  android.hardware.bluetooth.audio.LdacChannelMode[] channelMode;
+  android.hardware.bluetooth.audio.LdacQualityIndex[] qualityIndex;
   byte[] bitsPerSample;
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl
index a9d6c5e..88d6faf 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl
@@ -34,8 +34,8 @@
 package android.hardware.bluetooth.audio;
 @Backing(type="byte") @VintfStability
 enum LdacChannelMode {
-  UNKNOWN = 1,
-  STEREO = 2,
-  DUAL = 4,
-  MONO = 8,
+  UNKNOWN = 0,
+  STEREO = 1,
+  DUAL = 2,
+  MONO = 3,
 }
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 693392f..35e4358 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 {
-  HIGH = 1,
-  MID = 2,
-  LOW = 4,
-  ABR = 8,
+  HIGH = 0,
+  MID = 1,
+  LOW = 2,
+  ABR = 3,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl
similarity index 81%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl
index 295fde9..9818d54 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.bluetooth.audio;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+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/PcmCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl
index 6cfe5cd..0c2f87d 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/SbcAllocMethod.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
index 5170f16..091f6d7 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
@@ -34,6 +34,6 @@
 package android.hardware.bluetooth.audio;
 @Backing(type="byte") @VintfStability
 enum SbcAllocMethod {
-  ALLOC_MD_S = 1,
-  ALLOC_MD_L = 2,
+  ALLOC_MD_S = 0,
+  ALLOC_MD_L = 1,
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcCapabilities.aidl
index ec3aa0f..c8d7e7e 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcCapabilities.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcCapabilities.aidl
@@ -35,10 +35,10 @@
 @VintfStability
 parcelable SbcCapabilities {
   int[] sampleRateHz;
-  android.hardware.bluetooth.audio.SbcChannelMode channelMode;
+  android.hardware.bluetooth.audio.SbcChannelMode[] channelMode;
   byte[] blockLength;
   byte[] numSubbands;
-  android.hardware.bluetooth.audio.SbcAllocMethod allocMethod;
+  android.hardware.bluetooth.audio.SbcAllocMethod[] allocMethod;
   byte[] bitsPerSample;
   int minBitpool;
   int maxBitpool;
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl
index 88fca4a..6441a99 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl
@@ -34,9 +34,9 @@
 package android.hardware.bluetooth.audio;
 @Backing(type="byte") @VintfStability
 enum SbcChannelMode {
-  UNKNOWN = 1,
-  JOINT_STEREO = 2,
-  STEREO = 4,
-  DUAL = 8,
-  MONO = 16,
+  UNKNOWN = 0,
+  JOINT_STEREO = 1,
+  STEREO = 2,
+  DUAL = 3,
+  MONO = 4,
 }
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 86%
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 a7224ca..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,12 +33,12 @@
 
 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;
@@ -46,6 +46,6 @@
   @VintfStability
   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/AacCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl
index 4303883..c4153e9 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl
@@ -24,11 +24,9 @@
  */
 @VintfStability
 parcelable AacCapabilities {
-    /* bitfield */
-    AacObjectType objectType;
+    AacObjectType[] objectType;
     int[] sampleRateHz;
-    /* bitfield */
-    ChannelMode channelMode;
+    ChannelMode[] channelMode;
     boolean variableBitRateSupported;
     byte[] bitsPerSample;
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacObjectType.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacObjectType.aidl
index 480e422..4e9958c 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacObjectType.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacObjectType.aidl
@@ -22,17 +22,17 @@
     /**
      * MPEG-2 Low Complexity. Support is Mandatory.
      */
-    MPEG2_LC = 1,
+    MPEG2_LC,
     /**
      * MPEG-4 Low Complexity. Support is Optional.
      */
-    MPEG4_LC = 1 << 1,
+    MPEG4_LC,
     /**
      * MPEG-4 Long Term Prediction. Support is Optional.
      */
-    MPEG4_LTP = 1 << 2,
+    MPEG4_LTP,
     /**
      * MPEG-4 Scalable. Support is Optional.
      */
-    MPEG4_SCALABLE = 1 << 3,
+    MPEG4_SCALABLE,
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxCapabilities.aidl
index 6a37fc6..f5605d3 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxCapabilities.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxCapabilities.aidl
@@ -24,7 +24,6 @@
 @VintfStability
 parcelable AptxCapabilities {
     int[] sampleRateHz;
-    /* bitfield */
-    ChannelMode channelMode;
+    ChannelMode[] channelMode;
     byte[] bitsPerSample;
 }
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/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastCapability.aidl
similarity index 69%
copy from bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
copy to bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastCapability.aidl
index 732427f..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;
+        @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;
+    // 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/ChannelMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ChannelMode.aidl
index 2df879d..6613872 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ChannelMode.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ChannelMode.aidl
@@ -19,7 +19,7 @@
 @VintfStability
 @Backing(type="byte")
 enum ChannelMode {
-    UNKNOWN = 1,
-    MONO = 1 << 1,
-    STEREO = 1 << 2,
+    UNKNOWN,
+    MONO,
+    STEREO,
 }
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 a2c5ae9..6f88f30 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
@@ -72,4 +72,14 @@
      * @param status true for SUCCESS or false for FAILURE
      */
     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/LdacCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacCapabilities.aidl
index 44cca7e..1dbec08 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacCapabilities.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacCapabilities.aidl
@@ -26,9 +26,7 @@
 @VintfStability
 parcelable LdacCapabilities {
     int[] sampleRateHz;
-    /* bitfiled */
-    LdacChannelMode channelMode;
-    /* bitfiled */
-    LdacQualityIndex qualityIndex;
+    LdacChannelMode[] channelMode;
+    LdacQualityIndex[] qualityIndex;
     byte[] bitsPerSample;
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl
index 3acca32..3cc910f 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl
@@ -22,8 +22,8 @@
 @VintfStability
 @Backing(type="byte")
 enum LdacChannelMode {
-    UNKNOWN = 1,
-    STEREO = 1 << 1,
-    DUAL = 1 << 2,
-    MONO = 1 << 3,
+    UNKNOWN,
+    STEREO,
+    DUAL,
+    MONO,
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
index cb12583..9993b8b 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
      */
-    HIGH = 1,
+    HIGH,
     /**
      * 660kbps
      */
-    MID = 1 << 1,
+    MID,
     /**
      * 330kbps
      */
-    LOW = 1 << 2,
+    LOW,
     /**
      * Adaptive Bit Rate mode
      */
-    ABR = 1 << 3,
+    ABR,
 }
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/PcmCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl
index f5d699e..776b777 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/SbcAllocMethod.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
index 7047e34..1159f30 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
@@ -22,9 +22,9 @@
     /**
      * SNR
      */
-    ALLOC_MD_S = 1,
+    ALLOC_MD_S,
     /**
      * Loudness
      */
-    ALLOC_MD_L = 1 << 1,
+    ALLOC_MD_L,
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl
index cf62ed4..743a1f7 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl
@@ -25,12 +25,10 @@
 @VintfStability
 parcelable SbcCapabilities {
     int[] sampleRateHz;
-    /* bitfield */
-    SbcChannelMode channelMode;
+    SbcChannelMode[] channelMode;
     byte[] blockLength;
     byte[] numSubbands;
-    /* bitfield */
-    SbcAllocMethod allocMethod;
+    SbcAllocMethod[] allocMethod;
     byte[] bitsPerSample;
     /*
      * range from 2 to 250.
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl
index 7eb38cd..68e3267 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl
@@ -19,9 +19,9 @@
 @VintfStability
 @Backing(type="byte")
 enum SbcChannelMode {
-    UNKNOWN = 1,
-    JOINT_STEREO = 1 << 1,
-    STEREO = 1 << 2,
-    DUAL = 1 << 3,
-    MONO = 1 << 4,
+    UNKNOWN,
+    JOINT_STEREO,
+    STEREO,
+    DUAL,
+    MONO,
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl
similarity index 77%
rename from bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
rename to bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl
index 732427f..cd8a4c1 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl
@@ -22,10 +22,10 @@
 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;
@@ -35,13 +35,11 @@
         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;
+    // The number of connected device
+    int deviceCount;
+    // Supported channel count for each device
+    int channelCountPerDevice;
     LeAudioCodecCapabilities leAudioCodecCapabilities;
 }
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp
new file mode 100644
index 0000000..fc8a911
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BTAudioProviderA2dpHW"
+
+#include "A2dpOffloadAudioProvider.h"
+
+#include <BluetoothAudioCodecs.h>
+#include <BluetoothAudioSessionReport.h>
+#include <android-base/logging.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+A2dpOffloadAudioProvider::A2dpOffloadAudioProvider() {
+  session_type_ = SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH;
+}
+
+bool A2dpOffloadAudioProvider::isValid(const SessionType& session_type) {
+  return (session_type == session_type_);
+}
+
+ndk::ScopedAStatus A2dpOffloadAudioProvider::startSession(
+    const std::shared_ptr<IBluetoothAudioPort>& host_if,
+    const AudioConfiguration& audio_config, DataMQDesc* _aidl_return) {
+  if (audio_config.getTag() != AudioConfiguration::a2dpConfig) {
+    LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
+                 << audio_config.toString();
+    *_aidl_return = DataMQDesc();
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+  }
+  if (!BluetoothAudioCodecs::IsOffloadCodecConfigurationValid(
+          session_type_, audio_config.get<AudioConfiguration::a2dpConfig>())) {
+    LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
+                 << audio_config.toString();
+    *_aidl_return = DataMQDesc();
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+  }
+  return BluetoothAudioProvider::startSession(host_if, audio_config,
+                                              _aidl_return);
+}
+
+ndk::ScopedAStatus A2dpOffloadAudioProvider::onSessionReady(
+    DataMQDesc* _aidl_return) {
+  *_aidl_return = DataMQDesc();
+  BluetoothAudioSessionReport::OnSessionStarted(session_type_, stack_iface_,
+                                                nullptr, *audio_config_);
+  return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
\ No newline at end of file
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h
new file mode 100644
index 0000000..5934f5b
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "BluetoothAudioProvider.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+class A2dpOffloadAudioProvider : public BluetoothAudioProvider {
+ public:
+  A2dpOffloadAudioProvider();
+
+  bool isValid(const SessionType& session_type) override;
+
+  ndk::ScopedAStatus startSession(
+      const std::shared_ptr<IBluetoothAudioPort>& host_if,
+      const AudioConfiguration& audio_config, DataMQDesc* _aidl_return);
+
+ private:
+  ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override;
+};
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.cpp b/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.cpp
new file mode 100644
index 0000000..7e49074
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BTAudioProviderA2dpSW"
+
+#include "A2dpSoftwareAudioProvider.h"
+
+#include <BluetoothAudioCodecs.h>
+#include <BluetoothAudioSessionReport.h>
+#include <android-base/logging.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+// Here the buffer size is based on SBC
+static constexpr uint32_t kPcmFrameSize = 4;  // 16 bits per sample / stereo
+// SBC is 128, and here we choose the LCM of 16, 24, and 32
+static constexpr uint32_t kPcmFrameCount = 96;
+static constexpr uint32_t kRtpFrameSize = kPcmFrameSize * kPcmFrameCount;
+// The max counts by 1 tick (20ms) for SBC is about 7. Since using 96 for the
+// PCM counts, here we just choose a greater number
+static constexpr uint32_t kRtpFrameCount = 10;
+static constexpr uint32_t kBufferSize = kRtpFrameSize * kRtpFrameCount;
+static constexpr uint32_t kBufferCount = 2;  // double buffer
+static constexpr uint32_t kDataMqSize = kBufferSize * kBufferCount;
+
+A2dpSoftwareAudioProvider::A2dpSoftwareAudioProvider()
+    : BluetoothAudioProvider(), data_mq_(nullptr) {
+  LOG(INFO) << __func__ << " - size of audio buffer " << kDataMqSize
+            << " byte(s)";
+  std::unique_ptr<DataMQ> data_mq(
+      new DataMQ(kDataMqSize, /* EventFlag */ true));
+  if (data_mq && data_mq->isValid()) {
+    data_mq_ = std::move(data_mq);
+    session_type_ = SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH;
+  } else {
+    ALOGE_IF(!data_mq, "failed to allocate data MQ");
+    ALOGE_IF(data_mq && !data_mq->isValid(), "data MQ is invalid");
+  }
+}
+
+bool A2dpSoftwareAudioProvider::isValid(const SessionType& sessionType) {
+  return (sessionType == session_type_ && data_mq_ && data_mq_->isValid());
+}
+
+ndk::ScopedAStatus A2dpSoftwareAudioProvider::startSession(
+    const std::shared_ptr<IBluetoothAudioPort>& host_if,
+    const AudioConfiguration& audio_config, DataMQDesc* _aidl_return) {
+  if (audio_config.getTag() != AudioConfiguration::pcmConfig) {
+    LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
+                 << audio_config.toString();
+    *_aidl_return = DataMQDesc();
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+  }
+  const PcmConfiguration& pcm_config =
+      audio_config.get<AudioConfiguration::pcmConfig>();
+  if (!BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid(pcm_config)) {
+    LOG(WARNING) << __func__ << " - Unsupported PCM Configuration="
+                 << pcm_config.toString();
+    *_aidl_return = DataMQDesc();
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+  }
+
+  return BluetoothAudioProvider::startSession(host_if, audio_config,
+                                              _aidl_return);
+}
+
+ndk::ScopedAStatus A2dpSoftwareAudioProvider::onSessionReady(
+    DataMQDesc* _aidl_return) {
+  if (data_mq_ == nullptr || !data_mq_->isValid()) {
+    *_aidl_return = DataMQDesc();
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+  }
+  *_aidl_return = data_mq_->dupeDesc();
+  BluetoothAudioSessionReport::OnSessionStarted(session_type_, stack_iface_,
+                                                _aidl_return, *audio_config_);
+  return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
\ No newline at end of file
diff --git a/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.h b/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.h
new file mode 100644
index 0000000..3bc0a13
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "BluetoothAudioProvider.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+class A2dpSoftwareAudioProvider : public BluetoothAudioProvider {
+ public:
+  A2dpSoftwareAudioProvider();
+
+  bool isValid(const SessionType& sessionType) override;
+
+  ndk::ScopedAStatus startSession(
+      const std::shared_ptr<IBluetoothAudioPort>& host_if,
+      const AudioConfiguration& audio_config, DataMQDesc* _aidl_return);
+
+ private:
+  // audio data queue for software encoding
+  std::unique_ptr<DataMQ> data_mq_;
+
+  ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override;
+};
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/bluetooth/audio/aidl/default/Android.bp b/bluetooth/audio/aidl/default/Android.bp
new file mode 100644
index 0000000..846702f
--- /dev/null
+++ b/bluetooth/audio/aidl/default/Android.bp
@@ -0,0 +1,34 @@
+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_shared {
+    name: "android.hardware.bluetooth.audio-V1-impl",
+    vendor: true,
+    vintf_fragments: ["bluetooth_audio.xml"],
+    srcs: [
+        "BluetoothAudioProvider.cpp",
+        "BluetoothAudioProviderFactory.cpp",
+        "A2dpOffloadAudioProvider.cpp",
+        "A2dpSoftwareAudioProvider.cpp",
+        "HearingAidAudioProvider.cpp",
+        "LeAudioOffloadAudioProvider.cpp",
+        "LeAudioSoftwareAudioProvider.cpp",
+    ],
+    export_include_dirs: ["."],
+    header_libs: ["libhardware_headers"],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "libcutils",
+        "libfmq",
+        "liblog",
+        "android.hardware.bluetooth.audio-V1-ndk",
+        "libbluetooth_audio_session_aidl",
+    ],
+}
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
new file mode 100644
index 0000000..c2ffa2e
--- /dev/null
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
@@ -0,0 +1,138 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "BTAudioProviderStub"
+
+#include "BluetoothAudioProvider.h"
+
+#include <BluetoothAudioSessionReport.h>
+#include <android-base/logging.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+BluetoothAudioProvider::BluetoothAudioProvider() {
+  death_recipient_ = ::ndk::ScopedAIBinder_DeathRecipient(
+      AIBinder_DeathRecipient_new(binderDiedCallbackAidl));
+}
+
+ndk::ScopedAStatus BluetoothAudioProvider::startSession(
+    const std::shared_ptr<IBluetoothAudioPort>& host_if,
+    const AudioConfiguration& audio_config, DataMQDesc* _aidl_return) {
+  if (host_if == nullptr) {
+    *_aidl_return = DataMQDesc();
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+  }
+  audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
+  stack_iface_ = host_if;
+
+  AIBinder_linkToDeath(stack_iface_->asBinder().get(), death_recipient_.get(),
+                       this);
+
+  onSessionReady(_aidl_return);
+  return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BluetoothAudioProvider::endSession() {
+  LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
+
+  if (stack_iface_ != nullptr) {
+    BluetoothAudioSessionReport::OnSessionEnded(session_type_);
+
+    AIBinder_unlinkToDeath(stack_iface_->asBinder().get(),
+                           death_recipient_.get(), this);
+  } else {
+    LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+              << " has NO session";
+  }
+
+  stack_iface_ = nullptr;
+  audio_config_ = nullptr;
+
+  return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BluetoothAudioProvider::streamStarted(
+    BluetoothAudioStatus status) {
+  LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+            << ", status=" << toString(status);
+
+  if (stack_iface_ != nullptr) {
+    BluetoothAudioSessionReport::ReportControlStatus(session_type_, true,
+                                                     status);
+  } else {
+    LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
+                 << ", status=" << toString(status) << " has NO session";
+  }
+
+  return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BluetoothAudioProvider::streamSuspended(
+    BluetoothAudioStatus status) {
+  LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+            << ", status=" << toString(status);
+
+  if (stack_iface_ != nullptr) {
+    BluetoothAudioSessionReport::ReportControlStatus(session_type_, false,
+                                                     status);
+  } else {
+    LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
+                 << ", status=" << toString(status) << " has NO session";
+  }
+  return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BluetoothAudioProvider::updateAudioConfiguration(
+    const AudioConfiguration& audio_config) {
+  LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
+
+  if (stack_iface_ == nullptr || audio_config_ == nullptr) {
+    LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+              << " has NO session";
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+  }
+
+  if (audio_config.getTag() != audio_config_->getTag()) {
+    LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+              << " audio config type is not match";
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+  }
+
+  audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
+  BluetoothAudioSessionReport::ReportAudioConfigChanged(session_type_,
+                                                        *audio_config_);
+  return ndk::ScopedAStatus::ok();
+}
+
+void BluetoothAudioProvider::binderDiedCallbackAidl(void* ptr) {
+  LOG(ERROR) << __func__ << " - BluetoothAudio Service died";
+  auto provider = static_cast<BluetoothAudioProvider*>(ptr);
+  if (provider == nullptr) {
+    LOG(ERROR) << __func__ << ": Null AudioProvider HAL died";
+    return;
+  }
+  provider->endSession();
+}
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
\ No newline at end of file
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
new file mode 100644
index 0000000..f7acbdf
--- /dev/null
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <aidl/android/hardware/bluetooth/audio/BnBluetoothAudioProvider.h>
+#include <aidl/android/hardware/bluetooth/audio/SessionType.h>
+#include <fmq/AidlMessageQueue.h>
+
+using ::aidl::android::hardware::common::fmq::MQDescriptor;
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::android::AidlMessageQueue;
+
+using MqDataType = int8_t;
+using MqDataMode = SynchronizedReadWrite;
+using DataMQ = AidlMessageQueue<MqDataType, MqDataMode>;
+using DataMQDesc = MQDescriptor<MqDataType, MqDataMode>;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+class BluetoothAudioProvider : public BnBluetoothAudioProvider {
+ public:
+  BluetoothAudioProvider();
+
+  ndk::ScopedAStatus startSession(
+      const std::shared_ptr<IBluetoothAudioPort>& host_if,
+      const AudioConfiguration& audio_config, DataMQDesc* _aidl_return);
+  ndk::ScopedAStatus endSession();
+  ndk::ScopedAStatus streamStarted(BluetoothAudioStatus status);
+  ndk::ScopedAStatus streamSuspended(BluetoothAudioStatus status);
+  ndk::ScopedAStatus updateAudioConfiguration(
+      const AudioConfiguration& audio_config);
+
+  virtual bool isValid(const SessionType& sessionType) = 0;
+
+ protected:
+  virtual ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) = 0;
+  static void binderDiedCallbackAidl(void* cookie_ptr);
+
+  ::ndk::ScopedAIBinder_DeathRecipient death_recipient_;
+
+  std::shared_ptr<IBluetoothAudioPort> stack_iface_;
+  std::unique_ptr<AudioConfiguration> audio_config_ = nullptr;
+  SessionType session_type_;
+};
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
\ No newline at end of file
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
new file mode 100644
index 0000000..8e6cee7
--- /dev/null
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "BTAudioProvidersFactory"
+
+#include "BluetoothAudioProviderFactory.h"
+
+#include <BluetoothAudioCodecs.h>
+#include <android-base/logging.h>
+
+#include "A2dpOffloadAudioProvider.h"
+#include "A2dpSoftwareAudioProvider.h"
+#include "BluetoothAudioProvider.h"
+#include "HearingAidAudioProvider.h"
+#include "LeAudioOffloadAudioProvider.h"
+#include "LeAudioSoftwareAudioProvider.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+BluetoothAudioProviderFactory::BluetoothAudioProviderFactory() {}
+
+ndk::ScopedAStatus BluetoothAudioProviderFactory::openProvider(
+    const SessionType session_type,
+    std::shared_ptr<IBluetoothAudioProvider>* _aidl_return) {
+  LOG(INFO) << __func__ << " - SessionType=" << toString(session_type);
+  std::shared_ptr<BluetoothAudioProvider> provider = nullptr;
+
+  switch (session_type) {
+    case SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH:
+      provider = ndk::SharedRefBase::make<A2dpSoftwareAudioProvider>();
+      break;
+    case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
+      provider = ndk::SharedRefBase::make<A2dpOffloadAudioProvider>();
+      break;
+    case SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
+      provider = ndk::SharedRefBase::make<HearingAidAudioProvider>();
+      break;
+    case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
+      provider = ndk::SharedRefBase::make<LeAudioSoftwareOutputAudioProvider>();
+      break;
+    case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
+      provider = ndk::SharedRefBase::make<LeAudioOffloadOutputAudioProvider>();
+      break;
+    case SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH:
+      provider = ndk::SharedRefBase::make<LeAudioSoftwareInputAudioProvider>();
+      break;
+    case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
+      provider = ndk::SharedRefBase::make<LeAudioOffloadInputAudioProvider>();
+      break;
+    default:
+      provider = nullptr;
+      break;
+  }
+
+  if (provider == nullptr || !provider->isValid(session_type)) {
+    provider = nullptr;
+    LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type);
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+  }
+  *_aidl_return = provider;
+
+  return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus BluetoothAudioProviderFactory::getProviderCapabilities(
+    const SessionType session_type,
+    std::vector<AudioCapabilities>* _aidl_return) {
+  if (session_type == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+    auto codec_capabilities =
+        BluetoothAudioCodecs::GetA2dpOffloadCodecCapabilities(session_type);
+    _aidl_return->resize(codec_capabilities.size());
+    for (int i = 0; i < codec_capabilities.size(); i++) {
+      _aidl_return->at(i).set<AudioCapabilities::a2dpCapabilities>(
+          codec_capabilities[i]);
+    }
+  } else if (session_type ==
+                 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+             session_type ==
+                 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+    std::vector<LeAudioCodecCapabilitiesSetting> db_codec_capabilities =
+        BluetoothAudioCodecs::GetLeAudioOffloadCodecCapabilities(session_type);
+    if (db_codec_capabilities.size()) {
+      _aidl_return->resize(db_codec_capabilities.size());
+      for (int i = 0; i < db_codec_capabilities.size(); ++i) {
+        _aidl_return->at(i).set<AudioCapabilities::leAudioCapabilities>(
+            db_codec_capabilities[i]);
+      }
+    }
+  } else if (session_type != SessionType::UNKNOWN) {
+    auto pcm_capabilities = BluetoothAudioCodecs::GetSoftwarePcmCapabilities();
+    _aidl_return->resize(pcm_capabilities.size());
+    for (int i = 0; i < pcm_capabilities.size(); i++) {
+      _aidl_return->at(i).set<AudioCapabilities::pcmCapabilities>(
+          pcm_capabilities[i]);
+    }
+  }
+
+  LOG(INFO) << __func__ << " - SessionType=" << toString(session_type)
+            << " supports " << _aidl_return->size() << " codecs";
+  return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
\ No newline at end of file
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.h b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.h
new file mode 100644
index 0000000..96d888c
--- /dev/null
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/bluetooth/audio/BnBluetoothAudioProviderFactory.h>
+
+#include "A2dpOffloadAudioProvider.h"
+#include "A2dpSoftwareAudioProvider.h"
+#include "BluetoothAudioProvider.h"
+#include "HearingAidAudioProvider.h"
+#include "LeAudioOffloadAudioProvider.h"
+#include "LeAudioSoftwareAudioProvider.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+class BluetoothAudioProviderFactory : public BnBluetoothAudioProviderFactory {
+ public:
+  BluetoothAudioProviderFactory();
+
+  ndk::ScopedAStatus openProvider(
+      const SessionType session_type,
+      std::shared_ptr<IBluetoothAudioProvider>* _aidl_return) override;
+
+  ndk::ScopedAStatus getProviderCapabilities(
+      const SessionType session_type,
+      std::vector<AudioCapabilities>* _aidl_return) override;
+};
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/bluetooth/audio/aidl/default/HearingAidAudioProvider.cpp b/bluetooth/audio/aidl/default/HearingAidAudioProvider.cpp
new file mode 100644
index 0000000..a993059
--- /dev/null
+++ b/bluetooth/audio/aidl/default/HearingAidAudioProvider.cpp
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "BTAudioProviderHearingAid"
+
+#include "HearingAidAudioProvider.h"
+
+#include <BluetoothAudioCodecs.h>
+#include <BluetoothAudioSessionReport.h>
+#include <android-base/logging.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+static constexpr uint32_t kPcmFrameSize = 4;  // 16 bits per sample / stereo
+static constexpr uint32_t kPcmFrameCount = 128;
+static constexpr uint32_t kRtpFrameSize = kPcmFrameSize * kPcmFrameCount;
+static constexpr uint32_t kRtpFrameCount = 7;  // max counts by 1 tick (20ms)
+static constexpr uint32_t kBufferSize = kRtpFrameSize * kRtpFrameCount;
+static constexpr uint32_t kBufferCount = 1;  // single buffer
+static constexpr uint32_t kDataMqSize = kBufferSize * kBufferCount;
+
+HearingAidAudioProvider::HearingAidAudioProvider()
+    : BluetoothAudioProvider(), data_mq_(nullptr) {
+  LOG(INFO) << __func__ << " - size of audio buffer " << kDataMqSize
+            << " byte(s)";
+  std::unique_ptr<DataMQ> data_mq(
+      new DataMQ(kDataMqSize, /* EventFlag */ true));
+  if (data_mq && data_mq->isValid()) {
+    data_mq_ = std::move(data_mq);
+    session_type_ = SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH;
+  } else {
+    ALOGE_IF(!data_mq, "failed to allocate data MQ");
+    ALOGE_IF(data_mq && !data_mq->isValid(), "data MQ is invalid");
+  }
+}
+bool HearingAidAudioProvider::isValid(const SessionType& sessionType) {
+  return (sessionType == session_type_ && data_mq_ && data_mq_->isValid());
+}
+
+ndk::ScopedAStatus HearingAidAudioProvider::startSession(
+    const std::shared_ptr<IBluetoothAudioPort>& host_if,
+    const AudioConfiguration& audio_config, DataMQDesc* _aidl_return) {
+  if (audio_config.getTag() != AudioConfiguration::pcmConfig) {
+    LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
+                 << audio_config.toString();
+    *_aidl_return = DataMQDesc();
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+  }
+  const auto& pcm_config = audio_config.get<AudioConfiguration::pcmConfig>();
+  if (!BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid(pcm_config)) {
+    LOG(WARNING) << __func__ << " - Unsupported PCM Configuration="
+                 << pcm_config.toString();
+    *_aidl_return = DataMQDesc();
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+  }
+
+  return BluetoothAudioProvider::startSession(host_if, audio_config,
+                                              _aidl_return);
+}
+
+ndk::ScopedAStatus HearingAidAudioProvider::onSessionReady(
+    DataMQDesc* _aidl_return) {
+  if (data_mq_ == nullptr || !data_mq_->isValid()) {
+    *_aidl_return = DataMQDesc();
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+  }
+  auto desc = data_mq_->dupeDesc();
+  BluetoothAudioSessionReport::OnSessionStarted(session_type_, stack_iface_,
+                                                &desc, *audio_config_);
+  *_aidl_return = data_mq_->dupeDesc();
+  return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
\ No newline at end of file
diff --git a/bluetooth/audio/aidl/default/HearingAidAudioProvider.h b/bluetooth/audio/aidl/default/HearingAidAudioProvider.h
new file mode 100644
index 0000000..a7e19e9
--- /dev/null
+++ b/bluetooth/audio/aidl/default/HearingAidAudioProvider.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "BluetoothAudioProvider.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+class HearingAidAudioProvider : public BluetoothAudioProvider {
+ public:
+  HearingAidAudioProvider();
+
+  bool isValid(const SessionType& sessionType) override;
+
+  ndk::ScopedAStatus startSession(
+      const std::shared_ptr<IBluetoothAudioPort>& host_if,
+      const AudioConfiguration& audio_config, DataMQDesc* _aidl_return);
+
+ private:
+  // audio data queue for software encoding
+  std::unique_ptr<DataMQ> data_mq_;
+
+  ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override;
+};
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
new file mode 100644
index 0000000..4078783
--- /dev/null
+++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "BTAudioProviderLeAudioSW"
+
+#include "LeAudioOffloadAudioProvider.h"
+
+#include <BluetoothAudioCodecs.h>
+#include <BluetoothAudioSessionReport.h>
+#include <android-base/logging.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+LeAudioOffloadOutputAudioProvider::LeAudioOffloadOutputAudioProvider()
+    : LeAudioOffloadAudioProvider() {
+  session_type_ = SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH;
+}
+
+LeAudioOffloadInputAudioProvider::LeAudioOffloadInputAudioProvider()
+    : LeAudioOffloadAudioProvider() {
+  session_type_ = SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH;
+}
+
+LeAudioOffloadAudioProvider::LeAudioOffloadAudioProvider()
+    : BluetoothAudioProvider() {}
+
+bool LeAudioOffloadAudioProvider::isValid(const SessionType& sessionType) {
+  return (sessionType == session_type_);
+}
+
+ndk::ScopedAStatus LeAudioOffloadAudioProvider::startSession(
+    const std::shared_ptr<IBluetoothAudioPort>& host_if,
+    const AudioConfiguration& audio_config, DataMQDesc* _aidl_return) {
+  if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
+    LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
+                 << audio_config.toString();
+    *_aidl_return = DataMQDesc();
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+  }
+  const auto& le_audio_config =
+      audio_config.get<AudioConfiguration::leAudioConfig>();
+  if (!BluetoothAudioCodecs::IsOffloadLeAudioConfigurationValid(
+          session_type_, le_audio_config)) {
+    LOG(WARNING) << __func__ << " - Unsupported LC3 Offloaded Configuration="
+                 << le_audio_config.toString();
+    *_aidl_return = DataMQDesc();
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+  }
+
+  return BluetoothAudioProvider::startSession(host_if, audio_config,
+                                              _aidl_return);
+}
+
+ndk::ScopedAStatus LeAudioOffloadAudioProvider::onSessionReady(
+    DataMQDesc* _aidl_return) {
+  BluetoothAudioSessionReport::OnSessionStarted(session_type_, stack_iface_,
+                                                nullptr, *audio_config_);
+  *_aidl_return = DataMQDesc();
+  return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
\ No newline at end of file
diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
new file mode 100644
index 0000000..a27a2e7
--- /dev/null
+++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "BluetoothAudioProvider.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+class LeAudioOffloadAudioProvider : public BluetoothAudioProvider {
+ public:
+  LeAudioOffloadAudioProvider();
+
+  bool isValid(const SessionType& sessionType) override;
+
+  ndk::ScopedAStatus startSession(
+      const std::shared_ptr<IBluetoothAudioPort>& host_if,
+      const AudioConfiguration& audio_config, DataMQDesc* _aidl_return);
+
+ private:
+  ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override;
+};
+
+class LeAudioOffloadOutputAudioProvider : public LeAudioOffloadAudioProvider {
+ public:
+  LeAudioOffloadOutputAudioProvider();
+};
+
+class LeAudioOffloadInputAudioProvider : public LeAudioOffloadAudioProvider {
+ public:
+  LeAudioOffloadInputAudioProvider();
+};
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp
new file mode 100644
index 0000000..f9962fd
--- /dev/null
+++ b/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp
@@ -0,0 +1,125 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "BTAudioProviderLeAudioHW"
+
+#include "LeAudioSoftwareAudioProvider.h"
+
+#include <BluetoothAudioCodecs.h>
+#include <BluetoothAudioSessionReport.h>
+#include <android-base/logging.h>
+
+#include <cstdint>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+static constexpr uint32_t kBufferOutCount = 2;  // two frame buffer
+static constexpr uint32_t kBufferInCount = 2;   // two frame buffer
+
+inline uint32_t channel_mode_to_channel_count(ChannelMode channel_mode) {
+  switch (channel_mode) {
+    case ChannelMode::MONO:
+      return 1;
+    case ChannelMode::STEREO:
+      return 2;
+    default:
+      return 0;
+  }
+  return 0;
+}
+
+LeAudioSoftwareOutputAudioProvider::LeAudioSoftwareOutputAudioProvider()
+    : LeAudioSoftwareAudioProvider() {
+  session_type_ = SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH;
+}
+
+LeAudioSoftwareInputAudioProvider::LeAudioSoftwareInputAudioProvider()
+    : LeAudioSoftwareAudioProvider() {
+  session_type_ = SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH;
+}
+
+LeAudioSoftwareAudioProvider::LeAudioSoftwareAudioProvider()
+    : BluetoothAudioProvider(), data_mq_(nullptr) {}
+
+bool LeAudioSoftwareAudioProvider::isValid(const SessionType& sessionType) {
+  return (sessionType == session_type_);
+}
+
+ndk::ScopedAStatus LeAudioSoftwareAudioProvider::startSession(
+    const std::shared_ptr<IBluetoothAudioPort>& host_if,
+    const AudioConfiguration& audio_config, DataMQDesc* _aidl_return) {
+  if (audio_config.getTag() != AudioConfiguration::pcmConfig) {
+    LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
+                 << audio_config.toString();
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+  }
+  const auto& pcm_config = audio_config.get<AudioConfiguration::pcmConfig>();
+  if (!BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid(pcm_config)) {
+    LOG(WARNING) << __func__ << " - Unsupported PCM Configuration="
+                 << pcm_config.toString();
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+  }
+
+  uint32_t buffer_modifier = 0;
+  if (session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH)
+    buffer_modifier = kBufferOutCount;
+  else if (session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH)
+    buffer_modifier = kBufferInCount;
+
+  uint32_t data_mq_size =
+      (ceil(pcm_config.sampleRateHz) / 1000) *
+      channel_mode_to_channel_count(pcm_config.channelMode) *
+      (pcm_config.bitsPerSample / 8) * (pcm_config.dataIntervalUs / 1000) *
+      buffer_modifier;
+
+  LOG(INFO) << __func__ << " - size of audio buffer " << data_mq_size
+            << " byte(s)";
+
+  std::unique_ptr<DataMQ> temp_data_mq(
+      new DataMQ(data_mq_size, /* EventFlag */ true));
+  if (temp_data_mq == nullptr || !temp_data_mq->isValid()) {
+    ALOGE_IF(!temp_data_mq, "failed to allocate data MQ");
+    ALOGE_IF(temp_data_mq && !temp_data_mq->isValid(), "data MQ is invalid");
+    *_aidl_return = DataMQDesc();
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+  }
+  data_mq_ = std::move(temp_data_mq);
+
+  return BluetoothAudioProvider::startSession(host_if, audio_config,
+                                              _aidl_return);
+}
+
+ndk::ScopedAStatus LeAudioSoftwareAudioProvider::onSessionReady(
+    DataMQDesc* _aidl_return) {
+  if (data_mq_ == nullptr || !data_mq_->isValid()) {
+    *_aidl_return = DataMQDesc();
+    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+  }
+  *_aidl_return = data_mq_->dupeDesc();
+  BluetoothAudioSessionReport::OnSessionStarted(session_type_, stack_iface_,
+                                                _aidl_return, *audio_config_);
+  return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
\ No newline at end of file
diff --git a/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.h b/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.h
new file mode 100644
index 0000000..fa58182
--- /dev/null
+++ b/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "BluetoothAudioProvider.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+class LeAudioSoftwareAudioProvider : public BluetoothAudioProvider {
+ public:
+  LeAudioSoftwareAudioProvider();
+
+  bool isValid(const SessionType& sessionType) override;
+
+  ndk::ScopedAStatus startSession(
+      const std::shared_ptr<IBluetoothAudioPort>& host_if,
+      const AudioConfiguration& audio_config, DataMQDesc* _aidl_return);
+
+ private:
+  // audio data queue for software encoding
+  std::unique_ptr<DataMQ> data_mq_;
+
+  ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override;
+};
+
+class LeAudioSoftwareOutputAudioProvider : public LeAudioSoftwareAudioProvider {
+ public:
+  LeAudioSoftwareOutputAudioProvider();
+};
+
+class LeAudioSoftwareInputAudioProvider : public LeAudioSoftwareAudioProvider {
+ public:
+  LeAudioSoftwareInputAudioProvider();
+};
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
\ No newline at end of file
diff --git a/bluetooth/audio/aidl/default/bluetooth_audio.xml b/bluetooth/audio/aidl/default/bluetooth_audio.xml
new file mode 100644
index 0000000..1859a1a
--- /dev/null
+++ b/bluetooth/audio/aidl/default/bluetooth_audio.xml
@@ -0,0 +1,6 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.bluetooth.audio</name>
+        <fqname>IBluetoothAudioProviderFactory/default</fqname>
+    </hal>
+</manifest>
\ No newline at end of file
diff --git a/bluetooth/audio/utils/Android.bp b/bluetooth/audio/utils/Android.bp
index 4f712bf..974357e 100644
--- a/bluetooth/audio/utils/Android.bp
+++ b/bluetooth/audio/utils/Android.bp
@@ -32,5 +32,30 @@
         "libhidlbase",
         "liblog",
         "libutils",
+        "libbluetooth_audio_session_aidl",
+    ],
+}
+
+cc_library_shared {
+    name: "libbluetooth_audio_session_aidl",
+    vendor: true,
+    srcs: [
+        "aidl_session/BluetoothAudioCodecs.cpp",
+        "aidl_session/BluetoothAudioSession.cpp",
+        "aidl_session/HidlToAidlMiddleware.cpp",
+    ],
+    export_include_dirs: ["aidl_session/"],
+    header_libs: ["libhardware_headers"],
+    shared_libs: [
+        "android.hardware.bluetooth.audio@2.0",
+        "android.hardware.bluetooth.audio@2.1",
+        "android.hardware.bluetooth.audio@2.2",
+        "libbase",
+        "libcutils",
+        "libbinder_ndk",
+        "libfmq",
+        "liblog",
+        "android.hardware.bluetooth.audio-V1-ndk",
+        "libhidlbase",
     ],
 }
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
new file mode 100644
index 0000000..92cd0f5
--- /dev/null
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
@@ -0,0 +1,489 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "BTAudioCodecsAidl"
+
+#include "BluetoothAudioCodecs.h"
+
+#include <aidl/android/hardware/bluetooth/audio/AacCapabilities.h>
+#include <aidl/android/hardware/bluetooth/audio/AacObjectType.h>
+#include <aidl/android/hardware/bluetooth/audio/AptxCapabilities.h>
+#include <aidl/android/hardware/bluetooth/audio/ChannelMode.h>
+#include <aidl/android/hardware/bluetooth/audio/LdacCapabilities.h>
+#include <aidl/android/hardware/bluetooth/audio/LdacChannelMode.h>
+#include <aidl/android/hardware/bluetooth/audio/LdacQualityIndex.h>
+#include <aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.h>
+#include <aidl/android/hardware/bluetooth/audio/SbcCapabilities.h>
+#include <aidl/android/hardware/bluetooth/audio/SbcChannelMode.h>
+#include <android-base/logging.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+static const PcmCapabilities kDefaultSoftwarePcmCapabilities = {
+    .sampleRateHz = {16000, 24000, 44100, 48000, 88200, 96000},
+    .channelMode = {ChannelMode::MONO, ChannelMode::STEREO},
+    .bitsPerSample = {16, 24, 32},
+    .dataIntervalUs = {},
+};
+
+static const SbcCapabilities kDefaultOffloadSbcCapability = {
+    .sampleRateHz = {44100},
+    .channelMode = {SbcChannelMode::MONO, SbcChannelMode::JOINT_STEREO},
+    .blockLength = {4, 8, 12, 16},
+    .numSubbands = {8},
+    .allocMethod = {SbcAllocMethod::ALLOC_MD_L},
+    .bitsPerSample = {16},
+    .minBitpool = 2,
+    .maxBitpool = 53};
+
+static const AacCapabilities kDefaultOffloadAacCapability = {
+    .objectType = {AacObjectType::MPEG2_LC},
+    .sampleRateHz = {44100},
+    .channelMode = {ChannelMode::STEREO},
+    .variableBitRateSupported = true,
+    .bitsPerSample = {16}};
+
+static const LdacCapabilities kDefaultOffloadLdacCapability = {
+    .sampleRateHz = {44100, 48000, 88200, 96000},
+    .channelMode = {LdacChannelMode::DUAL, LdacChannelMode::STEREO},
+    .qualityIndex = {LdacQualityIndex::HIGH},
+    .bitsPerSample = {16, 24, 32}};
+
+static const AptxCapabilities kDefaultOffloadAptxCapability = {
+    .sampleRateHz = {44100, 48000},
+    .channelMode = {ChannelMode::STEREO},
+    .bitsPerSample = {16},
+};
+
+static const AptxCapabilities kDefaultOffloadAptxHdCapability = {
+    .sampleRateHz = {44100, 48000},
+    .channelMode = {ChannelMode::STEREO},
+    .bitsPerSample = {24},
+};
+
+static const Lc3Capabilities kDefaultOffloadLc3Capability = {
+    .samplingFrequencyHz = {44100, 48000},
+    .frameDurationUs = {7500, 10000},
+    .channelMode = {ChannelMode::MONO, ChannelMode::STEREO},
+};
+
+const std::vector<CodecCapabilities> kDefaultOffloadA2dpCodecCapabilities = {
+    {.codecType = CodecType::SBC, .capabilities = {}},
+    {.codecType = CodecType::AAC, .capabilities = {}},
+    {.codecType = CodecType::LDAC, .capabilities = {}},
+    {.codecType = CodecType::APTX, .capabilities = {}},
+    {.codecType = CodecType::APTX_HD, .capabilities = {}},
+    {.codecType = CodecType::LC3, .capabilities = {}}};
+
+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 Lc3Capabilities kLc3Capability_16_1 = {
+    .samplingFrequencyHz = {16000},
+    .frameDurationUs = {7500},
+    .octetsPerFrame = {30}};
+
+// Default Supported Codecs
+// LC3 16_2: sample rate: 16 kHz, frame duration: 10 ms, octets per frame: 40
+static const Lc3Capabilities kLc3Capability_16_2 = {
+    .samplingFrequencyHz = {16000},
+    .frameDurationUs = {10000},
+    .octetsPerFrame = {40}};
+
+// Default Supported Codecs
+// LC3 48_4: sample rate: 48 kHz, frame duration: 10 ms, octets per frame: 120
+static const Lc3Capabilities kLc3Capability_48_4 = {
+    .samplingFrequencyHz = {48000},
+    .frameDurationUs = {10000},
+    .octetsPerFrame = {120}};
+
+static const std::vector<Lc3Capabilities> supportedLc3CapabilityList = {
+    kLc3Capability_48_4, kLc3Capability_16_2, kLc3Capability_16_1};
+
+static AudioLocation stereoAudio = static_cast<AudioLocation>(
+    static_cast<uint8_t>(AudioLocation::FRONT_LEFT) |
+    static_cast<uint8_t>(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)};
+
+template <class T>
+bool BluetoothAudioCodecs::ContainedInVector(
+    const std::vector<T>& vector, const typename identity<T>::type& target) {
+  return std::find(vector.begin(), vector.end(), target) != vector.end();
+}
+
+bool BluetoothAudioCodecs::IsOffloadSbcConfigurationValid(
+    const CodecConfiguration::CodecSpecific& codec_specific) {
+  if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::sbcConfig) {
+    LOG(WARNING) << __func__
+                 << ": Invalid CodecSpecific=" << codec_specific.toString();
+    return false;
+  }
+  const SbcConfiguration sbc_data =
+      codec_specific.get<CodecConfiguration::CodecSpecific::sbcConfig>();
+
+  if (ContainedInVector(kDefaultOffloadSbcCapability.sampleRateHz,
+                        sbc_data.sampleRateHz) &&
+      ContainedInVector(kDefaultOffloadSbcCapability.blockLength,
+                        sbc_data.blockLength) &&
+      ContainedInVector(kDefaultOffloadSbcCapability.numSubbands,
+                        sbc_data.numSubbands) &&
+      ContainedInVector(kDefaultOffloadSbcCapability.bitsPerSample,
+                        sbc_data.bitsPerSample) &&
+      ContainedInVector(kDefaultOffloadSbcCapability.channelMode,
+                        sbc_data.channelMode) &&
+      ContainedInVector(kDefaultOffloadSbcCapability.allocMethod,
+                        sbc_data.allocMethod) &&
+      sbc_data.minBitpool <= sbc_data.maxBitpool &&
+      kDefaultOffloadSbcCapability.minBitpool <= sbc_data.minBitpool &&
+      kDefaultOffloadSbcCapability.maxBitpool >= sbc_data.maxBitpool) {
+    return true;
+  }
+  LOG(WARNING) << __func__
+               << ": Unsupported CodecSpecific=" << codec_specific.toString();
+  return false;
+}
+
+bool BluetoothAudioCodecs::IsOffloadAacConfigurationValid(
+    const CodecConfiguration::CodecSpecific& codec_specific) {
+  if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::aacConfig) {
+    LOG(WARNING) << __func__
+                 << ": Invalid CodecSpecific=" << codec_specific.toString();
+    return false;
+  }
+  const AacConfiguration aac_data =
+      codec_specific.get<CodecConfiguration::CodecSpecific::aacConfig>();
+
+  if (ContainedInVector(kDefaultOffloadAacCapability.sampleRateHz,
+                        aac_data.sampleRateHz) &&
+      ContainedInVector(kDefaultOffloadAacCapability.bitsPerSample,
+                        aac_data.bitsPerSample) &&
+      ContainedInVector(kDefaultOffloadAacCapability.channelMode,
+                        aac_data.channelMode) &&
+      ContainedInVector(kDefaultOffloadAacCapability.objectType,
+                        aac_data.objectType) &&
+      (!aac_data.variableBitRateEnabled ||
+       kDefaultOffloadAacCapability.variableBitRateSupported)) {
+    return true;
+  }
+  LOG(WARNING) << __func__
+               << ": Unsupported CodecSpecific=" << codec_specific.toString();
+  return false;
+}
+
+bool BluetoothAudioCodecs::IsOffloadLdacConfigurationValid(
+    const CodecConfiguration::CodecSpecific& codec_specific) {
+  if (codec_specific.getTag() !=
+      CodecConfiguration::CodecSpecific::ldacConfig) {
+    LOG(WARNING) << __func__
+                 << ": Invalid CodecSpecific=" << codec_specific.toString();
+    return false;
+  }
+  const LdacConfiguration ldac_data =
+      codec_specific.get<CodecConfiguration::CodecSpecific::ldacConfig>();
+
+  if (ContainedInVector(kDefaultOffloadLdacCapability.sampleRateHz,
+                        ldac_data.sampleRateHz) &&
+      ContainedInVector(kDefaultOffloadLdacCapability.bitsPerSample,
+                        ldac_data.bitsPerSample) &&
+      ContainedInVector(kDefaultOffloadLdacCapability.channelMode,
+                        ldac_data.channelMode) &&
+      ContainedInVector(kDefaultOffloadLdacCapability.qualityIndex,
+                        ldac_data.qualityIndex)) {
+    return true;
+  }
+  LOG(WARNING) << __func__
+               << ": Unsupported CodecSpecific=" << codec_specific.toString();
+  return false;
+}
+
+bool BluetoothAudioCodecs::IsOffloadAptxConfigurationValid(
+    const CodecConfiguration::CodecSpecific& codec_specific) {
+  if (codec_specific.getTag() !=
+      CodecConfiguration::CodecSpecific::aptxConfig) {
+    LOG(WARNING) << __func__
+                 << ": Invalid CodecSpecific=" << codec_specific.toString();
+    return false;
+  }
+  const AptxConfiguration aptx_data =
+      codec_specific.get<CodecConfiguration::CodecSpecific::aptxConfig>();
+
+  if (ContainedInVector(kDefaultOffloadAptxCapability.sampleRateHz,
+                        aptx_data.sampleRateHz) &&
+      ContainedInVector(kDefaultOffloadAptxCapability.bitsPerSample,
+                        aptx_data.bitsPerSample) &&
+      ContainedInVector(kDefaultOffloadAptxCapability.channelMode,
+                        aptx_data.channelMode)) {
+    return true;
+  }
+  LOG(WARNING) << __func__
+               << ": Unsupported CodecSpecific=" << codec_specific.toString();
+  return false;
+}
+
+bool BluetoothAudioCodecs::IsOffloadAptxHdConfigurationValid(
+    const CodecConfiguration::CodecSpecific& codec_specific) {
+  if (codec_specific.getTag() !=
+      CodecConfiguration::CodecSpecific::aptxConfig) {
+    LOG(WARNING) << __func__
+                 << ": Invalid CodecSpecific=" << codec_specific.toString();
+    return false;
+  }
+  const AptxConfiguration aptx_data =
+      codec_specific.get<CodecConfiguration::CodecSpecific::aptxConfig>();
+
+  if (ContainedInVector(kDefaultOffloadAptxHdCapability.sampleRateHz,
+                        aptx_data.sampleRateHz) &&
+      ContainedInVector(kDefaultOffloadAptxHdCapability.bitsPerSample,
+                        aptx_data.bitsPerSample) &&
+      ContainedInVector(kDefaultOffloadAptxHdCapability.channelMode,
+                        aptx_data.channelMode)) {
+    return true;
+  }
+  LOG(WARNING) << __func__
+               << ": Unsupported CodecSpecific=" << codec_specific.toString();
+  return false;
+}
+
+bool BluetoothAudioCodecs::IsOffloadLc3ConfigurationValid(
+    const CodecConfiguration::CodecSpecific& codec_specific) {
+  if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::lc3Config) {
+    LOG(WARNING) << __func__
+                 << ": Invalid CodecSpecific=" << codec_specific.toString();
+    return false;
+  }
+  const Lc3Configuration lc3_data =
+      codec_specific.get<CodecConfiguration::CodecSpecific::lc3Config>();
+
+  if (ContainedInVector(kDefaultOffloadLc3Capability.samplingFrequencyHz,
+                        lc3_data.samplingFrequencyHz) &&
+      ContainedInVector(kDefaultOffloadLc3Capability.frameDurationUs,
+                        lc3_data.frameDurationUs) &&
+      ContainedInVector(kDefaultOffloadLc3Capability.channelMode,
+                        lc3_data.channelMode)) {
+    return true;
+  }
+  LOG(WARNING) << __func__
+               << ": Unsupported CodecSpecific=" << codec_specific.toString();
+  return false;
+}
+
+bool BluetoothAudioCodecs::IsOffloadLeAudioConfigurationValid(
+    const SessionType& session_type, const LeAudioConfiguration&) {
+  if (session_type !=
+          SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
+      session_type !=
+          SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+    return false;
+  }
+  return true;
+}
+
+std::vector<PcmCapabilities>
+BluetoothAudioCodecs::GetSoftwarePcmCapabilities() {
+  return {kDefaultSoftwarePcmCapabilities};
+}
+
+std::vector<CodecCapabilities>
+BluetoothAudioCodecs::GetA2dpOffloadCodecCapabilities(
+    const SessionType& session_type) {
+  if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+    return {};
+  }
+  std::vector<CodecCapabilities> offload_a2dp_codec_capabilities =
+      kDefaultOffloadA2dpCodecCapabilities;
+  for (auto& codec_capability : offload_a2dp_codec_capabilities) {
+    switch (codec_capability.codecType) {
+      case CodecType::SBC:
+        codec_capability.capabilities
+            .set<CodecCapabilities::Capabilities::sbcCapabilities>(
+                kDefaultOffloadSbcCapability);
+        break;
+      case CodecType::AAC:
+        codec_capability.capabilities
+            .set<CodecCapabilities::Capabilities::aacCapabilities>(
+                kDefaultOffloadAacCapability);
+        break;
+      case CodecType::LDAC:
+        codec_capability.capabilities
+            .set<CodecCapabilities::Capabilities::ldacCapabilities>(
+                kDefaultOffloadLdacCapability);
+        break;
+      case CodecType::APTX:
+        codec_capability.capabilities
+            .set<CodecCapabilities::Capabilities::aptxCapabilities>(
+                kDefaultOffloadAptxCapability);
+        break;
+      case CodecType::APTX_HD:
+        codec_capability.capabilities
+            .set<CodecCapabilities::Capabilities::aptxCapabilities>(
+                kDefaultOffloadAptxHdCapability);
+        break;
+      case CodecType::LC3:
+        codec_capability.capabilities
+            .set<CodecCapabilities::Capabilities::lc3Capabilities>(
+                kDefaultOffloadLc3Capability);
+        break;
+      case CodecType::UNKNOWN:
+        codec_capability = {};
+        break;
+    }
+  }
+  return offload_a2dp_codec_capabilities;
+}
+
+bool BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid(
+    const PcmConfiguration& pcm_config) {
+  if (ContainedInVector(kDefaultSoftwarePcmCapabilities.sampleRateHz,
+                        pcm_config.sampleRateHz) &&
+      ContainedInVector(kDefaultSoftwarePcmCapabilities.bitsPerSample,
+                        pcm_config.bitsPerSample) &&
+      ContainedInVector(kDefaultSoftwarePcmCapabilities.channelMode,
+                        pcm_config.channelMode)
+      // data interval is not checked for now
+      // && pcm_config.dataIntervalUs != 0
+  ) {
+    return true;
+  }
+  LOG(WARNING) << __func__
+               << ": Unsupported CodecSpecific=" << pcm_config.toString();
+  return false;
+}
+
+bool BluetoothAudioCodecs::IsOffloadCodecConfigurationValid(
+    const SessionType& session_type, const CodecConfiguration& codec_config) {
+  if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+    LOG(ERROR) << __func__
+               << ": Invalid SessionType=" << toString(session_type);
+    return false;
+  }
+  const CodecConfiguration::CodecSpecific& codec_specific = codec_config.config;
+  switch (codec_config.codecType) {
+    case CodecType::SBC:
+      if (IsOffloadSbcConfigurationValid(codec_specific)) {
+        return true;
+      }
+      break;
+    case CodecType::AAC:
+      if (IsOffloadAacConfigurationValid(codec_specific)) {
+        return true;
+      }
+      break;
+    case CodecType::LDAC:
+      if (IsOffloadLdacConfigurationValid(codec_specific)) {
+        return true;
+      }
+      break;
+    case CodecType::APTX:
+      if (IsOffloadAptxConfigurationValid(codec_specific)) {
+        return true;
+      }
+      break;
+    case CodecType::APTX_HD:
+      if (IsOffloadAptxHdConfigurationValid(codec_specific)) {
+        return true;
+      }
+      break;
+    case CodecType::LC3:
+      if (IsOffloadLc3ConfigurationValid(codec_specific)) {
+        return true;
+      }
+      break;
+    case CodecType::UNKNOWN:
+      break;
+  }
+  return false;
+}
+
+UnicastCapability composeUnicastLc3Capability(
+    AudioLocation audioLocation, uint8_t deviceCnt, uint8_t channelCount,
+    const Lc3Capabilities& capability) {
+  return {
+      .codecType = CodecType::LC3,
+      .supportedChannel = audioLocation,
+      .deviceCount = deviceCnt,
+      .channelCountPerDevice = channelCount,
+      .leAudioCodecCapabilities =
+          UnicastCapability::LeAudioCodecCapabilities(capability),
+  };
+}
+
+std::vector<LeAudioCodecCapabilitiesSetting>
+BluetoothAudioCodecs::GetLeAudioOffloadCodecCapabilities(
+    const SessionType& session_type) {
+  if (session_type !=
+          SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
+      session_type !=
+          SessionType::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 hardware
+}  // namespace android
+}  // namespace aidl
\ No newline at end of file
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h
new file mode 100644
index 0000000..c542ce5
--- /dev/null
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/bluetooth/audio/CodecCapabilities.h>
+#include <aidl/android/hardware/bluetooth/audio/CodecConfiguration.h>
+#include <aidl/android/hardware/bluetooth/audio/Lc3Configuration.h>
+#include <aidl/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.h>
+#include <aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.h>
+#include <aidl/android/hardware/bluetooth/audio/PcmCapabilities.h>
+#include <aidl/android/hardware/bluetooth/audio/PcmConfiguration.h>
+#include <aidl/android/hardware/bluetooth/audio/SessionType.h>
+
+#include <vector>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+class BluetoothAudioCodecs {
+ public:
+  static std::vector<PcmCapabilities> GetSoftwarePcmCapabilities();
+  static std::vector<CodecCapabilities> GetA2dpOffloadCodecCapabilities(
+      const SessionType& session_type);
+
+  static bool IsSoftwarePcmConfigurationValid(
+      const PcmConfiguration& pcm_config);
+  static bool IsOffloadCodecConfigurationValid(
+      const SessionType& session_type, const CodecConfiguration& codec_config);
+
+  static bool IsOffloadLeAudioConfigurationValid(
+      const SessionType& session_type, const Lc3Configuration& codec_config);
+
+  static bool IsOffloadLeAudioConfigurationValid(
+      const SessionType& session_type,
+      const LeAudioConfiguration& codec_config);
+
+  static std::vector<LeAudioCodecCapabilitiesSetting>
+  GetLeAudioOffloadCodecCapabilities(const SessionType& session_type);
+
+ private:
+  template <typename T>
+  struct identity {
+    typedef T type;
+  };
+  template <class T>
+  static bool ContainedInVector(const std::vector<T>& vector,
+                                const typename identity<T>::type& target);
+  template <class T>
+  static bool ContainedInBitmask(const T& bitmask, const T& target);
+  static bool IsSingleBit(uint32_t bitmasks, uint32_t bitfield);
+  static bool IsOffloadSbcConfigurationValid(
+      const CodecConfiguration::CodecSpecific& codec_specific);
+  static bool IsOffloadAacConfigurationValid(
+      const CodecConfiguration::CodecSpecific& codec_specific);
+  static bool IsOffloadLdacConfigurationValid(
+      const CodecConfiguration::CodecSpecific& codec_specific);
+  static bool IsOffloadAptxConfigurationValid(
+      const CodecConfiguration::CodecSpecific& codec_specific);
+  static bool IsOffloadAptxHdConfigurationValid(
+      const CodecConfiguration::CodecSpecific& codec_specific);
+  static bool IsOffloadLc3ConfigurationValid(
+      const CodecConfiguration::CodecSpecific& codec_specific);
+  static bool IsOffloadLeAudioConfigurationValid(
+      const SessionType& session_type, const LeAudioCodecConfiguration&);
+};
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
new file mode 100644
index 0000000..95e473e
--- /dev/null
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
@@ -0,0 +1,581 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/types.h>
+#define LOG_TAG "BTAudioSessionAidl"
+
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+#include <android/binder_manager.h>
+
+#include "BluetoothAudioSession.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+static constexpr int kFmqSendTimeoutMs = 1000;  // 1000 ms timeout for sending
+static constexpr int kFmqReceiveTimeoutMs =
+    1000;                               // 1000 ms timeout for receiving
+static constexpr int kWritePollMs = 1;  // polled non-blocking interval
+static constexpr int kReadPollMs = 1;   // polled non-blocking interval
+
+const CodecConfiguration BluetoothAudioSession::kInvalidCodecConfiguration = {};
+const LeAudioConfiguration kInvalidLeAudioConfiguration = {};
+AudioConfiguration BluetoothAudioSession::invalidSoftwareAudioConfiguration =
+    {};
+AudioConfiguration BluetoothAudioSession::invalidOffloadAudioConfiguration = {};
+AudioConfiguration BluetoothAudioSession::invalidLeOffloadAudioConfig = {};
+
+BluetoothAudioSession::BluetoothAudioSession(const SessionType& session_type)
+    : session_type_(session_type), stack_iface_(nullptr), data_mq_(nullptr) {
+  invalidSoftwareAudioConfiguration.set<AudioConfiguration::pcmConfig>(
+      kInvalidPcmConfiguration);
+  invalidOffloadAudioConfiguration.set<AudioConfiguration::a2dpConfig>(
+      kInvalidCodecConfiguration);
+  invalidLeOffloadAudioConfig.set<AudioConfiguration::leAudioConfig>(
+      kInvalidLeAudioConfiguration);
+}
+
+/***
+ *
+ * Callback methods
+ *
+ ***/
+
+void BluetoothAudioSession::OnSessionStarted(
+    const std::shared_ptr<IBluetoothAudioPort> stack_iface,
+    const DataMQDesc* mq_desc, const AudioConfiguration& audio_config) {
+  std::lock_guard<std::recursive_mutex> guard(mutex_);
+  if (stack_iface == nullptr) {
+    LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
+               << ", IBluetoothAudioPort Invalid";
+  } else if (!UpdateAudioConfig(audio_config)) {
+    LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
+               << ", AudioConfiguration=" << audio_config.toString()
+               << " Invalid";
+  } else if (!UpdateDataPath(mq_desc)) {
+    LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
+               << " MqDescriptor Invalid";
+    if (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+      audio_config_ = std::make_unique<AudioConfiguration>(
+          invalidOffloadAudioConfiguration);
+    } else {
+      audio_config_ = std::make_unique<AudioConfiguration>(
+          invalidSoftwareAudioConfiguration);
+    }
+  } else {
+    stack_iface_ = stack_iface;
+    LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+              << ", AudioConfiguration=" << audio_config.toString();
+    ReportSessionStatus();
+  }
+}
+
+void BluetoothAudioSession::OnSessionEnded() {
+  std::lock_guard<std::recursive_mutex> guard(mutex_);
+  bool toggled = IsSessionReady();
+  LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
+  if (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+    audio_config_ =
+        std::make_unique<AudioConfiguration>(invalidOffloadAudioConfiguration);
+  } else {
+    audio_config_ =
+        std::make_unique<AudioConfiguration>(invalidSoftwareAudioConfiguration);
+  }
+  stack_iface_ = nullptr;
+  UpdateDataPath(nullptr);
+  if (toggled) {
+    ReportSessionStatus();
+  }
+}
+
+/***
+ *
+ * Util methods
+ *
+ ***/
+
+const AudioConfiguration& BluetoothAudioSession::GetAudioConfig() {
+  std::lock_guard<std::recursive_mutex> guard(mutex_);
+  if (!IsSessionReady()) {
+    if (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+      return invalidOffloadAudioConfiguration;
+    } else {
+      return invalidSoftwareAudioConfiguration;
+    }
+    switch (session_type_) {
+      case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
+        return invalidOffloadAudioConfiguration;
+      case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
+      case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
+        return invalidLeOffloadAudioConfig;
+      default:
+        return invalidSoftwareAudioConfiguration;
+    }
+  }
+  return *audio_config_;
+}
+
+void BluetoothAudioSession::ReportAudioConfigChanged(
+    const AudioConfiguration& audio_config) {
+  if (session_type_ !=
+          SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
+      session_type_ !=
+          SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+    return;
+  }
+  std::lock_guard<std::recursive_mutex> guard(mutex_);
+  audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
+  if (observers_.empty()) {
+    LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
+                 << " has NO port state observer";
+    return;
+  }
+  for (auto& observer : observers_) {
+    uint16_t cookie = observer.first;
+    std::shared_ptr<struct PortStatusCallbacks> cb = observer.second;
+    LOG(INFO) << __func__ << " for SessionType=" << toString(session_type_)
+              << ", bluetooth_audio=0x"
+              << ::android::base::StringPrintf("%04x", cookie);
+    if (cb->audio_configuration_changed_cb_ != nullptr) {
+      cb->audio_configuration_changed_cb_(cookie);
+    }
+  }
+}
+
+bool BluetoothAudioSession::IsSessionReady() {
+  std::lock_guard<std::recursive_mutex> guard(mutex_);
+
+  bool is_mq_valid =
+      (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+       session_type_ ==
+           SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+       session_type_ ==
+           SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
+       (data_mq_ != nullptr && data_mq_->isValid()));
+  return stack_iface_ != nullptr && is_mq_valid;
+}
+
+/***
+ *
+ * Status callback methods
+ *
+ ***/
+
+uint16_t BluetoothAudioSession::RegisterStatusCback(
+    const PortStatusCallbacks& callbacks) {
+  std::lock_guard<std::recursive_mutex> guard(mutex_);
+  uint16_t cookie = ObserversCookieGetInitValue(session_type_);
+  uint16_t cookie_upper_bound = ObserversCookieGetUpperBound(session_type_);
+
+  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_)
+               << " has " << observers_.size()
+               << " observers already (No Resource)";
+    return kObserversCookieUndefined;
+  }
+  std::shared_ptr<PortStatusCallbacks> cb =
+      std::make_shared<PortStatusCallbacks>();
+  *cb = callbacks;
+  observers_[cookie] = cb;
+  return cookie;
+}
+
+void BluetoothAudioSession::UnregisterStatusCback(uint16_t cookie) {
+  std::lock_guard<std::recursive_mutex> guard(mutex_);
+  if (observers_.erase(cookie) != 1) {
+    LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
+                 << " no such provider=0x"
+                 << ::android::base::StringPrintf("%04x", cookie);
+  }
+}
+
+/***
+ *
+ * Stream methods
+ *
+ ***/
+
+bool BluetoothAudioSession::StartStream() {
+  std::lock_guard<std::recursive_mutex> guard(mutex_);
+  if (!IsSessionReady()) {
+    LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
+               << " has NO session";
+    return false;
+  }
+  auto hal_retval = stack_iface_->startStream();
+  if (!hal_retval.isOk()) {
+    LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
+                 << toString(session_type_) << " failed";
+    return false;
+  }
+  return true;
+}
+
+bool BluetoothAudioSession::SuspendStream() {
+  std::lock_guard<std::recursive_mutex> guard(mutex_);
+  if (!IsSessionReady()) {
+    LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
+               << " has NO session";
+    return false;
+  }
+  auto hal_retval = stack_iface_->suspendStream();
+  if (!hal_retval.isOk()) {
+    LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
+                 << toString(session_type_) << " failed";
+    return false;
+  }
+  return true;
+}
+
+void BluetoothAudioSession::StopStream() {
+  std::lock_guard<std::recursive_mutex> guard(mutex_);
+  if (!IsSessionReady()) {
+    return;
+  }
+  auto hal_retval = stack_iface_->stopStream();
+  if (!hal_retval.isOk()) {
+    LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
+                 << toString(session_type_) << " failed";
+  }
+}
+
+/***
+ *
+ * Private methods
+ *
+ ***/
+
+bool BluetoothAudioSession::UpdateDataPath(const DataMQDesc* mq_desc) {
+  if (mq_desc == nullptr) {
+    // usecase of reset by nullptr
+    data_mq_ = nullptr;
+    return true;
+  }
+  std::unique_ptr<DataMQ> temp_mq;
+  temp_mq.reset(new DataMQ(*mq_desc));
+  if (!temp_mq || !temp_mq->isValid()) {
+    data_mq_ = nullptr;
+    return false;
+  }
+  data_mq_ = std::move(temp_mq);
+  return true;
+}
+
+bool BluetoothAudioSession::UpdateAudioConfig(
+    const AudioConfiguration& audio_config) {
+  bool is_software_session =
+      (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
+       session_type_ == SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH ||
+       session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH ||
+       session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
+  bool is_offload_a2dp_session =
+      (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
+  bool is_offload_le_audio_session =
+      (session_type_ ==
+           SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+       session_type_ ==
+           SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
+  auto audio_config_tag = audio_config.getTag();
+  bool is_software_audio_config =
+      (is_software_session &&
+       audio_config_tag == AudioConfiguration::pcmConfig);
+  bool is_a2dp_offload_audio_config =
+      (is_offload_a2dp_session &&
+       audio_config_tag == AudioConfiguration::a2dpConfig);
+  bool is_le_audio_offload_audio_config =
+      (is_offload_le_audio_session &&
+       audio_config_tag == AudioConfiguration::leAudioConfig);
+  if (!is_software_audio_config && !is_a2dp_offload_audio_config &&
+      !is_le_audio_offload_audio_config) {
+    return false;
+  }
+  audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
+  return true;
+}
+
+void BluetoothAudioSession::ReportSessionStatus() {
+  // This is locked already by OnSessionStarted / OnSessionEnded
+  if (observers_.empty()) {
+    LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+              << " has NO port state observer";
+    return;
+  }
+  for (auto& observer : observers_) {
+    uint16_t cookie = observer.first;
+    std::shared_ptr<PortStatusCallbacks> callback = observer.second;
+    LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+              << " notify to bluetooth_audio=0x"
+              << ::android::base::StringPrintf("%04x", cookie);
+    callback->session_changed_cb_(cookie);
+  }
+}
+
+/***
+ *
+ * PCM methods
+ *
+ ***/
+
+size_t BluetoothAudioSession::OutWritePcmData(const void* buffer,
+                                              size_t bytes) {
+  if (buffer == nullptr || bytes <= 0) {
+    return 0;
+  }
+  size_t total_written = 0;
+  int timeout_ms = kFmqSendTimeoutMs;
+  do {
+    std::unique_lock<std::recursive_mutex> lock(mutex_);
+    if (!IsSessionReady()) {
+      break;
+    }
+    size_t num_bytes_to_write = data_mq_->availableToWrite();
+    if (num_bytes_to_write) {
+      if (num_bytes_to_write > (bytes - total_written)) {
+        num_bytes_to_write = bytes - total_written;
+      }
+
+      if (!data_mq_->write(
+              static_cast<const MQDataType*>(buffer) + total_written,
+              num_bytes_to_write)) {
+        LOG(ERROR) << "FMQ datapath writing " << total_written << "/" << bytes
+                   << " failed";
+        return total_written;
+      }
+      total_written += num_bytes_to_write;
+    } else if (timeout_ms >= kWritePollMs) {
+      lock.unlock();
+      usleep(kWritePollMs * 1000);
+      timeout_ms -= kWritePollMs;
+    } else {
+      LOG(DEBUG) << "Data " << total_written << "/" << bytes << " overflow "
+                 << (kFmqSendTimeoutMs - timeout_ms) << " ms";
+      return total_written;
+    }
+  } while (total_written < bytes);
+  return total_written;
+}
+
+size_t BluetoothAudioSession::InReadPcmData(void* buffer, size_t bytes) {
+  if (buffer == nullptr || bytes <= 0) {
+    return 0;
+  }
+  size_t total_read = 0;
+  int timeout_ms = kFmqReceiveTimeoutMs;
+  do {
+    std::unique_lock<std::recursive_mutex> lock(mutex_);
+    if (!IsSessionReady()) {
+      break;
+    }
+    size_t num_bytes_to_read = data_mq_->availableToRead();
+    if (num_bytes_to_read) {
+      if (num_bytes_to_read > (bytes - total_read)) {
+        num_bytes_to_read = bytes - total_read;
+      }
+      if (!data_mq_->read(static_cast<MQDataType*>(buffer) + total_read,
+                          num_bytes_to_read)) {
+        LOG(ERROR) << "FMQ datapath reading " << total_read << "/" << bytes
+                   << " failed";
+        return total_read;
+      }
+      total_read += num_bytes_to_read;
+    } else if (timeout_ms >= kReadPollMs) {
+      lock.unlock();
+      usleep(kReadPollMs * 1000);
+      timeout_ms -= kReadPollMs;
+      continue;
+    } else {
+      LOG(DEBUG) << "Data " << total_read << "/" << bytes << " overflow "
+                 << (kFmqReceiveTimeoutMs - timeout_ms) << " ms";
+      return total_read;
+    }
+  } while (total_read < bytes);
+  return total_read;
+}
+
+/***
+ *
+ * Other methods
+ *
+ ***/
+
+void BluetoothAudioSession::ReportControlStatus(bool start_resp,
+                                                BluetoothAudioStatus status) {
+  std::lock_guard<std::recursive_mutex> guard(mutex_);
+  if (observers_.empty()) {
+    LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
+                 << " has NO port state observer";
+    return;
+  }
+  for (auto& observer : observers_) {
+    uint16_t cookie = observer.first;
+    std::shared_ptr<PortStatusCallbacks> callback = observer.second;
+    LOG(INFO) << __func__ << " - status=" << toString(status)
+              << " for SessionType=" << toString(session_type_)
+              << ", bluetooth_audio=0x"
+              << ::android::base::StringPrintf("%04x", cookie)
+              << (start_resp ? " started" : " suspended");
+    callback->control_result_cb_(cookie, start_resp, status);
+  }
+}
+
+bool BluetoothAudioSession::GetPresentationPosition(
+    PresentationPosition& presentation_position) {
+  std::lock_guard<std::recursive_mutex> guard(mutex_);
+  if (!IsSessionReady()) {
+    LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
+               << " has NO session";
+    return false;
+  }
+  bool retval = false;
+
+  if (!stack_iface_->getPresentationPosition(&presentation_position).isOk()) {
+    LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
+                 << toString(session_type_) << " failed";
+    return false;
+  }
+  return retval;
+}
+
+void BluetoothAudioSession::UpdateSourceMetadata(
+    const struct source_metadata& source_metadata) {
+  std::lock_guard<std::recursive_mutex> guard(mutex_);
+  if (!IsSessionReady()) {
+    LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
+               << " has NO session";
+    return;
+  }
+
+  ssize_t track_count = source_metadata.track_count;
+  LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << ","
+            << track_count << " track(s)";
+  if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
+      session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+    return;
+  }
+
+  SourceMetadata hal_source_metadata;
+  hal_source_metadata.tracks.resize(track_count);
+  for (int i = 0; i < track_count; i++) {
+    hal_source_metadata.tracks[i].usage =
+        static_cast<media::audio::common::AudioUsage>(
+            source_metadata.tracks[i].usage);
+    hal_source_metadata.tracks[i].contentType =
+        static_cast<media::audio::common::AudioContentType>(
+            source_metadata.tracks[i].content_type);
+    hal_source_metadata.tracks[i].gain = source_metadata.tracks[i].gain;
+    LOG(VERBOSE) << __func__ << " - SessionType=" << toString(session_type_)
+                 << ", usage=" << toString(hal_source_metadata.tracks[i].usage)
+                 << ", content="
+                 << toString(hal_source_metadata.tracks[i].contentType)
+                 << ", gain=" << hal_source_metadata.tracks[i].gain;
+  }
+
+  auto hal_retval = stack_iface_->updateSourceMetadata(hal_source_metadata);
+  if (!hal_retval.isOk()) {
+    LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
+                 << toString(session_type_) << " failed";
+  }
+}
+
+void BluetoothAudioSession::UpdateSinkMetadata(
+    const struct sink_metadata& sink_metadata) {
+  std::lock_guard<std::recursive_mutex> guard(mutex_);
+  if (!IsSessionReady()) {
+    LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
+               << " has NO session";
+    return;
+  }
+
+  ssize_t track_count = sink_metadata.track_count;
+  LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << ","
+            << track_count << " track(s)";
+  if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
+      session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+    return;
+  }
+
+  SinkMetadata hal_sink_metadata;
+  hal_sink_metadata.tracks.resize(track_count);
+  for (int i = 0; i < track_count; i++) {
+    hal_sink_metadata.tracks[i].source =
+        static_cast<media::audio::common::AudioSource>(
+            sink_metadata.tracks[i].source);
+    hal_sink_metadata.tracks[i].gain = sink_metadata.tracks[i].gain;
+    LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+              << ", source=" << sink_metadata.tracks[i].source
+              << ", dest_device=" << sink_metadata.tracks[i].dest_device
+              << ", gain=" << sink_metadata.tracks[i].gain
+              << ", dest_device_address="
+              << sink_metadata.tracks[i].dest_device_address;
+  }
+
+  auto hal_retval = stack_iface_->updateSinkMetadata(hal_sink_metadata);
+  if (!hal_retval.isOk()) {
+    LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
+                 << toString(session_type_) << " failed";
+  }
+}
+
+bool BluetoothAudioSession::IsAidlAvailable() {
+  if (is_aidl_checked) return is_aidl_available;
+  is_aidl_available =
+      (AServiceManager_checkService(
+           kDefaultAudioProviderFactoryInterface.c_str()) != nullptr);
+  is_aidl_checked = true;
+  return is_aidl_available;
+}
+
+/***
+ *
+ * BluetoothAudioSessionInstance
+ *
+ ***/
+std::mutex BluetoothAudioSessionInstance::mutex_;
+std::unordered_map<SessionType, std::shared_ptr<BluetoothAudioSession>>
+    BluetoothAudioSessionInstance::sessions_map_;
+
+std::shared_ptr<BluetoothAudioSession>
+BluetoothAudioSessionInstance::GetSessionInstance(
+    const SessionType& session_type) {
+  std::lock_guard<std::mutex> guard(mutex_);
+
+  if (!sessions_map_.empty()) {
+    auto entry = sessions_map_.find(session_type);
+    if (entry != sessions_map_.end()) {
+      return entry->second;
+    }
+  }
+  std::shared_ptr<BluetoothAudioSession> session_ptr =
+      std::make_shared<BluetoothAudioSession>(session_type);
+  sessions_map_[session_type] = session_ptr;
+  return session_ptr;
+}
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
\ No newline at end of file
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h
new file mode 100644
index 0000000..85fd571
--- /dev/null
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/audio/common/SinkMetadata.h>
+#include <aidl/android/hardware/audio/common/SourceMetadata.h>
+#include <aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.h>
+#include <aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.h>
+#include <aidl/android/hardware/bluetooth/audio/SessionType.h>
+#include <fmq/AidlMessageQueue.h>
+#include <hardware/audio.h>
+
+#include <mutex>
+#include <unordered_map>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+using ::aidl::android::hardware::common::fmq::MQDescriptor;
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::android::AidlMessageQueue;
+
+using ::aidl::android::hardware::audio::common::SinkMetadata;
+using ::aidl::android::hardware::audio::common::SourceMetadata;
+
+using MQDataType = int8_t;
+using MQDataMode = SynchronizedReadWrite;
+using DataMQ = AidlMessageQueue<MQDataType, MQDataMode>;
+using DataMQDesc =
+    ::aidl::android::hardware::common::fmq::MQDescriptor<MQDataType,
+                                                         MQDataMode>;
+
+static constexpr uint16_t kObserversCookieSize = 0x0010;  // 0x0000 ~ 0x000f
+static constexpr uint16_t kObserversCookieUndefined =
+    (static_cast<uint16_t>(SessionType::UNKNOWN) << 8 & 0xff00);
+inline SessionType ObserversCookieGetSessionType(uint16_t cookie) {
+  return static_cast<SessionType>(cookie >> 8 & 0x00ff);
+}
+inline uint16_t ObserversCookieGetInitValue(SessionType session_type) {
+  return (static_cast<uint16_t>(session_type) << 8 & 0xff00);
+}
+inline uint16_t ObserversCookieGetUpperBound(SessionType session_type) {
+  return (static_cast<uint16_t>(session_type) << 8 & 0xff00) +
+         kObserversCookieSize;
+}
+
+/***
+ * This presents the callbacks of started / suspended and session changed,
+ * and the bluetooth_audio module uses to receive the status notification
+ ***/
+struct PortStatusCallbacks {
+  /***
+   * 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,
+                     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 {
+ public:
+  BluetoothAudioSession(const SessionType& session_type);
+
+  /***
+   * The function helps to check if this session is ready or not
+   * @return: true if the Bluetooth stack has started the specified session
+   ***/
+  bool IsSessionReady();
+
+  /***
+   * The report function is used to report that the Bluetooth stack has started
+   * this session without any failure, and will invoke session_changed_cb_ to
+   * notify those registered bluetooth_audio outputs
+   ***/
+  void OnSessionStarted(const std::shared_ptr<IBluetoothAudioPort> stack_iface,
+                        const DataMQDesc* mq_desc,
+                        const 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();
+
+  /***
+   * 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, BluetoothAudioStatus status);
+
+  /***
+   * The control function helps the bluetooth_audio module to register
+   * PortStatusCallbacks
+   * @return: cookie - the assigned number to this bluetooth_audio output
+   ***/
+  uint16_t RegisterStatusCback(const PortStatusCallbacks& cbacks);
+
+  /***
+   * The control function helps the bluetooth_audio module to unregister
+   * PortStatusCallbacks
+   * @param: cookie - indicates which bluetooth_audio output is
+   ***/
+  void UnregisterStatusCback(uint16_t cookie);
+
+  /***
+   * The control function is for the bluetooth_audio module to get the current
+   * AudioConfiguration
+   ***/
+  const AudioConfiguration& GetAudioConfig();
+
+  /***
+   * 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 AudioConfiguration& audio_config);
+
+  /***
+   * 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();
+  bool GetPresentationPosition(PresentationPosition& presentation_position);
+  void UpdateSourceMetadata(const struct source_metadata& source_metadata);
+  void UpdateSinkMetadata(const struct sink_metadata& sink_metadata);
+
+  // The control function writes stream to FMQ
+  size_t OutWritePcmData(const void* buffer, size_t bytes);
+  // The control function read stream from FMQ
+  size_t InReadPcmData(void* buffer, size_t bytes);
+
+  // Return if IBluetoothAudioProviderFactory implementation existed
+  static bool IsAidlAvailable();
+
+  static constexpr PcmConfiguration kInvalidPcmConfiguration = {};
+  // can't be constexpr because of non-literal type
+  static const CodecConfiguration kInvalidCodecConfiguration;
+
+  static AudioConfiguration invalidSoftwareAudioConfiguration;
+  static AudioConfiguration invalidOffloadAudioConfiguration;
+  static AudioConfiguration invalidLeOffloadAudioConfig;
+
+ private:
+  // using recursive_mutex to allow hwbinder to re-enter again.
+  std::recursive_mutex mutex_;
+  SessionType session_type_;
+
+  // audio control path to use for both software and offloading
+  std::shared_ptr<IBluetoothAudioPort> stack_iface_;
+  // audio data path (FMQ) for software encoding
+  std::unique_ptr<DataMQ> data_mq_;
+  // audio data configuration for both software and offloading
+  std::unique_ptr<AudioConfiguration> audio_config_;
+
+  // saving those registered bluetooth_audio's callbacks
+  std::unordered_map<uint16_t, std::shared_ptr<struct PortStatusCallbacks>>
+      observers_;
+
+  bool UpdateDataPath(const DataMQDesc* mq_desc);
+  bool UpdateAudioConfig(const AudioConfiguration& audio_config);
+  // invoking the registered session_changed_cb_
+  void ReportSessionStatus();
+
+  static inline std::atomic<bool> is_aidl_checked = false;
+  static inline std::atomic<bool> is_aidl_available = false;
+  static inline const std::string kDefaultAudioProviderFactoryInterface =
+      std::string() + IBluetoothAudioProviderFactory::descriptor + "/default";
+};
+
+class BluetoothAudioSessionInstance {
+ public:
+  // The API is to fetch the specified session of A2DP / Hearing Aid
+  static std::shared_ptr<BluetoothAudioSession> GetSessionInstance(
+      const SessionType& session_type);
+
+ private:
+  static std::mutex mutex_;
+  static std::unordered_map<SessionType, std::shared_ptr<BluetoothAudioSession>>
+      sessions_map_;
+};
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
\ No newline at end of file
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h
new file mode 100644
index 0000000..a3ed428
--- /dev/null
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "BluetoothAudioSession.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+class BluetoothAudioSessionControl {
+ public:
+  /***
+   * The control API helps to check if session is ready or not
+   * @return: true if the Bluetooth stack has started th specified session
+   ***/
+  static bool IsSessionReady(const SessionType& session_type) {
+    std::shared_ptr<BluetoothAudioSession> session_ptr =
+        BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->IsSessionReady();
+    }
+
+    return false;
+  }
+
+  /***
+   * The control API helps the bluetooth_audio module to register
+   * PortStatusCallbacks
+   * @return: cookie - the assigned number to this bluetooth_audio output
+   ***/
+  static uint16_t RegisterControlResultCback(
+      const SessionType& session_type, const PortStatusCallbacks& cbacks) {
+    std::shared_ptr<BluetoothAudioSession> session_ptr =
+        BluetoothAudioSessionInstance::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
+   * @param: cookie - indicates which bluetooth_audio output is
+   ***/
+  static void UnregisterControlResultCback(const SessionType& session_type,
+                                           uint16_t cookie) {
+    std::shared_ptr<BluetoothAudioSession> session_ptr =
+        BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      session_ptr->UnregisterStatusCback(cookie);
+    }
+  }
+
+  /***
+   * The control API for the bluetooth_audio module to get current
+   * AudioConfiguration
+   ***/
+  static const AudioConfiguration GetAudioConfig(
+      const SessionType& session_type) {
+    std::shared_ptr<BluetoothAudioSession> session_ptr =
+        BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->GetAudioConfig();
+    } else if (session_type ==
+               SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+      return BluetoothAudioSession::invalidOffloadAudioConfiguration;
+    } else {
+      return BluetoothAudioSession::invalidSoftwareAudioConfiguration;
+    }
+  }
+
+  /***
+   * Those control APIs for the bluetooth_audio module to start / suspend /
+  stop
+   * stream, to check position, and to update metadata.
+  ***/
+  static bool StartStream(const SessionType& session_type) {
+    std::shared_ptr<BluetoothAudioSession> session_ptr =
+        BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->StartStream();
+    }
+    return false;
+  }
+
+  static bool SuspendStream(const SessionType& session_type) {
+    std::shared_ptr<BluetoothAudioSession> session_ptr =
+        BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->SuspendStream();
+    }
+    return false;
+  }
+
+  static void StopStream(const SessionType& session_type) {
+    std::shared_ptr<BluetoothAudioSession> session_ptr =
+        BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      session_ptr->StopStream();
+    }
+  }
+
+  static bool GetPresentationPosition(
+      const SessionType& session_type,
+      PresentationPosition& presentation_position) {
+    std::shared_ptr<BluetoothAudioSession> session_ptr =
+        BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->GetPresentationPosition(presentation_position);
+    }
+    return false;
+  }
+
+  static void UpdateSourceMetadata(
+      const SessionType& session_type,
+      const struct source_metadata& source_metadata) {
+    std::shared_ptr<BluetoothAudioSession> session_ptr =
+        BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      session_ptr->UpdateSourceMetadata(source_metadata);
+    }
+  }
+
+  static void UpdateSinkMetadata(const SessionType& session_type,
+                                 const struct sink_metadata& sink_metadata) {
+    std::shared_ptr<BluetoothAudioSession> session_ptr =
+        BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      session_ptr->UpdateSinkMetadata(sink_metadata);
+    }
+  }
+
+  /***
+   * The control API writes stream to FMQ
+   ***/
+  static size_t OutWritePcmData(const SessionType& session_type,
+                                const void* buffer, size_t bytes) {
+    std::shared_ptr<BluetoothAudioSession> session_ptr =
+        BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->OutWritePcmData(buffer, bytes);
+    }
+    return 0;
+  }
+
+  /***
+   * The control API reads stream from FMQ
+   ***/
+  static size_t InReadPcmData(const SessionType& session_type, void* buffer,
+                              size_t bytes) {
+    std::shared_ptr<BluetoothAudioSession> session_ptr =
+        BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->InReadPcmData(buffer, bytes);
+    }
+    return 0;
+  }
+};
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
\ No newline at end of file
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionReport.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionReport.h
new file mode 100644
index 0000000..18569c3
--- /dev/null
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionReport.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "BluetoothAudioSession.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+class BluetoothAudioSessionReport {
+ public:
+  /***
+   * The API reports the Bluetooth stack has started the session, and will
+   * inform registered bluetooth_audio outputs
+   ***/
+  static void OnSessionStarted(
+      const SessionType& session_type,
+      const std::shared_ptr<IBluetoothAudioPort> host_iface,
+      const DataMQDesc* data_mq, const AudioConfiguration& audio_config) {
+    std::shared_ptr<BluetoothAudioSession> session_ptr =
+        BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      session_ptr->OnSessionStarted(host_iface, data_mq, audio_config);
+    }
+  }
+
+  /***
+   * The API reports the Bluetooth stack has ended the session, and will
+   * inform registered bluetooth_audio outputs
+   ***/
+  static void OnSessionEnded(const SessionType& session_type) {
+    std::shared_ptr<BluetoothAudioSession> session_ptr =
+        BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      session_ptr->OnSessionEnded();
+    }
+  }
+
+  /***
+   * The API reports the Bluetooth stack has replied the result of startStream
+   * or suspendStream, and will inform registered bluetooth_audio outputs
+   ***/
+  static void ReportControlStatus(const SessionType& session_type,
+                                  const bool& start_resp,
+                                  BluetoothAudioStatus status) {
+    std::shared_ptr<BluetoothAudioSession> session_ptr =
+        BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      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 SessionType& session_type,
+                                       const AudioConfiguration& audio_config) {
+    std::shared_ptr<BluetoothAudioSession> session_ptr =
+        BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      session_ptr->ReportAudioConfigChanged(audio_config);
+    }
+  }
+};
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
\ No newline at end of file
diff --git a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp
new file mode 100644
index 0000000..91e0238
--- /dev/null
+++ b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp
@@ -0,0 +1,775 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "BtAudioNakahara"
+
+#include <aidl/android/hardware/bluetooth/audio/AudioConfiguration.h>
+#include <aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.h>
+#include <aidl/android/hardware/bluetooth/audio/SessionType.h>
+#include <android-base/logging.h>
+
+#include <functional>
+#include <unordered_map>
+
+#include "../aidl_session/BluetoothAudioSession.h"
+#include "../aidl_session/BluetoothAudioSessionControl.h"
+#include "HidlToAidlMiddleware_2_0.h"
+#include "HidlToAidlMiddleware_2_1.h"
+#include "HidlToAidlMiddleware_2_2.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+using HidlStatus = ::android::hardware::bluetooth::audio::V2_0::Status;
+using PcmConfig_2_0 =
+    ::android::hardware::bluetooth::audio::V2_0::PcmParameters;
+using SampleRate_2_0 = ::android::hardware::bluetooth::audio::V2_0::SampleRate;
+using ChannelMode_2_0 =
+    ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
+using BitsPerSample_2_0 =
+    ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
+using CodecConfig_2_0 =
+    ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration;
+using CodecType_2_0 = ::android::hardware::bluetooth::audio::V2_0::CodecType;
+using SbcConfig_2_0 =
+    ::android::hardware::bluetooth::audio::V2_0::SbcParameters;
+using AacConfig_2_0 =
+    ::android::hardware::bluetooth::audio::V2_0::AacParameters;
+using LdacConfig_2_0 =
+    ::android::hardware::bluetooth::audio::V2_0::LdacParameters;
+using AptxConfig_2_0 =
+    ::android::hardware::bluetooth::audio::V2_0::AptxParameters;
+using SbcAllocMethod_2_0 =
+    ::android::hardware::bluetooth::audio::V2_0::SbcAllocMethod;
+using SbcBlockLength_2_0 =
+    ::android::hardware::bluetooth::audio::V2_0::SbcBlockLength;
+using SbcChannelMode_2_0 =
+    ::android::hardware::bluetooth::audio::V2_0::SbcChannelMode;
+using SbcNumSubbands_2_0 =
+    ::android::hardware::bluetooth::audio::V2_0::SbcNumSubbands;
+using AacObjectType_2_0 =
+    ::android::hardware::bluetooth::audio::V2_0::AacObjectType;
+using AacVarBitRate_2_0 =
+    ::android::hardware::bluetooth::audio::V2_0::AacVariableBitRate;
+using LdacChannelMode_2_0 =
+    ::android::hardware::bluetooth::audio::V2_0::LdacChannelMode;
+using LdacQualityIndex_2_0 =
+    ::android::hardware::bluetooth::audio::V2_0::LdacQualityIndex;
+
+using PcmConfig_2_1 =
+    ::android::hardware::bluetooth::audio::V2_1::PcmParameters;
+using SampleRate_2_1 = ::android::hardware::bluetooth::audio::V2_1::SampleRate;
+using Lc3CodecConfig_2_1 =
+    ::android::hardware::bluetooth::audio::V2_1::Lc3CodecConfiguration;
+using Lc3Config_2_1 =
+    ::android::hardware::bluetooth::audio::V2_1::Lc3Parameters;
+using Lc3FrameDuration_2_1 =
+    ::android::hardware::bluetooth::audio::V2_1::Lc3FrameDuration;
+
+using LeAudioConfig_2_2 =
+    ::android::hardware::bluetooth::audio::V2_2::LeAudioConfiguration;
+using LeAudioMode_2_2 =
+    ::android::hardware::bluetooth::audio::V2_2::LeAudioMode;
+
+std::mutex legacy_callback_lock;
+std::unordered_map<
+    SessionType,
+    std::unordered_map<uint16_t, std::shared_ptr<PortStatusCallbacks_2_2>>>
+    legacy_callback_table;
+
+const static std::unordered_map<SessionType_2_0, SessionType>
+    session_type_2_0_to_aidl_map{
+        {SessionType_2_0::A2DP_SOFTWARE_ENCODING_DATAPATH,
+         SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH},
+        {SessionType_2_0::A2DP_HARDWARE_OFFLOAD_DATAPATH,
+         SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH},
+        {SessionType_2_0::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
+         SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH},
+    };
+
+const static std::unordered_map<SessionType_2_1, SessionType>
+    session_type_2_1_to_aidl_map{
+        {SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH,
+         SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH},
+        {SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH,
+         SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH},
+        {SessionType_2_1::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
+         SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH},
+        {SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
+         SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH},
+        {SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH,
+         SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH},
+        {SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+         SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH},
+        {SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+         SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH},
+    };
+
+const static std::unordered_map<int32_t, SampleRate_2_0>
+    sample_rate_to_hidl_2_0_map{
+        {44100, SampleRate_2_0::RATE_44100},
+        {48000, SampleRate_2_0::RATE_48000},
+        {88200, SampleRate_2_0::RATE_88200},
+        {96000, SampleRate_2_0::RATE_96000},
+        {176400, SampleRate_2_0::RATE_176400},
+        {192000, SampleRate_2_0::RATE_192000},
+        {16000, SampleRate_2_0::RATE_16000},
+        {24000, SampleRate_2_0::RATE_24000},
+    };
+
+const static std::unordered_map<int32_t, SampleRate_2_1>
+    sample_rate_to_hidl_2_1_map{
+        {44100, SampleRate_2_1::RATE_44100},
+        {48000, SampleRate_2_1::RATE_48000},
+        {88200, SampleRate_2_1::RATE_88200},
+        {96000, SampleRate_2_1::RATE_96000},
+        {176400, SampleRate_2_1::RATE_176400},
+        {192000, SampleRate_2_1::RATE_192000},
+        {16000, SampleRate_2_1::RATE_16000},
+        {24000, SampleRate_2_1::RATE_24000},
+        {8000, SampleRate_2_1::RATE_8000},
+        {32000, SampleRate_2_1::RATE_32000},
+    };
+
+const static std::unordered_map<CodecType, CodecType_2_0>
+    codec_type_to_hidl_2_0_map{
+        {CodecType::UNKNOWN, CodecType_2_0::UNKNOWN},
+        {CodecType::SBC, CodecType_2_0::SBC},
+        {CodecType::AAC, CodecType_2_0::AAC},
+        {CodecType::APTX, CodecType_2_0::APTX},
+        {CodecType::APTX_HD, CodecType_2_0::APTX_HD},
+        {CodecType::LDAC, CodecType_2_0::LDAC},
+        {CodecType::LC3, CodecType_2_0::UNKNOWN},
+    };
+
+const static std::unordered_map<SbcChannelMode, SbcChannelMode_2_0>
+    sbc_channel_mode_to_hidl_2_0_map{
+        {SbcChannelMode::UNKNOWN, SbcChannelMode_2_0::UNKNOWN},
+        {SbcChannelMode::JOINT_STEREO, SbcChannelMode_2_0::JOINT_STEREO},
+        {SbcChannelMode::STEREO, SbcChannelMode_2_0::STEREO},
+        {SbcChannelMode::DUAL, SbcChannelMode_2_0::DUAL},
+        {SbcChannelMode::MONO, SbcChannelMode_2_0::MONO},
+    };
+
+const static std::unordered_map<int8_t, SbcBlockLength_2_0>
+    sbc_block_length_to_hidl_map{
+        {4, SbcBlockLength_2_0::BLOCKS_4},
+        {8, SbcBlockLength_2_0::BLOCKS_8},
+        {12, SbcBlockLength_2_0::BLOCKS_12},
+        {16, SbcBlockLength_2_0::BLOCKS_16},
+    };
+
+const static std::unordered_map<int8_t, SbcNumSubbands_2_0>
+    sbc_subbands_to_hidl_map{
+        {4, SbcNumSubbands_2_0::SUBBAND_4},
+        {8, SbcNumSubbands_2_0::SUBBAND_8},
+    };
+
+const static std::unordered_map<SbcAllocMethod, SbcAllocMethod_2_0>
+    sbc_alloc_method_to_hidl_map{
+        {SbcAllocMethod::ALLOC_MD_S, SbcAllocMethod_2_0::ALLOC_MD_S},
+        {SbcAllocMethod::ALLOC_MD_L, SbcAllocMethod_2_0::ALLOC_MD_L},
+    };
+
+const static std::unordered_map<AacObjectType, AacObjectType_2_0>
+    aac_object_type_to_hidl_map{
+        {AacObjectType::MPEG2_LC, AacObjectType_2_0::MPEG2_LC},
+        {AacObjectType::MPEG4_LC, AacObjectType_2_0::MPEG4_LC},
+        {AacObjectType::MPEG4_LTP, AacObjectType_2_0::MPEG4_LTP},
+        {AacObjectType::MPEG4_SCALABLE, AacObjectType_2_0::MPEG4_SCALABLE},
+    };
+
+const static std::unordered_map<LdacChannelMode, LdacChannelMode_2_0>
+    ldac_channel_mode_to_hidl_map{
+        {LdacChannelMode::UNKNOWN, LdacChannelMode_2_0::UNKNOWN},
+        {LdacChannelMode::STEREO, LdacChannelMode_2_0::STEREO},
+        {LdacChannelMode::DUAL, LdacChannelMode_2_0::DUAL},
+        {LdacChannelMode::MONO, LdacChannelMode_2_0::MONO},
+    };
+
+const static std::unordered_map<LdacQualityIndex, LdacQualityIndex_2_0>
+    ldac_qindex_to_hidl_map{
+        {LdacQualityIndex::HIGH, LdacQualityIndex_2_0::QUALITY_HIGH},
+        {LdacQualityIndex::MID, LdacQualityIndex_2_0::QUALITY_MID},
+        {LdacQualityIndex::LOW, LdacQualityIndex_2_0::QUALITY_LOW},
+        {LdacQualityIndex::ABR, LdacQualityIndex_2_0::QUALITY_ABR},
+    };
+
+const static std::unordered_map<LeAudioMode, LeAudioMode_2_2>
+    leaudio_mode_to_hidl_map{
+        {LeAudioMode::UNKNOWN, LeAudioMode_2_2::UNKNOWN},
+        {LeAudioMode::UNICAST, LeAudioMode_2_2::UNICAST},
+        {LeAudioMode::BROADCAST, LeAudioMode_2_2::BROADCAST},
+    };
+
+inline SessionType from_session_type_2_0(
+    const SessionType_2_0& session_type_hidl) {
+  auto it = session_type_2_0_to_aidl_map.find(session_type_hidl);
+  if (it != session_type_2_0_to_aidl_map.end()) return it->second;
+  return SessionType::UNKNOWN;
+}
+
+inline SessionType from_session_type_2_1(
+    const SessionType_2_1& session_type_hidl) {
+  auto it = session_type_2_1_to_aidl_map.find(session_type_hidl);
+  if (it != session_type_2_1_to_aidl_map.end()) return it->second;
+  return SessionType::UNKNOWN;
+}
+
+inline HidlStatus to_hidl_status(const BluetoothAudioStatus& status) {
+  switch (status) {
+    case BluetoothAudioStatus::SUCCESS:
+      return HidlStatus::SUCCESS;
+    case BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION:
+      return HidlStatus::UNSUPPORTED_CODEC_CONFIGURATION;
+    default:
+      return HidlStatus::FAILURE;
+  }
+}
+
+inline SampleRate_2_0 to_hidl_sample_rate_2_0(const int32_t sample_rate_hz) {
+  auto it = sample_rate_to_hidl_2_0_map.find(sample_rate_hz);
+  if (it != sample_rate_to_hidl_2_0_map.end()) return it->second;
+  return SampleRate_2_0::RATE_UNKNOWN;
+}
+
+inline SampleRate_2_1 to_hidl_sample_rate_2_1(const int32_t sample_rate_hz) {
+  auto it = sample_rate_to_hidl_2_1_map.find(sample_rate_hz);
+  if (it != sample_rate_to_hidl_2_1_map.end()) return it->second;
+  return SampleRate_2_1::RATE_UNKNOWN;
+}
+
+inline BitsPerSample_2_0 to_hidl_bits_per_sample(const int8_t bit_per_sample) {
+  switch (bit_per_sample) {
+    case 16:
+      return BitsPerSample_2_0::BITS_16;
+    case 24:
+      return BitsPerSample_2_0::BITS_24;
+    case 32:
+      return BitsPerSample_2_0::BITS_32;
+    default:
+      return BitsPerSample_2_0::BITS_UNKNOWN;
+  }
+}
+
+inline ChannelMode_2_0 to_hidl_channel_mode(const ChannelMode channel_mode) {
+  switch (channel_mode) {
+    case ChannelMode::MONO:
+      return ChannelMode_2_0::MONO;
+    case ChannelMode::STEREO:
+      return ChannelMode_2_0::STEREO;
+    default:
+      return ChannelMode_2_0::UNKNOWN;
+  }
+}
+
+inline PcmConfig_2_0 to_hidl_pcm_config_2_0(
+    const PcmConfiguration& pcm_config) {
+  PcmConfig_2_0 hidl_pcm_config;
+  hidl_pcm_config.sampleRate = to_hidl_sample_rate_2_0(pcm_config.sampleRateHz);
+  hidl_pcm_config.channelMode = to_hidl_channel_mode(pcm_config.channelMode);
+  hidl_pcm_config.bitsPerSample =
+      to_hidl_bits_per_sample(pcm_config.bitsPerSample);
+  return hidl_pcm_config;
+}
+
+inline CodecType_2_0 to_hidl_codec_type_2_0(const CodecType codec_type) {
+  auto it = codec_type_to_hidl_2_0_map.find(codec_type);
+  if (it != codec_type_to_hidl_2_0_map.end()) return it->second;
+  return CodecType_2_0::UNKNOWN;
+}
+
+inline SbcConfig_2_0 to_hidl_sbc_config(const SbcConfiguration sbc_config) {
+  SbcConfig_2_0 hidl_sbc_config;
+  hidl_sbc_config.minBitpool = sbc_config.minBitpool;
+  hidl_sbc_config.maxBitpool = sbc_config.maxBitpool;
+  hidl_sbc_config.sampleRate = to_hidl_sample_rate_2_0(sbc_config.sampleRateHz);
+  hidl_sbc_config.bitsPerSample =
+      to_hidl_bits_per_sample(sbc_config.bitsPerSample);
+  if (sbc_channel_mode_to_hidl_2_0_map.find(sbc_config.channelMode) !=
+      sbc_channel_mode_to_hidl_2_0_map.end()) {
+    hidl_sbc_config.channelMode =
+        sbc_channel_mode_to_hidl_2_0_map.at(sbc_config.channelMode);
+  }
+  if (sbc_block_length_to_hidl_map.find(sbc_config.blockLength) !=
+      sbc_block_length_to_hidl_map.end()) {
+    hidl_sbc_config.blockLength =
+        sbc_block_length_to_hidl_map.at(sbc_config.blockLength);
+  }
+  if (sbc_subbands_to_hidl_map.find(sbc_config.numSubbands) !=
+      sbc_subbands_to_hidl_map.end()) {
+    hidl_sbc_config.numSubbands =
+        sbc_subbands_to_hidl_map.at(sbc_config.numSubbands);
+  }
+  if (sbc_alloc_method_to_hidl_map.find(sbc_config.allocMethod) !=
+      sbc_alloc_method_to_hidl_map.end()) {
+    hidl_sbc_config.allocMethod =
+        sbc_alloc_method_to_hidl_map.at(sbc_config.allocMethod);
+  }
+  return hidl_sbc_config;
+}
+
+inline AacConfig_2_0 to_hidl_aac_config(const AacConfiguration aac_config) {
+  AacConfig_2_0 hidl_aac_config;
+  hidl_aac_config.sampleRate = to_hidl_sample_rate_2_0(aac_config.sampleRateHz);
+  hidl_aac_config.bitsPerSample =
+      to_hidl_bits_per_sample(aac_config.bitsPerSample);
+  hidl_aac_config.channelMode = to_hidl_channel_mode(aac_config.channelMode);
+  if (aac_object_type_to_hidl_map.find(aac_config.objectType) !=
+      aac_object_type_to_hidl_map.end()) {
+    hidl_aac_config.objectType =
+        aac_object_type_to_hidl_map.at(aac_config.objectType);
+  }
+  hidl_aac_config.variableBitRateEnabled = aac_config.variableBitRateEnabled
+                                               ? AacVarBitRate_2_0::ENABLED
+                                               : AacVarBitRate_2_0::DISABLED;
+  return hidl_aac_config;
+}
+
+inline LdacConfig_2_0 to_hidl_ldac_config(const LdacConfiguration ldac_config) {
+  LdacConfig_2_0 hidl_ldac_config;
+  hidl_ldac_config.sampleRate =
+      to_hidl_sample_rate_2_0(ldac_config.sampleRateHz);
+  hidl_ldac_config.bitsPerSample =
+      to_hidl_bits_per_sample(ldac_config.bitsPerSample);
+  if (ldac_channel_mode_to_hidl_map.find(ldac_config.channelMode) !=
+      ldac_channel_mode_to_hidl_map.end()) {
+    hidl_ldac_config.channelMode =
+        ldac_channel_mode_to_hidl_map.at(ldac_config.channelMode);
+  }
+  if (ldac_qindex_to_hidl_map.find(ldac_config.qualityIndex) !=
+      ldac_qindex_to_hidl_map.end()) {
+    hidl_ldac_config.qualityIndex =
+        ldac_qindex_to_hidl_map.at(ldac_config.qualityIndex);
+  }
+  return hidl_ldac_config;
+}
+
+inline AptxConfig_2_0 to_hidl_aptx_config(const AptxConfiguration aptx_config) {
+  AptxConfig_2_0 hidl_aptx_config;
+  hidl_aptx_config.sampleRate =
+      to_hidl_sample_rate_2_0(aptx_config.sampleRateHz);
+  hidl_aptx_config.bitsPerSample =
+      to_hidl_bits_per_sample(aptx_config.bitsPerSample);
+  hidl_aptx_config.channelMode = to_hidl_channel_mode(aptx_config.channelMode);
+  return hidl_aptx_config;
+}
+
+inline CodecConfig_2_0 to_hidl_codec_config_2_0(
+    const CodecConfiguration& codec_config) {
+  CodecConfig_2_0 hidl_codec_config;
+  hidl_codec_config.codecType = to_hidl_codec_type_2_0(codec_config.codecType);
+  hidl_codec_config.encodedAudioBitrate =
+      static_cast<uint32_t>(codec_config.encodedAudioBitrate);
+  hidl_codec_config.peerMtu = static_cast<uint32_t>(codec_config.peerMtu);
+  hidl_codec_config.isScmstEnabled = codec_config.isScmstEnabled;
+  switch (codec_config.config.getTag()) {
+    case CodecConfiguration::CodecSpecific::sbcConfig:
+      hidl_codec_config.config.sbcConfig(to_hidl_sbc_config(
+          codec_config.config
+              .get<CodecConfiguration::CodecSpecific::sbcConfig>()));
+      break;
+    case CodecConfiguration::CodecSpecific::aacConfig:
+      hidl_codec_config.config.aacConfig(to_hidl_aac_config(
+          codec_config.config
+              .get<CodecConfiguration::CodecSpecific::aacConfig>()));
+      break;
+    case CodecConfiguration::CodecSpecific::ldacConfig:
+      hidl_codec_config.config.ldacConfig(to_hidl_ldac_config(
+          codec_config.config
+              .get<CodecConfiguration::CodecSpecific::ldacConfig>()));
+      break;
+    case CodecConfiguration::CodecSpecific::aptxConfig:
+      hidl_codec_config.config.aptxConfig(to_hidl_aptx_config(
+          codec_config.config
+              .get<CodecConfiguration::CodecSpecific::aptxConfig>()));
+      break;
+    default:
+      break;
+  }
+  return hidl_codec_config;
+}
+
+inline AudioConfig_2_0 to_hidl_audio_config_2_0(
+    const AudioConfiguration& audio_config) {
+  AudioConfig_2_0 hidl_audio_config;
+  if (audio_config.getTag() == AudioConfiguration::pcmConfig) {
+    hidl_audio_config.pcmConfig(to_hidl_pcm_config_2_0(
+        audio_config.get<AudioConfiguration::pcmConfig>()));
+  } else if (audio_config.getTag() == AudioConfiguration::a2dpConfig) {
+    hidl_audio_config.codecConfig(to_hidl_codec_config_2_0(
+        audio_config.get<AudioConfiguration::a2dpConfig>()));
+  }
+  return hidl_audio_config;
+}
+
+inline PcmConfig_2_1 to_hidl_pcm_config_2_1(
+    const PcmConfiguration& pcm_config) {
+  PcmConfig_2_1 hidl_pcm_config;
+  hidl_pcm_config.sampleRate = to_hidl_sample_rate_2_1(pcm_config.sampleRateHz);
+  hidl_pcm_config.channelMode = to_hidl_channel_mode(pcm_config.channelMode);
+  hidl_pcm_config.bitsPerSample =
+      to_hidl_bits_per_sample(pcm_config.bitsPerSample);
+  hidl_pcm_config.dataIntervalUs =
+      static_cast<uint32_t>(pcm_config.dataIntervalUs);
+  return hidl_pcm_config;
+}
+
+inline Lc3Config_2_1 to_hidl_lc3_config_2_1(
+    const Lc3Configuration& lc3_config) {
+  Lc3Config_2_1 hidl_lc3_config;
+  hidl_lc3_config.pcmBitDepth = to_hidl_bits_per_sample(lc3_config.pcmBitDepth);
+  hidl_lc3_config.samplingFrequency =
+      to_hidl_sample_rate_2_1(lc3_config.samplingFrequencyHz);
+  if (lc3_config.samplingFrequencyHz == 10000)
+    hidl_lc3_config.frameDuration = Lc3FrameDuration_2_1::DURATION_10000US;
+  else if (lc3_config.samplingFrequencyHz == 7500)
+    hidl_lc3_config.frameDuration = Lc3FrameDuration_2_1::DURATION_7500US;
+  hidl_lc3_config.octetsPerFrame =
+      static_cast<uint32_t>(lc3_config.octetsPerFrame);
+  hidl_lc3_config.blocksPerSdu = static_cast<uint32_t>(lc3_config.blocksPerSdu);
+  return hidl_lc3_config;
+}
+
+inline Lc3CodecConfig_2_1 to_hidl_leaudio_config_2_1(
+    const LeAudioConfiguration& leaudio_config) {
+  auto& unicast_config =
+      leaudio_config.modeConfig
+          .get<LeAudioConfiguration::LeAudioModeConfig::unicastConfig>();
+
+  auto& le_codec_config = unicast_config.leAudioCodecConfig
+                              .get<LeAudioCodecConfiguration::lc3Config>();
+
+  Lc3CodecConfig_2_1 hidl_lc3_codec_config;
+  hidl_lc3_codec_config.lc3Config = to_hidl_lc3_config_2_1(le_codec_config);
+
+  hidl_lc3_codec_config.audioChannelAllocation =
+      unicast_config.streamMap.size();
+
+  return hidl_lc3_codec_config;
+}
+
+inline LeAudioConfig_2_2 to_hidl_leaudio_config_2_2(
+    const LeAudioConfiguration& leaudio_config) {
+  LeAudioConfig_2_2 hidl_leaudio_config;
+  if (leaudio_mode_to_hidl_map.find(leaudio_config.mode) !=
+      leaudio_mode_to_hidl_map.end()) {
+    hidl_leaudio_config.mode = leaudio_mode_to_hidl_map.at(leaudio_config.mode);
+  }
+
+  if (leaudio_config.modeConfig.getTag() ==
+      LeAudioConfiguration::LeAudioModeConfig::unicastConfig) {
+    auto& unicast_config =
+        leaudio_config.modeConfig
+            .get<LeAudioConfiguration::LeAudioModeConfig::unicastConfig>();
+    ::android::hardware::bluetooth::audio::V2_2::UnicastConfig
+        hidl_unicast_config;
+    hidl_unicast_config.peerDelay =
+        static_cast<uint32_t>(unicast_config.peerDelay);
+
+    auto& lc3_config = unicast_config.leAudioCodecConfig
+                           .get<LeAudioCodecConfiguration::lc3Config>();
+    hidl_unicast_config.lc3Config = to_hidl_lc3_config_2_1(lc3_config);
+
+    hidl_unicast_config.streamMap.resize(unicast_config.streamMap.size());
+    for (int i = 0; i < unicast_config.streamMap.size(); i++) {
+      hidl_unicast_config.streamMap[i].audioChannelAllocation =
+          static_cast<uint32_t>(
+              unicast_config.streamMap[i].audioChannelAllocation);
+      hidl_unicast_config.streamMap[i].streamHandle =
+          static_cast<uint16_t>(unicast_config.streamMap[i].streamHandle);
+    }
+  } else if (leaudio_config.modeConfig.getTag() ==
+             LeAudioConfiguration::LeAudioModeConfig::broadcastConfig) {
+    auto bcast_config =
+        leaudio_config.modeConfig
+            .get<LeAudioConfiguration::LeAudioModeConfig::broadcastConfig>();
+    ::android::hardware::bluetooth::audio::V2_2::BroadcastConfig
+        hidl_bcast_config;
+    hidl_bcast_config.streamMap.resize(bcast_config.streamMap.size());
+    for (int i = 0; i < bcast_config.streamMap.size(); i++) {
+      hidl_bcast_config.streamMap[i].audioChannelAllocation =
+          static_cast<uint32_t>(
+              bcast_config.streamMap[i].audioChannelAllocation);
+      hidl_bcast_config.streamMap[i].streamHandle =
+          static_cast<uint16_t>(bcast_config.streamMap[i].streamHandle);
+      hidl_bcast_config.streamMap[i].lc3Config = to_hidl_lc3_config_2_1(
+          bcast_config.streamMap[i]
+              .leAudioCodecConfig.get<LeAudioCodecConfiguration::lc3Config>());
+    }
+  }
+  return hidl_leaudio_config;
+}
+
+inline AudioConfig_2_1 to_hidl_audio_config_2_1(
+    const AudioConfiguration& audio_config) {
+  AudioConfig_2_1 hidl_audio_config;
+  switch (audio_config.getTag()) {
+    case AudioConfiguration::pcmConfig:
+      hidl_audio_config.pcmConfig(to_hidl_pcm_config_2_1(
+          audio_config.get<AudioConfiguration::pcmConfig>()));
+      break;
+    case AudioConfiguration::a2dpConfig:
+      hidl_audio_config.codecConfig(to_hidl_codec_config_2_0(
+          audio_config.get<AudioConfiguration::a2dpConfig>()));
+      break;
+    case AudioConfiguration::leAudioConfig:
+      hidl_audio_config.leAudioCodecConfig(to_hidl_leaudio_config_2_1(
+          audio_config.get<AudioConfiguration::leAudioConfig>()));
+      break;
+  }
+  return hidl_audio_config;
+}
+
+inline AudioConfig_2_2 to_hidl_audio_config_2_2(
+    const AudioConfiguration& audio_config) {
+  AudioConfig_2_2 hidl_audio_config;
+  switch (audio_config.getTag()) {
+    case AudioConfiguration::pcmConfig:
+      hidl_audio_config.pcmConfig(to_hidl_pcm_config_2_1(
+          audio_config.get<AudioConfiguration::pcmConfig>()));
+      break;
+    case AudioConfiguration::a2dpConfig:
+      hidl_audio_config.codecConfig(to_hidl_codec_config_2_0(
+          audio_config.get<AudioConfiguration::a2dpConfig>()));
+      break;
+    case AudioConfiguration::leAudioConfig:
+      hidl_audio_config.leAudioConfig(to_hidl_leaudio_config_2_2(
+          audio_config.get<AudioConfiguration::leAudioConfig>()));
+      break;
+  }
+  return hidl_audio_config;
+}
+
+/***
+ *
+ * 2.0
+ *
+ ***/
+
+bool HidlToAidlMiddleware_2_0::IsSessionReady(
+    const SessionType_2_0& session_type) {
+  return BluetoothAudioSessionControl::IsSessionReady(
+      from_session_type_2_0(session_type));
+}
+
+uint16_t HidlToAidlMiddleware_2_0::RegisterControlResultCback(
+    const SessionType_2_0& session_type,
+    const PortStatusCallbacks_2_0& cbacks) {
+  PortStatusCallbacks_2_2 callback_2_2{
+      .control_result_cb_ = cbacks.control_result_cb_,
+      .session_changed_cb_ = cbacks.session_changed_cb_,
+  };
+  return HidlToAidlMiddleware_2_2::RegisterControlResultCback(
+      static_cast<SessionType_2_1>(session_type), callback_2_2);
+}
+
+void HidlToAidlMiddleware_2_0::UnregisterControlResultCback(
+    const SessionType_2_0& session_type, uint16_t cookie) {
+  HidlToAidlMiddleware_2_2::UnregisterControlResultCback(
+      static_cast<SessionType_2_1>(session_type), cookie);
+}
+
+const AudioConfig_2_0 HidlToAidlMiddleware_2_0::GetAudioConfig(
+    const SessionType_2_0& session_type) {
+  return to_hidl_audio_config_2_0(BluetoothAudioSessionControl::GetAudioConfig(
+      from_session_type_2_0(session_type)));
+}
+
+bool HidlToAidlMiddleware_2_0::StartStream(
+    const SessionType_2_0& session_type) {
+  return BluetoothAudioSessionControl::StartStream(
+      from_session_type_2_0(session_type));
+}
+
+void HidlToAidlMiddleware_2_0::StopStream(const SessionType_2_0& session_type) {
+  return BluetoothAudioSessionControl::StopStream(
+      from_session_type_2_0(session_type));
+}
+
+bool HidlToAidlMiddleware_2_0::SuspendStream(
+    const SessionType_2_0& session_type) {
+  return BluetoothAudioSessionControl::SuspendStream(
+      from_session_type_2_0(session_type));
+}
+
+bool HidlToAidlMiddleware_2_0::GetPresentationPosition(
+    const SessionType_2_0& session_type, uint64_t* remote_delay_report_ns,
+    uint64_t* total_bytes_readed, timespec* data_position) {
+  PresentationPosition presentation_position;
+  auto ret_val = BluetoothAudioSessionControl::GetPresentationPosition(
+      from_session_type_2_0(session_type), presentation_position);
+  if (remote_delay_report_ns)
+    *remote_delay_report_ns = presentation_position.remoteDeviceAudioDelayNanos;
+  if (total_bytes_readed)
+    *total_bytes_readed = presentation_position.transmittedOctets;
+  if (data_position)
+    *data_position = {
+        .tv_sec = static_cast<__kernel_old_time_t>(
+            presentation_position.transmittedOctetsTimestamp.tvSec),
+        .tv_nsec = static_cast<long>(
+            presentation_position.transmittedOctetsTimestamp.tvNSec)};
+  return ret_val;
+}
+
+void HidlToAidlMiddleware_2_0::UpdateTracksMetadata(
+    const SessionType_2_0& session_type,
+    const struct source_metadata* source_metadata) {
+  return BluetoothAudioSessionControl::UpdateSourceMetadata(
+      from_session_type_2_0(session_type), *source_metadata);
+}
+
+size_t HidlToAidlMiddleware_2_0::OutWritePcmData(
+    const SessionType_2_0& session_type, const void* buffer, size_t bytes) {
+  return BluetoothAudioSessionControl::OutWritePcmData(
+      from_session_type_2_0(session_type), buffer, bytes);
+}
+
+bool HidlToAidlMiddleware_2_0::IsAidlAvailable() {
+  return BluetoothAudioSession::IsAidlAvailable();
+}
+
+/***
+ *
+ * 2.1
+ *
+ ***/
+
+const AudioConfig_2_1 HidlToAidlMiddleware_2_1::GetAudioConfig(
+    const SessionType_2_1& session_type) {
+  return to_hidl_audio_config_2_1(BluetoothAudioSessionControl::GetAudioConfig(
+      from_session_type_2_1(session_type)));
+}
+
+/***
+ *
+ * 2.2
+ *
+ ***/
+
+bool HidlToAidlMiddleware_2_2::IsSessionReady(
+    const SessionType_2_1& session_type) {
+  return BluetoothAudioSessionControl::IsSessionReady(
+      from_session_type_2_1(session_type));
+}
+
+uint16_t HidlToAidlMiddleware_2_2::RegisterControlResultCback(
+    const SessionType_2_1& session_type,
+    const PortStatusCallbacks_2_2& cbacks) {
+  LOG(INFO) << __func__ << ": " << toString(session_type);
+  auto aidl_session_type = from_session_type_2_1(session_type);
+  // Pass the exact reference to the lambda
+  auto& session_legacy_callback_table =
+      legacy_callback_table[aidl_session_type];
+  PortStatusCallbacks aidl_callbacks{};
+  if (cbacks.control_result_cb_) {
+    aidl_callbacks.control_result_cb_ =
+        [&session_legacy_callback_table](uint16_t cookie, bool start_resp,
+                                         const BluetoothAudioStatus& status) {
+          if (session_legacy_callback_table.find(cookie) ==
+              session_legacy_callback_table.end()) {
+            LOG(ERROR) << __func__ << ": Unknown callback invoked!";
+            return;
+          }
+          auto& cback = session_legacy_callback_table[cookie];
+          cback->control_result_cb_(cookie, start_resp, to_hidl_status(status));
+        };
+  }
+  if (cbacks.session_changed_cb_) {
+    aidl_callbacks.session_changed_cb_ =
+        [&session_legacy_callback_table](uint16_t cookie) {
+          if (session_legacy_callback_table.find(cookie) ==
+              session_legacy_callback_table.end()) {
+            LOG(ERROR) << __func__ << ": Unknown callback invoked!";
+            return;
+          }
+          auto& cback = session_legacy_callback_table[cookie];
+          cback->session_changed_cb_(cookie);
+        };
+  };
+  if (cbacks.audio_configuration_changed_cb_) {
+    aidl_callbacks.audio_configuration_changed_cb_ =
+        [&session_legacy_callback_table](uint16_t cookie) {
+          if (session_legacy_callback_table.find(cookie) ==
+              session_legacy_callback_table.end()) {
+            LOG(ERROR) << __func__ << ": Unknown callback invoked!";
+            return;
+          }
+          auto& cback = session_legacy_callback_table[cookie];
+          cback->audio_configuration_changed_cb_(cookie);
+        };
+  };
+  auto cookie = BluetoothAudioSessionControl::RegisterControlResultCback(
+      aidl_session_type, aidl_callbacks);
+  {
+    std::lock_guard<std::mutex> guard(legacy_callback_lock);
+    session_legacy_callback_table[cookie] =
+        std::make_shared<PortStatusCallbacks_2_2>(cbacks);
+  }
+  return cookie;
+}
+
+void HidlToAidlMiddleware_2_2::UnregisterControlResultCback(
+    const SessionType_2_1& session_type, uint16_t cookie) {
+  LOG(INFO) << __func__ << ": " << toString(session_type);
+  auto aidl_session_type = from_session_type_2_1(session_type);
+  BluetoothAudioSessionControl::UnregisterControlResultCback(aidl_session_type,
+                                                             cookie);
+  auto& session_callback_table = legacy_callback_table[aidl_session_type];
+  if (session_callback_table.find(cookie) != session_callback_table.end()) {
+    std::lock_guard<std::mutex> guard(legacy_callback_lock);
+    session_callback_table.erase(cookie);
+  }
+}
+
+const AudioConfig_2_2 HidlToAidlMiddleware_2_2::GetAudioConfig(
+    const SessionType_2_1& session_type) {
+  return to_hidl_audio_config_2_2(BluetoothAudioSessionControl::GetAudioConfig(
+      from_session_type_2_1(session_type)));
+}
+
+bool HidlToAidlMiddleware_2_2::StartStream(
+    const SessionType_2_1& session_type) {
+  return BluetoothAudioSessionControl::StartStream(
+      from_session_type_2_1(session_type));
+}
+
+bool HidlToAidlMiddleware_2_2::SuspendStream(
+    const SessionType_2_1& session_type) {
+  return BluetoothAudioSessionControl::SuspendStream(
+      from_session_type_2_1(session_type));
+}
+
+void HidlToAidlMiddleware_2_2::StopStream(const SessionType_2_1& session_type) {
+  return BluetoothAudioSessionControl::StopStream(
+      from_session_type_2_1(session_type));
+}
+
+void HidlToAidlMiddleware_2_2::UpdateSinkMetadata(
+    const SessionType_2_1& session_type,
+    const struct sink_metadata* sink_metadata) {
+  return BluetoothAudioSessionControl::UpdateSinkMetadata(
+      from_session_type_2_1(session_type), *sink_metadata);
+}
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_0.h b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_0.h
new file mode 100644
index 0000000..d10ee37
--- /dev/null
+++ b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_0.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/hardware/bluetooth/audio/2.0/types.h>
+
+#include "../session/BluetoothAudioSession.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+using SessionType_2_0 =
+    ::android::hardware::bluetooth::audio::V2_0::SessionType;
+using PortStatusCallbacks_2_0 =
+    ::android::bluetooth::audio::PortStatusCallbacks;
+using AudioConfig_2_0 =
+    ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration;
+
+class HidlToAidlMiddleware_2_0 {
+ public:
+  static bool IsAidlAvailable();
+
+  static bool IsSessionReady(const SessionType_2_0& session_type);
+
+  static uint16_t RegisterControlResultCback(
+      const SessionType_2_0& session_type,
+      const PortStatusCallbacks_2_0& cbacks);
+
+  static void UnregisterControlResultCback(const SessionType_2_0& session_type,
+                                           uint16_t cookie);
+
+  static const AudioConfig_2_0 GetAudioConfig(
+      const SessionType_2_0& session_type);
+
+  static bool StartStream(const SessionType_2_0& session_type);
+
+  static void StopStream(const SessionType_2_0& session_type);
+
+  static bool SuspendStream(const SessionType_2_0& session_type);
+
+  static bool GetPresentationPosition(const SessionType_2_0& session_type,
+                                      uint64_t* remote_delay_report_ns,
+                                      uint64_t* total_bytes_readed,
+                                      timespec* data_position);
+
+  static void UpdateTracksMetadata(
+      const SessionType_2_0& session_type,
+      const struct source_metadata* source_metadata);
+
+  static size_t OutWritePcmData(const SessionType_2_0& session_type,
+                                const void* buffer, size_t bytes);
+};
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_1.h b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_1.h
new file mode 100644
index 0000000..82dce96
--- /dev/null
+++ b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_1.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/hardware/bluetooth/audio/2.1/types.h>
+
+#include "../session/BluetoothAudioSession.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+using SessionType_2_1 =
+    ::android::hardware::bluetooth::audio::V2_1::SessionType;
+using AudioConfig_2_1 =
+    ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration;
+
+class HidlToAidlMiddleware_2_1 {
+ public:
+  static const AudioConfig_2_1 GetAudioConfig(
+      const SessionType_2_1& session_type);
+};
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_2.h b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_2.h
new file mode 100644
index 0000000..149e404
--- /dev/null
+++ b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_2.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/hardware/bluetooth/audio/2.2/types.h>
+
+#include "../session/BluetoothAudioSession.h"
+#include "../session/BluetoothAudioSession_2_2.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+using SessionType_2_1 =
+    ::android::hardware::bluetooth::audio::V2_1::SessionType;
+using PortStatusCallbacks_2_0 =
+    ::android::bluetooth::audio::PortStatusCallbacks;
+using PortStatusCallbacks_2_2 =
+    ::android::bluetooth::audio::PortStatusCallbacks_2_2;
+using AudioConfig_2_2 =
+    ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration;
+
+class HidlToAidlMiddleware_2_2 {
+ public:
+  static bool IsSessionReady(const SessionType_2_1& session_type);
+
+  static uint16_t RegisterControlResultCback(
+      const SessionType_2_1& session_type,
+      const PortStatusCallbacks_2_2& cbacks);
+
+  static void UnregisterControlResultCback(const SessionType_2_1& session_type,
+                                           uint16_t cookie);
+
+  static const AudioConfig_2_2 GetAudioConfig(
+      const SessionType_2_1& session_type);
+
+  static bool StartStream(const SessionType_2_1& session_type);
+
+  static bool SuspendStream(const SessionType_2_1& session_type);
+
+  static void StopStream(const SessionType_2_1& session_type);
+
+  static void UpdateSinkMetadata(const SessionType_2_1& session_type,
+                                 const struct sink_metadata* sink_metadata);
+};
+
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession.cpp
index 2f3ddaf..6d5608b 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession.cpp
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession.cpp
@@ -21,10 +21,13 @@
 #include <android-base/logging.h>
 #include <android-base/stringprintf.h>
 
+#include "../aidl_session/HidlToAidlMiddleware_2_0.h"
+
 namespace android {
 namespace bluetooth {
 namespace audio {
 
+using ::aidl::android::hardware::bluetooth::audio::HidlToAidlMiddleware_2_0;
 using ::android::hardware::audio::common::V5_0::AudioContentType;
 using ::android::hardware::audio::common::V5_0::AudioUsage;
 using ::android::hardware::audio::common::V5_0::PlaybackTrackMetadata;
@@ -149,6 +152,8 @@
 // The function helps to check if this session is ready or not
 // @return: true if the Bluetooth stack has started the specified session
 bool BluetoothAudioSession::IsSessionReady() {
+  if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
+    return HidlToAidlMiddleware_2_0::IsSessionReady(session_type_);
   std::lock_guard<std::recursive_mutex> guard(mutex_);
   bool dataMQ_valid =
       (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH ||
@@ -200,6 +205,9 @@
 // @return: cookie - the assigned number to this bluetooth_audio output
 uint16_t BluetoothAudioSession::RegisterStatusCback(
     const PortStatusCallbacks& cbacks) {
+  if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
+    return HidlToAidlMiddleware_2_0::RegisterControlResultCback(session_type_,
+                                                                cbacks);
   std::lock_guard<std::recursive_mutex> guard(mutex_);
   uint16_t cookie = ObserversCookieGetInitValue(session_type_);
   uint16_t cookie_upper_bound = ObserversCookieGetUpperBound(session_type_);
@@ -227,6 +235,9 @@
 // PortStatusCallbacks
 // @param: cookie - indicates which bluetooth_audio output is
 void BluetoothAudioSession::UnregisterStatusCback(uint16_t cookie) {
+  if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
+    return HidlToAidlMiddleware_2_0::UnregisterControlResultCback(session_type_,
+                                                                  cookie);
   std::lock_guard<std::recursive_mutex> guard(mutex_);
   if (observers_.erase(cookie) != 1) {
     LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
@@ -238,6 +249,9 @@
 // The control function is for the bluetooth_audio module to get the current
 // AudioConfiguration
 const AudioConfiguration& BluetoothAudioSession::GetAudioConfig() {
+  if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
+    return (audio_config_ =
+                HidlToAidlMiddleware_2_0::GetAudioConfig(session_type_));
   std::lock_guard<std::recursive_mutex> guard(mutex_);
   if (IsSessionReady()) {
     return audio_config_;
@@ -251,6 +265,8 @@
 // Those control functions are for the bluetooth_audio module to start, suspend,
 // stop stream, to check position, and to update metadata.
 bool BluetoothAudioSession::StartStream() {
+  if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
+    return HidlToAidlMiddleware_2_0::StartStream(session_type_);
   std::lock_guard<std::recursive_mutex> guard(mutex_);
   if (!IsSessionReady()) {
     LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
@@ -267,6 +283,8 @@
 }
 
 bool BluetoothAudioSession::SuspendStream() {
+  if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
+    return HidlToAidlMiddleware_2_0::SuspendStream(session_type_);
   std::lock_guard<std::recursive_mutex> guard(mutex_);
   if (!IsSessionReady()) {
     LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
@@ -283,6 +301,8 @@
 }
 
 void BluetoothAudioSession::StopStream() {
+  if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
+    return HidlToAidlMiddleware_2_0::StopStream(session_type_);
   std::lock_guard<std::recursive_mutex> guard(mutex_);
   if (!IsSessionReady()) {
     return;
@@ -297,6 +317,10 @@
 bool BluetoothAudioSession::GetPresentationPosition(
     uint64_t* remote_delay_report_ns, uint64_t* total_bytes_readed,
     timespec* data_position) {
+  if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
+    return HidlToAidlMiddleware_2_0::GetPresentationPosition(
+        session_type_, remote_delay_report_ns, total_bytes_readed,
+        data_position);
   std::lock_guard<std::recursive_mutex> guard(mutex_);
   if (!IsSessionReady()) {
     LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
@@ -330,6 +354,9 @@
 
 void BluetoothAudioSession::UpdateTracksMetadata(
     const struct source_metadata* source_metadata) {
+  if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
+    return HidlToAidlMiddleware_2_0::UpdateTracksMetadata(session_type_,
+                                                          source_metadata);
   std::lock_guard<std::recursive_mutex> guard(mutex_);
   if (!IsSessionReady()) {
     LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
@@ -374,6 +401,9 @@
 // The control function writes stream to FMQ
 size_t BluetoothAudioSession::OutWritePcmData(const void* buffer,
                                               size_t bytes) {
+  if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
+    return HidlToAidlMiddleware_2_0::OutWritePcmData(session_type_, buffer,
+                                                     bytes);
   if (buffer == nullptr || !bytes) return 0;
   size_t totalWritten = 0;
   int ms_timeout = kFmqSendTimeoutMs;
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp
index bf1f9b5..276a291 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp
@@ -21,9 +21,14 @@
 #include <android-base/logging.h>
 #include <android-base/stringprintf.h>
 
+#include "../aidl_session/HidlToAidlMiddleware_2_0.h"
+#include "../aidl_session/HidlToAidlMiddleware_2_1.h"
+
 namespace android {
 namespace bluetooth {
 namespace audio {
+using ::aidl::android::hardware::bluetooth::audio::HidlToAidlMiddleware_2_0;
+using ::aidl::android::hardware::bluetooth::audio::HidlToAidlMiddleware_2_1;
 using SessionType_2_1 =
     ::android::hardware::bluetooth::audio::V2_1::SessionType;
 using SessionType_2_0 =
@@ -72,6 +77,7 @@
   } else {
     session_type_2_1_ = (session_type);
   }
+  raw_session_type_ = session_type;
 }
 
 std::shared_ptr<BluetoothAudioSession>
@@ -83,6 +89,8 @@
 // AudioConfiguration
 const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration
 BluetoothAudioSession_2_1::GetAudioConfig() {
+  if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
+    return HidlToAidlMiddleware_2_1::GetAudioConfig(raw_session_type_);
   std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
   if (audio_session->IsSessionReady()) {
     // If session is unknown it means it should be 2.0 type
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h
index 5a35153..e634064 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h
@@ -31,6 +31,7 @@
   std::shared_ptr<BluetoothAudioSession> audio_session;
 
   ::android::hardware::bluetooth::audio::V2_1::SessionType session_type_2_1_;
+  ::android::hardware::bluetooth::audio::V2_1::SessionType raw_session_type_;
 
   // audio data configuration for both software and offloading
   ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
index 60ac4ec..4613ddc 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
@@ -22,10 +22,15 @@
 #include <android-base/stringprintf.h>
 #include <android/hardware/bluetooth/audio/2.2/IBluetoothAudioPort.h>
 
+#include "../aidl_session/HidlToAidlMiddleware_2_0.h"
+#include "../aidl_session/HidlToAidlMiddleware_2_2.h"
+
 namespace android {
 namespace bluetooth {
 namespace audio {
 
+using ::aidl::android::hardware::bluetooth::audio::HidlToAidlMiddleware_2_0;
+using ::aidl::android::hardware::bluetooth::audio::HidlToAidlMiddleware_2_2;
 using ::android::hardware::audio::common::V5_0::AudioSource;
 using ::android::hardware::audio::common::V5_0::RecordTrackMetadata;
 using ::android::hardware::audio::common::V5_0::SinkMetadata;
@@ -93,6 +98,7 @@
   } else {
     session_type_2_1_ = (session_type);
   }
+  raw_session_type_ = session_type;
   invalidSoftwareAudioConfiguration.pcmConfig(kInvalidPcmParameters);
   invalidOffloadAudioConfiguration.codecConfig(
       audio_session->kInvalidCodecConfiguration);
@@ -100,6 +106,8 @@
 }
 
 bool BluetoothAudioSession_2_2::IsSessionReady() {
+  if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
+    return HidlToAidlMiddleware_2_2::IsSessionReady(raw_session_type_);
   if (session_type_2_1_ !=
           SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
       session_type_2_1_ !=
@@ -122,6 +130,9 @@
 
 void BluetoothAudioSession_2_2::UpdateSinkMetadata(
     const struct sink_metadata* sink_metadata) {
+  if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
+    return HidlToAidlMiddleware_2_2::UpdateSinkMetadata(raw_session_type_,
+                                                        sink_metadata);
   std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
   if (!IsSessionReady()) {
     LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_2_1_)
@@ -172,6 +183,8 @@
 // AudioConfiguration
 const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
 BluetoothAudioSession_2_2::GetAudioConfig() {
+  if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
+    return HidlToAidlMiddleware_2_2::GetAudioConfig(raw_session_type_);
   std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
   if (IsSessionReady()) {
     auto audio_config_discriminator = audio_config_2_2_.getDiscriminator();
@@ -226,6 +239,8 @@
 // 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() {
+  if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
+    return HidlToAidlMiddleware_2_2::StartStream(raw_session_type_);
   std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
   if (!IsSessionReady()) {
     LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_2_1_)
@@ -242,6 +257,8 @@
 }
 
 bool BluetoothAudioSession_2_2::SuspendStream() {
+  if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
+    return HidlToAidlMiddleware_2_2::SuspendStream(raw_session_type_);
   std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
   if (!IsSessionReady()) {
     LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_2_1_)
@@ -258,6 +275,8 @@
 }
 
 void BluetoothAudioSession_2_2::StopStream() {
+  if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
+    return HidlToAidlMiddleware_2_2::StopStream(raw_session_type_);
   std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
   if (!IsSessionReady()) {
     return;
@@ -395,6 +414,9 @@
 // @return: cookie - the assigned number to this bluetooth_audio output
 uint16_t BluetoothAudioSession_2_2::RegisterStatusCback(
     const PortStatusCallbacks_2_2& cbacks) {
+  if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
+    return HidlToAidlMiddleware_2_2::RegisterControlResultCback(
+        raw_session_type_, cbacks);
   if (session_type_2_1_ !=
           SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
       session_type_2_1_ !=
@@ -432,6 +454,9 @@
 // PortStatusCallbacks_2_2
 // @param: cookie - indicates which bluetooth_audio output is
 void BluetoothAudioSession_2_2::UnregisterStatusCback(uint16_t cookie) {
+  if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
+    return HidlToAidlMiddleware_2_2::UnregisterControlResultCback(
+        raw_session_type_, 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 &&
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
index 3673fd8..b6f96ab 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
@@ -68,6 +68,7 @@
   std::shared_ptr<BluetoothAudioSession_2_1> audio_session_2_1;
 
   ::android::hardware::bluetooth::audio::V2_1::SessionType session_type_2_1_;
+  ::android::hardware::bluetooth::audio::V2_1::SessionType raw_session_type_;
 
   // audio data configuration for both software and offloading
   ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
diff --git a/common/support/Android.bp b/common/support/Android.bp
index b24893b..718901e 100644
--- a/common/support/Android.bp
+++ b/common/support/Android.bp
@@ -11,7 +11,11 @@
     name: "libaidlcommonsupport",
     vendor_available: true,
     host_supported: true,
-    defaults: ["libbinder_ndk_host_user"],
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
     srcs: ["NativeHandle.cpp"],
     export_include_dirs: ["include"],
     shared_libs: [
@@ -28,7 +32,11 @@
 cc_test {
     name: "libaidlcommonsupport_test",
     host_supported: true,
-    defaults: ["libbinder_ndk_host_user"],
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
     srcs: ["test.cpp"],
     static_libs: [
         "android.hardware.common-V2-ndk",
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index cf85688..a52fde4 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -77,14 +77,6 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.automotive.sv</name>
-        <version>1.0</version>
-        <interface>
-            <name>ISurroundViewService</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
     <hal format="aidl" optional="true">
         <name>android.hardware.automotive.vehicle</name>
         <interface>
@@ -110,6 +102,7 @@
     </hal>
     <hal format="aidl" optional="true">
         <name>android.hardware.biometrics.face</name>
+        <version>2</version>
         <interface>
             <name>IFace</name>
             <instance>default</instance>
@@ -328,7 +321,7 @@
     </hal>
     <hal format="aidl" optional="true">
         <name>android.hardware.identity</name>
-        <version>1-3</version>
+        <version>1-4</version>
         <interface>
             <name>IIdentityCredentialStore</name>
             <instance>default</instance>
@@ -455,7 +448,7 @@
     </hal>
     <hal format="aidl" optional="true">
         <name>android.hardware.neuralnetworks</name>
-        <version>1-3</version>
+        <version>1-4</version>
         <interface>
             <name>IDevice</name>
             <regex-instance>.*</regex-instance>
@@ -777,7 +770,7 @@
     </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.wifi</name>
-        <version>1.3-5</version>
+        <version>1.3-6</version>
         <interface>
             <name>IWifi</name>
             <instance>default</instance>
diff --git a/compatibility_matrices/exclude/fcm_exclude.cpp b/compatibility_matrices/exclude/fcm_exclude.cpp
index 2aa4bb2..414c502 100644
--- a/compatibility_matrices/exclude/fcm_exclude.cpp
+++ b/compatibility_matrices/exclude/fcm_exclude.cpp
@@ -56,6 +56,7 @@
             "android.hardware.common",
             "android.hardware.common.fmq",
             "android.hardware.graphics.common",
+            "android.hardware.input.common",
             "android.hardware.keymaster",
             "android.hardware.radio",
             "android.hardware.uwb.fira_android",
diff --git a/current.txt b/current.txt
index 1dbf5ab..1fedaa0 100644
--- a/current.txt
+++ b/current.txt
@@ -907,6 +907,7 @@
 # ABI preserving changes to HALs during Android T
 62ace52d9c3ff1f60f94118557a2aaf0b953513e59dcd34d5f94ae28d4c7e780 android.hardware.fastboot@1.0::IFastboot
 f767a132ef28275294db15353f14f3876a4048770751931a77d038d4228f2cb7 android.hardware.graphics.composer@2.4::IComposerClient
+d0fb32f3ddeb9af7115ab32905225ea69b930d2472be8e9610f0cf136c15aefb android.hardware.keymaster@4.0::IKeymasterDevice # b/210424594
 ca62a2a95d173ed323309e5e00f653ad3cceec82a6e5e4976a249cb5aafe2515 android.hardware.neuralnetworks@1.2::types
 fa76bced6b1b71c40fc706c508a9011284c57f57831cd0cf5f45653ed4ea463e android.hardware.neuralnetworks@1.3::types
 
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/gnss/aidl/Android.bp b/gnss/aidl/Android.bp
index 12dd0ac..d90cf0b 100644
--- a/gnss/aidl/Android.bp
+++ b/gnss/aidl/Android.bp
@@ -24,27 +24,12 @@
 }
 
 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"],
+    srcs: [
+        "android/hardware/gnss/*.aidl",
+        "android/hardware/gnss/visibility_control/*.aidl",
+    ],
     stability: "vintf",
     backend: {
         java: {
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl
index ebb5d0b..aa514da 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl
@@ -37,4 +37,11 @@
   android.hardware.gnss.GnssMeasurement[] measurements;
   android.hardware.gnss.GnssClock clock;
   android.hardware.gnss.ElapsedRealtime elapsedRealtime;
+  @nullable android.hardware.gnss.GnssData.GnssAgc[] gnssAgcs;
+  @VintfStability
+  parcelable GnssAgc {
+    double agcLevelDb;
+    android.hardware.gnss.GnssConstellationType constellation = android.hardware.gnss.GnssConstellationType.UNKNOWN;
+    long carrierFrequencyHz;
+  }
 }
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 1b4c581..281c531 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
@@ -53,6 +53,7 @@
   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);
+  android.hardware.gnss.IGnssAntennaInfo getExtensionGnssAntennaInfo();
   const int ERROR_INVALID_ARGUMENT = 1;
   const int ERROR_ALREADY_INIT = 2;
   const int ERROR_GENERIC = 3;
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssAntennaInfo.aidl
similarity index 89%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssAntennaInfo.aidl
index 295fde9..2734ac1 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssAntennaInfo.aidl
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.gnss;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+interface IGnssAntennaInfo {
+  void setCallback(in android.hardware.gnss.IGnssAntennaInfoCallback callback);
+  void close();
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssAntennaInfoCallback.aidl
similarity index 63%
copy from bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssAntennaInfoCallback.aidl
index a7224ca..ada9707 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssAntennaInfoCallback.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,30 @@
 // with such a backward incompatible 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.gnss;
 @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;
+interface IGnssAntennaInfoCallback {
+  void gnssAntennaInfoCb(in android.hardware.gnss.IGnssAntennaInfoCallback.GnssAntennaInfo[] gnssAntennaInfos);
   @VintfStability
-  parcelable VendorCapabilities {
-    ParcelableHolder extension;
+  parcelable Row {
+    double[] row;
   }
   @VintfStability
-  union LeAudioCodecCapabilities {
-    android.hardware.bluetooth.audio.Lc3Capabilities lc3Capabilities;
-    android.hardware.bluetooth.audio.LeAudioCapabilities.VendorCapabilities vendorCapabillities;
+  parcelable Coord {
+    double x;
+    double xUncertainty;
+    double y;
+    double yUncertainty;
+    double z;
+    double zUncertainty;
+  }
+  @VintfStability
+  parcelable GnssAntennaInfo {
+    long carrierFrequencyHz;
+    android.hardware.gnss.IGnssAntennaInfoCallback.Coord phaseCenterOffsetCoordinateMillimeters;
+    android.hardware.gnss.IGnssAntennaInfoCallback.Row[] phaseCenterVariationCorrectionMillimeters;
+    android.hardware.gnss.IGnssAntennaInfoCallback.Row[] phaseCenterVariationCorrectionUncertaintyMillimeters;
+    android.hardware.gnss.IGnssAntennaInfoCallback.Row[] signalGainCorrectionDbi;
+    android.hardware.gnss.IGnssAntennaInfoCallback.Row[] signalGainCorrectionUncertaintyDbi;
   }
 }
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss.visibility_control/current/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl
similarity index 96%
rename from gnss/aidl/aidl_api/android.hardware.gnss.visibility_control/current/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl
rename to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl
index 7ef08d2..f674099 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss.visibility_control/current/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl
@@ -34,6 +34,6 @@
 package android.hardware.gnss.visibility_control;
 @VintfStability
 interface IGnssVisibilityControl {
-  void enableNfwLocationAccess(in String[] proxyApps);
+  void enableNfwLocationAccess(in @utf8InCpp 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/current/android/hardware/gnss/visibility_control/IGnssVisibilityControlCallback.aidl
similarity index 100%
rename from gnss/aidl/aidl_api/android.hardware.gnss.visibility_control/current/android/hardware/gnss/visibility_control/IGnssVisibilityControlCallback.aidl
rename to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/visibility_control/IGnssVisibilityControlCallback.aidl
diff --git a/gnss/aidl/android/hardware/gnss/GnssData.aidl b/gnss/aidl/android/hardware/gnss/GnssData.aidl
index ed30c98..204eb65 100644
--- a/gnss/aidl/android/hardware/gnss/GnssData.aidl
+++ b/gnss/aidl/android/hardware/gnss/GnssData.aidl
@@ -18,6 +18,7 @@
 
 import android.hardware.gnss.ElapsedRealtime;
 import android.hardware.gnss.GnssClock;
+import android.hardware.gnss.GnssConstellationType;
 import android.hardware.gnss.GnssMeasurement;
 
 /**
@@ -41,4 +42,55 @@
      * clock.
      */
     ElapsedRealtime elapsedRealtime;
-}
\ No newline at end of file
+
+    /**
+     * Represents a reading of GNSS AGC value of a constellation type and a frequency band.
+     */
+    @VintfStability
+    parcelable GnssAgc {
+        /**
+         * Automatic gain control (AGC) level. AGC acts as a variable gain amplifier adjusting the
+         * power of the incoming signal. The AGC level may be used to indicate potential
+         * interference. Higher gain (and/or lower input power) must be output as a positive number.
+         * Hence in cases of strong jamming, in the band of this signal, this value must go more
+         * negative. This value must be consistent given the same level of the incoming signal
+         * power.
+         *
+         * Note: Different hardware designs (e.g. antenna, pre-amplification, or other RF HW
+         * components) may also affect the typical output of this value on any given hardware design
+         * in an open sky test - the important aspect of this output is that changes in this value
+         * are indicative of changes on input signal power in the frequency band for this
+         * measurement.
+         */
+        double agcLevelDb;
+
+        /**
+         * Constellation type of the SV that transmits the signal.
+         */
+        GnssConstellationType constellation = GnssConstellationType.UNKNOWN;
+
+        /**
+         * 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 not set, 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 raw measurement structs must be reported for this same
+         * satellite, in one of the measurement structs, all the values related
+         * to L1 must be filled, and in the other all of the values related to
+         * L5 must be filled.
+         */
+        long carrierFrequencyHz;
+    }
+
+    /**
+     * The array of GNSS AGC values.
+     *
+     * This field must be reported when the GNSS measurement engine is running, even when the
+     * GnssMeasurement or GnssClock fields are not reported yet. E.g., when a GNSS signal is too
+     * weak to be acquired, the AGC value must still be reported.
+     */
+    @nullable GnssAgc[] gnssAgcs;
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl
index 4ddc6a6..e1d4670 100644
--- a/gnss/aidl/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl
@@ -18,6 +18,7 @@
 
 import android.hardware.gnss.GnssLocation;
 import android.hardware.gnss.IAGnss;
+import android.hardware.gnss.IGnssAntennaInfo;
 import android.hardware.gnss.IGnssBatching;
 import android.hardware.gnss.IGnssCallback;
 import android.hardware.gnss.IGnssConfiguration;
@@ -277,4 +278,11 @@
     void setPositionMode(in GnssPositionMode mode, in GnssPositionRecurrence recurrence,
             in int minIntervalMs, in int preferredAccuracyMeters, in int preferredTimeMs,
             in boolean lowPowerMode);
+
+    /*
+     * This method returns the IGnssAntennaInfo.
+     *
+     * @return Handle to the IGnssAntennaInfo.
+     */
+    IGnssAntennaInfo getExtensionGnssAntennaInfo();
 }
diff --git a/gnss/aidl/android/hardware/gnss/IGnssAntennaInfo.aidl b/gnss/aidl/android/hardware/gnss/IGnssAntennaInfo.aidl
new file mode 100644
index 0000000..de83b67
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssAntennaInfo.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.gnss;
+
+import android.hardware.gnss.IGnssAntennaInfoCallback;
+
+/**
+ * Extended interface for GNSS antenna information support.
+ */
+@VintfStability
+interface IGnssAntennaInfo {
+    /**
+     * Registers the callback routines with the HAL.
+     *
+     * @param callback Handle to the GnssAntennaInfo callback interface.
+     */
+    void setCallback(in IGnssAntennaInfoCallback callback);
+
+    /**
+     * Stops updates from the HAL, and unregisters the callback routines.
+     * After a call to close(), the previously registered callbacks must be
+     * considered invalid by the HAL.
+     * If close() is invoked without a previous setCallback, this function must perform
+     * no work.
+     */
+    void close();
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnssAntennaInfoCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssAntennaInfoCallback.aidl
new file mode 100644
index 0000000..ef0a7fc
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssAntennaInfoCallback.aidl
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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;
+
+/**
+ * The callback interface to report GNSS antenna information from the HAL.
+ */
+@VintfStability
+interface IGnssAntennaInfoCallback {
+    /**
+     * A row of doubles. This is used to represent a row in a 2D array, which are used to
+     * characterize the phase center variation corrections and signal gain corrections.
+     */
+    @VintfStability
+    parcelable Row {
+        double[] row;
+    }
+
+    /**
+     * A point in 3D space, with associated uncertainty.
+     */
+    @VintfStability
+    parcelable Coord {
+        double x;
+
+        double xUncertainty;
+
+        double y;
+
+        double yUncertainty;
+
+        double z;
+
+        double zUncertainty;
+    }
+
+    @VintfStability
+    parcelable GnssAntennaInfo {
+        /**
+         * The carrier frequency in Hz.
+         */
+        long carrierFrequencyHz;
+
+        /**
+         * Phase center offset (PCO) with associated 1-sigma uncertainty. PCO is defined with
+         * respect to the origin of the Android sensor coordinate system, e.g., center of primary
+         * screen for mobiles - see sensor or form factor documents for details.
+         */
+        Coord phaseCenterOffsetCoordinateMillimeters;
+
+        /**
+         * 2D vectors representing the phase center variation (PCV) corrections, in
+         * millimeters, at regularly spaced azimuthal angle (theta) and zenith angle
+         * (phi). The PCV correction is added to the phase measurement to obtain the
+         * corrected value.
+         *
+         * The azimuthal angle, theta, is defined with respect to the X axis of the
+         * Android sensor coordinate system, increasing toward the Y axis. The zenith
+         * angle, phi, is defined with respect to the Z axis of the Android Sensor
+         * coordinate system, increasing toward the X-Y plane.
+         *
+         * Each row vector (outer vectors) represents a fixed theta. The first row
+         * corresponds to a theta angle of 0 degrees. The last row corresponds to a
+         * theta angle of (360 - deltaTheta) degrees, where deltaTheta is the regular
+         * spacing between azimuthal angles, i.e., deltaTheta = 360 / (number of rows).
+         *
+         * The columns (inner vectors) represent fixed zenith angles, beginning at 0
+         * degrees and ending at 180 degrees. They are separated by deltaPhi, the regular
+         * spacing between zenith angles, i.e., deltaPhi = 180 / (number of columns - 1).
+         *
+         * This field is optional, i.e., an empty vector.
+         */
+        Row[] phaseCenterVariationCorrectionMillimeters;
+
+        /**
+         * 2D vectors of 1-sigma uncertainty in millimeters associated with the PCV
+         * correction values.
+         *
+         * This field is optional, i.e., an empty vector.
+         */
+        Row[] phaseCenterVariationCorrectionUncertaintyMillimeters;
+
+        /**
+         * 2D vectors representing the signal gain corrections at regularly spaced
+         * azimuthal angle (theta) and zenith angle (phi). The values are calculated or
+         * measured at the antenna feed point without considering the radio and receiver
+         * noise figure and path loss contribution, in dBi, i.e., decibel over isotropic
+         * antenna with the same total power. The signal gain correction is added the
+         * signal gain measurement to obtain the corrected value.
+         *
+         * The azimuthal angle, theta, is defined with respect to the X axis of the
+         * Android sensor coordinate system, increasing toward the Y axis. The zenith
+         * angle, phi, is defined with respect to the Z axis of the Android Sensor
+         * coordinate system, increasing toward the X-Y plane.
+         *
+         * Each row vector (outer vectors) represents a fixed theta. The first row
+         * corresponds to a theta angle of 0 degrees. The last row corresponds to a
+         * theta angle of (360 - deltaTheta) degrees, where deltaTheta is the regular
+         * spacing between azimuthal angles, i.e., deltaTheta = 360 / (number of rows).
+         *
+         * The columns (inner vectors) represent fixed zenith angles, beginning at 0
+         * degrees and ending at 180 degrees. They are separated by deltaPhi, the regular
+         * spacing between zenith angles, i.e., deltaPhi = 180 / (number of columns - 1).
+         *
+         * This field is optional, i.e., an empty vector.
+         */
+        Row[] signalGainCorrectionDbi;
+
+        /**
+         * 2D vectors of 1-sigma uncertainty in dBi associated with the signal
+         * gain correction values.
+         *
+         * This field is optional, i.e., an empty vector.
+         */
+        Row[] signalGainCorrectionUncertaintyDbi;
+    }
+
+    /**
+     * Called when on connection, and on known-change to these values, such as upon a known
+     * GNSS RF antenna tuning change, or a foldable device state change.
+     *
+     * This is optional. It can never be called if the GNSS antenna information is not
+     * available.
+     */
+    void gnssAntennaInfoCb(in GnssAntennaInfo[] gnssAntennaInfos);
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
index 157c912..a74d097 100644
--- a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
@@ -67,7 +67,7 @@
     /** 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 */
+    /** Capability bit mask indicating that GNSS supports antenna info */
     const int CAPABILITY_ANTENNA_INFO = 1 << 11;
 
     /** Capability bit mask indicating that GNSS supports correlation vector */
diff --git a/gnss/aidl/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl b/gnss/aidl/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl
index 93c3f2c..c9c1549 100644
--- a/gnss/aidl/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl
+++ b/gnss/aidl/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl
@@ -71,7 +71,7 @@
      * 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);
+    void enableNfwLocationAccess(in @utf8InCpp String[] proxyApps);
 
     /**
      * Registers the callback for HAL implementation to use.
diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp
index 29c26d1..0031dcf 100644
--- a/gnss/aidl/default/Android.bp
+++ b/gnss/aidl/default/Android.bp
@@ -52,12 +52,12 @@
         "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",
+        "GnssAntennaInfo.cpp",
         "GnssBatching.cpp",
         "GnssDebug.cpp",
         "GnssGeofence.cpp",
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index e296351..2c6df99 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -20,6 +20,8 @@
 #include <inttypes.h>
 #include <log/log.h>
 #include "AGnss.h"
+#include "DeviceFileReader.h"
+#include "GnssAntennaInfo.h"
 #include "GnssBatching.h"
 #include "GnssConfiguration.h"
 #include "GnssDebug.h"
@@ -28,10 +30,13 @@
 #include "GnssNavigationMessageInterface.h"
 #include "GnssPsds.h"
 #include "GnssVisibilityControl.h"
+#include "NmeaFixInfo.h"
 #include "Utils.h"
 
 namespace aidl::android::hardware::gnss {
+using ::android::hardware::gnss::common::NmeaFixInfo;
 using ::android::hardware::gnss::common::Utils;
+
 using ndk::ScopedAStatus;
 using GnssSvInfo = IGnssCallback::GnssSvInfo;
 
@@ -52,7 +57,8 @@
 
     int capabilities = (int)(IGnssCallback::CAPABILITY_SATELLITE_BLOCKLIST |
                              IGnssCallback::CAPABILITY_SATELLITE_PVT |
-                             IGnssCallback::CAPABILITY_CORRELATION_VECTOR);
+                             IGnssCallback::CAPABILITY_CORRELATION_VECTOR |
+                             IGnssCallback::CAPABILITY_ANTENNA_INFO);
 
     auto status = sGnssCallback->gnssSetCapabilitiesCb(capabilities);
     if (!status.isOk()) {
@@ -62,6 +68,12 @@
     return ScopedAStatus::ok();
 }
 
+std::unique_ptr<GnssLocation> Gnss::getLocationFromHW() {
+    std::string inputStr =
+            ::android::hardware::gnss::common::DeviceFileReader::Instance().getLocationData();
+    return ::android::hardware::gnss::common::NmeaFixInfo::getAidlLocationFromInputStr(inputStr);
+}
+
 ScopedAStatus Gnss::start() {
     ALOGD("start()");
     if (mIsActive) {
@@ -82,9 +94,14 @@
             auto svStatus = filterBlocklistedSatellites(Utils::getMockSvInfoList());
             this->reportSvStatus(svStatus);
 
+            auto currentLocation = getLocationFromHW();
             mGnssPowerIndication->notePowerConsumption();
-            const auto location = Utils::getMockLocation();
-            this->reportLocation(location);
+            if (currentLocation != nullptr) {
+                this->reportLocation(*currentLocation);
+            } else {
+                const auto location = Utils::getMockLocation();
+                this->reportLocation(location);
+            }
             std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
         }
     });
@@ -264,4 +281,12 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus Gnss::getExtensionGnssAntennaInfo(
+        std::shared_ptr<IGnssAntennaInfo>* iGnssAntennaInfo) {
+    ALOGD("Gnss::getExtensionGnssAntennaInfo");
+
+    *iGnssAntennaInfo = SharedRefBase::make<GnssAntennaInfo>();
+    return ndk::ScopedAStatus::ok();
+}
+
 }  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h
index 384c862..b92f4fb 100644
--- a/gnss/aidl/default/Gnss.h
+++ b/gnss/aidl/default/Gnss.h
@@ -18,6 +18,7 @@
 
 #include <aidl/android/hardware/gnss/BnAGnss.h>
 #include <aidl/android/hardware/gnss/BnGnss.h>
+#include <aidl/android/hardware/gnss/BnGnssAntennaInfo.h>
 #include <aidl/android/hardware/gnss/BnGnssBatching.h>
 #include <aidl/android/hardware/gnss/BnGnssConfiguration.h>
 #include <aidl/android/hardware/gnss/BnGnssDebug.h>
@@ -69,6 +70,8 @@
     ndk::ScopedAStatus getExtensionGnssVisibilityControl(
             std::shared_ptr<android::hardware::gnss::visibility_control::IGnssVisibilityControl>*
                     iGnssVisibilityControl) override;
+    ndk::ScopedAStatus getExtensionGnssAntennaInfo(
+            std::shared_ptr<IGnssAntennaInfo>* iGnssAntennaInfo) override;
 
     std::shared_ptr<GnssConfiguration> mGnssConfiguration;
     std::shared_ptr<GnssPowerIndication> mGnssPowerIndication;
@@ -79,6 +82,7 @@
     std::vector<IGnssCallback::GnssSvInfo> filterBlocklistedSatellites(
             std::vector<IGnssCallback::GnssSvInfo> gnssSvInfoList);
     void reportGnssStatusValue(const IGnssCallback::GnssStatusValue gnssStatusValue) const;
+    std::unique_ptr<GnssLocation> getLocationFromHW();
 
     static std::shared_ptr<IGnssCallback> sGnssCallback;
 
diff --git a/gnss/aidl/default/GnssAntennaInfo.cpp b/gnss/aidl/default/GnssAntennaInfo.cpp
new file mode 100644
index 0000000..72def71
--- /dev/null
+++ b/gnss/aidl/default/GnssAntennaInfo.cpp
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "GnssAntennaInfoAidl"
+
+#include "GnssAntennaInfo.h"
+#include <aidl/android/hardware/gnss/BnGnss.h>
+#include <log/log.h>
+#include "Utils.h"
+
+namespace aidl::android::hardware::gnss {
+
+using namespace ::android::hardware::gnss;
+using Row = IGnssAntennaInfoCallback::Row;
+using Coord = IGnssAntennaInfoCallback::Coord;
+
+std::shared_ptr<IGnssAntennaInfoCallback> GnssAntennaInfo::sCallback = nullptr;
+
+GnssAntennaInfo::GnssAntennaInfo() : mMinIntervalMs(1000) {}
+
+GnssAntennaInfo::~GnssAntennaInfo() {
+    stop();
+}
+
+// Methods from ::android::hardware::gnss::V2_1::IGnssAntennaInfo follow.
+ndk::ScopedAStatus GnssAntennaInfo::setCallback(
+        const std::shared_ptr<IGnssAntennaInfoCallback>& callback) {
+    ALOGD("setCallback");
+    std::unique_lock<std::mutex> lock(mMutex);
+    sCallback = callback;
+
+    if (mIsActive) {
+        ALOGW("GnssAntennaInfo callback already set. Resetting the callback...");
+        stop();
+    }
+    start();
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssAntennaInfo::close() {
+    ALOGD("close");
+    stop();
+    std::unique_lock<std::mutex> lock(mMutex);
+    sCallback = nullptr;
+    return ndk::ScopedAStatus::ok();
+}
+
+void GnssAntennaInfo::start() {
+    ALOGD("start");
+    mIsActive = true;
+    mThread = std::thread([this]() {
+        while (mIsActive == true) {
+            if (sCallback != nullptr) {
+                IGnssAntennaInfoCallback::GnssAntennaInfo mockAntennaInfo_1 = {
+                        .carrierFrequencyHz = 1575420000,
+                        .phaseCenterOffsetCoordinateMillimeters = Coord{.x = 1,
+                                                                        .xUncertainty = 0.1,
+                                                                        .y = 2,
+                                                                        .yUncertainty = 0.1,
+                                                                        .z = 3,
+                                                                        .zUncertainty = 0.1},
+                        .phaseCenterVariationCorrectionMillimeters =
+                                {
+                                        Row{std::vector<double>{1, -1, 5, -2, 3, -1}},
+                                        Row{std::vector<double>{-2, 3, 2, 0, 1, 2}},
+                                        Row{std::vector<double>{1, 3, 2, -1, -3, 5}},
+                                },
+                        .phaseCenterVariationCorrectionUncertaintyMillimeters =
+                                {
+                                        Row{std::vector<double>{0.1, 0.2, 0.4, 0.1, 0.2, 0.3}},
+                                        Row{std::vector<double>{0.3, 0.2, 0.3, 0.6, 0.1, 0.1}},
+                                        Row{std::vector<double>{0.1, 0.1, 0.4, 0.2, 0.5, 0.3}},
+                                },
+                        .signalGainCorrectionDbi =
+                                {
+                                        Row{std::vector<double>{2, -3, 1, -3, 0, -4}},
+                                        Row{std::vector<double>{1, 0, -4, 1, 3, -2}},
+                                        Row{std::vector<double>{3, -2, 0, -2, 3, 0}},
+                                },
+                        .signalGainCorrectionUncertaintyDbi =
+                                {
+                                        Row{std::vector<double>{0.3, 0.1, 0.2, 0.6, 0.1, 0.3}},
+                                        Row{std::vector<double>{0.1, 0.1, 0.5, 0.2, 0.3, 0.1}},
+                                        Row{std::vector<double>{0.2, 0.4, 0.2, 0.1, 0.1, 0.2}},
+                                },
+                };
+
+                IGnssAntennaInfoCallback::GnssAntennaInfo mockAntennaInfo_2 = {
+                        .carrierFrequencyHz = 1176450000,
+                        .phaseCenterOffsetCoordinateMillimeters = Coord{.x = 5,
+                                                                        .xUncertainty = 0.1,
+                                                                        .y = 6,
+                                                                        .yUncertainty = 0.1,
+                                                                        .z = 7,
+                                                                        .zUncertainty = 0.1},
+                };
+
+                std::vector<IGnssAntennaInfoCallback::GnssAntennaInfo> mockAntennaInfos = {
+                        mockAntennaInfo_1,
+                        mockAntennaInfo_2,
+                };
+                this->reportAntennaInfo(mockAntennaInfos);
+            }
+
+            /** For mock implementation this is good. On real device, we should only report
+                antennaInfo at start and when there is a configuration change. **/
+            std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
+        }
+    });
+}
+
+void GnssAntennaInfo::stop() {
+    ALOGD("stop");
+    mIsActive = false;
+    if (mThread.joinable()) {
+        mThread.join();
+    }
+}
+
+void GnssAntennaInfo::reportAntennaInfo(
+        const std::vector<IGnssAntennaInfoCallback::GnssAntennaInfo>& antennaInfo) const {
+    std::unique_lock<std::mutex> lock(mMutex);
+
+    if (sCallback == nullptr) {
+        ALOGE("%s: No non-null callback", __func__);
+        return;
+    }
+
+    auto ret = sCallback->gnssAntennaInfoCb(antennaInfo);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+}  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssAntennaInfo.h b/gnss/aidl/default/GnssAntennaInfo.h
new file mode 100644
index 0000000..2cf7b13
--- /dev/null
+++ b/gnss/aidl/default/GnssAntennaInfo.h
@@ -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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/gnss/BnGnssAntennaInfo.h>
+#include <atomic>
+#include <mutex>
+#include <thread>
+
+namespace aidl::android::hardware::gnss {
+
+struct GnssAntennaInfo : public BnGnssAntennaInfo {
+  public:
+    GnssAntennaInfo();
+    ~GnssAntennaInfo();
+    ndk::ScopedAStatus setCallback(
+            const std::shared_ptr<IGnssAntennaInfoCallback>& callback) override;
+    ndk::ScopedAStatus close() override;
+
+  private:
+    void start();
+    void stop();
+    void reportAntennaInfo(
+            const std::vector<IGnssAntennaInfoCallback::GnssAntennaInfo>& antennaInfo) const;
+
+    // Guarded by mMutex
+    static std::shared_ptr<IGnssAntennaInfoCallback> sCallback;
+
+    std::atomic<bool> mIsActive;
+    std::atomic<long> mMinIntervalMs;
+    std::thread mThread;
+
+    // Synchronization lock for sCallback
+    mutable std::mutex mMutex;
+};
+
+}  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp
index d532fad..b23a646 100644
--- a/gnss/aidl/vts/Android.bp
+++ b/gnss/aidl/vts/Android.bp
@@ -31,6 +31,7 @@
         "gnss_hal_test.cpp",
         "gnss_hal_test_cases.cpp",
         "AGnssCallbackAidl.cpp",
+        "GnssAntennaInfoCallbackAidl.cpp",
         "GnssBatchingCallback.cpp",
         "GnssCallbackAidl.cpp",
         "GnssGeofenceCallback.cpp",
@@ -50,7 +51,6 @@
     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/GnssAntennaInfoCallbackAidl.cpp b/gnss/aidl/vts/GnssAntennaInfoCallbackAidl.cpp
new file mode 100644
index 0000000..11001cd
--- /dev/null
+++ b/gnss/aidl/vts/GnssAntennaInfoCallbackAidl.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "GnssAntennaInfoCallbackAidl.h"
+#include <inttypes.h>
+#include <log/log.h>
+
+android::binder::Status GnssAntennaInfoCallbackAidl::gnssAntennaInfoCb(
+        const std::vector<IGnssAntennaInfoCallback::GnssAntennaInfo>& gnssAntennaInfos) {
+    ALOGD("GnssAntennaInfo received. Size = %d", (int)gnssAntennaInfos.size());
+    antenna_info_cbq_.store(gnssAntennaInfos);
+    return android::binder::Status::ok();
+}
diff --git a/gnss/aidl/vts/GnssAntennaInfoCallbackAidl.h b/gnss/aidl/vts/GnssAntennaInfoCallbackAidl.h
new file mode 100644
index 0000000..77e1057
--- /dev/null
+++ b/gnss/aidl/vts/GnssAntennaInfoCallbackAidl.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 <android/hardware/gnss/BnGnssAntennaInfoCallback.h>
+#include <vector>
+#include "GnssCallbackEventQueue.h"
+
+/** Implementation for IGnssAntennaInfoCallback. */
+class GnssAntennaInfoCallbackAidl : public android::hardware::gnss::BnGnssAntennaInfoCallback {
+  public:
+    GnssAntennaInfoCallbackAidl() : antenna_info_cbq_("info"){};
+    ~GnssAntennaInfoCallbackAidl(){};
+
+    android::binder::Status gnssAntennaInfoCb(
+            const std::vector<IGnssAntennaInfoCallback::GnssAntennaInfo>& gnssAntennaInfos)
+            override;
+
+    android::hardware::gnss::common::GnssCallbackEventQueue<
+            std::vector<IGnssAntennaInfoCallback::GnssAntennaInfo>>
+            antenna_info_cbq_;
+};
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index 9acef8b..f5f0aa4 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -18,6 +18,7 @@
 
 #include <android/hardware/gnss/IAGnss.h>
 #include <android/hardware/gnss/IGnss.h>
+#include <android/hardware/gnss/IGnssAntennaInfo.h>
 #include <android/hardware/gnss/IGnssBatching.h>
 #include <android/hardware/gnss/IGnssDebug.h>
 #include <android/hardware/gnss/IGnssMeasurementCallback.h>
@@ -27,6 +28,7 @@
 #include <android/hardware/gnss/visibility_control/IGnssVisibilityControl.h>
 #include <cutils/properties.h>
 #include "AGnssCallbackAidl.h"
+#include "GnssAntennaInfoCallbackAidl.h"
 #include "GnssBatchingCallback.h"
 #include "GnssGeofenceCallback.h"
 #include "GnssMeasurementCallbackAidl.h"
@@ -44,6 +46,8 @@
 using android::hardware::gnss::GnssPowerStats;
 using android::hardware::gnss::IAGnss;
 using android::hardware::gnss::IGnss;
+using android::hardware::gnss::IGnssAntennaInfo;
+using android::hardware::gnss::IGnssAntennaInfoCallback;
 using android::hardware::gnss::IGnssBatching;
 using android::hardware::gnss::IGnssBatchingCallback;
 using android::hardware::gnss::IGnssCallback;
@@ -923,7 +927,8 @@
     status = iGnssVisibilityControl->setCallback(gnssVisibilityControlCallback);
     ASSERT_TRUE(status.isOk());
 
-    std::vector<String16> proxyApps{String16("com.example.ims"), String16("com.example.mdt")};
+    std::vector<std::string> proxyApps{std::string("com.example.ims"),
+                                       std::string("com.example.mdt")};
     status = iGnssVisibilityControl->enableNfwLocationAccess(proxyApps);
     ASSERT_TRUE(status.isOk());
 }
@@ -966,3 +971,127 @@
     status = iGnssMeasurement->close();
     ASSERT_TRUE(status.isOk());
 }
+
+/*
+ * TestGnssAgcInGnssMeasurement:
+ * 1. Gets the GnssMeasurementExtension and verifies that it returns a non-null extension.
+ * 2. Sets a GnssMeasurementCallback, waits for a measurement.
+ */
+TEST_P(GnssHalTest, TestGnssAgcInGnssMeasurement) {
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        return;
+    }
+    const int kFirstGnssMeasurementTimeoutSeconds = 10;
+    const int kNumMeasurementEvents = 15;
+
+    sp<IGnssMeasurementInterface> iGnssMeasurement;
+    auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
+    ASSERT_TRUE(status.isOk());
+    ASSERT_TRUE(iGnssMeasurement != nullptr);
+
+    auto callback = sp<GnssMeasurementCallbackAidl>::make();
+    status = iGnssMeasurement->setCallback(callback, /* enableFullTracking= */ false,
+                                           /* enableCorrVecOutputs */ false);
+    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);
+
+        ASSERT_TRUE(lastMeasurement.gnssAgcs.has_value());
+        for (const auto& gnssAgc : lastMeasurement.gnssAgcs.value()) {
+            ASSERT_TRUE(gnssAgc.has_value());
+            ASSERT_TRUE(gnssAgc.value().carrierFrequencyHz >= 0);
+        }
+    }
+
+    status = iGnssMeasurement->close();
+    ASSERT_TRUE(status.isOk());
+}
+
+/*
+ * TestGnssAntennaInfo:
+ * Sets a GnssAntennaInfoCallback, waits for report, and verifies
+ * 1. phaseCenterOffsetCoordinateMillimeters is valid
+ * 2. phaseCenterOffsetCoordinateUncertaintyMillimeters is valid.
+ * PhaseCenterVariationCorrections and SignalGainCorrections are optional.
+ */
+TEST_P(GnssHalTest, TestGnssAntennaInfo) {
+    const int kAntennaInfoTimeoutSeconds = 2;
+
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        return;
+    }
+
+    sp<IGnssAntennaInfo> iGnssAntennaInfo;
+    auto status = aidl_gnss_hal_->getExtensionGnssAntennaInfo(&iGnssAntennaInfo);
+    ASSERT_TRUE(status.isOk());
+
+    if (!(aidl_gnss_cb_->last_capabilities_ & (int)GnssCallbackAidl::CAPABILITY_ANTENNA_INFO) ||
+        iGnssAntennaInfo == nullptr) {
+        ALOGD("GnssAntennaInfo AIDL is not supported.");
+        return;
+    }
+
+    auto callback = sp<GnssAntennaInfoCallbackAidl>::make();
+    status = iGnssAntennaInfo->setCallback(callback);
+    ASSERT_TRUE(status.isOk());
+
+    std::vector<IGnssAntennaInfoCallback::GnssAntennaInfo> antennaInfos;
+    ASSERT_TRUE(callback->antenna_info_cbq_.retrieve(antennaInfos, kAntennaInfoTimeoutSeconds));
+    EXPECT_EQ(callback->antenna_info_cbq_.calledCount(), 1);
+    ASSERT_TRUE(antennaInfos.size() > 0);
+
+    for (auto antennaInfo : antennaInfos) {
+        // Remaining fields are optional
+        if (!antennaInfo.phaseCenterVariationCorrectionMillimeters.empty()) {
+            int numRows = antennaInfo.phaseCenterVariationCorrectionMillimeters.size();
+            int numColumns = antennaInfo.phaseCenterVariationCorrectionMillimeters[0].row.size();
+            // Must have at least 1 row and 2 columns
+            ASSERT_TRUE(numRows >= 1 && numColumns >= 2);
+
+            // Corrections and uncertainties must have same dimensions
+            ASSERT_TRUE(antennaInfo.phaseCenterVariationCorrectionMillimeters.size() ==
+                        antennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters.size());
+            ASSERT_TRUE(
+                    antennaInfo.phaseCenterVariationCorrectionMillimeters[0].row.size() ==
+                    antennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters[0].row.size());
+
+            // Must be rectangular
+            for (auto row : antennaInfo.phaseCenterVariationCorrectionMillimeters) {
+                ASSERT_TRUE(row.row.size() == numColumns);
+            }
+            for (auto row : antennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters) {
+                ASSERT_TRUE(row.row.size() == numColumns);
+            }
+        }
+        if (!antennaInfo.signalGainCorrectionDbi.empty()) {
+            int numRows = antennaInfo.signalGainCorrectionDbi.size();
+            int numColumns = antennaInfo.signalGainCorrectionUncertaintyDbi[0].row.size();
+            // Must have at least 1 row and 2 columns
+            ASSERT_TRUE(numRows >= 1 && numColumns >= 2);
+
+            // Corrections and uncertainties must have same dimensions
+            ASSERT_TRUE(antennaInfo.signalGainCorrectionDbi.size() ==
+                        antennaInfo.signalGainCorrectionUncertaintyDbi.size());
+            ASSERT_TRUE(antennaInfo.signalGainCorrectionDbi[0].row.size() ==
+                        antennaInfo.signalGainCorrectionUncertaintyDbi[0].row.size());
+
+            // Must be rectangular
+            for (auto row : antennaInfo.signalGainCorrectionDbi) {
+                ASSERT_TRUE(row.row.size() == numColumns);
+            }
+            for (auto row : antennaInfo.signalGainCorrectionUncertaintyDbi) {
+                ASSERT_TRUE(row.row.size() == numColumns);
+            }
+        }
+    }
+
+    iGnssAntennaInfo->close();
+}
diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp
index 05bec88..b896f04 100644
--- a/gnss/common/utils/default/Android.bp
+++ b/gnss/common/utils/default/Android.bp
@@ -39,6 +39,7 @@
         "v2_1/GnssMeasurement.cpp",
         "v2_1/GnssMeasurementCorrections.cpp",
         "DeviceFileReader.cpp",
+        "FixLocationParser.cpp",
         "GnssRawMeasurementParser.cpp",
         "GnssReplayUtils.cpp",
         "MockLocation.cpp",
diff --git a/gnss/common/utils/default/FixLocationParser.cpp b/gnss/common/utils/default/FixLocationParser.cpp
new file mode 100644
index 0000000..f391d96
--- /dev/null
+++ b/gnss/common/utils/default/FixLocationParser.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FixLocationParser.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+
+using aidl::android::hardware::gnss::ElapsedRealtime;
+using aidl::android::hardware::gnss::GnssLocation;
+
+std::unique_ptr<GnssLocation> FixLocationParser::getLocationFromInputStr(
+        const std::string& locationStr) {
+    /*
+     * Fix,Provider,LatitudeDegrees,LongitudeDegrees,AltitudeMeters,SpeedMps,
+     * AccuracyMeters,BearingDegrees,UnixTimeMillis,SpeedAccuracyMps,BearingAccuracyDegrees,
+     * elapsedRealtimeNanos
+     */
+    if (locationStr.empty()) {
+        return nullptr;
+    }
+    std::vector<std::string> locationStrRecords;
+    ParseUtils::splitStr(locationStr, LINE_SEPARATOR, locationStrRecords);
+    if (locationStrRecords.empty()) {
+        return nullptr;
+    }
+
+    std::vector<std::string> locationValues;
+    ParseUtils::splitStr(locationStrRecords[0], COMMA_SEPARATOR, locationValues);
+    if (locationValues.size() < 12) {
+        return nullptr;
+    }
+    ElapsedRealtime elapsedRealtime = {
+            .flags = ElapsedRealtime::HAS_TIMESTAMP_NS | ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS,
+            .timestampNs = ::android::elapsedRealtimeNano(),
+            // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks.
+            // In an actual implementation provide an estimate of the synchronization uncertainty
+            // or don't set the field.
+            .timeUncertaintyNs = 1020400};
+
+    GnssLocation location = {
+            .gnssLocationFlags = 0xFF,
+            .latitudeDegrees = ParseUtils::tryParseDouble(locationValues[2], 0),
+            .longitudeDegrees = ParseUtils::tryParseDouble(locationValues[3], 0),
+            .altitudeMeters = ParseUtils::tryParseDouble(locationValues[4], 0),
+            .speedMetersPerSec = ParseUtils::tryParseDouble(locationValues[5], 0),
+            .bearingDegrees = ParseUtils::tryParseDouble(locationValues[7], 0),
+            .horizontalAccuracyMeters = ParseUtils::tryParseDouble(locationValues[6], 0),
+            .verticalAccuracyMeters = ParseUtils::tryParseDouble(locationValues[6], 0),
+            .speedAccuracyMetersPerSecond = ParseUtils::tryParseDouble(locationValues[9], 0),
+            .bearingAccuracyDegrees = ParseUtils::tryParseDouble(locationValues[10], 0),
+            .timestampMillis = ParseUtils::tryParseLongLong(locationValues[8], 0),
+            .elapsedRealtime = elapsedRealtime};
+    return std::make_unique<GnssLocation>(location);
+}
+
+}  // namespace common
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
\ No newline at end of file
diff --git a/gnss/common/utils/default/GnssReplayUtils.cpp b/gnss/common/utils/default/GnssReplayUtils.cpp
index e3f4ff8..5356477 100644
--- a/gnss/common/utils/default/GnssReplayUtils.cpp
+++ b/gnss/common/utils/default/GnssReplayUtils.cpp
@@ -41,7 +41,7 @@
 
 bool ReplayUtils::isNMEA(const std::string& inputStr) {
     return !inputStr.empty() && (inputStr.find("$GPRMC,", 0) != std::string::npos ||
-                                 inputStr.find("$GPRMA,", 0) != std::string::npos);
+                                 inputStr.find("$GPGGA,", 0) != std::string::npos);
 }
 
 }  // namespace common
diff --git a/gnss/common/utils/default/NmeaFixInfo.cpp b/gnss/common/utils/default/NmeaFixInfo.cpp
index c7ee134..22aef90 100644
--- a/gnss/common/utils/default/NmeaFixInfo.cpp
+++ b/gnss/common/utils/default/NmeaFixInfo.cpp
@@ -34,6 +34,9 @@
 namespace gnss {
 namespace common {
 
+using aidl::android::hardware::gnss::ElapsedRealtime;
+using aidl::android::hardware::gnss::GnssLocation;
+
 NmeaFixInfo::NmeaFixInfo() : hasGMCRecord(false), hasGGARecord(false) {}
 
 float NmeaFixInfo::getAltitudeMeters() const {
@@ -237,6 +240,40 @@
 }
 
 /**
+ * Convert V2_0::GnssLocation to aidl::GnssLocation.
+ */
+std::unique_ptr<GnssLocation> NmeaFixInfo::getAidlLocationFromInputStr(
+        const std::string& inputStr) {
+    std::unique_ptr<V2_0::GnssLocation> locationV2 = getLocationFromInputStr(inputStr);
+    if (locationV2 == nullptr) {
+        return nullptr;
+    }
+
+    ElapsedRealtime elapsedRealtime = {
+            .flags = ElapsedRealtime::HAS_TIMESTAMP_NS | ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS,
+            .timestampNs = ::android::elapsedRealtimeNano(),
+            // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks.
+            // In an actual implementation provide an estimate of the synchronization uncertainty
+            // or don't set the field.
+            .timeUncertaintyNs = 1020400};
+
+    GnssLocation location = {
+            .gnssLocationFlags = locationV2->v1_0.gnssLocationFlags,
+            .latitudeDegrees = locationV2->v1_0.latitudeDegrees,
+            .longitudeDegrees = locationV2->v1_0.longitudeDegrees,
+            .altitudeMeters = locationV2->v1_0.altitudeMeters,
+            .speedMetersPerSec = locationV2->v1_0.speedMetersPerSec,
+            .bearingDegrees = locationV2->v1_0.bearingDegrees,
+            .horizontalAccuracyMeters = locationV2->v1_0.horizontalAccuracyMeters,
+            .verticalAccuracyMeters = locationV2->v1_0.verticalAccuracyMeters,
+            .speedAccuracyMetersPerSecond = locationV2->v1_0.speedAccuracyMetersPerSecond,
+            .bearingAccuracyDegrees = locationV2->v1_0.bearingAccuracyDegrees,
+            .timestampMillis = locationV2->v1_0.timestamp,
+            .elapsedRealtime = elapsedRealtime};
+    return std::make_unique<GnssLocation>(location);
+}
+
+/**
  * Parses the input string in NMEA format and convert to GnssLocation.
  */
 std::unique_ptr<V2_0::GnssLocation> NmeaFixInfo::toGnssLocation() const {
diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp
index 563c6d5..1ff84eb 100644
--- a/gnss/common/utils/default/Utils.cpp
+++ b/gnss/common/utils/default/Utils.cpp
@@ -38,6 +38,7 @@
 using GnssSvFlags = aidl::android::hardware::gnss::IGnssCallback::GnssSvFlags;
 
 using GnssSvFlagsV1_0 = V1_0::IGnssCallback::GnssSvFlags;
+using GnssAgc = aidl::android::hardware::gnss::GnssData::GnssAgc;
 using GnssMeasurementFlagsV1_0 = V1_0::IGnssMeasurementCallback::GnssMeasurementFlags;
 using GnssMeasurementFlagsV2_1 = V2_1::IGnssMeasurementCallback::GnssMeasurementFlags;
 using GnssMeasurementStateV2_0 = V2_0::IGnssMeasurementCallback::GnssMeasurementState;
@@ -231,8 +232,23 @@
         measurement.flags |= GnssMeasurement::HAS_CORRELATION_VECTOR;
     }
 
-    GnssData gnssData = {
-            .measurements = {measurement}, .clock = clock, .elapsedRealtime = timestamp};
+    GnssAgc gnssAgc1 = {
+            .agcLevelDb = 3.5,
+            .constellation = GnssConstellationType::GLONASS,
+            .carrierFrequencyHz = (int64_t)kGloG1FreqHz,
+    };
+
+    GnssAgc gnssAgc2 = {
+            .agcLevelDb = -5.1,
+            .constellation = GnssConstellationType::GPS,
+            .carrierFrequencyHz = (int64_t)kGpsL1FreqHz,
+    };
+
+    GnssData gnssData = {.measurements = {measurement},
+                         .clock = clock,
+                         .elapsedRealtime = timestamp,
+                         .gnssAgcs = std::make_optional(std::vector(
+                                 {std::make_optional(gnssAgc1), std::make_optional(gnssAgc2)}))};
     return gnssData;
 }
 
diff --git a/gnss/common/utils/default/include/FixLocationParser.h b/gnss/common/utils/default/include/FixLocationParser.h
new file mode 100644
index 0000000..a738914
--- /dev/null
+++ b/gnss/common/utils/default/include/FixLocationParser.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_gnss_common_default_FixLocationParser_H_
+#define android_hardware_gnss_common_default_FixLocationParser_H_
+
+#include <aidl/android/hardware/gnss/BnGnss.h>
+
+#include <utils/SystemClock.h>
+#include <string>
+#include <vector>
+
+#include <Constants.h>
+#include <Utils.h>
+#include <log/log.h>
+#include "Constants.h"
+#include "ParseUtils.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+
+struct FixLocationParser {
+  public:
+    static std::unique_ptr<aidl::android::hardware::gnss::GnssLocation> getLocationFromInputStr(
+            const std::string& inputStr);
+};
+
+}  // namespace common
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_common_default_FixLocationParser_H_
\ No newline at end of file
diff --git a/gnss/common/utils/default/include/NmeaFixInfo.h b/gnss/common/utils/default/include/NmeaFixInfo.h
index 5c27045..4073361 100644
--- a/gnss/common/utils/default/include/NmeaFixInfo.h
+++ b/gnss/common/utils/default/include/NmeaFixInfo.h
@@ -22,6 +22,7 @@
 #include <hidl/Status.h>
 #include <ctime>
 #include <string>
+#include "aidl/android/hardware/gnss/IGnss.h"
 namespace android {
 namespace hardware {
 namespace gnss {
@@ -45,6 +46,8 @@
 
   public:
     static std::unique_ptr<V2_0::GnssLocation> getLocationFromInputStr(const std::string& inputStr);
+    static std::unique_ptr<aidl::android::hardware::gnss::GnssLocation> getAidlLocationFromInputStr(
+            const std::string& inputStr);
 
   private:
     static void splitStr(const std::string& line, const char& delimiter,
diff --git a/graphics/composer/2.1/default/OWNERS b/graphics/composer/2.1/default/OWNERS
index 709c4d1..331c80d 100644
--- a/graphics/composer/2.1/default/OWNERS
+++ b/graphics/composer/2.1/default/OWNERS
@@ -1,3 +1,4 @@
 # Graphics team
 adyabr@google.com
+alecmouri@google.com
 lpy@google.com
diff --git a/graphics/composer/2.1/utils/OWNERS b/graphics/composer/2.1/utils/OWNERS
index 7af69b4..83c4f5f 100644
--- a/graphics/composer/2.1/utils/OWNERS
+++ b/graphics/composer/2.1/utils/OWNERS
@@ -1,2 +1,3 @@
 adyabr@google.com
+alecmouri@google.com
 lpy@google.com
diff --git a/graphics/composer/2.1/vts/OWNERS b/graphics/composer/2.1/vts/OWNERS
index ea06752..a643bbd 100644
--- a/graphics/composer/2.1/vts/OWNERS
+++ b/graphics/composer/2.1/vts/OWNERS
@@ -1,5 +1,6 @@
 # Graphics team
 adyabr@google.com
+alecmouri@google.com
 lpy@google.com
 
 # VTS team
diff --git a/graphics/composer/2.1/vts/functional/OWNERS b/graphics/composer/2.1/vts/functional/OWNERS
index a2ed8c8..3d970d1 100644
--- a/graphics/composer/2.1/vts/functional/OWNERS
+++ b/graphics/composer/2.1/vts/functional/OWNERS
@@ -1,2 +1,4 @@
 # Bug component: 25423
+adyabr@google.com
+alecmouri@google.com
 sumir@google.com
diff --git a/graphics/composer/2.2/default/OWNERS b/graphics/composer/2.2/default/OWNERS
index 709c4d1..e8f584d 100644
--- a/graphics/composer/2.2/default/OWNERS
+++ b/graphics/composer/2.2/default/OWNERS
@@ -1,3 +1,5 @@
 # Graphics team
 adyabr@google.com
+alecmouri@google.com
 lpy@google.com
+
diff --git a/graphics/composer/2.2/utils/OWNERS b/graphics/composer/2.2/utils/OWNERS
index 709c4d1..331c80d 100644
--- a/graphics/composer/2.2/utils/OWNERS
+++ b/graphics/composer/2.2/utils/OWNERS
@@ -1,3 +1,4 @@
 # Graphics team
 adyabr@google.com
+alecmouri@google.com
 lpy@google.com
diff --git a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp
index 30596fc..a1794af 100644
--- a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp
+++ b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp
@@ -17,6 +17,7 @@
 #include <composer-vts/2.2/ReadbackVts.h>
 #include <composer-vts/2.2/RenderEngineVts.h>
 #include "renderengine/ExternalTexture.h"
+#include "renderengine/impl/ExternalTexture.h"
 
 namespace android {
 namespace hardware {
@@ -281,11 +282,11 @@
 
 LayerSettings TestBufferLayer::toRenderEngineLayerSettings() {
     LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
-    layerSettings.source.buffer.buffer = std::make_shared<renderengine::ExternalTexture>(
+    layerSettings.source.buffer.buffer = std::make_shared<renderengine::impl::ExternalTexture>(
             new GraphicBuffer(mBufferHandle->get(), GraphicBuffer::CLONE_HANDLE, mWidth, mHeight,
                               static_cast<int32_t>(mFormat), 1, mUsage, mStride),
             mRenderEngine.getInternalRenderEngine(),
-            renderengine::ExternalTexture::Usage::READABLE);
+            renderengine::impl::ExternalTexture::Usage::READABLE);
 
     layerSettings.source.buffer.usePremultipliedAlpha =
             mBlendMode == IComposerClient::BlendMode::PREMULTIPLIED;
diff --git a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
index 2d4cc7d..4a33fb5 100644
--- a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
+++ b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <composer-vts/2.2/RenderEngineVts.h>
+#include "renderengine/impl/ExternalTexture.h"
 
 namespace android {
 namespace hardware {
@@ -68,8 +69,8 @@
                    [](renderengine::LayerSettings& settings) -> renderengine::LayerSettings {
                        return settings;
                    });
-    auto texture = std::make_shared<renderengine::ExternalTexture>(
-            mGraphicBuffer, *mRenderEngine, renderengine::ExternalTexture::Usage::WRITEABLE);
+    auto texture = std::make_shared<renderengine::impl::ExternalTexture>(
+            mGraphicBuffer, *mRenderEngine, renderengine::impl::ExternalTexture::Usage::WRITEABLE);
     auto [status, readyFence] = mRenderEngine
                                         ->drawLayers(mDisplaySettings, compositionLayers, texture,
                                                      true, std::move(bufferFence))
diff --git a/graphics/composer/2.2/vts/functional/OWNERS b/graphics/composer/2.2/vts/functional/OWNERS
index 31b0dc7..a4eb0ca 100644
--- a/graphics/composer/2.2/vts/functional/OWNERS
+++ b/graphics/composer/2.2/vts/functional/OWNERS
@@ -1,5 +1,6 @@
 # Bug component: 25423
 # Graphics team
 adyabr@google.com
+alecmouri@google.com
 lpy@google.com
 sumir@google.com
diff --git a/graphics/composer/2.3/default/OWNERS b/graphics/composer/2.3/default/OWNERS
index 709c4d1..331c80d 100644
--- a/graphics/composer/2.3/default/OWNERS
+++ b/graphics/composer/2.3/default/OWNERS
@@ -1,3 +1,4 @@
 # Graphics team
 adyabr@google.com
+alecmouri@google.com
 lpy@google.com
diff --git a/graphics/composer/2.3/utils/OWNERS b/graphics/composer/2.3/utils/OWNERS
index 709c4d1..331c80d 100644
--- a/graphics/composer/2.3/utils/OWNERS
+++ b/graphics/composer/2.3/utils/OWNERS
@@ -1,3 +1,4 @@
 # Graphics team
 adyabr@google.com
+alecmouri@google.com
 lpy@google.com
diff --git a/graphics/composer/2.3/vts/functional/OWNERS b/graphics/composer/2.3/vts/functional/OWNERS
index 31b0dc7..a4eb0ca 100644
--- a/graphics/composer/2.3/vts/functional/OWNERS
+++ b/graphics/composer/2.3/vts/functional/OWNERS
@@ -1,5 +1,6 @@
 # Bug component: 25423
 # Graphics team
 adyabr@google.com
+alecmouri@google.com
 lpy@google.com
 sumir@google.com
diff --git a/graphics/composer/2.4/default/OWNERS b/graphics/composer/2.4/default/OWNERS
index 709c4d1..331c80d 100644
--- a/graphics/composer/2.4/default/OWNERS
+++ b/graphics/composer/2.4/default/OWNERS
@@ -1,3 +1,4 @@
 # Graphics team
 adyabr@google.com
+alecmouri@google.com
 lpy@google.com
diff --git a/graphics/composer/2.4/utils/OWNERS b/graphics/composer/2.4/utils/OWNERS
index 709c4d1..331c80d 100644
--- a/graphics/composer/2.4/utils/OWNERS
+++ b/graphics/composer/2.4/utils/OWNERS
@@ -1,3 +1,4 @@
 # Graphics team
 adyabr@google.com
+alecmouri@google.com
 lpy@google.com
diff --git a/graphics/composer/2.4/vts/functional/OWNERS b/graphics/composer/2.4/vts/functional/OWNERS
index 31b0dc7..a4eb0ca 100644
--- a/graphics/composer/2.4/vts/functional/OWNERS
+++ b/graphics/composer/2.4/vts/functional/OWNERS
@@ -1,5 +1,6 @@
 # Bug component: 25423
 # Graphics team
 adyabr@google.com
+alecmouri@google.com
 lpy@google.com
 sumir@google.com
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 37af84a..5593c57 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
@@ -62,6 +62,9 @@
   void registerCallback(in android.hardware.graphics.composer3.IComposerCallback callback);
   void setActiveConfig(long display, int config);
   android.hardware.graphics.composer3.VsyncPeriodChangeTimeline setActiveConfigWithConstraints(long display, int config, in android.hardware.graphics.composer3.VsyncPeriodChangeConstraints vsyncPeriodChangeConstraints);
+  void setBootDisplayConfig(long display, int config);
+  void clearBootDisplayConfig(long display);
+  int getPreferredBootDisplayConfig(long display);
   void setAutoLowLatencyMode(long display, boolean on);
   void setClientTargetSlotCount(long display, int clientTargetSlotCount);
   void setColorMode(long display, android.hardware.graphics.composer3.ColorMode mode, android.hardware.graphics.composer3.RenderIntent intent);
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 49fbede..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
@@ -53,4 +53,5 @@
   @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/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
index fd2627e..c86b9bd 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -567,6 +567,58 @@
             long display, int config, in VsyncPeriodChangeConstraints vsyncPeriodChangeConstraints);
 
     /**
+     * Sets the display config in which the device boots.
+     *
+     * If the device is unable to boot in this config for any reason (example HDMI display changed),
+     * the implementation should try to find a config which matches the resolution and refresh-rate
+     * of this config. If no such config exists, the implementation's preferred display config
+     * should be used.
+     *
+     * @param display is the display for which the boot config is set.
+     * @param config is the new boot config for the display.
+     *
+     * @exception EX_BAD_DISPLAY when an invalid display handle was passed in.
+     * @exception EX_BAD_CONFIG when an invalid config id was passed in.
+     *
+     * @see getDisplayConfigs
+     * @see clearBootDisplayConfig
+     * @see getPreferredBootDisplayConfig
+     */
+    void setBootDisplayConfig(long display, int config);
+
+    /**
+     * Clears the boot display config.
+     *
+     * The device should boot in the implementation's preferred display config.
+     *
+     * @param display is the display for which the cached boot config is cleared.
+     *
+     * @exception EX_BAD_DISPLAY when an invalid display handle was passed in.
+     *
+     * @see getDisplayConfigs
+     * @see setBootDisplayConfig
+     * @see getPreferredBootDisplayConfig
+     */
+    void clearBootDisplayConfig(long display);
+
+    /**
+     * Returns the implementation's preferred display config.
+     *
+     * This is the display config used by the implementation at boot time, if the boot display
+     * config has not been requested yet, or if it has been previously cleared.
+     *
+     * @param display is the display to which the preferred config is queried.
+     * @return the implementation's preferred display config.
+     *
+     * @exception EX_BAD_DISPLAY when an invalid display handle was passed in.
+     *
+     * @see getDisplayConfigs
+     * @see setBootDisplayConfig
+     * @see clearBootDisplayConfig
+     */
+    int getPreferredBootDisplayConfig(long display);
+
+    /**
      * Requests the display to enable/disable its low latency mode.
      *
      * If the display is connected via HDMI 2.1, then Auto Low Latency Mode should be triggered. If
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
index e481d12..0a2711b 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
@@ -256,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/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp
index 6e42e86..1cfd3f9 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
@@ -716,6 +716,61 @@
     }
 }
 
+TEST_P(GraphicsComposerAidlTest, setBootDisplayConfig_BadDisplay) {
+    int32_t config = 0;
+    auto const error = mComposerClient->setBootDisplayConfig(mInvalidDisplayId, config);
+
+    EXPECT_FALSE(error.isOk());
+    EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, setBootDisplayConfig_BadConfig) {
+    for (VtsDisplay& display : mDisplays) {
+        int32_t invalidConfigId = GetInvalidConfigId();
+        const auto error = mComposerClient->setBootDisplayConfig(display.get(), invalidConfigId);
+        EXPECT_FALSE(error.isOk());
+        EXPECT_EQ(IComposerClient::EX_BAD_CONFIG, error.getServiceSpecificError());
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, setBootDisplayConfig) {
+    std::vector<int32_t> configs;
+    EXPECT_TRUE(mComposerClient->getDisplayConfigs(mPrimaryDisplay, &configs).isOk());
+    for (auto config : configs) {
+        EXPECT_TRUE(mComposerClient->setBootDisplayConfig(mPrimaryDisplay, config).isOk());
+    }
+}
+
+TEST_P(GraphicsComposerAidlTest, clearBootDisplayConfig_BadDisplay) {
+    auto const error = mComposerClient->clearBootDisplayConfig(mInvalidDisplayId);
+
+    EXPECT_FALSE(error.isOk());
+    EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, clearBootDisplayConfig) {
+    EXPECT_TRUE(mComposerClient->clearBootDisplayConfig(mPrimaryDisplay).isOk());
+}
+
+TEST_P(GraphicsComposerAidlTest, getPreferredBootDisplayConfig_BadDisplay) {
+    int32_t config;
+    auto const error = mComposerClient->getPreferredBootDisplayConfig(mInvalidDisplayId, &config);
+
+    EXPECT_FALSE(error.isOk());
+    EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, getPreferredBootDisplayConfig) {
+    int32_t preferredDisplayConfig = 0;
+    auto const error = mComposerClient->getPreferredBootDisplayConfig(mPrimaryDisplay,
+                                                                      &preferredDisplayConfig);
+    EXPECT_TRUE(error.isOk());
+
+    std::vector<int32_t> configs;
+    EXPECT_TRUE(mComposerClient->getDisplayConfigs(mPrimaryDisplay, &configs).isOk());
+    EXPECT_NE(configs.end(), std::find(configs.begin(), configs.end(), preferredDisplayConfig));
+}
+
 TEST_P(GraphicsComposerAidlTest, setAutoLowLatencyModeBadDisplay) {
     EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY,
               mComposerClient->setAutoLowLatencyMode(mInvalidDisplayId, true)
@@ -1453,8 +1508,7 @@
         presentFence2->waitForever(LOG_TAG);
 
         const auto actualPresentTime = presentFence2->getSignalTime();
-        const auto presentError = std::abs(expectedPresentTime - actualPresentTime);
-        EXPECT_LE(presentError, vsyncPeriod / 2);
+        EXPECT_GE(actualPresentTime, expectedPresentTime - vsyncPeriod / 2);
 
         ASSERT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::OFF).isOk());
     }
@@ -1526,7 +1580,7 @@
     execute();
     {
         const auto errors = mReader.takeErrors();
-        EXPECT_EQ(1, errors.size());
+        ASSERT_EQ(1, errors.size());
         EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode);
     }
 
@@ -1534,7 +1588,7 @@
     execute();
     {
         const auto errors = mReader.takeErrors();
-        EXPECT_EQ(1, errors.size());
+        ASSERT_EQ(1, errors.size());
         EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode);
     }
 }
@@ -1726,6 +1780,26 @@
     ASSERT_TRUE(mReader.takeErrors().empty());
 }
 
+TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_BLOCKING_REGION) {
+    int64_t layer;
+    EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
+
+    Rect empty{0, 0, 0, 0};
+    Rect unit{0, 0, 1, 1};
+
+    mWriter.setLayerBlockingRegion(mPrimaryDisplay, layer, std::vector<Rect>(1, empty));
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerBlockingRegion(mPrimaryDisplay, layer, std::vector<Rect>(1, unit));
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerBlockingRegion(mPrimaryDisplay, layer, std::vector<Rect>());
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+}
+
 TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_BLEND_MODE) {
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
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 deb5ac3..ee597a1 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
@@ -22,6 +22,7 @@
 #include <aidl/android/hardware/graphics/common/BufferUsage.h>
 #include "include/RenderEngineVts.h"
 #include "renderengine/ExternalTexture.h"
+#include "renderengine/impl/ExternalTexture.h"
 
 // TODO(b/129481165): remove the #pragma below and fix conversion issues
 #pragma clang diagnostic pop  // ignored "-Wconversion
@@ -300,12 +301,13 @@
 
 LayerSettings TestBufferLayer::toRenderEngineLayerSettings() {
     LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
-    layerSettings.source.buffer.buffer = std::make_shared<::android::renderengine::ExternalTexture>(
-            ::android::sp<::android::GraphicBuffer>::make(
-                    mGraphicBuffer->handle, ::android::GraphicBuffer::CLONE_HANDLE, mWidth, mHeight,
-                    static_cast<int32_t>(mPixelFormat), 1, mUsage, mStride),
-            mRenderEngine.getInternalRenderEngine(),
-            ::android::renderengine::ExternalTexture::Usage::READABLE);
+    layerSettings.source.buffer.buffer =
+            std::make_shared<::android::renderengine::impl::ExternalTexture>(
+                    ::android::sp<::android::GraphicBuffer>::make(
+                            mGraphicBuffer->handle, ::android::GraphicBuffer::CLONE_HANDLE, mWidth,
+                            mHeight, static_cast<int32_t>(mPixelFormat), 1, mUsage, mStride),
+                    mRenderEngine.getInternalRenderEngine(),
+                    ::android::renderengine::impl::ExternalTexture::Usage::READABLE);
 
     layerSettings.source.buffer.usePremultipliedAlpha = mBlendMode == BlendMode::PREMULTIPLIED;
 
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp
index 50ce462..6ff064f 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp
@@ -15,6 +15,7 @@
  */
 
 #include "include/RenderEngineVts.h"
+#include "renderengine/impl/ExternalTexture.h"
 
 namespace aidl::android::hardware::graphics::composer3::vts {
 
@@ -62,9 +63,9 @@
                    std::back_insert_iterator(compositionLayers),
                    [](::android::renderengine::LayerSettings& settings)
                            -> ::android::renderengine::LayerSettings { return settings; });
-    auto texture = std::make_shared<::android::renderengine::ExternalTexture>(
+    auto texture = std::make_shared<::android::renderengine::impl::ExternalTexture>(
             mGraphicBuffer, *mRenderEngine,
-            ::android::renderengine::ExternalTexture::Usage::WRITEABLE);
+            ::android::renderengine::impl::ExternalTexture::Usage::WRITEABLE);
     auto [status, readyFence] = mRenderEngine
                                         ->drawLayers(mDisplaySettings, compositionLayers, texture,
                                                      true, std::move(bufferFence))
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
index b2776d6..d3266e7 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
@@ -213,6 +213,10 @@
         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();
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 22bb4fa..86bca69 100644
--- a/health/aidl/Android.bp
+++ b/health/aidl/Android.bp
@@ -62,9 +62,11 @@
         "android.hardware.health@2.0",
         "android.hardware.health@2.1",
     ],
-    defaults: [
-        "libbinder_ndk_host_user",
-    ],
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
 }
 
 java_library {
diff --git a/health/utils/libhealthshim/Android.bp b/health/utils/libhealthshim/Android.bp
index 311e951..42e4ea7 100644
--- a/health/utils/libhealthshim/Android.bp
+++ b/health/utils/libhealthshim/Android.bp
@@ -24,9 +24,11 @@
 cc_defaults {
     name: "libhealthshim_defaults",
     host_supported: true, // for testing
-    defaults: [
-        "libbinder_ndk_host_user",
-    ],
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
     cflags: [
         "-Wall",
         "-Werror",
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/Certificate.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/Certificate.aidl
index d8a8128..83e1797 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/Certificate.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/Certificate.aidl
@@ -12,7 +12,8 @@
  * WITHOUT 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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/CipherSuite.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/CipherSuite.aidl
index 2685525..e6ec04e 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/CipherSuite.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/CipherSuite.aidl
@@ -12,7 +12,8 @@
  * WITHOUT 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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl
index f8d5a9e..cd8d56b 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/HardwareInformation.aidl
@@ -12,7 +12,8 @@
  * WITHOUT 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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl
index 3224e4b..5065641 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl
@@ -12,7 +12,8 @@
  * WITHOUT 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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl
index c6fb3c8..c912c52 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredentialStore.aidl
@@ -12,7 +12,8 @@
  * WITHOUT 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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -36,6 +37,7 @@
   android.hardware.identity.HardwareInformation getHardwareInformation();
   android.hardware.identity.IWritableIdentityCredential createCredential(in @utf8InCpp String docType, in boolean testCredential);
   android.hardware.identity.IIdentityCredential getCredential(in android.hardware.identity.CipherSuite cipherSuite, in byte[] credentialData);
+  android.hardware.identity.IPresentationSession createPresentationSession(in android.hardware.identity.CipherSuite cipherSuite);
   const int STATUS_OK = 0;
   const int STATUS_FAILED = 1;
   const int STATUS_CIPHER_SUITE_NOT_SUPPORTED = 2;
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IPresentationSession.aidl
similarity index 80%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IPresentationSession.aidl
index 295fde9..705dc29 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IPresentationSession.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,12 +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.biometrics.fingerprint;
+package android.hardware.identity;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+interface IPresentationSession {
+  byte[] getEphemeralKeyPair();
+  long getAuthChallenge();
+  void setReaderEphemeralPublicKey(in byte[] publicKey);
+  void setSessionTranscript(in byte[] sessionTranscript);
+  android.hardware.identity.IIdentityCredential getCredential(in byte[] credentialData);
 }
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl
index 19a29ec..9a0fa9e 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IWritableIdentityCredential.aidl
@@ -12,7 +12,8 @@
  * WITHOUT 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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestDataItem.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestDataItem.aidl
index c9c2b9f..cec8e0c 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestDataItem.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestDataItem.aidl
@@ -12,7 +12,8 @@
  * WITHOUT 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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestNamespace.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestNamespace.aidl
index aaf1e20..05b9ec2 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestNamespace.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/RequestNamespace.aidl
@@ -12,7 +12,8 @@
  * WITHOUT 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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/SecureAccessControlProfile.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/SecureAccessControlProfile.aidl
index 695fb3f..2003594 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/SecureAccessControlProfile.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/SecureAccessControlProfile.aidl
@@ -12,7 +12,8 @@
  * WITHOUT 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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
index 8ae293b..84d6ed0 100644
--- a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
+++ b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
@@ -17,9 +17,9 @@
 package android.hardware.identity;
 
 import android.hardware.identity.Certificate;
+import android.hardware.identity.IWritableIdentityCredential;
 import android.hardware.identity.RequestNamespace;
 import android.hardware.identity.SecureAccessControlProfile;
-import android.hardware.identity.IWritableIdentityCredential;
 import android.hardware.keymaster.HardwareAuthToken;
 import android.hardware.keymaster.VerificationToken;
 
@@ -44,6 +44,9 @@
      * This method was deprecated in API version 3 because there's no challenge so freshness
      * can't be checked. Use deleteCredentalWithChallenge() instead.
      *
+     * If the method is called on an instance obtained via IPresentationSession.getCredential(),
+     * STATUS_FAILED must be returned.
+     *
      * @return a COSE_Sign1 signature described above
      * @deprecated use deleteCredentalWithChallenge() instead.
      */
@@ -60,6 +63,9 @@
      * This method may only be called once per instance. If called more than once, STATUS_FAILED
      * will be returned.
      *
+     * If the method is called on an instance obtained via IPresentationSession.getCredential(),
+     * STATUS_FAILED must be returned.
+     *
      * @return the private key, in DER format as specified in RFC 5915.
      */
     byte[] createEphemeralKeyPair();
@@ -70,6 +76,9 @@
      * This method may only be called once per instance. If called more than once, STATUS_FAILED
      * will be returned.
      *
+     * If the method is called on an instance obtained via IPresentationSession.getCredential(),
+     * STATUS_FAILED must be returned.
+     *
      * @param publicKey contains the reader's ephemeral public key, in uncompressed
      *        form (e.g. 0x04 || X || Y).
      */
@@ -83,6 +92,9 @@
      * This method may only be called once per instance. If called more than once, STATUS_FAILED
      * will be returned. If user authentication is not needed, this method may not be called.
      *
+     * If the method is called on an instance obtained via IPresentationSession.getCredential(),
+     * STATUS_FAILED must be returned.
+     *
      * @return challenge, a non-zero number.
      */
     long createAuthChallenge();
@@ -371,6 +383,9 @@
      * This CBOR enables an issuer to determine the exact state of the credential it
      * returns issuer-signed data for.
      *
+     * If the method is called on an instance obtained via IPresentationSession.getCredential(),
+     * STATUS_FAILED must be returned.
+     *
      * @param out signingKeyBlob contains an AES-GCM-ENC(storageKey, R, signingKey, docType)
      *     where signingKey is an EC private key in uncompressed form. That is, the returned
      *     blob is an encrypted copy of the newly-generated private signing key.
@@ -420,6 +435,9 @@
      *
      * This method was introduced in API version 3.
      *
+     * If the method is called on an instance obtained via IPresentationSession.getCredential(),
+     * STATUS_FAILED must be returned.
+     *
      * @param challenge a challenge set by the issuer to ensure freshness. Maximum size is 32 bytes
      *     and it may be empty. Fails with STATUS_INVALID_DATA if bigger than 32 bytes.
      * @return a COSE_Sign1 signature described above.
@@ -442,6 +460,9 @@
      *
      * This method was introduced in API version 3.
      *
+     * If the method is called on an instance obtained via IPresentationSession.getCredential(),
+     * STATUS_FAILED must be returned.
+     *
      * @param challenge a challenge set by the issuer to ensure freshness. Maximum size is 32 bytes
      *     and it may be empty. Fails with STATUS_INVALID_DATA if bigger than 32 bytes.
      * @return a COSE_Sign1 signature described above.
@@ -456,6 +477,9 @@
      *
      * This method was introduced in API version 3.
      *
+     * If the method is called on an instance obtained via IPresentationSession.getCredential(),
+     * STATUS_FAILED must be returned.
+     *
      * @return an IWritableIdentityCredential
      */
     IWritableIdentityCredential updateCredential();
diff --git a/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl b/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl
index 638be79..86be7f5 100644
--- a/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl
+++ b/identity/aidl/android/hardware/identity/IIdentityCredentialStore.aidl
@@ -16,10 +16,11 @@
 
 package android.hardware.identity;
 
-import android.hardware.identity.IIdentityCredential;
-import android.hardware.identity.IWritableIdentityCredential;
-import android.hardware.identity.HardwareInformation;
 import android.hardware.identity.CipherSuite;
+import android.hardware.identity.HardwareInformation;
+import android.hardware.identity.IIdentityCredential;
+import android.hardware.identity.IPresentationSession;
+import android.hardware.identity.IWritableIdentityCredential;
 
 /**
  * IIdentityCredentialStore provides an interface to a secure store for user identity documents.
@@ -105,7 +106,7 @@
  * STATUS_* integers defined in this interface. Each method states which status can be returned
  * and under which circumstances.
  *
- * The API described here is API version 3 which corresponds to feature version 202101
+ * The API described here is API version 4 which corresponds to feature version 202201
  * of the android.security.identity Framework API. An XML file declaring the feature
  * android.hardware.identity_credential (or android.hardware.identity_credential.direct_access
  * if implementing the Direct Access HAL) should be included declaring this feature version.
@@ -241,4 +242,25 @@
      * @return an IIdentityCredential interface that provides operations on the Credential.
      */
     IIdentityCredential getCredential(in CipherSuite cipherSuite, in byte[] credentialData);
+
+    /**
+     * createPresentationSession creates IPresentationSession interface which can be used to
+     * present one or more credentials to a remote verifier device.
+     *
+     * The cipher suite used to communicate with the remote verifier must be specified. Currently
+     * only a single cipher-suite is supported. Support for other cipher suites may be added in a
+     * future version of this HAL. If the requested cipher suite is not support the call fails
+     * with STATUS_CIPHER_SUITE_NOT_SUPPORTED.
+     *
+     * In this version of the HAL, implementations are only required to support a single session
+     * being active. In a future version, implementations may be required to support multiple
+     * presentation sessions being active at the same time.
+     *
+     * This method was introduced in API version 4.
+     *
+     * @param cipherSuite The cipher suite to use.
+     *
+     * @return an IPresentationSession interface.
+     */
+    IPresentationSession createPresentationSession(in CipherSuite cipherSuite);
 }
diff --git a/identity/aidl/android/hardware/identity/IPresentationSession.aidl b/identity/aidl/android/hardware/identity/IPresentationSession.aidl
new file mode 100644
index 0000000..b0449f0
--- /dev/null
+++ b/identity/aidl/android/hardware/identity/IPresentationSession.aidl
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.identity;
+
+import android.hardware.identity.CipherSuite;
+import android.hardware.identity.IIdentityCredential;
+
+/**
+ * An interface to present multiple credentials in the same session.
+ *
+ * This interface was introduced in API version 4.
+ *
+ */
+@VintfStability
+interface IPresentationSession {
+    /**
+     * Gets the ephemeral EC key pair to be used in establishing a secure session with a reader.
+     * This method returns the private key so the caller can perform an ECDH key agreement operation
+     * with the reader.  The reason for generating the key pair in the secure environment is so that
+     * the secure environment knows what public key to expect to find in the session transcript
+     * when presenting credentials.
+     *
+     * The generated key matches the selected cipher suite of the presentation session (e.g. EC
+     * key using the P-256 curve).
+     *
+     * @return the private key, in DER format as specified in RFC 5915.
+     */
+    byte[] getEphemeralKeyPair();
+
+    /**
+     * Gets the challenge value to be used for proving successful user authentication. This
+     * is to be included in the authToken passed to the IIdentityCredential.startRetrieval()
+     * method and the verificationToken passed to the IIdentityCredential.setVerificationToken()
+     * method.
+     *
+     * @return challenge, a non-zero number.
+     */
+    long getAuthChallenge();
+
+    /**
+     * Sets the public part of the reader's ephemeral key pair to be used to complete
+     * an ECDH key agreement for the session.
+     *
+     * The curve of the key must match the curve for the key returned by getEphemeralKeyPair().
+     *
+     * This method may only be called once per instance. If called more than once, STATUS_FAILED
+     * must be returned.
+     *
+     * @param publicKey contains the reader's ephemeral public key, in uncompressed
+     *        form (e.g. 0x04 || X || Y).
+     */
+    void setReaderEphemeralPublicKey(in byte[] publicKey);
+
+    /**
+     * Sets the session transcript for the session.
+     *
+     * This can be empty but if it's non-empty it must be valid CBOR.
+     *
+     * This method may only be called once per instance. If called more than once, STATUS_FAILED
+     * must be returned.
+     *
+     * @param sessionTrancsript the session transcript.
+     */
+    void setSessionTranscript(in byte[] sessionTranscript);
+
+    /**
+     * getCredential() retrieves an IIdentityCredential interface for presentation in the
+     * current presentation session.
+     *
+     * On the returned instance only the methods startRetrieval(), startRetrieveEntryValue(),
+     * retrieveEntryValue(), finishRetrieval(), setRequestedNamespaces(), setVerificationToken()
+     * may be called. Other methods will fail with STATUS_FAILED.
+     *
+     * The implementation is expected to get the session transcript, ephemeral key, reader
+     * ephemeral key, and auth challenge from this instance.
+     *
+     * @param credentialData is a CBOR-encoded structure containing metadata about the credential
+     *     and an encrypted byte array that contains data used to secure the credential.  See the
+     *     return argument of the same name in IWritableIdentityCredential.finishAddingEntries().
+     *
+     *     Note that the format of credentialData may depend on the feature version.
+     *     Implementations must support credentialData created by an earlier feature version.
+     *
+     * @return an IIdentityCredential interface that provides operations on the Credential.
+     */
+    IIdentityCredential getCredential(in byte[] credentialData);
+}
diff --git a/identity/aidl/default/Android.bp b/identity/aidl/default/Android.bp
index 3de8d30..ca24afa 100644
--- a/identity/aidl/default/Android.bp
+++ b/identity/aidl/default/Android.bp
@@ -13,6 +13,7 @@
     srcs: [
         "common/IdentityCredential.cpp",
         "common/IdentityCredentialStore.cpp",
+        "common/PresentationSession.cpp",
         "common/WritableIdentityCredential.cpp",
     ],
     export_include_dirs: [
@@ -39,8 +40,8 @@
         "libsoft_attestation_cert",
         "libpuresoftkeymasterdevice",
         "android.hardware.identity-support-lib",
-        "android.hardware.identity-V3-ndk",
-        "android.hardware.keymaster-V3-ndk",
+        "android.hardware.identity-V4-ndk",
+        "android.hardware.keymaster-V4-ndk",
     ],
 }
 
@@ -49,6 +50,7 @@
     vendor_available: true,
     srcs: [
         "libeic/EicCbor.c",
+        "libeic/EicSession.c",
         "libeic/EicPresentation.c",
         "libeic/EicProvisioning.c",
         "EicOpsImpl.cc",
@@ -100,8 +102,8 @@
         "libsoft_attestation_cert",
         "libpuresoftkeymasterdevice",
         "android.hardware.identity-support-lib",
-        "android.hardware.identity-V3-ndk",
-        "android.hardware.keymaster-V3-ndk",
+        "android.hardware.identity-V4-ndk",
+        "android.hardware.keymaster-V4-ndk",
         "android.hardware.identity-libeic-hal-common",
         "android.hardware.identity-libeic-library",
     ],
diff --git a/identity/aidl/default/EicOpsImpl.cc b/identity/aidl/default/EicOpsImpl.cc
index 8ec4cc9..c98a91e 100644
--- a/identity/aidl/default/EicOpsImpl.cc
+++ b/identity/aidl/default/EicOpsImpl.cc
@@ -20,9 +20,13 @@
 #include <tuple>
 #include <vector>
 
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <string.h>
+
 #include <android-base/logging.h>
 #include <android-base/stringprintf.h>
-#include <string.h>
 
 #include <android/hardware/identity/support/IdentityCredentialSupport.h>
 
@@ -63,6 +67,11 @@
     return strlen(s);
 }
 
+void* eicMemMem(const uint8_t* haystack, size_t haystackLen, const uint8_t* needle,
+                size_t needleLen) {
+    return memmem(haystack, haystackLen, needle, needleLen);
+}
+
 int eicCryptoMemCmp(const void* s1, const void* s2, size_t n) {
     return CRYPTO_memcmp(s1, s2, n);
 }
@@ -117,6 +126,25 @@
     return true;
 }
 
+bool eicNextId(uint32_t* id) {
+    uint32_t oldId = *id;
+    uint32_t newId = 0;
+
+    do {
+        union {
+            uint8_t value8;
+            uint32_t value32;
+        } value;
+        if (!eicOpsRandom(&value.value8, sizeof(value))) {
+            return false;
+        }
+        newId = value.value32;
+    } while (newId == oldId && newId == 0);
+
+    *id = newId;
+    return true;
+}
+
 bool eicOpsEncryptAes128Gcm(
         const uint8_t* key,    // Must be 16 bytes
         const uint8_t* nonce,  // Must be 12 bytes
diff --git a/identity/aidl/default/EicTests.cpp b/identity/aidl/default/EicTests.cpp
index a28080d..7b69b75 100644
--- a/identity/aidl/default/EicTests.cpp
+++ b/identity/aidl/default/EicTests.cpp
@@ -66,7 +66,8 @@
     // Then present data from it...
     //
     FakeSecureHardwarePresentationProxy presentationProxy;
-    ASSERT_TRUE(presentationProxy.initialize(isTestCredential, docType, credData.value()));
+    ASSERT_TRUE(presentationProxy.initialize(0 /* sessionId */, isTestCredential, docType,
+                                             credData.value()));
     AccessCheckResult res =
             presentationProxy.startRetrieveEntryValue(nameSpace, name, 1, content.size(), acpIds);
     ASSERT_EQ(res, AccessCheckResult::kNoAccessControlProfiles);
diff --git a/identity/aidl/default/FakeSecureHardwareProxy.cpp b/identity/aidl/default/FakeSecureHardwareProxy.cpp
index f0307dc..91e634c 100644
--- a/identity/aidl/default/FakeSecureHardwareProxy.cpp
+++ b/identity/aidl/default/FakeSecureHardwareProxy.cpp
@@ -23,6 +23,7 @@
 #include <android-base/logging.h>
 #include <android-base/stringprintf.h>
 #include <string.h>
+#include <map>
 
 #include <openssl/sha.h>
 
@@ -52,38 +53,110 @@
 
 // ----------------------------------------------------------------------
 
-FakeSecureHardwareProvisioningProxy::FakeSecureHardwareProvisioningProxy() {}
+// The singleton EicProvisioning object used everywhere.
+//
+EicProvisioning FakeSecureHardwareProvisioningProxy::ctx_;
 
-FakeSecureHardwareProvisioningProxy::~FakeSecureHardwareProvisioningProxy() {}
-
-bool FakeSecureHardwareProvisioningProxy::shutdown() {
-    LOG(INFO) << "FakeSecureHardwarePresentationProxy shutdown";
-    return true;
+FakeSecureHardwareProvisioningProxy::~FakeSecureHardwareProvisioningProxy() {
+    if (id_ != 0) {
+        shutdown();
+    }
 }
 
 bool FakeSecureHardwareProvisioningProxy::initialize(bool testCredential) {
-    LOG(INFO) << "FakeSecureHardwareProvisioningProxy created, sizeof(EicProvisioning): "
-              << sizeof(EicProvisioning);
-    return eicProvisioningInit(&ctx_, testCredential);
+    if (id_ != 0) {
+        LOG(WARNING) << "Proxy is already initialized";
+        return false;
+    }
+    bool initialized = eicProvisioningInit(&ctx_, testCredential);
+    if (!initialized) {
+        return false;
+    }
+    optional<uint32_t> id = getId();
+    if (!id) {
+        LOG(WARNING) << "Error getting id";
+        return false;
+    }
+    id_ = id.value();
+    return true;
 }
 
 bool FakeSecureHardwareProvisioningProxy::initializeForUpdate(
-        bool testCredential, string docType, vector<uint8_t> encryptedCredentialKeys) {
-    return eicProvisioningInitForUpdate(&ctx_, testCredential, docType.c_str(),
-                                        docType.size(),
-                                        encryptedCredentialKeys.data(),
-                                        encryptedCredentialKeys.size());
+        bool testCredential, const string& docType,
+        const vector<uint8_t>& encryptedCredentialKeys) {
+    if (id_ != 0) {
+        LOG(WARNING) << "Proxy is already initialized";
+        return false;
+    }
+    bool initialized = eicProvisioningInitForUpdate(&ctx_, testCredential, docType.c_str(),
+                                                    docType.size(), encryptedCredentialKeys.data(),
+                                                    encryptedCredentialKeys.size());
+    if (!initialized) {
+        return false;
+    }
+    optional<uint32_t> id = getId();
+    if (!id) {
+        LOG(WARNING) << "Error getting id";
+        return false;
+    }
+    id_ = id.value();
+    return true;
+}
+
+optional<uint32_t> FakeSecureHardwareProvisioningProxy::getId() {
+    uint32_t id;
+    if (!eicProvisioningGetId(&ctx_, &id)) {
+        return std::nullopt;
+    }
+    return id;
+}
+
+bool FakeSecureHardwareProvisioningProxy::validateId(const string& callerName) {
+    if (id_ == 0) {
+        LOG(WARNING) << "FakeSecureHardwareProvisioningProxy::" << callerName
+                     << ": While validating expected id is 0";
+        return false;
+    }
+    optional<uint32_t> id = getId();
+    if (!id) {
+        LOG(WARNING) << "FakeSecureHardwareProvisioningProxy::" << callerName
+                     << ": Error getting id for validating";
+        return false;
+    }
+    if (id.value() != id_) {
+        LOG(WARNING) << "FakeSecureHardwareProvisioningProxy::" << callerName
+                     << ": While validating expected id " << id_ << " but got " << id.value();
+        return false;
+    }
+    return true;
+}
+
+bool FakeSecureHardwareProvisioningProxy::shutdown() {
+    bool validated = validateId(__func__);
+    id_ = 0;
+    if (!validated) {
+        return false;
+    }
+    if (!eicProvisioningShutdown(&ctx_)) {
+        LOG(INFO) << "Error shutting down provisioning";
+        return false;
+    }
+    return true;
 }
 
 // Returns public key certificate.
 optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::createCredentialKey(
         const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId) {
+    if (!validateId(__func__)) {
+        return std::nullopt;
+    }
+
     uint8_t publicKeyCert[4096];
     size_t publicKeyCertSize = sizeof publicKeyCert;
     if (!eicProvisioningCreateCredentialKey(&ctx_, challenge.data(), challenge.size(),
                                             applicationId.data(), applicationId.size(),
                                             publicKeyCert, &publicKeyCertSize)) {
-        return {};
+        return std::nullopt;
     }
     vector<uint8_t> pubKeyCert(publicKeyCertSize);
     memcpy(pubKeyCert.data(), publicKeyCert, publicKeyCertSize);
@@ -91,8 +164,11 @@
 }
 
 bool FakeSecureHardwareProvisioningProxy::startPersonalization(
-        int accessControlProfileCount, vector<int> entryCounts, const string& docType,
+        int accessControlProfileCount, const vector<int>& entryCounts, const string& docType,
         size_t expectedProofOfProvisioningSize) {
+    if (!validateId(__func__)) {
+        return false;
+    }
 
     if (!eicProvisioningStartPersonalization(&ctx_, accessControlProfileCount,
                                              entryCounts.data(),
@@ -108,13 +184,17 @@
 optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::addAccessControlProfile(
         int id, const vector<uint8_t>& readerCertificate, bool userAuthenticationRequired,
         uint64_t timeoutMillis, uint64_t secureUserId) {
+    if (!validateId(__func__)) {
+        return std::nullopt;
+    }
+
     vector<uint8_t> mac(28);
     uint8_t scratchSpace[512];
     if (!eicProvisioningAddAccessControlProfile(
                 &ctx_, id, readerCertificate.data(), readerCertificate.size(),
                 userAuthenticationRequired, timeoutMillis, secureUserId, mac.data(),
                 scratchSpace, sizeof(scratchSpace))) {
-        return {};
+        return std::nullopt;
     }
     return mac;
 }
@@ -122,6 +202,10 @@
 bool FakeSecureHardwareProvisioningProxy::beginAddEntry(const vector<int>& accessControlProfileIds,
                                                         const string& nameSpace, const string& name,
                                                         uint64_t entrySize) {
+    if (!validateId(__func__)) {
+        return false;
+    }
+
     uint8_t scratchSpace[512];
     vector<uint8_t> uint8AccessControlProfileIds;
     for (size_t i = 0; i < accessControlProfileIds.size(); i++) {
@@ -138,6 +222,10 @@
 optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::addEntryValue(
         const vector<int>& accessControlProfileIds, const string& nameSpace, const string& name,
         const vector<uint8_t>& content) {
+    if (!validateId(__func__)) {
+        return std::nullopt;
+    }
+
     vector<uint8_t> eicEncryptedContent;
     uint8_t scratchSpace[512];
     vector<uint8_t> uint8AccessControlProfileIds;
@@ -150,16 +238,20 @@
                 &ctx_, uint8AccessControlProfileIds.data(), uint8AccessControlProfileIds.size(),
                 nameSpace.c_str(), nameSpace.size(), name.c_str(), name.size(), content.data(),
                 content.size(), eicEncryptedContent.data(), scratchSpace, sizeof(scratchSpace))) {
-        return {};
+        return std::nullopt;
     }
     return eicEncryptedContent;
 }
 
 // Returns signatureOfToBeSigned (EIC_ECDSA_P256_SIGNATURE_SIZE bytes).
 optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::finishAddingEntries() {
+    if (!validateId(__func__)) {
+        return std::nullopt;
+    }
+
     vector<uint8_t> signatureOfToBeSigned(EIC_ECDSA_P256_SIGNATURE_SIZE);
     if (!eicProvisioningFinishAddingEntries(&ctx_, signatureOfToBeSigned.data())) {
-        return {};
+        return std::nullopt;
     }
     return signatureOfToBeSigned;
 }
@@ -167,11 +259,15 @@
 // Returns encryptedCredentialKeys.
 optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::finishGetCredentialData(
         const string& docType) {
+    if (!validateId(__func__)) {
+        return std::nullopt;
+    }
+
     vector<uint8_t> encryptedCredentialKeys(116);
     size_t size = encryptedCredentialKeys.size();
     if (!eicProvisioningFinishGetCredentialData(&ctx_, docType.c_str(), docType.size(),
                                                 encryptedCredentialKeys.data(), &size)) {
-        return {};
+        return std::nullopt;
     }
     encryptedCredentialKeys.resize(size);
     return encryptedCredentialKeys;
@@ -179,21 +275,200 @@
 
 // ----------------------------------------------------------------------
 
-FakeSecureHardwarePresentationProxy::FakeSecureHardwarePresentationProxy() {}
+// The singleton EicSession object used everywhere.
+//
+EicSession FakeSecureHardwareSessionProxy::ctx_;
 
-FakeSecureHardwarePresentationProxy::~FakeSecureHardwarePresentationProxy() {}
+FakeSecureHardwareSessionProxy::~FakeSecureHardwareSessionProxy() {
+    if (id_ != 0) {
+        shutdown();
+    }
+}
 
-bool FakeSecureHardwarePresentationProxy::initialize(bool testCredential, string docType,
-                                                     vector<uint8_t> encryptedCredentialKeys) {
-    LOG(INFO) << "FakeSecureHardwarePresentationProxy created, sizeof(EicPresentation): "
-              << sizeof(EicPresentation);
-    return eicPresentationInit(&ctx_, testCredential, docType.c_str(), docType.size(),
-                               encryptedCredentialKeys.data(), encryptedCredentialKeys.size());
+bool FakeSecureHardwareSessionProxy::initialize() {
+    if (id_ != 0) {
+        LOG(WARNING) << "Proxy is already initialized";
+        return false;
+    }
+    bool initialized = eicSessionInit(&ctx_);
+    if (!initialized) {
+        return false;
+    }
+    optional<uint32_t> id = getId();
+    if (!id) {
+        LOG(WARNING) << "Error getting id";
+        return false;
+    }
+    id_ = id.value();
+    return true;
+}
+
+optional<uint32_t> FakeSecureHardwareSessionProxy::getId() {
+    uint32_t id;
+    if (!eicSessionGetId(&ctx_, &id)) {
+        return std::nullopt;
+    }
+    return id;
+}
+
+bool FakeSecureHardwareSessionProxy::shutdown() {
+    bool validated = validateId(__func__);
+    id_ = 0;
+    if (!validated) {
+        return false;
+    }
+    if (!eicSessionShutdown(&ctx_)) {
+        LOG(INFO) << "Error shutting down session";
+        return false;
+    }
+    return true;
+}
+
+bool FakeSecureHardwareSessionProxy::validateId(const string& callerName) {
+    if (id_ == 0) {
+        LOG(WARNING) << "FakeSecureHardwareSessionProxy::" << callerName
+                     << ": While validating expected id is 0";
+        return false;
+    }
+    optional<uint32_t> id = getId();
+    if (!id) {
+        LOG(WARNING) << "FakeSecureHardwareSessionProxy::" << callerName
+                     << ": Error getting id for validating";
+        return false;
+    }
+    if (id.value() != id_) {
+        LOG(WARNING) << "FakeSecureHardwareSessionProxy::" << callerName
+                     << ": While validating expected id " << id_ << " but got " << id.value();
+        return false;
+    }
+    return true;
+}
+
+optional<uint64_t> FakeSecureHardwareSessionProxy::getAuthChallenge() {
+    if (!validateId(__func__)) {
+        return std::nullopt;
+    }
+
+    uint64_t authChallenge;
+    if (!eicSessionGetAuthChallenge(&ctx_, &authChallenge)) {
+        return std::nullopt;
+    }
+    return authChallenge;
+}
+
+optional<vector<uint8_t>> FakeSecureHardwareSessionProxy::getEphemeralKeyPair() {
+    if (!validateId(__func__)) {
+        return std::nullopt;
+    }
+
+    vector<uint8_t> priv(EIC_P256_PRIV_KEY_SIZE);
+    if (!eicSessionGetEphemeralKeyPair(&ctx_, priv.data())) {
+        return std::nullopt;
+    }
+    return priv;
+}
+
+bool FakeSecureHardwareSessionProxy::setReaderEphemeralPublicKey(
+        const vector<uint8_t>& readerEphemeralPublicKey) {
+    if (!validateId(__func__)) {
+        return false;
+    }
+
+    return eicSessionSetReaderEphemeralPublicKey(&ctx_, readerEphemeralPublicKey.data());
+}
+
+bool FakeSecureHardwareSessionProxy::setSessionTranscript(
+        const vector<uint8_t>& sessionTranscript) {
+    if (!validateId(__func__)) {
+        return false;
+    }
+
+    return eicSessionSetSessionTranscript(&ctx_, sessionTranscript.data(),
+                                          sessionTranscript.size());
+}
+
+// ----------------------------------------------------------------------
+
+// The singleton EicPresentation object used everywhere.
+//
+EicPresentation FakeSecureHardwarePresentationProxy::ctx_;
+
+FakeSecureHardwarePresentationProxy::~FakeSecureHardwarePresentationProxy() {
+    if (id_ != 0) {
+        shutdown();
+    }
+}
+
+bool FakeSecureHardwarePresentationProxy::initialize(
+        uint32_t sessionId, bool testCredential, const string& docType,
+        const vector<uint8_t>& encryptedCredentialKeys) {
+    if (id_ != 0) {
+        LOG(WARNING) << "Proxy is already initialized";
+        return false;
+    }
+    bool initialized =
+            eicPresentationInit(&ctx_, sessionId, testCredential, docType.c_str(), docType.size(),
+                                encryptedCredentialKeys.data(), encryptedCredentialKeys.size());
+    if (!initialized) {
+        return false;
+    }
+    optional<uint32_t> id = getId();
+    if (!id) {
+        LOG(WARNING) << "Error getting id";
+        return false;
+    }
+    id_ = id.value();
+    return true;
+}
+
+optional<uint32_t> FakeSecureHardwarePresentationProxy::getId() {
+    uint32_t id;
+    if (!eicPresentationGetId(&ctx_, &id)) {
+        return std::nullopt;
+    }
+    return id;
+}
+
+bool FakeSecureHardwarePresentationProxy::validateId(const string& callerName) {
+    if (id_ == 0) {
+        LOG(WARNING) << "FakeSecureHardwarePresentationProxy::" << callerName
+                     << ": While validating expected id is 0";
+        return false;
+    }
+    optional<uint32_t> id = getId();
+    if (!id) {
+        LOG(WARNING) << "FakeSecureHardwarePresentationProxy::" << callerName
+                     << ": Error getting id for validating";
+        return false;
+    }
+    if (id.value() != id_) {
+        LOG(WARNING) << "FakeSecureHardwarePresentationProxy::" << callerName
+                     << ": While validating expected id " << id_ << " but got " << id.value();
+        return false;
+    }
+    return true;
+}
+
+bool FakeSecureHardwarePresentationProxy::shutdown() {
+    bool validated = validateId(__func__);
+    id_ = 0;
+    if (!validated) {
+        return false;
+    }
+    if (!eicPresentationShutdown(&ctx_)) {
+        LOG(INFO) << "Error shutting down presentation";
+        return false;
+    }
+    return true;
 }
 
 // Returns publicKeyCert (1st component) and signingKeyBlob (2nd component)
 optional<pair<vector<uint8_t>, vector<uint8_t>>>
-FakeSecureHardwarePresentationProxy::generateSigningKeyPair(string docType, time_t now) {
+FakeSecureHardwarePresentationProxy::generateSigningKeyPair(const string& docType, time_t now) {
+    if (!validateId(__func__)) {
+        return std::nullopt;
+    }
+
     uint8_t publicKeyCert[512];
     size_t publicKeyCertSize = sizeof(publicKeyCert);
     vector<uint8_t> signingKeyBlob(60);
@@ -201,7 +476,7 @@
     if (!eicPresentationGenerateSigningKeyPair(&ctx_, docType.c_str(), docType.size(), now,
                                                publicKeyCert, &publicKeyCertSize,
                                                signingKeyBlob.data())) {
-        return {};
+        return std::nullopt;
     }
 
     vector<uint8_t> cert;
@@ -213,33 +488,44 @@
 
 // Returns private key
 optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::createEphemeralKeyPair() {
+    if (!validateId(__func__)) {
+        return std::nullopt;
+    }
+
     vector<uint8_t> priv(EIC_P256_PRIV_KEY_SIZE);
     if (!eicPresentationCreateEphemeralKeyPair(&ctx_, priv.data())) {
-        return {};
+        return std::nullopt;
     }
     return priv;
 }
 
 optional<uint64_t> FakeSecureHardwarePresentationProxy::createAuthChallenge() {
+    if (!validateId(__func__)) {
+        return std::nullopt;
+    }
+
     uint64_t challenge;
     if (!eicPresentationCreateAuthChallenge(&ctx_, &challenge)) {
-        return {};
+        return std::nullopt;
     }
     return challenge;
 }
 
-bool FakeSecureHardwarePresentationProxy::shutdown() {
-    LOG(INFO) << "FakeSecureHardwarePresentationProxy shutdown";
-    return true;
-}
-
 bool FakeSecureHardwarePresentationProxy::pushReaderCert(const vector<uint8_t>& certX509) {
+    if (!validateId(__func__)) {
+        return false;
+    }
+
     return eicPresentationPushReaderCert(&ctx_, certX509.data(), certX509.size());
 }
 
 bool FakeSecureHardwarePresentationProxy::validateRequestMessage(
         const vector<uint8_t>& sessionTranscript, const vector<uint8_t>& requestMessage,
         int coseSignAlg, const vector<uint8_t>& readerSignatureOfToBeSigned) {
+    if (!validateId(__func__)) {
+        return false;
+    }
+
     return eicPresentationValidateRequestMessage(
             &ctx_, sessionTranscript.data(), sessionTranscript.size(), requestMessage.data(),
             requestMessage.size(), coseSignAlg, readerSignatureOfToBeSigned.data(),
@@ -251,6 +537,10 @@
         int hardwareAuthenticatorType, uint64_t timeStamp, const vector<uint8_t>& mac,
         uint64_t verificationTokenChallenge, uint64_t verificationTokenTimestamp,
         int verificationTokenSecurityLevel, const vector<uint8_t>& verificationTokenMac) {
+    if (!validateId(__func__)) {
+        return false;
+    }
+
     return eicPresentationSetAuthToken(&ctx_, challenge, secureUserId, authenticatorId,
                                        hardwareAuthenticatorType, timeStamp, mac.data(), mac.size(),
                                        verificationTokenChallenge, verificationTokenTimestamp,
@@ -261,6 +551,10 @@
 optional<bool> FakeSecureHardwarePresentationProxy::validateAccessControlProfile(
         int id, const vector<uint8_t>& readerCertificate, bool userAuthenticationRequired,
         int timeoutMillis, uint64_t secureUserId, const vector<uint8_t>& mac) {
+    if (!validateId(__func__)) {
+        return std::nullopt;
+    }
+
     bool accessGranted = false;
     uint8_t scratchSpace[512];
     if (!eicPresentationValidateAccessControlProfile(&ctx_, id, readerCertificate.data(),
@@ -268,12 +562,16 @@
                                                      userAuthenticationRequired, timeoutMillis,
                                                      secureUserId, mac.data(), &accessGranted,
                                                      scratchSpace, sizeof(scratchSpace))) {
-        return {};
+        return std::nullopt;
     }
     return accessGranted;
 }
 
 bool FakeSecureHardwarePresentationProxy::startRetrieveEntries() {
+    if (!validateId(__func__)) {
+        return false;
+    }
+
     return eicPresentationStartRetrieveEntries(&ctx_);
 }
 
@@ -281,6 +579,10 @@
         const vector<uint8_t>& sessionTranscript, const vector<uint8_t>& readerEphemeralPublicKey,
         const vector<uint8_t>& signingKeyBlob, const string& docType,
         unsigned int numNamespacesWithValues, size_t expectedProofOfProvisioningSize) {
+    if (!validateId(__func__)) {
+        return false;
+    }
+
     if (signingKeyBlob.size() != 60) {
         eicDebug("Unexpected size %zd of signingKeyBlob, expected 60", signingKeyBlob.size());
         return false;
@@ -294,6 +596,10 @@
 AccessCheckResult FakeSecureHardwarePresentationProxy::startRetrieveEntryValue(
         const string& nameSpace, const string& name, unsigned int newNamespaceNumEntries,
         int32_t entrySize, const vector<int32_t>& accessControlProfileIds) {
+    if (!validateId(__func__)) {
+        return AccessCheckResult::kFailed;
+    }
+
     uint8_t scratchSpace[512];
     vector<uint8_t> uint8AccessControlProfileIds;
     for (size_t i = 0; i < accessControlProfileIds.size(); i++) {
@@ -324,6 +630,10 @@
 optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::retrieveEntryValue(
         const vector<uint8_t>& encryptedContent, const string& nameSpace, const string& name,
         const vector<int32_t>& accessControlProfileIds) {
+    if (!validateId(__func__)) {
+        return std::nullopt;
+    }
+
     uint8_t scratchSpace[512];
     vector<uint8_t> uint8AccessControlProfileIds;
     for (size_t i = 0; i < accessControlProfileIds.size(); i++) {
@@ -337,16 +647,20 @@
                 nameSpace.c_str(), nameSpace.size(), name.c_str(), name.size(),
                 uint8AccessControlProfileIds.data(), uint8AccessControlProfileIds.size(),
                 scratchSpace, sizeof(scratchSpace))) {
-        return {};
+        return std::nullopt;
     }
     return content;
 }
 
 optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::finishRetrieval() {
+    if (!validateId(__func__)) {
+        return std::nullopt;
+    }
+
     vector<uint8_t> mac(32);
     size_t macSize = 32;
     if (!eicPresentationFinishRetrieval(&ctx_, mac.data(), &macSize)) {
-        return {};
+        return std::nullopt;
     }
     mac.resize(macSize);
     return mac;
@@ -355,11 +669,15 @@
 optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::deleteCredential(
         const string& docType, const vector<uint8_t>& challenge, bool includeChallenge,
         size_t proofOfDeletionCborSize) {
+    if (!validateId(__func__)) {
+        return std::nullopt;
+    }
+
     vector<uint8_t> signatureOfToBeSigned(EIC_ECDSA_P256_SIGNATURE_SIZE);
     if (!eicPresentationDeleteCredential(&ctx_, docType.c_str(), docType.size(), challenge.data(),
                                          challenge.size(), includeChallenge,
                                          proofOfDeletionCborSize, signatureOfToBeSigned.data())) {
-        return {};
+        return std::nullopt;
     }
     return signatureOfToBeSigned;
 }
@@ -367,11 +685,15 @@
 optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::proveOwnership(
         const string& docType, bool testCredential, const vector<uint8_t>& challenge,
         size_t proofOfOwnershipCborSize) {
+    if (!validateId(__func__)) {
+        return std::nullopt;
+    }
+
     vector<uint8_t> signatureOfToBeSigned(EIC_ECDSA_P256_SIGNATURE_SIZE);
     if (!eicPresentationProveOwnership(&ctx_, docType.c_str(), docType.size(), testCredential,
                                        challenge.data(), challenge.size(), proofOfOwnershipCborSize,
                                        signatureOfToBeSigned.data())) {
-        return {};
+        return std::nullopt;
     }
     return signatureOfToBeSigned;
 }
diff --git a/identity/aidl/default/FakeSecureHardwareProxy.h b/identity/aidl/default/FakeSecureHardwareProxy.h
index 6852c1a..df98c7a 100644
--- a/identity/aidl/default/FakeSecureHardwareProxy.h
+++ b/identity/aidl/default/FakeSecureHardwareProxy.h
@@ -27,21 +27,23 @@
 //
 class FakeSecureHardwareProvisioningProxy : public SecureHardwareProvisioningProxy {
   public:
-    FakeSecureHardwareProvisioningProxy();
+    FakeSecureHardwareProvisioningProxy() = default;
     virtual ~FakeSecureHardwareProvisioningProxy();
 
     bool initialize(bool testCredential) override;
 
-    bool initializeForUpdate(bool testCredential, string docType,
-                             vector<uint8_t> encryptedCredentialKeys) override;
+    bool initializeForUpdate(bool testCredential, const string& docType,
+                             const vector<uint8_t>& encryptedCredentialKeys) override;
 
     bool shutdown() override;
 
+    optional<uint32_t> getId() override;
+
     // Returns public key certificate.
     optional<vector<uint8_t>> createCredentialKey(const vector<uint8_t>& challenge,
                                                   const vector<uint8_t>& applicationId) override;
 
-    bool startPersonalization(int accessControlProfileCount, vector<int> entryCounts,
+    bool startPersonalization(int accessControlProfileCount, const vector<int>& entryCounts,
                               const string& docType,
                               size_t expectedProofOfProvisioningSize) override;
 
@@ -67,21 +69,81 @@
     optional<vector<uint8_t>> finishGetCredentialData(const string& docType) override;
 
   protected:
-    EicProvisioning ctx_;
+    // See docs for id_.
+    //
+    bool validateId(const string& callerName);
+
+    // We use a singleton libeic object, shared by all proxy instances.  This is to
+    // properly simulate a situation where libeic is used on constrained hardware
+    // with only enough RAM for a single instance of the libeic object.
+    //
+    static EicProvisioning ctx_;
+
+    // On the HAL side we keep track of the ID that was assigned to the libeic object
+    // created in secure hardware. For every call into libeic we validate that this
+    // identifier matches what is on the secure side. This is what the validateId()
+    // method does.
+    //
+    uint32_t id_ = 0;
+};
+
+// This implementation uses libEmbeddedIC in-process.
+//
+class FakeSecureHardwareSessionProxy : public SecureHardwareSessionProxy {
+  public:
+    FakeSecureHardwareSessionProxy() = default;
+    virtual ~FakeSecureHardwareSessionProxy();
+
+    bool initialize() override;
+
+    bool shutdown() override;
+
+    optional<uint32_t> getId() override;
+
+    optional<uint64_t> getAuthChallenge() override;
+
+    // Returns private key
+    optional<vector<uint8_t>> getEphemeralKeyPair() override;
+
+    bool setReaderEphemeralPublicKey(const vector<uint8_t>& readerEphemeralPublicKey) override;
+
+    bool setSessionTranscript(const vector<uint8_t>& sessionTranscript) override;
+
+  protected:
+    // See docs for id_.
+    //
+    bool validateId(const string& callerName);
+
+    // We use a singleton libeic object, shared by all proxy instances.  This is to
+    // properly simulate a situation where libeic is used on constrained hardware
+    // with only enough RAM for a single instance of the libeic object.
+    //
+    static EicSession ctx_;
+
+    // On the HAL side we keep track of the ID that was assigned to the libeic object
+    // created in secure hardware. For every call into libeic we validate that this
+    // identifier matches what is on the secure side. This is what the validateId()
+    // method does.
+    //
+    uint32_t id_ = 0;
 };
 
 // This implementation uses libEmbeddedIC in-process.
 //
 class FakeSecureHardwarePresentationProxy : public SecureHardwarePresentationProxy {
   public:
-    FakeSecureHardwarePresentationProxy();
+    FakeSecureHardwarePresentationProxy() = default;
     virtual ~FakeSecureHardwarePresentationProxy();
 
-    bool initialize(bool testCredential, string docType,
-                    vector<uint8_t> encryptedCredentialKeys) override;
+    bool initialize(uint32_t sessionId, bool testCredential, const string& docType,
+                    const vector<uint8_t>& encryptedCredentialKeys) override;
+
+    bool shutdown() override;
+
+    optional<uint32_t> getId() override;
 
     // Returns publicKeyCert (1st component) and signingKeyBlob (2nd component)
-    optional<pair<vector<uint8_t>, vector<uint8_t>>> generateSigningKeyPair(string docType,
+    optional<pair<vector<uint8_t>, vector<uint8_t>>> generateSigningKeyPair(const string& docType,
                                                                             time_t now) override;
 
     // Returns private key
@@ -133,10 +195,23 @@
                                              const vector<uint8_t>& challenge,
                                              size_t proofOfOwnershipCborSize) override;
 
-    bool shutdown() override;
-
   protected:
-    EicPresentation ctx_;
+    // See docs for id_.
+    //
+    bool validateId(const string& callerName);
+
+    // We use a singleton libeic object, shared by all proxy instances.  This is to
+    // properly simulate a situation where libeic is used on constrained hardware
+    // with only enough RAM for a single instance of the libeic object.
+    //
+    static EicPresentation ctx_;
+
+    // On the HAL side we keep track of the ID that was assigned to the libeic object
+    // created in secure hardware. For every call into libeic we validate that this
+    // identifier matches what is on the secure side. This is what the validateId()
+    // method does.
+    //
+    uint32_t id_ = 0;
 };
 
 // Factory implementation.
@@ -150,6 +225,10 @@
         return new FakeSecureHardwareProvisioningProxy();
     }
 
+    sp<SecureHardwareSessionProxy> createSessionProxy() override {
+        return new FakeSecureHardwareSessionProxy();
+    }
+
     sp<SecureHardwarePresentationProxy> createPresentationProxy() override {
         return new FakeSecureHardwarePresentationProxy();
     }
diff --git a/identity/aidl/default/android.hardware.identity_credential.xml b/identity/aidl/default/android.hardware.identity_credential.xml
index 5149792..20b2710 100644
--- a/identity/aidl/default/android.hardware.identity_credential.xml
+++ b/identity/aidl/default/android.hardware.identity_credential.xml
@@ -14,5 +14,5 @@
      limitations under the License.
 -->
 <permissions>
-  <feature name="android.hardware.identity_credential" version="202101" />
+  <feature name="android.hardware.identity_credential" version="202201" />
 </permissions>
diff --git a/identity/aidl/default/common/IdentityCredential.cpp b/identity/aidl/default/common/IdentityCredential.cpp
index 95557b5..7678ecb 100644
--- a/identity/aidl/default/common/IdentityCredential.cpp
+++ b/identity/aidl/default/common/IdentityCredential.cpp
@@ -72,14 +72,38 @@
     testCredential_ = testCredentialItem->value();
 
     encryptedCredentialKeys_ = encryptedCredentialKeysItem->value();
-    if (!hwProxy_->initialize(testCredential_, docType_, encryptedCredentialKeys_)) {
-        LOG(ERROR) << "hwProxy->initialize failed";
-        return false;
+
+    // If in a session, delay the initialization of the proxy.
+    //
+    if (!session_) {
+        ndk::ScopedAStatus status = ensureHwProxy();
+        if (!status.isOk()) {
+            LOG(ERROR) << "Error initializing hw proxy";
+            return IIdentityCredentialStore::STATUS_FAILED;
+        }
     }
 
     return IIdentityCredentialStore::STATUS_OK;
 }
 
+ndk::ScopedAStatus IdentityCredential::ensureHwProxy() {
+    if (hwProxy_) {
+        return ndk::ScopedAStatus::ok();
+    }
+    hwProxy_ = hwProxyFactory_->createPresentationProxy();
+    if (!hwProxy_) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "Error creating hw proxy"));
+    }
+    uint64_t sessionId = session_ ? session_->getSessionId() : EIC_PRESENTATION_ID_UNSET;
+    if (!hwProxy_->initialize(sessionId, testCredential_, docType_, encryptedCredentialKeys_)) {
+        hwProxy_.clear();
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "Error initializing hw proxy"));
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
 ndk::ScopedAStatus IdentityCredential::deleteCredential(
         vector<uint8_t>* outProofOfDeletionSignature) {
     return deleteCredentialCommon({}, false, outProofOfDeletionSignature);
@@ -93,6 +117,14 @@
 ndk::ScopedAStatus IdentityCredential::deleteCredentialCommon(
         const vector<uint8_t>& challenge, bool includeChallenge,
         vector<uint8_t>* outProofOfDeletionSignature) {
+    if (session_) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "Cannot be called in a session"));
+    }
+    ndk::ScopedAStatus status = ensureHwProxy();
+    if (!status.isOk()) {
+        return status;
+    }
     if (challenge.size() > 32) {
         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
                 IIdentityCredentialStore::STATUS_INVALID_DATA, "Challenge too big"));
@@ -128,6 +160,14 @@
 
 ndk::ScopedAStatus IdentityCredential::proveOwnership(
         const vector<uint8_t>& challenge, vector<uint8_t>* outProofOfOwnershipSignature) {
+    if (session_) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "Cannot be called in a session"));
+    }
+    ndk::ScopedAStatus status = ensureHwProxy();
+    if (!status.isOk()) {
+        return status;
+    }
     if (challenge.size() > 32) {
         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
                 IIdentityCredentialStore::STATUS_INVALID_DATA, "Challenge too big"));
@@ -159,6 +199,14 @@
 }
 
 ndk::ScopedAStatus IdentityCredential::createEphemeralKeyPair(vector<uint8_t>* outKeyPair) {
+    if (session_) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "Cannot be called in a session"));
+    }
+    ndk::ScopedAStatus status = ensureHwProxy();
+    if (!status.isOk()) {
+        return status;
+    }
     optional<vector<uint8_t>> ephemeralPriv = hwProxy_->createEphemeralKeyPair();
     if (!ephemeralPriv) {
         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
@@ -186,11 +234,23 @@
 
 ndk::ScopedAStatus IdentityCredential::setReaderEphemeralPublicKey(
         const vector<uint8_t>& publicKey) {
+    if (session_) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "Cannot be called in a session"));
+    }
     readerPublicKey_ = publicKey;
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus IdentityCredential::createAuthChallenge(int64_t* outChallenge) {
+    if (session_) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "Cannot be called in a session"));
+    }
+    ndk::ScopedAStatus status = ensureHwProxy();
+    if (!status.isOk()) {
+        return status;
+    }
     optional<uint64_t> challenge = hwProxy_->createAuthChallenge();
     if (!challenge) {
         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
@@ -217,16 +277,22 @@
         const HardwareAuthToken& authToken, const vector<uint8_t>& itemsRequest,
         const vector<uint8_t>& signingKeyBlob, const vector<uint8_t>& sessionTranscript,
         const vector<uint8_t>& readerSignature, const vector<int32_t>& requestCounts) {
-    std::unique_ptr<cppbor::Item> sessionTranscriptItem;
-    if (sessionTranscript.size() > 0) {
-        auto [item, _, message] = cppbor::parse(sessionTranscript);
-        if (item == nullptr) {
-            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
-                    IIdentityCredentialStore::STATUS_INVALID_DATA,
-                    "SessionTranscript contains invalid CBOR"));
-        }
-        sessionTranscriptItem = std::move(item);
+    ndk::ScopedAStatus status = ensureHwProxy();
+    if (!status.isOk()) {
+        return status;
     }
+
+    // If in a session, ensure the passed-in session transcript matches the
+    // session transcript from the session.
+    if (session_) {
+        if (sessionTranscript != session_->getSessionTranscript()) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_SESSION_TRANSCRIPT_MISMATCH,
+                    "In a session and passed-in SessionTranscript doesn't match the one "
+                    "from the session"));
+        }
+    }
+
     if (numStartRetrievalCalls_ > 0) {
         if (sessionTranscript_ != sessionTranscript) {
             LOG(ERROR) << "Session Transcript changed";
@@ -390,32 +456,36 @@
         }
     }
 
-    // TODO: move this check to the TA
-#if 1
-    // To prevent replay-attacks, we check that the public part of the ephemeral
-    // key we previously created, is present in the DeviceEngagement part of
-    // SessionTranscript as a COSE_Key, in uncompressed form.
-    //
-    // We do this by just searching for the X and Y coordinates.
-    if (sessionTranscript.size() > 0) {
-        auto [getXYSuccess, ePubX, ePubY] = support::ecPublicKeyGetXandY(ephemeralPublicKey_);
-        if (!getXYSuccess) {
-            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
-                    IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND,
-                    "Error extracting X and Y from ePub"));
-        }
-        if (sessionTranscript.size() > 0 &&
-            !(memmem(sessionTranscript.data(), sessionTranscript.size(), ePubX.data(),
-                     ePubX.size()) != nullptr &&
-              memmem(sessionTranscript.data(), sessionTranscript.size(), ePubY.data(),
-                     ePubY.size()) != nullptr)) {
-            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
-                    IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND,
-                    "Did not find ephemeral public key's X and Y coordinates in "
-                    "SessionTranscript (make sure leading zeroes are not used)"));
+    if (session_) {
+        // If presenting in a session, the TA has already done this check.
+
+    } else {
+        // To prevent replay-attacks, we check that the public part of the ephemeral
+        // key we previously created, is present in the DeviceEngagement part of
+        // SessionTranscript as a COSE_Key, in uncompressed form.
+        //
+        // We do this by just searching for the X and Y coordinates.
+        //
+        // Would be nice to move this check to the TA.
+        if (sessionTranscript.size() > 0) {
+            auto [getXYSuccess, ePubX, ePubY] = support::ecPublicKeyGetXandY(ephemeralPublicKey_);
+            if (!getXYSuccess) {
+                return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                        IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND,
+                        "Error extracting X and Y from ePub"));
+            }
+            if (sessionTranscript.size() > 0 &&
+                !(memmem(sessionTranscript.data(), sessionTranscript.size(), ePubX.data(),
+                         ePubX.size()) != nullptr &&
+                  memmem(sessionTranscript.data(), sessionTranscript.size(), ePubY.data(),
+                         ePubY.size()) != nullptr)) {
+                return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                        IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND,
+                        "Did not find ephemeral public key's X and Y coordinates in "
+                        "SessionTranscript (make sure leading zeroes are not used)"));
+            }
         }
     }
-#endif
 
     // itemsRequest: If non-empty, contains request data that may be signed by the
     // reader.  The content can be defined in the way appropriate for the
@@ -537,21 +607,38 @@
 
     // Finally, pass info so the HMAC key can be derived and the TA can start
     // creating the DeviceNameSpaces CBOR...
-    if (sessionTranscript_.size() > 0 && readerPublicKey_.size() > 0 && signingKeyBlob.size() > 0) {
-        // We expect the reader ephemeral public key to be same size and curve
-        // as the ephemeral key we generated (e.g. P-256 key), otherwise ECDH
-        // won't work. So its length should be 65 bytes and it should be
-        // starting with 0x04.
-        if (readerPublicKey_.size() != 65 || readerPublicKey_[0] != 0x04) {
-            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
-                    IIdentityCredentialStore::STATUS_FAILED,
-                    "Reader public key is not in expected format"));
+    if (!session_) {
+        if (sessionTranscript_.size() > 0 && readerPublicKey_.size() > 0 &&
+            signingKeyBlob.size() > 0) {
+            // We expect the reader ephemeral public key to be same size and curve
+            // as the ephemeral key we generated (e.g. P-256 key), otherwise ECDH
+            // won't work. So its length should be 65 bytes and it should be
+            // starting with 0x04.
+            if (readerPublicKey_.size() != 65 || readerPublicKey_[0] != 0x04) {
+                return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                        IIdentityCredentialStore::STATUS_FAILED,
+                        "Reader public key is not in expected format"));
+            }
+            vector<uint8_t> pubKeyP256(readerPublicKey_.begin() + 1, readerPublicKey_.end());
+            if (!hwProxy_->calcMacKey(sessionTranscript_, pubKeyP256, signingKeyBlob, docType_,
+                                      numNamespacesWithValues, expectedDeviceNameSpacesSize_)) {
+                return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                        IIdentityCredentialStore::STATUS_FAILED,
+                        "Error starting retrieving entries"));
+            }
         }
-        vector<uint8_t> pubKeyP256(readerPublicKey_.begin() + 1, readerPublicKey_.end());
-        if (!hwProxy_->calcMacKey(sessionTranscript_, pubKeyP256, signingKeyBlob, docType_,
-                                  numNamespacesWithValues, expectedDeviceNameSpacesSize_)) {
-            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
-                    IIdentityCredentialStore::STATUS_FAILED, "Error starting retrieving entries"));
+    } else {
+        if (session_->getSessionTranscript().size() > 0 &&
+            session_->getReaderEphemeralPublicKey().size() > 0 && signingKeyBlob.size() > 0) {
+            // Don't actually pass the reader ephemeral public key in, the TA will get
+            // it from the session object.
+            //
+            if (!hwProxy_->calcMacKey(sessionTranscript_, {}, signingKeyBlob, docType_,
+                                      numNamespacesWithValues, expectedDeviceNameSpacesSize_)) {
+                return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                        IIdentityCredentialStore::STATUS_FAILED,
+                        "Error starting retrieving entries"));
+            }
         }
     }
 
@@ -665,6 +752,11 @@
 ndk::ScopedAStatus IdentityCredential::startRetrieveEntryValue(
         const string& nameSpace, const string& name, int32_t entrySize,
         const vector<int32_t>& accessControlProfileIds) {
+    ndk::ScopedAStatus status = ensureHwProxy();
+    if (!status.isOk()) {
+        return status;
+    }
+
     if (name.empty()) {
         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
                 IIdentityCredentialStore::STATUS_INVALID_DATA, "Name cannot be empty"));
@@ -785,6 +877,11 @@
 
 ndk::ScopedAStatus IdentityCredential::retrieveEntryValue(const vector<uint8_t>& encryptedContent,
                                                           vector<uint8_t>* outContent) {
+    ndk::ScopedAStatus status = ensureHwProxy();
+    if (!status.isOk()) {
+        return status;
+    }
+
     optional<vector<uint8_t>> content = hwProxy_->retrieveEntryValue(
             encryptedContent, currentNameSpace_, currentName_, currentAccessControlProfileIds_);
     if (!content) {
@@ -829,6 +926,11 @@
 
 ndk::ScopedAStatus IdentityCredential::finishRetrieval(vector<uint8_t>* outMac,
                                                        vector<uint8_t>* outDeviceNameSpaces) {
+    ndk::ScopedAStatus status = ensureHwProxy();
+    if (!status.isOk()) {
+        return status;
+    }
+
     if (currentNameSpaceDeviceNameSpacesMap_.size() > 0) {
         deviceNameSpacesMap_.add(currentNameSpace_,
                                  std::move(currentNameSpaceDeviceNameSpacesMap_));
@@ -846,18 +948,23 @@
                         .c_str()));
     }
 
-    // If there's no signing key or no sessionTranscript or no reader ephemeral
-    // public key, we return the empty MAC.
+    // If the TA calculated a MAC (it might not have), format it as a COSE_Mac0
+    //
     optional<vector<uint8_t>> mac;
-    if (signingKeyBlob_.size() > 0 && sessionTranscript_.size() > 0 &&
-        readerPublicKey_.size() > 0) {
-        optional<vector<uint8_t>> digestToBeMaced = hwProxy_->finishRetrieval();
-        if (!digestToBeMaced || digestToBeMaced.value().size() != 32) {
+    optional<vector<uint8_t>> digestToBeMaced = hwProxy_->finishRetrieval();
+
+    // The MAC not being set means an error occurred.
+    if (!digestToBeMaced) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_INVALID_DATA, "Error generating digestToBeMaced"));
+    }
+    // Size 0 means that the MAC isn't set. If it's set, it has to be 32 bytes.
+    if (digestToBeMaced.value().size() != 0) {
+        if (digestToBeMaced.value().size() != 32) {
             return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
                     IIdentityCredentialStore::STATUS_INVALID_DATA,
-                    "Error generating digestToBeMaced"));
+                    "Unexpected size for digestToBeMaced"));
         }
-        // Now construct COSE_Mac0 from the returned MAC...
         mac = support::coseMacWithDigest(digestToBeMaced.value(), {} /* data */);
     }
 
@@ -868,6 +975,15 @@
 
 ndk::ScopedAStatus IdentityCredential::generateSigningKeyPair(
         vector<uint8_t>* outSigningKeyBlob, Certificate* outSigningKeyCertificate) {
+    if (session_) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "Cannot be called in a session"));
+    }
+    ndk::ScopedAStatus status = ensureHwProxy();
+    if (!status.isOk()) {
+        return status;
+    }
+
     time_t now = time(NULL);
     optional<pair<vector<uint8_t>, vector<uint8_t>>> pair =
             hwProxy_->generateSigningKeyPair(docType_, now);
@@ -885,9 +1001,18 @@
 
 ndk::ScopedAStatus IdentityCredential::updateCredential(
         shared_ptr<IWritableIdentityCredential>* outWritableCredential) {
-    sp<SecureHardwareProvisioningProxy> hwProxy = hwProxyFactory_->createProvisioningProxy();
+    if (session_) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "Cannot be called in a session"));
+    }
+    sp<SecureHardwareProvisioningProxy> provisioningHwProxy =
+            hwProxyFactory_->createProvisioningProxy();
+    if (!provisioningHwProxy) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "Error creating provisioning proxy"));
+    }
     shared_ptr<WritableIdentityCredential> wc =
-            ndk::SharedRefBase::make<WritableIdentityCredential>(hwProxy, docType_,
+            ndk::SharedRefBase::make<WritableIdentityCredential>(provisioningHwProxy, docType_,
                                                                  testCredential_);
     if (!wc->initializeForUpdate(encryptedCredentialKeys_)) {
         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
diff --git a/identity/aidl/default/common/IdentityCredential.h b/identity/aidl/default/common/IdentityCredential.h
index ef9d133..2935fb8 100644
--- a/identity/aidl/default/common/IdentityCredential.h
+++ b/identity/aidl/default/common/IdentityCredential.h
@@ -30,6 +30,7 @@
 #include <cppbor.h>
 
 #include "IdentityCredentialStore.h"
+#include "PresentationSession.h"
 #include "SecureHardwareProxy.h"
 
 namespace aidl::android::hardware::identity {
@@ -46,11 +47,11 @@
 class IdentityCredential : public BnIdentityCredential {
   public:
     IdentityCredential(sp<SecureHardwareProxyFactory> hwProxyFactory,
-                       sp<SecureHardwarePresentationProxy> hwProxy,
-                       const vector<uint8_t>& credentialData)
+                       const vector<uint8_t>& credentialData,
+                       std::shared_ptr<PresentationSession> session)
         : hwProxyFactory_(hwProxyFactory),
-          hwProxy_(hwProxy),
           credentialData_(credentialData),
+          session_(std::move(session)),
           numStartRetrievalCalls_(0),
           expectedDeviceNameSpacesSize_(0) {}
 
@@ -94,10 +95,13 @@
                                               bool includeChallenge,
                                               vector<uint8_t>* outProofOfDeletionSignature);
 
+    // Creates and initializes hwProxy_.
+    ndk::ScopedAStatus ensureHwProxy();
+
     // Set by constructor
     sp<SecureHardwareProxyFactory> hwProxyFactory_;
-    sp<SecureHardwarePresentationProxy> hwProxy_;
     vector<uint8_t> credentialData_;
+    shared_ptr<PresentationSession> session_;
     int numStartRetrievalCalls_;
 
     // Set by initialize()
@@ -105,6 +109,9 @@
     bool testCredential_;
     vector<uint8_t> encryptedCredentialKeys_;
 
+    // Set by ensureHwProxy()
+    sp<SecureHardwarePresentationProxy> hwProxy_;
+
     // Set by createEphemeralKeyPair()
     vector<uint8_t> ephemeralPublicKey_;
 
diff --git a/identity/aidl/default/common/IdentityCredentialStore.cpp b/identity/aidl/default/common/IdentityCredentialStore.cpp
index e6b5466..4703ffe 100644
--- a/identity/aidl/default/common/IdentityCredentialStore.cpp
+++ b/identity/aidl/default/common/IdentityCredentialStore.cpp
@@ -20,6 +20,7 @@
 
 #include "IdentityCredential.h"
 #include "IdentityCredentialStore.h"
+#include "PresentationSession.h"
 #include "WritableIdentityCredential.h"
 
 namespace aidl::android::hardware::identity {
@@ -61,9 +62,8 @@
                 "Unsupported cipher suite"));
     }
 
-    sp<SecureHardwarePresentationProxy> hwProxy = hwProxyFactory_->createPresentationProxy();
-    shared_ptr<IdentityCredential> credential =
-            ndk::SharedRefBase::make<IdentityCredential>(hwProxyFactory_, hwProxy, credentialData);
+    shared_ptr<IdentityCredential> credential = ndk::SharedRefBase::make<IdentityCredential>(
+            hwProxyFactory_, credentialData, nullptr /* session */);
     auto ret = credential->initialize();
     if (ret != IIdentityCredentialStore::STATUS_OK) {
         return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
@@ -73,4 +73,25 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus IdentityCredentialStore::createPresentationSession(
+        CipherSuite cipherSuite, shared_ptr<IPresentationSession>* outSession) {
+    // We only support CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256 right now.
+    if (cipherSuite != CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_CIPHER_SUITE_NOT_SUPPORTED,
+                "Unsupported cipher suite"));
+    }
+
+    sp<SecureHardwareSessionProxy> hwProxy = hwProxyFactory_->createSessionProxy();
+    shared_ptr<PresentationSession> session =
+            ndk::SharedRefBase::make<PresentationSession>(hwProxyFactory_, hwProxy);
+    auto ret = session->initialize();
+    if (ret != IIdentityCredentialStore::STATUS_OK) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                int(ret), "Error initializing PresentationSession"));
+    }
+    *outSession = session;
+    return ndk::ScopedAStatus::ok();
+}
+
 }  // namespace aidl::android::hardware::identity
diff --git a/identity/aidl/default/common/IdentityCredentialStore.h b/identity/aidl/default/common/IdentityCredentialStore.h
index d35e632..77b894d 100644
--- a/identity/aidl/default/common/IdentityCredentialStore.h
+++ b/identity/aidl/default/common/IdentityCredentialStore.h
@@ -47,6 +47,9 @@
     ndk::ScopedAStatus getCredential(CipherSuite cipherSuite, const vector<uint8_t>& credentialData,
                                      shared_ptr<IIdentityCredential>* outCredential) override;
 
+    ndk::ScopedAStatus createPresentationSession(
+            CipherSuite cipherSuite, shared_ptr<IPresentationSession>* outSession) override;
+
   private:
     sp<SecureHardwareProxyFactory> hwProxyFactory_;
 };
diff --git a/identity/aidl/default/common/PresentationSession.cpp b/identity/aidl/default/common/PresentationSession.cpp
new file mode 100644
index 0000000..fbd8972
--- /dev/null
+++ b/identity/aidl/default/common/PresentationSession.cpp
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "PresentationSession"
+
+#include "PresentationSession.h"
+#include "IdentityCredentialStore.h"
+
+#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+
+#include <string.h>
+
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+
+#include <cppbor.h>
+#include <cppbor_parse.h>
+
+#include "FakeSecureHardwareProxy.h"
+#include "IdentityCredential.h"
+#include "PresentationSession.h"
+
+namespace aidl::android::hardware::identity {
+
+using ::std::optional;
+
+using namespace ::android::hardware::identity;
+
+PresentationSession::~PresentationSession() {}
+
+int PresentationSession::initialize() {
+    if (!hwProxy_->initialize()) {
+        LOG(ERROR) << "hwProxy->initialize failed";
+        return IIdentityCredentialStore::STATUS_FAILED;
+    }
+
+    optional<uint64_t> id = hwProxy_->getId();
+    if (!id) {
+        LOG(ERROR) << "Error getting id for session";
+        return IIdentityCredentialStore::STATUS_FAILED;
+    }
+    id_ = id.value();
+
+    optional<vector<uint8_t>> ephemeralKeyPriv = hwProxy_->getEphemeralKeyPair();
+    if (!ephemeralKeyPriv) {
+        LOG(ERROR) << "Error getting ephemeral private key for session";
+        return IIdentityCredentialStore::STATUS_FAILED;
+    }
+    optional<vector<uint8_t>> ephemeralKeyPair =
+            support::ecPrivateKeyToKeyPair(ephemeralKeyPriv.value());
+    if (!ephemeralKeyPair) {
+        LOG(ERROR) << "Error creating ephemeral key-pair";
+        return IIdentityCredentialStore::STATUS_FAILED;
+    }
+    ephemeralKeyPair_ = ephemeralKeyPair.value();
+
+    optional<uint64_t> authChallenge = hwProxy_->getAuthChallenge();
+    if (!authChallenge) {
+        LOG(ERROR) << "Error getting authChallenge for session";
+        return IIdentityCredentialStore::STATUS_FAILED;
+    }
+    authChallenge_ = authChallenge.value();
+
+    return IIdentityCredentialStore::STATUS_OK;
+}
+
+ndk::ScopedAStatus PresentationSession::getEphemeralKeyPair(vector<uint8_t>* outKeyPair) {
+    *outKeyPair = ephemeralKeyPair_;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus PresentationSession::getAuthChallenge(int64_t* outChallenge) {
+    *outChallenge = authChallenge_;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus PresentationSession::setReaderEphemeralPublicKey(
+        const vector<uint8_t>& publicKey) {
+    // We expect the reader ephemeral public key to be same size and curve
+    // as the ephemeral key we generated (e.g. P-256 key), otherwise ECDH
+    // won't work. So its length should be 65 bytes and it should be
+    // starting with 0x04.
+    if (publicKey.size() != 65 || publicKey[0] != 0x04) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED,
+                "Reader public key is not in expected format"));
+    }
+    readerPublicKey_ = publicKey;
+    vector<uint8_t> pubKeyP256(publicKey.begin() + 1, publicKey.end());
+    if (!hwProxy_->setReaderEphemeralPublicKey(pubKeyP256)) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED,
+                "Error setting readerEphemeralPublicKey for session"));
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus PresentationSession::setSessionTranscript(
+        const vector<uint8_t>& sessionTranscript) {
+    sessionTranscript_ = sessionTranscript;
+    if (!hwProxy_->setSessionTranscript(sessionTranscript)) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED,
+                "Error setting SessionTranscript for session"));
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus PresentationSession::getCredential(
+        const vector<uint8_t>& credentialData, shared_ptr<IIdentityCredential>* outCredential) {
+    shared_ptr<PresentationSession> p = ref<PresentationSession>();
+    shared_ptr<IdentityCredential> credential =
+            ndk::SharedRefBase::make<IdentityCredential>(hwProxyFactory_, credentialData, p);
+    int ret = credential->initialize();
+    if (ret != IIdentityCredentialStore::STATUS_OK) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                ret, "Error initializing IdentityCredential"));
+    }
+    *outCredential = std::move(credential);
+
+    return ndk::ScopedAStatus::ok();
+}
+
+uint64_t PresentationSession::getSessionId() {
+    return id_;
+}
+
+vector<uint8_t> PresentationSession::getSessionTranscript() {
+    return sessionTranscript_;
+}
+
+vector<uint8_t> PresentationSession::getReaderEphemeralPublicKey() {
+    return readerPublicKey_;
+}
+
+}  // namespace aidl::android::hardware::identity
diff --git a/identity/aidl/default/common/PresentationSession.h b/identity/aidl/default/common/PresentationSession.h
new file mode 100644
index 0000000..76ca67b
--- /dev/null
+++ b/identity/aidl/default/common/PresentationSession.h
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_IDENTITY_PRESENTATIONSESSION_H
+#define ANDROID_HARDWARE_IDENTITY_PRESENTATIONSESSION_H
+
+#include <aidl/android/hardware/identity/BnPresentationSession.h>
+#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+
+#include <vector>
+
+#include <cppbor.h>
+
+#include "IdentityCredentialStore.h"
+#include "SecureHardwareProxy.h"
+
+namespace aidl::android::hardware::identity {
+
+using ::aidl::android::hardware::keymaster::HardwareAuthToken;
+using ::aidl::android::hardware::keymaster::VerificationToken;
+using ::android::sp;
+using ::android::hardware::identity::SecureHardwareSessionProxy;
+using ::std::vector;
+
+class PresentationSession : public BnPresentationSession {
+  public:
+    PresentationSession(sp<SecureHardwareProxyFactory> hwProxyFactory,
+                        sp<SecureHardwareSessionProxy> hwProxy)
+        : hwProxyFactory_(std::move(hwProxyFactory)), hwProxy_(std::move(hwProxy)) {}
+
+    virtual ~PresentationSession();
+
+    // Creates ephemeral key and auth-challenge in TA. Returns a status code from
+    // IIdentityCredentialStore. Must be called right after construction.
+    int initialize();
+
+    uint64_t getSessionId();
+
+    vector<uint8_t> getSessionTranscript();
+    vector<uint8_t> getReaderEphemeralPublicKey();
+
+    // Methods from IPresentationSession follow.
+    ndk::ScopedAStatus getEphemeralKeyPair(vector<uint8_t>* outKeyPair) override;
+    ndk::ScopedAStatus getAuthChallenge(int64_t* outChallenge) override;
+    ndk::ScopedAStatus setReaderEphemeralPublicKey(const vector<uint8_t>& publicKey) override;
+    ndk::ScopedAStatus setSessionTranscript(const vector<uint8_t>& sessionTranscript) override;
+
+    ndk::ScopedAStatus getCredential(const vector<uint8_t>& credentialData,
+                                     shared_ptr<IIdentityCredential>* outCredential) override;
+
+  private:
+    // Set by constructor
+    sp<SecureHardwareProxyFactory> hwProxyFactory_;
+    sp<SecureHardwareSessionProxy> hwProxy_;
+
+    // Set by initialize()
+    uint64_t id_;
+    vector<uint8_t> ephemeralKeyPair_;
+    uint64_t authChallenge_;
+
+    // Set by setReaderEphemeralPublicKey()
+    vector<uint8_t> readerPublicKey_;
+
+    // Set by setSessionTranscript()
+    vector<uint8_t> sessionTranscript_;
+};
+
+}  // namespace aidl::android::hardware::identity
+
+#endif  // ANDROID_HARDWARE_IDENTITY_PRESENTATIONSESSION_H
diff --git a/identity/aidl/default/common/SecureHardwareProxy.h b/identity/aidl/default/common/SecureHardwareProxy.h
index a1ed1ef..a580444 100644
--- a/identity/aidl/default/common/SecureHardwareProxy.h
+++ b/identity/aidl/default/common/SecureHardwareProxy.h
@@ -42,6 +42,7 @@
 // Forward declare.
 //
 class SecureHardwareProvisioningProxy;
+class SecureHardwareSessionProxy;
 class SecureHardwarePresentationProxy;
 
 // This is a class used to create proxies.
@@ -52,6 +53,7 @@
     virtual ~SecureHardwareProxyFactory() {}
 
     virtual sp<SecureHardwareProvisioningProxy> createProvisioningProxy() = 0;
+    virtual sp<SecureHardwareSessionProxy> createSessionProxy() = 0;
     virtual sp<SecureHardwarePresentationProxy> createPresentationProxy() = 0;
 };
 
@@ -64,8 +66,12 @@
 
     virtual bool initialize(bool testCredential) = 0;
 
-    virtual bool initializeForUpdate(bool testCredential, string docType,
-                                     vector<uint8_t> encryptedCredentialKeys) = 0;
+    virtual bool initializeForUpdate(bool testCredential, const string& docType,
+                                     const vector<uint8_t>& encryptedCredentialKeys) = 0;
+
+    virtual optional<uint32_t> getId() = 0;
+
+    virtual bool shutdown() = 0;
 
     // Returns public key certificate chain with attestation.
     //
@@ -76,7 +82,7 @@
     virtual optional<vector<uint8_t>> createCredentialKey(const vector<uint8_t>& challenge,
                                                           const vector<uint8_t>& applicationId) = 0;
 
-    virtual bool startPersonalization(int accessControlProfileCount, vector<int> entryCounts,
+    virtual bool startPersonalization(int accessControlProfileCount, const vector<int>& entryCounts,
                                       const string& docType,
                                       size_t expectedProofOfProvisioningSize) = 0;
 
@@ -98,8 +104,6 @@
 
     // Returns encryptedCredentialKeys (80 bytes).
     virtual optional<vector<uint8_t>> finishGetCredentialData(const string& docType) = 0;
-
-    virtual bool shutdown() = 0;
 };
 
 enum AccessCheckResult {
@@ -110,6 +114,30 @@
     kReaderAuthenticationFailed,
 };
 
+// The proxy used for sessions.
+//
+class SecureHardwareSessionProxy : public RefBase {
+  public:
+    SecureHardwareSessionProxy() {}
+
+    virtual ~SecureHardwareSessionProxy() {}
+
+    virtual bool initialize() = 0;
+
+    virtual optional<uint32_t> getId() = 0;
+
+    virtual bool shutdown() = 0;
+
+    virtual optional<uint64_t> getAuthChallenge() = 0;
+
+    // Returns private key
+    virtual optional<vector<uint8_t>> getEphemeralKeyPair() = 0;
+
+    virtual bool setReaderEphemeralPublicKey(const vector<uint8_t>& readerEphemeralPublicKey) = 0;
+
+    virtual bool setSessionTranscript(const vector<uint8_t>& sessionTranscript) = 0;
+};
+
 // The proxy used for presentation.
 //
 class SecureHardwarePresentationProxy : public RefBase {
@@ -117,12 +145,16 @@
     SecureHardwarePresentationProxy() {}
     virtual ~SecureHardwarePresentationProxy() {}
 
-    virtual bool initialize(bool testCredential, string docType,
-                            vector<uint8_t> encryptedCredentialKeys) = 0;
+    virtual bool initialize(uint32_t sessionId, bool testCredential, const string& docType,
+                            const vector<uint8_t>& encryptedCredentialKeys) = 0;
+
+    virtual optional<uint32_t> getId() = 0;
+
+    virtual bool shutdown() = 0;
 
     // Returns publicKeyCert (1st component) and signingKeyBlob (2nd component)
-    virtual optional<pair<vector<uint8_t>, vector<uint8_t>>> generateSigningKeyPair(string docType,
-                                                                                    time_t now) = 0;
+    virtual optional<pair<vector<uint8_t>, vector<uint8_t>>> generateSigningKeyPair(
+            const string& docType, time_t now) = 0;
 
     // Returns private key
     virtual optional<vector<uint8_t>> createEphemeralKeyPair() = 0;
@@ -174,8 +206,6 @@
     virtual optional<vector<uint8_t>> proveOwnership(const string& docType, bool testCredential,
                                                      const vector<uint8_t>& challenge,
                                                      size_t proofOfOwnershipCborSize) = 0;
-
-    virtual bool shutdown() = 0;
 };
 
 }  // namespace android::hardware::identity
diff --git a/identity/aidl/default/identity-default.xml b/identity/aidl/default/identity-default.xml
index a074250..cc0ddc7 100644
--- a/identity/aidl/default/identity-default.xml
+++ b/identity/aidl/default/identity-default.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.identity</name>
-        <version>3</version>
+        <version>4</version>
         <interface>
             <name>IIdentityCredentialStore</name>
             <instance>default</instance>
diff --git a/identity/aidl/default/libeic/EicCommon.h b/identity/aidl/default/libeic/EicCommon.h
index 476276e..2a08a35 100644
--- a/identity/aidl/default/libeic/EicCommon.h
+++ b/identity/aidl/default/libeic/EicCommon.h
@@ -21,6 +21,9 @@
 #ifndef ANDROID_HARDWARE_IDENTITY_EIC_COMMON_H
 #define ANDROID_HARDWARE_IDENTITY_EIC_COMMON_H
 
+// KeyMint auth-challenges are 64-bit numbers and 0 typically means unset.
+#define EIC_KM_AUTH_CHALLENGE_UNSET 0
+
 // Feature version 202009:
 //
 //         CredentialKeys = [
diff --git a/identity/aidl/default/libeic/EicOps.h b/identity/aidl/default/libeic/EicOps.h
index d4fcf0e..aa26e62 100644
--- a/identity/aidl/default/libeic/EicOps.h
+++ b/identity/aidl/default/libeic/EicOps.h
@@ -141,6 +141,10 @@
 // String length, see strlen(3).
 size_t eicStrLen(const char* s);
 
+// Locate a substring, see memmem(3)
+void* eicMemMem(const uint8_t* haystack, size_t haystackLen, const uint8_t* needle,
+                size_t needleLen);
+
 // Memory compare, see CRYPTO_memcmp(3SSL)
 //
 // It takes an amount of time dependent on len, but independent of the contents of the
@@ -151,6 +155,12 @@
 // Random number generation.
 bool eicOpsRandom(uint8_t* buf, size_t numBytes);
 
+// Creates a new non-zero identifier in |id|.
+//
+// Is guaranteed to be non-zero and different than what is already in |id|.
+//
+bool eicNextId(uint32_t* id);
+
 // If |testCredential| is true, returns the 128-bit AES Hardware-Bound Key (16 bytes).
 //
 // Otherwise returns all zeroes (16 bytes).
@@ -295,6 +305,8 @@
                              int verificationTokenSecurityLevel,
                              const uint8_t* verificationTokenMac, size_t verificationTokenMacSize);
 
+// Also see eicOpsLookupActiveSessionFromId() defined in EicSession.h
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/identity/aidl/default/libeic/EicPresentation.c b/identity/aidl/default/libeic/EicPresentation.c
index 0d03ae9..104a559 100644
--- a/identity/aidl/default/libeic/EicPresentation.c
+++ b/identity/aidl/default/libeic/EicPresentation.c
@@ -16,11 +16,17 @@
 
 #include "EicPresentation.h"
 #include "EicCommon.h"
+#include "EicSession.h"
 
 #include <inttypes.h>
 
-bool eicPresentationInit(EicPresentation* ctx, bool testCredential, const char* docType,
-                         size_t docTypeLength, const uint8_t* encryptedCredentialKeys,
+// Global used for assigning ids for presentation objects.
+//
+static uint32_t gPresentationLastIdAssigned = 0;
+
+bool eicPresentationInit(EicPresentation* ctx, uint32_t sessionId, bool testCredential,
+                         const char* docType, size_t docTypeLength,
+                         const uint8_t* encryptedCredentialKeys,
                          size_t encryptedCredentialKeysSize) {
     uint8_t credentialKeys[EIC_CREDENTIAL_KEYS_CBOR_SIZE_FEATURE_VERSION_202101];
     bool expectPopSha256 = false;
@@ -39,6 +45,13 @@
     }
 
     eicMemSet(ctx, '\0', sizeof(EicPresentation));
+    ctx->sessionId = sessionId;
+
+    if (!eicNextId(&gPresentationLastIdAssigned)) {
+        eicDebug("Error getting id for object");
+        return false;
+    }
+    ctx->id = gPresentationLastIdAssigned;
 
     if (!eicOpsDecryptAes128Gcm(eicOpsGetHardwareBoundKey(testCredential), encryptedCredentialKeys,
                                 encryptedCredentialKeysSize,
@@ -86,6 +99,23 @@
     if (expectPopSha256) {
         eicMemCpy(ctx->proofOfProvisioningSha256, credentialKeys + 54, EIC_SHA256_DIGEST_SIZE);
     }
+
+    eicDebug("Initialized presentation with id %" PRIu32, ctx->id);
+    return true;
+}
+
+bool eicPresentationShutdown(EicPresentation* ctx) {
+    if (ctx->id == 0) {
+        eicDebug("Trying to shut down presentation with id 0");
+        return false;
+    }
+    eicDebug("Shut down presentation with id %" PRIu32, ctx->id);
+    eicMemSet(ctx, '\0', sizeof(EicPresentation));
+    return true;
+}
+
+bool eicPresentationGetId(EicPresentation* ctx, uint32_t* outId) {
+    *outId = ctx->id;
     return true;
 }
 
@@ -174,7 +204,7 @@
             eicDebug("Failed generating random challenge");
             return false;
         }
-    } while (ctx->authChallenge == 0);
+    } while (ctx->authChallenge == EIC_KM_AUTH_CHALLENGE_UNSET);
     eicDebug("Created auth challenge %" PRIu64, ctx->authChallenge);
     *authChallenge = ctx->authChallenge;
     return true;
@@ -190,6 +220,24 @@
                                            int coseSignAlg,
                                            const uint8_t* readerSignatureOfToBeSigned,
                                            size_t readerSignatureOfToBeSignedSize) {
+    if (ctx->sessionId != 0) {
+        EicSession* session = eicSessionGetForId(ctx->sessionId);
+        if (session == NULL) {
+            eicDebug("Error looking up session for sessionId %" PRIu32, ctx->sessionId);
+            return false;
+        }
+        EicSha256Ctx sha256;
+        uint8_t sessionTranscriptSha256[EIC_SHA256_DIGEST_SIZE];
+        eicOpsSha256Init(&sha256);
+        eicOpsSha256Update(&sha256, sessionTranscript, sessionTranscriptSize);
+        eicOpsSha256Final(&sha256, sessionTranscriptSha256);
+        if (eicCryptoMemCmp(sessionTranscriptSha256, session->sessionTranscriptSha256,
+                            EIC_SHA256_DIGEST_SIZE) != 0) {
+            eicDebug("SessionTranscript mismatch");
+            return false;
+        }
+    }
+
     if (ctx->readerPublicKeySize == 0) {
         eicDebug("No public key for reader");
         return false;
@@ -330,6 +378,20 @@
     return true;
 }
 
+static bool getChallenge(EicPresentation* ctx, uint64_t* outAuthChallenge) {
+    // Use authChallenge from session if applicable.
+    *outAuthChallenge = ctx->authChallenge;
+    if (ctx->sessionId != 0) {
+        EicSession* session = eicSessionGetForId(ctx->sessionId);
+        if (session == NULL) {
+            eicDebug("Error looking up session for sessionId %" PRIu32, ctx->sessionId);
+            return false;
+        }
+        *outAuthChallenge = session->authChallenge;
+    }
+    return true;
+}
+
 bool eicPresentationSetAuthToken(EicPresentation* ctx, uint64_t challenge, uint64_t secureUserId,
                                  uint64_t authenticatorId, int hardwareAuthenticatorType,
                                  uint64_t timeStamp, const uint8_t* mac, size_t macSize,
@@ -338,14 +400,19 @@
                                  int verificationTokenSecurityLevel,
                                  const uint8_t* verificationTokenMac,
                                  size_t verificationTokenMacSize) {
+    uint64_t authChallenge;
+    if (!getChallenge(ctx, &authChallenge)) {
+        return false;
+    }
+
     // It doesn't make sense to accept any tokens if eicPresentationCreateAuthChallenge()
     // was never called.
-    if (ctx->authChallenge == 0) {
-        eicDebug("Trying validate tokens when no auth-challenge was previously generated");
+    if (authChallenge == EIC_KM_AUTH_CHALLENGE_UNSET) {
+        eicDebug("Trying to validate tokens when no auth-challenge was previously generated");
         return false;
     }
     // At least the verification-token must have the same challenge as what was generated.
-    if (verificationTokenChallenge != ctx->authChallenge) {
+    if (verificationTokenChallenge != authChallenge) {
         eicDebug("Challenge in verification token does not match the challenge "
                  "previously generated");
         return false;
@@ -354,6 +421,7 @@
                 challenge, secureUserId, authenticatorId, hardwareAuthenticatorType, timeStamp, mac,
                 macSize, verificationTokenChallenge, verificationTokenTimestamp,
                 verificationTokenSecurityLevel, verificationTokenMac, verificationTokenMacSize)) {
+        eicDebug("Error validating authToken");
         return false;
     }
     ctx->authTokenChallenge = challenge;
@@ -377,11 +445,16 @@
     // Only ACP with auth-on-every-presentation - those with timeout == 0 - need the
     // challenge to match...
     if (timeoutMillis == 0) {
-        if (ctx->authTokenChallenge != ctx->authChallenge) {
+        uint64_t authChallenge;
+        if (!getChallenge(ctx, &authChallenge)) {
+            return false;
+        }
+
+        if (ctx->authTokenChallenge != authChallenge) {
             eicDebug("Challenge in authToken (%" PRIu64
                      ") doesn't match the challenge "
                      "that was created (%" PRIu64 ") for this session",
-                     ctx->authTokenChallenge, ctx->authChallenge);
+                     ctx->authTokenChallenge, authChallenge);
             return false;
         }
     }
@@ -490,6 +563,25 @@
                                const uint8_t signingKeyBlob[60], const char* docType,
                                size_t docTypeLength, unsigned int numNamespacesWithValues,
                                size_t expectedDeviceNamespacesSize) {
+    if (ctx->sessionId != 0) {
+        EicSession* session = eicSessionGetForId(ctx->sessionId);
+        if (session == NULL) {
+            eicDebug("Error looking up session for sessionId %" PRIu32, ctx->sessionId);
+            return false;
+        }
+        EicSha256Ctx sha256;
+        uint8_t sessionTranscriptSha256[EIC_SHA256_DIGEST_SIZE];
+        eicOpsSha256Init(&sha256);
+        eicOpsSha256Update(&sha256, sessionTranscript, sessionTranscriptSize);
+        eicOpsSha256Final(&sha256, sessionTranscriptSha256);
+        if (eicCryptoMemCmp(sessionTranscriptSha256, session->sessionTranscriptSha256,
+                            EIC_SHA256_DIGEST_SIZE) != 0) {
+            eicDebug("SessionTranscript mismatch");
+            return false;
+        }
+        readerEphemeralPublicKey = session->readerEphemeralPublicKey;
+    }
+
     uint8_t signingKeyPriv[EIC_P256_PRIV_KEY_SIZE];
     if (!eicOpsDecryptAes128Gcm(ctx->storageKey, signingKeyBlob, 60, (const uint8_t*)docType,
                                 docTypeLength, signingKeyPriv)) {
diff --git a/identity/aidl/default/libeic/EicPresentation.h b/identity/aidl/default/libeic/EicPresentation.h
index 6f7f432..a031890 100644
--- a/identity/aidl/default/libeic/EicPresentation.h
+++ b/identity/aidl/default/libeic/EicPresentation.h
@@ -30,7 +30,13 @@
 // The maximum size we support for public keys in reader certificates.
 #define EIC_PRESENTATION_MAX_READER_PUBLIC_KEY_SIZE 65
 
+// Constant used to convey that no session is associated with a presentation.
+#define EIC_PRESENTATION_ID_UNSET 0
+
 typedef struct {
+    // A non-zero number unique for this EicPresentation instance
+    uint32_t id;
+
     int featureLevel;
 
     uint8_t storageKey[EIC_AES_128_KEY_SIZE];
@@ -38,6 +44,10 @@
 
     uint8_t ephemeralPrivateKey[EIC_P256_PRIV_KEY_SIZE];
 
+    // If non-zero (not EIC_PRESENTATION_ID_UNSET), the id of the EicSession object this
+    // presentation object is associated with.
+    uint32_t sessionId;
+
     // The challenge generated with eicPresentationCreateAuthChallenge()
     uint64_t authChallenge;
 
@@ -93,10 +103,18 @@
     EicCbor cbor;
 } EicPresentation;
 
-bool eicPresentationInit(EicPresentation* ctx, bool testCredential, const char* docType,
-                         size_t docTypeLength, const uint8_t* encryptedCredentialKeys,
+// If sessionId is zero (EIC_PRESENTATION_ID_UNSET), the presentation object is not associated
+// with a session object. Otherwise it's the id of the session object.
+//
+bool eicPresentationInit(EicPresentation* ctx, uint32_t sessionId, bool testCredential,
+                         const char* docType, size_t docTypeLength,
+                         const uint8_t* encryptedCredentialKeys,
                          size_t encryptedCredentialKeysSize);
 
+bool eicPresentationShutdown(EicPresentation* ctx);
+
+bool eicPresentationGetId(EicPresentation* ctx, uint32_t* outId);
+
 bool eicPresentationGenerateSigningKeyPair(EicPresentation* ctx, const char* docType,
                                            size_t docTypeLength, time_t now,
                                            uint8_t* publicKeyCert, size_t* publicKeyCertSize,
diff --git a/identity/aidl/default/libeic/EicProvisioning.c b/identity/aidl/default/libeic/EicProvisioning.c
index c9df4fd..a241b71 100644
--- a/identity/aidl/default/libeic/EicProvisioning.c
+++ b/identity/aidl/default/libeic/EicProvisioning.c
@@ -17,8 +17,21 @@
 #include "EicProvisioning.h"
 #include "EicCommon.h"
 
+#include <inttypes.h>
+
+// Global used for assigning ids for provisioning objects.
+//
+static uint32_t gProvisioningLastIdAssigned = 0;
+
 bool eicProvisioningInit(EicProvisioning* ctx, bool testCredential) {
     eicMemSet(ctx, '\0', sizeof(EicProvisioning));
+
+    if (!eicNextId(&gProvisioningLastIdAssigned)) {
+        eicDebug("Error getting id for object");
+        return false;
+    }
+    ctx->id = gProvisioningLastIdAssigned;
+
     ctx->testCredential = testCredential;
     if (!eicOpsRandom(ctx->storageKey, EIC_AES_128_KEY_SIZE)) {
         return false;
@@ -47,6 +60,13 @@
     }
 
     eicMemSet(ctx, '\0', sizeof(EicProvisioning));
+
+    if (!eicNextId(&gProvisioningLastIdAssigned)) {
+        eicDebug("Error getting id for object");
+        return false;
+    }
+    ctx->id = gProvisioningLastIdAssigned;
+
     ctx->testCredential = testCredential;
 
     if (!eicOpsDecryptAes128Gcm(eicOpsGetHardwareBoundKey(testCredential), encryptedCredentialKeys,
@@ -96,6 +116,21 @@
     return true;
 }
 
+bool eicProvisioningShutdown(EicProvisioning* ctx) {
+    if (ctx->id == 0) {
+        eicDebug("Trying to shut down provsioning with id 0");
+        return false;
+    }
+    eicDebug("Shut down provsioning with id %" PRIu32, ctx->id);
+    eicMemSet(ctx, '\0', sizeof(EicProvisioning));
+    return true;
+}
+
+bool eicProvisioningGetId(EicProvisioning* ctx, uint32_t* outId) {
+    *outId = ctx->id;
+    return true;
+}
+
 bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* challenge,
                                         size_t challengeSize, const uint8_t* applicationId,
                                         size_t applicationIdSize, uint8_t* publicKeyCert,
diff --git a/identity/aidl/default/libeic/EicProvisioning.h b/identity/aidl/default/libeic/EicProvisioning.h
index 92f1e4a..d94f8f1 100644
--- a/identity/aidl/default/libeic/EicProvisioning.h
+++ b/identity/aidl/default/libeic/EicProvisioning.h
@@ -31,6 +31,9 @@
 #define EIC_MAX_NUM_ACCESS_CONTROL_PROFILE_IDS 32
 
 typedef struct {
+    // A non-zero number unique for this EicProvisioning instance
+    uint32_t id;
+
     // Set by eicCreateCredentialKey() OR eicProvisioningInitForUpdate()
     uint8_t credentialPrivateKey[EIC_P256_PRIV_KEY_SIZE];
 
@@ -68,6 +71,10 @@
                                   size_t docTypeLength, const uint8_t* encryptedCredentialKeys,
                                   size_t encryptedCredentialKeysSize);
 
+bool eicProvisioningShutdown(EicProvisioning* ctx);
+
+bool eicProvisioningGetId(EicProvisioning* ctx, uint32_t* outId);
+
 bool eicProvisioningCreateCredentialKey(EicProvisioning* ctx, const uint8_t* challenge,
                                         size_t challengeSize, const uint8_t* applicationId,
                                         size_t applicationIdSize, uint8_t* publicKeyCert,
diff --git a/identity/aidl/default/libeic/EicSession.c b/identity/aidl/default/libeic/EicSession.c
new file mode 100644
index 0000000..d0c7a0d
--- /dev/null
+++ b/identity/aidl/default/libeic/EicSession.c
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ */
+
+#include <inttypes.h>
+
+#include "EicCommon.h"
+#include "EicSession.h"
+
+// Global used for assigning ids for session objects.
+//
+static uint32_t gSessionLastIdAssigned = 0;
+
+// The current session object or NULL if never initialized or if it has been shut down.
+//
+static EicSession* gSessionCurrent = NULL;
+
+EicSession* eicSessionGetForId(uint32_t sessionId) {
+    if (gSessionCurrent != NULL && gSessionCurrent->id == sessionId) {
+        return gSessionCurrent;
+    }
+    return NULL;
+}
+
+bool eicSessionInit(EicSession* ctx) {
+    eicMemSet(ctx, '\0', sizeof(EicSession));
+
+    if (!eicNextId(&gSessionLastIdAssigned)) {
+        eicDebug("Error getting id for object");
+        return false;
+    }
+    ctx->id = gSessionLastIdAssigned;
+
+    do {
+        if (!eicOpsRandom((uint8_t*)&(ctx->authChallenge), sizeof(ctx->authChallenge))) {
+            eicDebug("Failed generating random challenge");
+            return false;
+        }
+    } while (ctx->authChallenge == EIC_KM_AUTH_CHALLENGE_UNSET);
+
+    if (!eicOpsCreateEcKey(ctx->ephemeralPrivateKey, ctx->ephemeralPublicKey)) {
+        eicDebug("Error creating ephemeral key-pair");
+        return false;
+    }
+
+    gSessionCurrent = ctx;
+    eicDebug("Initialized session with id %" PRIu32, ctx->id);
+    return true;
+}
+
+bool eicSessionShutdown(EicSession* ctx) {
+    if (ctx->id == 0) {
+        eicDebug("Trying to shut down session with id 0");
+        return false;
+    }
+    eicDebug("Shut down session with id %" PRIu32, ctx->id);
+    eicMemSet(ctx, '\0', sizeof(EicSession));
+    gSessionCurrent = NULL;
+    return true;
+}
+
+bool eicSessionGetId(EicSession* ctx, uint32_t* outId) {
+    *outId = ctx->id;
+    return true;
+}
+
+bool eicSessionGetAuthChallenge(EicSession* ctx, uint64_t* outAuthChallenge) {
+    *outAuthChallenge = ctx->authChallenge;
+    return true;
+}
+
+bool eicSessionGetEphemeralKeyPair(EicSession* ctx,
+                                   uint8_t ephemeralPrivateKey[EIC_P256_PRIV_KEY_SIZE]) {
+    eicMemCpy(ephemeralPrivateKey, ctx->ephemeralPrivateKey, EIC_P256_PRIV_KEY_SIZE);
+    return true;
+}
+
+bool eicSessionSetReaderEphemeralPublicKey(
+        EicSession* ctx, const uint8_t readerEphemeralPublicKey[EIC_P256_PUB_KEY_SIZE]) {
+    eicMemCpy(ctx->readerEphemeralPublicKey, readerEphemeralPublicKey, EIC_P256_PUB_KEY_SIZE);
+    return true;
+}
+
+bool eicSessionSetSessionTranscript(EicSession* ctx, const uint8_t* sessionTranscript,
+                                    size_t sessionTranscriptSize) {
+    // Only accept the SessionTranscript if X and Y from the ephemeral key
+    // we created is somewhere in SessionTranscript...
+    //
+    if (eicMemMem(sessionTranscript, sessionTranscriptSize, ctx->ephemeralPublicKey,
+                  EIC_P256_PUB_KEY_SIZE / 2) == NULL) {
+        eicDebug("Error finding X from ephemeralPublicKey in sessionTranscript");
+        return false;
+    }
+    if (eicMemMem(sessionTranscript, sessionTranscriptSize,
+                  ctx->ephemeralPublicKey + EIC_P256_PUB_KEY_SIZE / 2,
+                  EIC_P256_PUB_KEY_SIZE / 2) == NULL) {
+        eicDebug("Error finding Y from ephemeralPublicKey in sessionTranscript");
+        return false;
+    }
+
+    // To save space we only store the SHA-256 of SessionTranscript
+    //
+    EicSha256Ctx shaCtx;
+    eicOpsSha256Init(&shaCtx);
+    eicOpsSha256Update(&shaCtx, sessionTranscript, sessionTranscriptSize);
+    eicOpsSha256Final(&shaCtx, ctx->sessionTranscriptSha256);
+    return true;
+}
diff --git a/identity/aidl/default/libeic/EicSession.h b/identity/aidl/default/libeic/EicSession.h
new file mode 100644
index 0000000..0303dae
--- /dev/null
+++ b/identity/aidl/default/libeic/EicSession.h
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+#if !defined(EIC_INSIDE_LIBEIC_H) && !defined(EIC_COMPILATION)
+#error "Never include this file directly, include libeic.h instead."
+#endif
+
+#ifndef ANDROID_HARDWARE_IDENTITY_EIC_SESSION_H
+#define ANDROID_HARDWARE_IDENTITY_EIC_SESSION_H
+
+#include "EicOps.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+    // A non-zero number unique for this EicSession instance
+    uint32_t id;
+
+    // The challenge generated at construction time by eicSessionInit().
+    uint64_t authChallenge;
+
+    uint8_t ephemeralPrivateKey[EIC_P256_PRIV_KEY_SIZE];
+    uint8_t ephemeralPublicKey[EIC_P256_PUB_KEY_SIZE];
+
+    uint8_t readerEphemeralPublicKey[EIC_P256_PUB_KEY_SIZE];
+
+    uint8_t sessionTranscriptSha256[EIC_SHA256_DIGEST_SIZE];
+
+} EicSession;
+
+bool eicSessionInit(EicSession* ctx);
+
+bool eicSessionShutdown(EicSession* ctx);
+
+bool eicSessionGetId(EicSession* ctx, uint32_t* outId);
+
+bool eicSessionGetAuthChallenge(EicSession* ctx, uint64_t* outAuthChallenge);
+
+bool eicSessionGetEphemeralKeyPair(EicSession* ctx,
+                                   uint8_t ephemeralPrivateKey[EIC_P256_PRIV_KEY_SIZE]);
+
+bool eicSessionSetReaderEphemeralPublicKey(
+        EicSession* ctx, const uint8_t readerEphemeralPublicKey[EIC_P256_PUB_KEY_SIZE]);
+
+bool eicSessionSetSessionTranscript(EicSession* ctx, const uint8_t* sessionTranscript,
+                                    size_t sessionTranscriptSize);
+
+// Looks up an active session with the given id.
+//
+// Returns NULL if no active session with the given id is found.
+//
+EicSession* eicSessionGetForId(uint32_t sessionId);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // ANDROID_HARDWARE_IDENTITY_EIC_PRESENTATION_H
diff --git a/identity/aidl/default/libeic/libeic.h b/identity/aidl/default/libeic/libeic.h
index 20c8896..d89fc9a 100644
--- a/identity/aidl/default/libeic/libeic.h
+++ b/identity/aidl/default/libeic/libeic.h
@@ -27,10 +27,11 @@
  */
 #define EIC_INSIDE_LIBEIC_H
 #include "EicCbor.h"
+#include "EicCommon.h"
 #include "EicOps.h"
 #include "EicPresentation.h"
 #include "EicProvisioning.h"
-#include "EicCommon.h"
+#include "EicSession.h"
 #undef EIC_INSIDE_LIBEIC_H
 
 #ifdef __cplusplus
diff --git a/identity/aidl/vts/Android.bp b/identity/aidl/vts/Android.bp
index e5de91e..7b6f2c8 100644
--- a/identity/aidl/vts/Android.bp
+++ b/identity/aidl/vts/Android.bp
@@ -28,6 +28,7 @@
         "EndToEndTests.cpp",
         "TestCredentialTests.cpp",
         "AuthenticationKeyTests.cpp",
+        "PresentationSessionTests.cpp",
     ],
     shared_libs: [
         "libbinder",
@@ -40,9 +41,9 @@
         "libpuresoftkeymasterdevice",
         "android.hardware.keymaster@4.0",
         "android.hardware.identity-support-lib",
-        "android.hardware.identity-V3-cpp",
-        "android.hardware.keymaster-V3-cpp",
-        "android.hardware.keymaster-V3-ndk",
+        "android.hardware.identity-V4-cpp",
+        "android.hardware.keymaster-V4-cpp",
+        "android.hardware.keymaster-V4-ndk",
         "libkeymaster4support",
         "libkeymaster4_1support",
     ],
diff --git a/identity/aidl/vts/PresentationSessionTests.cpp b/identity/aidl/vts/PresentationSessionTests.cpp
new file mode 100644
index 0000000..88acb26
--- /dev/null
+++ b/identity/aidl/vts/PresentationSessionTests.cpp
@@ -0,0 +1,197 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "PresentationSessionTests"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/keymaster/HardwareAuthToken.h>
+#include <aidl/android/hardware/keymaster/VerificationToken.h>
+#include <android-base/logging.h>
+#include <android/hardware/identity/IIdentityCredentialStore.h>
+#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <cppbor.h>
+#include <cppbor_parse.h>
+#include <gtest/gtest.h>
+#include <future>
+#include <map>
+#include <utility>
+
+#include "Util.h"
+
+namespace android::hardware::identity {
+
+using std::endl;
+using std::make_pair;
+using std::map;
+using std::optional;
+using std::pair;
+using std::string;
+using std::tie;
+using std::vector;
+
+using ::android::sp;
+using ::android::String16;
+using ::android::binder::Status;
+
+using ::android::hardware::keymaster::HardwareAuthToken;
+using ::android::hardware::keymaster::VerificationToken;
+
+class PresentationSessionTests : public testing::TestWithParam<string> {
+  public:
+    virtual void SetUp() override {
+        credentialStore_ = android::waitForDeclaredService<IIdentityCredentialStore>(
+                String16(GetParam().c_str()));
+        ASSERT_NE(credentialStore_, nullptr);
+        halApiVersion_ = credentialStore_->getInterfaceVersion();
+    }
+
+    void provisionData();
+
+    void provisionSingleDocument(const string& docType, vector<uint8_t>* outCredentialData,
+                                 vector<uint8_t>* outCredentialPubKey);
+
+    // Set by provisionData
+    vector<uint8_t> credential1Data_;
+    vector<uint8_t> credential1PubKey_;
+    vector<uint8_t> credential2Data_;
+    vector<uint8_t> credential2PubKey_;
+
+    sp<IIdentityCredentialStore> credentialStore_;
+    int halApiVersion_;
+};
+
+void PresentationSessionTests::provisionData() {
+    provisionSingleDocument("org.iso.18013-5.2019.mdl", &credential1Data_, &credential1PubKey_);
+    provisionSingleDocument("org.blah.OtherhDocTypeXX", &credential2Data_, &credential2PubKey_);
+}
+
+void PresentationSessionTests::provisionSingleDocument(const string& docType,
+                                                       vector<uint8_t>* outCredentialData,
+                                                       vector<uint8_t>* outCredentialPubKey) {
+    bool testCredential = true;
+    sp<IWritableIdentityCredential> wc;
+    ASSERT_TRUE(credentialStore_->createCredential(docType, testCredential, &wc).isOk());
+
+    vector<uint8_t> attestationApplicationId;
+    vector<uint8_t> attestationChallenge = {1};
+    vector<Certificate> certChain;
+    ASSERT_TRUE(wc->getAttestationCertificate(attestationApplicationId, attestationChallenge,
+                                              &certChain)
+                        .isOk());
+
+    optional<vector<uint8_t>> optCredentialPubKey =
+            support::certificateChainGetTopMostKey(certChain[0].encodedCertificate);
+    ASSERT_TRUE(optCredentialPubKey);
+    *outCredentialPubKey = optCredentialPubKey.value();
+
+    size_t proofOfProvisioningSize = 106;
+    // Not in v1 HAL, may fail
+    wc->setExpectedProofOfProvisioningSize(proofOfProvisioningSize);
+
+    ASSERT_TRUE(wc->startPersonalization(1 /* numAccessControlProfiles */,
+                                         {1} /* numDataElementsPerNamespace */)
+                        .isOk());
+
+    // Access control profile 0: open access - don't care about the returned SACP
+    SecureAccessControlProfile sacp;
+    ASSERT_TRUE(wc->addAccessControlProfile(1, {}, false, 0, 0, &sacp).isOk());
+
+    // Single entry - don't care about the returned encrypted data
+    ASSERT_TRUE(wc->beginAddEntry({1}, "ns", "Some Data", 1).isOk());
+    vector<uint8_t> encryptedData;
+    ASSERT_TRUE(wc->addEntryValue({9}, &encryptedData).isOk());
+
+    vector<uint8_t> proofOfProvisioningSignature;
+    Status status = wc->finishAddingEntries(outCredentialData, &proofOfProvisioningSignature);
+    EXPECT_TRUE(status.isOk()) << status.exceptionCode() << ": " << status.exceptionMessage();
+}
+
+// This checks that any methods called on an IIdentityCredential obtained via a session
+// returns STATUS_FAILED except for startRetrieval(), startRetrieveEntryValue(),
+// retrieveEntryValue(), finishRetrieval(), setRequestedNamespaces(), setVerificationToken()
+//
+TEST_P(PresentationSessionTests, returnsFailureOnUnsupportedMethods) {
+    if (halApiVersion_ < 4) {
+        GTEST_SKIP() << "Need HAL API version 4, have " << halApiVersion_;
+    }
+
+    provisionData();
+
+    sp<IPresentationSession> session;
+    ASSERT_TRUE(credentialStore_
+                        ->createPresentationSession(
+                                CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256,
+                                &session)
+                        .isOk());
+
+    sp<IIdentityCredential> credential;
+    ASSERT_TRUE(session->getCredential(credential1Data_, &credential).isOk());
+
+    Status result;
+
+    vector<uint8_t> signatureProofOfDeletion;
+    result = credential->deleteCredential(&signatureProofOfDeletion);
+    EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
+    EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode());
+
+    vector<uint8_t> ephemeralKeyPair;
+    result = credential->createEphemeralKeyPair(&ephemeralKeyPair);
+    EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
+    EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode());
+
+    result = credential->setReaderEphemeralPublicKey({});
+    EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
+    EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode());
+
+    int64_t authChallenge;
+    result = credential->createAuthChallenge(&authChallenge);
+    EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
+    EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode());
+
+    Certificate certificate;
+    vector<uint8_t> signingKeyBlob;
+    result = credential->generateSigningKeyPair(&signingKeyBlob, &certificate);
+    EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
+    EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode());
+
+    result = credential->deleteCredentialWithChallenge({}, &signatureProofOfDeletion);
+    EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
+    EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode());
+
+    vector<uint8_t> signatureProofOfOwnership;
+    result = credential->proveOwnership({}, &signatureProofOfOwnership);
+    EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
+    EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode());
+
+    sp<IWritableIdentityCredential> writableCredential;
+    result = credential->updateCredential(&writableCredential);
+    EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
+    EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode());
+}
+
+// TODO: need to add tests to check that the returned IIdentityCredential works
+//       as intended.
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PresentationSessionTests);
+INSTANTIATE_TEST_SUITE_P(
+        Identity, PresentationSessionTests,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IIdentityCredentialStore::descriptor)),
+        android::PrintInstanceNameToString);
+
+}  // namespace android::hardware::identity
diff --git a/input/common/aidl/Android.bp b/input/common/aidl/Android.bp
new file mode 100644
index 0000000..6cf64a6
--- /dev/null
+++ b/input/common/aidl/Android.bp
@@ -0,0 +1,22 @@
+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.input.common",
+    srcs: ["android/hardware/input/common/*.aidl"],
+    stability: "vintf",
+    backend: {
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            enabled: false,
+        },
+    },
+}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/Error.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Action.aidl
similarity index 81%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/Error.aidl
copy to input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Action.aidl
index af7bc3c..a2e0381 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/Error.aidl
+++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Action.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 The Android Open Source Project
+ * 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.
@@ -31,16 +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.biometrics.fingerprint;
-@Backing(type="byte") @VintfStability
-enum Error {
-  UNKNOWN = 0,
-  HW_UNAVAILABLE = 1,
-  UNABLE_TO_PROCESS = 2,
-  TIMEOUT = 3,
-  NO_SPACE = 4,
-  CANCELED = 5,
-  UNABLE_TO_REMOVE = 6,
-  VENDOR = 7,
-  BAD_CALIBRATION = 8,
+package android.hardware.input.common;
+@Backing(type="int") @VintfStability
+enum Action {
+  DOWN = 0,
+  UP = 1,
+  MOVE = 2,
+  CANCEL = 3,
+  OUTSIDE = 4,
+  POINTER_DOWN = 5,
+  POINTER_UP = 6,
+  HOVER_MOVE = 7,
+  SCROLL = 8,
+  HOVER_ENTER = 9,
+  HOVER_EXIT = 10,
+  BUTTON_PRESS = 11,
+  BUTTON_RELEASE = 12,
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Axis.aidl
similarity index 65%
copy from bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
copy to input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Axis.aidl
index a7224ca..2114c7d 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
+++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Axis.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2021 The Android Open Source Project
+ * 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.
@@ -31,21 +31,52 @@
 // with such a backward incompatible 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.input.common;
+@Backing(type="int") @VintfStability
+enum Axis {
+  X = 0,
+  Y = 1,
+  PRESSURE = 2,
+  SIZE = 3,
+  TOUCH_MAJOR = 4,
+  TOUCH_MINOR = 5,
+  TOOL_MAJOR = 6,
+  TOOL_MINOR = 7,
+  ORIENTATION = 8,
+  VSCROLL = 9,
+  HSCROLL = 10,
+  Z = 11,
+  RX = 12,
+  RY = 13,
+  RZ = 14,
+  HAT_X = 15,
+  HAT_Y = 16,
+  LTRIGGER = 17,
+  RTRIGGER = 18,
+  THROTTLE = 19,
+  RUDDER = 20,
+  WHEEL = 21,
+  GAS = 22,
+  BRAKE = 23,
+  DISTANCE = 24,
+  TILT = 25,
+  SCROLL = 26,
+  RELATIVE_X = 27,
+  RELATIVE_Y = 28,
+  GENERIC_1 = 32,
+  GENERIC_2 = 33,
+  GENERIC_3 = 34,
+  GENERIC_4 = 35,
+  GENERIC_5 = 36,
+  GENERIC_6 = 37,
+  GENERIC_7 = 38,
+  GENERIC_8 = 39,
+  GENERIC_9 = 40,
+  GENERIC_10 = 41,
+  GENERIC_11 = 42,
+  GENERIC_12 = 43,
+  GENERIC_13 = 44,
+  GENERIC_14 = 45,
+  GENERIC_15 = 46,
+  GENERIC_16 = 47,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Button.aidl
similarity index 84%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Button.aidl
index 295fde9..10ad65a 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Button.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +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.biometrics.fingerprint;
-@VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+package android.hardware.input.common;
+@Backing(type="int") @VintfStability
+enum Button {
+  NONE = 0,
+  PRIMARY = 1,
+  SECONDARY = 2,
+  TERTIARY = 4,
+  BACK = 8,
+  FORWARD = 16,
+  STYLUS_PRIMARY = 32,
+  STYLUS_SECONDARY = 64,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Classification.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Classification.aidl
index 295fde9..ddd5246 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Classification.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +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.biometrics.fingerprint;
-@VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+package android.hardware.input.common;
+@Backing(type="byte") @VintfStability
+enum Classification {
+  NONE = 0,
+  AMBIGUOUS_GESTURE = 1,
+  DEEP_PRESS = 2,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/EdgeFlag.aidl
similarity index 85%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/EdgeFlag.aidl
index 295fde9..1040049 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/EdgeFlag.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +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.biometrics.fingerprint;
-@VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+package android.hardware.input.common;
+@Backing(type="int") @VintfStability
+enum EdgeFlag {
+  NONE = 0,
+  TOP = 1,
+  BOTTOM = 2,
+  LEFT = 4,
+  RIGHT = 8,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Flag.aidl
similarity index 85%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Flag.aidl
index 295fde9..d3fcd9f 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Flag.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +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.biometrics.fingerprint;
-@VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+package android.hardware.input.common;
+@Backing(type="int") @VintfStability
+enum Flag {
+  WINDOW_IS_OBSCURED = 1,
+  IS_GENERATED_GESTURE = 8,
+  TAINTED = -2147483648,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Meta.aidl
similarity index 75%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
copy to input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Meta.aidl
index c51aa03..2c229f9 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
+++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Meta.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 The Android Open Source Project
+ * 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.
@@ -31,20 +31,25 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.biometrics.fingerprint;
-@Backing(type="byte") @VintfStability
-enum AcquiredInfo {
-  UNKNOWN = 0,
-  GOOD = 1,
-  PARTIAL = 2,
-  INSUFFICIENT = 3,
-  SENSOR_DIRTY = 4,
-  TOO_SLOW = 5,
-  TOO_FAST = 6,
-  VENDOR = 7,
-  START = 8,
-  TOO_DARK = 9,
-  TOO_BRIGHT = 10,
-  IMMOBILE = 11,
-  RETRYING_CAPTURE = 12,
+package android.hardware.input.common;
+@Backing(type="int") @VintfStability
+enum Meta {
+  NONE = 0,
+  ALT_ON = 2,
+  ALT_LEFT_ON = 16,
+  ALT_RIGHT_ON = 32,
+  SHIFT_ON = 1,
+  SHIFT_LEFT_ON = 64,
+  SHIFT_RIGHT_ON = 128,
+  SYM_ON = 4,
+  FUNCTION_ON = 8,
+  CTRL_ON = 4096,
+  CTRL_LEFT_ON = 8192,
+  CTRL_RIGHT_ON = 16384,
+  META_ON = 65536,
+  META_LEFT_ON = 131072,
+  META_RIGHT_ON = 262144,
+  CAPS_LOCK_ON = 1048576,
+  NUM_LOCK_ON = 2097152,
+  SCROLL_LOCK_ON = 4194304,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/MotionEvent.aidl
similarity index 66%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/MotionEvent.aidl
index 295fde9..84af4bf 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/MotionEvent.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +31,26 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.biometrics.fingerprint;
+package android.hardware.input.common;
 @VintfStability
-parcelable SensorLocation {
+parcelable MotionEvent {
+  int deviceId;
+  android.hardware.input.common.Source source;
   int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+  long downTime;
+  long eventTime;
+  android.hardware.input.common.Action action;
+  byte actionIndex;
+  android.hardware.input.common.Button actionButton;
+  android.hardware.input.common.Flag flags;
+  android.hardware.input.common.PolicyFlag policyFlags;
+  android.hardware.input.common.EdgeFlag edgeFlags;
+  android.hardware.input.common.Meta metaState;
+  android.hardware.input.common.Button buttonState;
+  float xPrecision;
+  float yPrecision;
+  android.hardware.input.common.PointerProperties[] pointerProperties;
+  android.hardware.input.common.PointerCoords[] pointerCoords;
+  int deviceTimestamp;
+  android.hardware.input.common.VideoFrame[] frames;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PointerCoords.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PointerCoords.aidl
index 295fde9..353a106 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PointerCoords.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.input.common;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+parcelable PointerCoords {
+  long bits;
+  float[] values;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PointerProperties.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PointerProperties.aidl
index 295fde9..a49581b 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PointerProperties.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.input.common;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+parcelable PointerProperties {
+  int id;
+  android.hardware.input.common.ToolType toolType;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/Error.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PolicyFlag.aidl
similarity index 81%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/Error.aidl
copy to input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PolicyFlag.aidl
index af7bc3c..247e868 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/Error.aidl
+++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/PolicyFlag.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 The Android Open Source Project
+ * 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.
@@ -31,16 +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.biometrics.fingerprint;
-@Backing(type="byte") @VintfStability
-enum Error {
-  UNKNOWN = 0,
-  HW_UNAVAILABLE = 1,
-  UNABLE_TO_PROCESS = 2,
-  TIMEOUT = 3,
-  NO_SPACE = 4,
-  CANCELED = 5,
-  UNABLE_TO_REMOVE = 6,
-  VENDOR = 7,
-  BAD_CALIBRATION = 8,
+package android.hardware.input.common;
+@Backing(type="int") @VintfStability
+enum PolicyFlag {
+  WAKE = 1,
+  VIRTUAL = 2,
+  FUNCTION = 4,
+  GESTURE = 8,
+  INJECTED = 16777216,
+  TRUSTED = 33554432,
+  FILTERED = 67108864,
+  DISABLE_KEY_REPEAT = 134217728,
+  INTERACTIVE = 536870912,
+  PASS_TO_USER = 1073741824,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Source.aidl
similarity index 77%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
copy to input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Source.aidl
index c51aa03..24d02cd 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
+++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/Source.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 The Android Open Source Project
+ * 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.
@@ -31,20 +31,23 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.biometrics.fingerprint;
-@Backing(type="byte") @VintfStability
-enum AcquiredInfo {
+package android.hardware.input.common;
+@Backing(type="int") @VintfStability
+enum Source {
   UNKNOWN = 0,
-  GOOD = 1,
-  PARTIAL = 2,
-  INSUFFICIENT = 3,
-  SENSOR_DIRTY = 4,
-  TOO_SLOW = 5,
-  TOO_FAST = 6,
-  VENDOR = 7,
-  START = 8,
-  TOO_DARK = 9,
-  TOO_BRIGHT = 10,
-  IMMOBILE = 11,
-  RETRYING_CAPTURE = 12,
+  KEYBOARD = 257,
+  DPAD = 513,
+  GAMEPAD = 1025,
+  TOUCHSCREEN = 4098,
+  MOUSE = 8194,
+  STYLUS = 16386,
+  BLUETOOTH_STYLUS = 49154,
+  TRACKBALL = 65540,
+  MOUSE_RELATIVE = 131076,
+  TOUCHPAD = 1048584,
+  TOUCH_NAVIGATION = 2097152,
+  ROTARY_ENCODER = 4194304,
+  JOYSTICK = 16777232,
+  SENSOR = 67108864,
+  ANY = -256,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/SourceClass.aidl
similarity index 85%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/SourceClass.aidl
index 295fde9..96eede2 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/SourceClass.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +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.biometrics.fingerprint;
-@VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+package android.hardware.input.common;
+@Backing(type="byte") @VintfStability
+enum SourceClass {
+  NONE = 0,
+  BUTTON = 1,
+  POINTER = 2,
+  NAVIGATION = 4,
+  POSITION = 8,
+  JOYSTICK = 16,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/ToolType.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
copy to input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/ToolType.aidl
index 9c208c4..ac1b69d 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
+++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/ToolType.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 The Android Open Source Project
+ * 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.
@@ -31,13 +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.biometrics.fingerprint;
+package android.hardware.input.common;
 @Backing(type="byte") @VintfStability
-enum FingerprintSensorType {
+enum ToolType {
   UNKNOWN = 0,
-  REAR = 1,
-  UNDER_DISPLAY_ULTRASONIC = 2,
-  UNDER_DISPLAY_OPTICAL = 3,
-  POWER_BUTTON = 4,
-  HOME_BUTTON = 5,
+  FINGER = 1,
+  STYLUS = 2,
+  MOUSE = 3,
+  ERASER = 4,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/VideoFrame.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/VideoFrame.aidl
index 295fde9..14985c5 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/input/common/aidl/aidl_api/android.hardware.input.common/current/android/hardware/input/common/VideoFrame.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.input.common;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+parcelable VideoFrame {
+  char[] data;
+  int height;
+  int width;
+  long timestamp;
 }
diff --git a/input/common/aidl/android/hardware/input/common/Action.aidl b/input/common/aidl/android/hardware/input/common/Action.aidl
new file mode 100644
index 0000000..ebe5e67
--- /dev/null
+++ b/input/common/aidl/android/hardware/input/common/Action.aidl
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input.common;
+
+/**
+ * Motion event actions
+ */
+@VintfStability
+@Backing(type="int")
+enum Action {
+    /**
+     * A pressed gesture has started, the motion contains the initial starting location.
+     */
+    DOWN = 0,
+    /**
+     * A pressed gesture has finished, the motion contains the final release location
+     * as well as any intermediate points since the last down or move event.
+     */
+    UP = 1,
+    /**
+     * A change has happened during a press gesture (between AMOTION_EVENT_ACTION_DOWN and
+     * AMOTION_EVENT_ACTION_UP). The motion contains the most recent point.
+     */
+    MOVE = 2,
+    /**
+     * The current gesture has been aborted.
+     * You will not receive any more points in it. You must treat this as
+     * an up event, but not perform any action that you normally would.
+     */
+    CANCEL = 3,
+    /**
+     * A movement has happened outside of the normal bounds of the UI element.
+     * This does not provide a full gesture, but only the initial location of the movement/touch.
+     */
+    OUTSIDE = 4,
+    /**
+     * A non-primary pointer has gone down.
+     */
+    POINTER_DOWN = 5,
+    /**
+     * A non-primary pointer has gone up.
+     */
+    POINTER_UP = 6,
+    /**
+     * A change happened but the pointer is not down (unlike AMOTION_EVENT_ACTION_MOVE).
+     * The motion contains the most recent point, as well as any intermediate points since
+     * the last hover move event.
+     */
+    HOVER_MOVE = 7,
+    /**
+     * The motion event contains relative vertical and/or horizontal scroll offsets.
+     * Use getAxisValue to retrieve the information from AMOTION_EVENT_AXIS_VSCROLL
+     * and AMOTION_EVENT_AXIS_HSCROLL.
+     * The pointer may or may not be down when this event is dispatched.
+     * The framework will always deliver this action to the window under the pointer, which
+     * may not be the window currently touched.
+     */
+    SCROLL = 8,
+    /**
+     * The pointer is not down but has entered the boundaries of a window or view.
+     */
+    HOVER_ENTER = 9,
+    /**
+     * The pointer is not down but has exited the boundaries of a window or view.
+     */
+    HOVER_EXIT = 10,
+    /**
+     * One or more buttons have been pressed.
+     */
+    BUTTON_PRESS = 11,
+    /**
+     * One or more buttons have been released.
+     */
+    BUTTON_RELEASE = 12,
+}
diff --git a/input/common/aidl/android/hardware/input/common/Axis.aidl b/input/common/aidl/android/hardware/input/common/Axis.aidl
new file mode 100644
index 0000000..1150949
--- /dev/null
+++ b/input/common/aidl/android/hardware/input/common/Axis.aidl
@@ -0,0 +1,387 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input.common;
+
+/**
+ * Constants that identify each individual axis of a motion event.
+ * Each value represents a bit position. The user is expected to manually shift
+ * to the desired position (e.g., 1 << Axis.X) when reading or writing these
+ * from a bitfield manually.
+ */
+@VintfStability
+@Backing(type="int")
+enum Axis {
+    /**
+     * Axis constant: X axis of a motion event.
+     *
+     * - For a touch screen, reports the absolute X screen position of the center of
+     * the touch contact area.  The units are display pixels.
+     * - For a touch pad, reports the absolute X surface position of the center of the touch
+     * contact area. The units are device-dependent.
+     * - For a mouse, reports the absolute X screen position of the mouse pointer.
+     * The units are display pixels.
+     * - For a trackball, reports the relative horizontal displacement of the trackball.
+     * The value is normalized to a range from -1.0 (left) to 1.0 (right).
+     * - For a joystick, reports the absolute X position of the joystick.
+     * The value is normalized to a range from -1.0 (left) to 1.0 (right).
+     */
+    X = 0,
+    /**
+     * Axis constant: Y axis of a motion event.
+     *
+     * - For a touch screen, reports the absolute Y screen position of the center of
+     * the touch contact area.  The units are display pixels.
+     * - For a touch pad, reports the absolute Y surface position of the center of the touch
+     * contact area. The units are device-dependent.
+     * - For a mouse, reports the absolute Y screen position of the mouse pointer.
+     * The units are display pixels.
+     * - For a trackball, reports the relative vertical displacement of the trackball.
+     * The value is normalized to a range from -1.0 (up) to 1.0 (down).
+     * - For a joystick, reports the absolute Y position of the joystick.
+     * The value is normalized to a range from -1.0 (up or far) to 1.0 (down or near).
+     */
+    Y = 1,
+    /**
+     * Axis constant: Pressure axis of a motion event.
+     *
+     * - For a touch screen or touch pad, reports the approximate pressure applied to the surface
+     * by a finger or other tool.  The value is normalized to a range from
+     * 0 (no pressure at all) to 1 (normal pressure), although values higher than 1
+     * may be generated depending on the calibration of the input device.
+     * - For a trackball, the value is set to 1 if the trackball button is pressed
+     * or 0 otherwise.
+     * - For a mouse, the value is set to 1 if the primary mouse button is pressed
+     * or 0 otherwise.
+     */
+    PRESSURE = 2,
+    /**
+     * Axis constant: Size axis of a motion event.
+     *
+     * - For a touch screen or touch pad, reports the approximate size of the contact area in
+     * relation to the maximum detectable size for the device.  The value is normalized
+     * to a range from 0 (smallest detectable size) to 1 (largest detectable size),
+     * although it is not a linear scale. This value is of limited use.
+     * To obtain calibrated size information, see
+     * {@link TOUCH_MAJOR} or {@link TOOL_MAJOR}.
+     */
+    SIZE = 3,
+    /**
+     * Axis constant: TouchMajor axis of a motion event.
+     *
+     * - For a touch screen, reports the length of the major axis of an ellipse that
+     * represents the touch area at the point of contact.
+     * The units are display pixels.
+     * - For a touch pad, reports the length of the major axis of an ellipse that
+     * represents the touch area at the point of contact.
+     * The units are device-dependent.
+     */
+    TOUCH_MAJOR = 4,
+    /**
+     * Axis constant: TouchMinor axis of a motion event.
+     *
+     * - For a touch screen, reports the length of the minor axis of an ellipse that
+     * represents the touch area at the point of contact.
+     * The units are display pixels.
+     * - For a touch pad, reports the length of the minor axis of an ellipse that
+     * represents the touch area at the point of contact.
+     * The units are device-dependent.
+     *
+     * When the touch is circular, the major and minor axis lengths will be equal to one another.
+     */
+    TOUCH_MINOR = 5,
+    /**
+     * Axis constant: ToolMajor axis of a motion event.
+     *
+     * - For a touch screen, reports the length of the major axis of an ellipse that
+     * represents the size of the approaching finger or tool used to make contact.
+     * - For a touch pad, reports the length of the major axis of an ellipse that
+     * represents the size of the approaching finger or tool used to make contact.
+     * The units are device-dependent.
+     *
+     * When the touch is circular, the major and minor axis lengths will be equal to one another.
+     *
+     * The tool size may be larger than the touch size since the tool may not be fully
+     * in contact with the touch sensor.
+     */
+    TOOL_MAJOR = 6,
+    /**
+     * Axis constant: ToolMinor axis of a motion event.
+     *
+     * - For a touch screen, reports the length of the minor axis of an ellipse that
+     * represents the size of the approaching finger or tool used to make contact.
+     * - For a touch pad, reports the length of the minor axis of an ellipse that
+     * represents the size of the approaching finger or tool used to make contact.
+     * The units are device-dependent.
+     *
+     * When the touch is circular, the major and minor axis lengths will be equal to one another.
+     *
+     * The tool size may be larger than the touch size since the tool may not be fully
+     * in contact with the touch sensor.
+     */
+    TOOL_MINOR = 7,
+    /**
+     * Axis constant: Orientation axis of a motion event.
+     *
+     * - For a touch screen or touch pad, reports the orientation of the finger
+     * or tool in radians relative to the vertical plane of the device.
+     * An angle of 0 radians indicates that the major axis of contact is oriented
+     * upwards, is perfectly circular or is of unknown orientation.  A positive angle
+     * indicates that the major axis of contact is oriented to the right.  A negative angle
+     * indicates that the major axis of contact is oriented to the left.
+     * The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians
+     * (finger pointing fully right).
+     * - For a stylus, the orientation indicates the direction in which the stylus
+     * is pointing in relation to the vertical axis of the current orientation of the screen.
+     * The range is from -PI radians to PI radians, where 0 is pointing up,
+     * -PI/2 radians is pointing left, -PI or PI radians is pointing down, and PI/2 radians
+     * is pointing right.  See also {@link TILT}.
+     */
+    ORIENTATION = 8,
+    /**
+     * Axis constant: Vertical Scroll axis of a motion event.
+     *
+     * - For a mouse, reports the relative movement of the vertical scroll wheel.
+     * The value is normalized to a range from -1.0 (down) to 1.0 (up).
+     *
+     * The framework may use this axis to scroll views vertically.
+     */
+    VSCROLL = 9,
+    /**
+     * Axis constant: Horizontal Scroll axis of a motion event.
+     *
+     * - For a mouse, reports the relative movement of the horizontal scroll wheel.
+     * The value is normalized to a range from -1.0 (left) to 1.0 (right).
+     *
+     * The framework may use this axis to scroll views horizontally.
+     */
+    HSCROLL = 10,
+    /**
+     * Axis constant: Z axis of a motion event.
+     *
+     * - For a joystick, reports the absolute Z position of the joystick.
+     * The value is normalized to a range from -1.0 (high) to 1.0 (low).
+     * <em>On game pads with two analog joysticks, this axis is often reinterpreted
+     * to report the absolute X position of the second joystick instead.</em>
+     */
+    Z = 11,
+    /**
+     * Axis constant: X Rotation axis of a motion event.
+     *
+     * - For a joystick, reports the absolute rotation angle about the X axis.
+     * The value is normalized to a range from -1.0 (counter-clockwise) to 1.0 (clockwise).
+     */
+    RX = 12,
+    /**
+     * Axis constant: Y Rotation axis of a motion event.
+     *
+     * - For a joystick, reports the absolute rotation angle about the Y axis.
+     * The value is normalized to a range from -1.0 (counter-clockwise) to 1.0 (clockwise).
+     */
+    RY = 13,
+    /**
+     * Axis constant: Z Rotation axis of a motion event.
+     *
+     * - For a joystick, reports the absolute rotation angle about the Z axis.
+     * The value is normalized to a range from -1.0 (counter-clockwise) to 1.0 (clockwise).
+     * On game pads with two analog joysticks, this axis is often reinterpreted
+     * to report the absolute Y position of the second joystick instead.
+     */
+    RZ = 14,
+    /**
+     * Axis constant: Hat X axis of a motion event.
+     *
+     * - For a joystick, reports the absolute X position of the directional hat control.
+     * The value is normalized to a range from -1.0 (left) to 1.0 (right).
+     */
+    HAT_X = 15,
+    /**
+     * Axis constant: Hat Y axis of a motion event.
+     *
+     * - For a joystick, reports the absolute Y position of the directional hat control.
+     * The value is normalized to a range from -1.0 (up) to 1.0 (down).
+     */
+    HAT_Y = 16,
+    /**
+     * Axis constant: Left Trigger axis of a motion event.
+     *
+     * - For a joystick, reports the absolute position of the left trigger control.
+     * The value is normalized to a range from 0.0 (released) to 1.0 (fully pressed).
+     */
+    LTRIGGER = 17,
+    /**
+     * Axis constant: Right Trigger axis of a motion event.
+     *
+     * - For a joystick, reports the absolute position of the right trigger control.
+     * The value is normalized to a range from 0.0 (released) to 1.0 (fully pressed).
+     */
+    RTRIGGER = 18,
+    /**
+     * Axis constant: Throttle axis of a motion event.
+     *
+     * - For a joystick, reports the absolute position of the throttle control.
+     * The value is normalized to a range from 0.0 (fully open) to 1.0 (fully closed).
+     */
+    THROTTLE = 19,
+    /**
+     * Axis constant: Rudder axis of a motion event.
+     *
+     * - For a joystick, reports the absolute position of the rudder control.
+     * The value is normalized to a range from -1.0 (turn left) to 1.0 (turn right).
+     */
+    RUDDER = 20,
+    /**
+     * Axis constant: Wheel axis of a motion event.
+     *
+     * - For a joystick, reports the absolute position of the steering wheel control.
+     * The value is normalized to a range from -1.0 (turn left) to 1.0 (turn right).
+     */
+    WHEEL = 21,
+    /**
+     * Axis constant: Gas axis of a motion event.
+     *
+     * - For a joystick, reports the absolute position of the gas (accelerator) control.
+     * The value is normalized to a range from 0.0 (no acceleration)
+     * to 1.0 (maximum acceleration).
+     */
+    GAS = 22,
+    /**
+     * Axis constant: Brake axis of a motion event.
+     *
+     * - For a joystick, reports the absolute position of the brake control.
+     * The value is normalized to a range from 0.0 (no braking) to 1.0 (maximum braking).
+     */
+    BRAKE = 23,
+    /**
+     * Axis constant: Distance axis of a motion event.
+     *
+     * - For a stylus, reports the distance of the stylus from the screen.
+     * A value of 0.0 indicates direct contact and larger values indicate increasing
+     * distance from the surface.
+     */
+    DISTANCE = 24,
+    /**
+     * Axis constant: Tilt axis of a motion event.
+     *
+     * - For a stylus, reports the tilt angle of the stylus in radians where
+     * 0 radians indicates that the stylus is being held perpendicular to the
+     * surface, and PI/2 radians indicates that the stylus is being held flat
+     * against the surface.
+     */
+    TILT = 25,
+    /**
+     * Axis constant:  Generic scroll axis of a motion event.
+     *
+     * - This is used for scroll axis motion events that can't be classified as strictly
+     *   vertical or horizontal. The movement of a rotating scroller is an example of this.
+     */
+    SCROLL = 26,
+    /**
+     * Axis constant: The movement of x position of a motion event.
+     *
+     * - For a mouse, reports a difference of x position between the previous position.
+     * This is useful when pointer is captured, in that case the mouse pointer doesn't
+     * change the location but this axis reports the difference which allows the app
+     * to see how the mouse is moved.
+     */
+    RELATIVE_X = 27,
+    /**
+     * Axis constant: The movement of y position of a motion event.
+     *
+     * Same as {@link RELATIVE_X}, but for y position.
+     */
+    RELATIVE_Y = 28,
+    /**
+     * Axis constant: Generic 1 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_1 = 32,
+    /**
+     * Axis constant: Generic 2 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_2 = 33,
+    /**
+     * Axis constant: Generic 3 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_3 = 34,
+    /**
+     * Axis constant: Generic 4 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_4 = 35,
+    /**
+     * Axis constant: Generic 5 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_5 = 36,
+    /**
+     * Axis constant: Generic 6 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_6 = 37,
+    /**
+     * Axis constant: Generic 7 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_7 = 38,
+    /**
+     * Axis constant: Generic 8 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_8 = 39,
+    /**
+     * Axis constant: Generic 9 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_9 = 40,
+    /**
+     * Axis constant: Generic 10 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_10 = 41,
+    /**
+     * Axis constant: Generic 11 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_11 = 42,
+    /**
+     * Axis constant: Generic 12 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_12 = 43,
+    /**
+     * Axis constant: Generic 13 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_13 = 44,
+    /**
+     * Axis constant: Generic 14 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_14 = 45,
+    /**
+     * Axis constant: Generic 15 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_15 = 46,
+    /**
+     * Axis constant: Generic 16 axis of a motion event.
+     * The interpretation of a generic axis is device-specific.
+     */
+    GENERIC_16 = 47,
+}
diff --git a/input/common/aidl/android/hardware/input/common/Button.aidl b/input/common/aidl/android/hardware/input/common/Button.aidl
new file mode 100644
index 0000000..4bbd5f5
--- /dev/null
+++ b/input/common/aidl/android/hardware/input/common/Button.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input.common;
+
+/**
+ * Buttons that are associated with motion events.
+ */
+@VintfStability
+@Backing(type="int")
+enum Button {
+    NONE = 0,
+    PRIMARY = 1 << 0,
+    SECONDARY = 1 << 1,
+    TERTIARY = 1 << 2,
+    BACK = 1 << 3,
+    FORWARD = 1 << 4,
+    STYLUS_PRIMARY = 1 << 5,
+    STYLUS_SECONDARY = 1 << 6,
+}
diff --git a/input/common/aidl/android/hardware/input/common/Classification.aidl b/input/common/aidl/android/hardware/input/common/Classification.aidl
new file mode 100644
index 0000000..f573174
--- /dev/null
+++ b/input/common/aidl/android/hardware/input/common/Classification.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input.common;
+
+/**
+ * Classification of the current gesture, if available.
+ */
+@VintfStability
+@Backing(type="byte")
+enum Classification {
+    NONE = 0,
+    /**
+     * Too early to classify the gesture, need more events.
+     */
+    AMBIGUOUS_GESTURE = 1,
+    /**
+     * User is force-pressing the screen.
+     */
+    DEEP_PRESS = 2,
+}
diff --git a/input/common/aidl/android/hardware/input/common/EdgeFlag.aidl b/input/common/aidl/android/hardware/input/common/EdgeFlag.aidl
new file mode 100644
index 0000000..8d22635
--- /dev/null
+++ b/input/common/aidl/android/hardware/input/common/EdgeFlag.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input.common;
+
+/**
+ * Edge flags
+ */
+@VintfStability
+@Backing(type="int")
+enum EdgeFlag {
+    /**
+     * No edges are intersected
+     */
+    NONE = 0,
+    /**
+     * Motion intersected top edge of the screen
+     */
+    TOP = 1 << 0,
+    /**
+     * Motion intersected bottom edge of the screen
+     */
+    BOTTOM = 1 << 1,
+    /**
+     * Motion intersected left edge of the screen
+     */
+    LEFT = 1 << 2,
+    /**
+     * Motion intersected right edge of the screen
+     */
+    RIGHT = 1 << 3,
+}
diff --git a/input/common/aidl/android/hardware/input/common/Flag.aidl b/input/common/aidl/android/hardware/input/common/Flag.aidl
new file mode 100644
index 0000000..600bdd3
--- /dev/null
+++ b/input/common/aidl/android/hardware/input/common/Flag.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input.common;
+
+/**
+ * Motion event flags
+ */
+@VintfStability
+@Backing(type="int")
+enum Flag {
+    /**
+     * Indicates that the window that received this motion event is partly
+     * or wholly obscured by another visible window above it. This flag is set to true
+     * even if the event did not directly pass through the obscured area.
+     * A security sensitive application can check this flag to identify situations in which
+     * a malicious application may have covered up part of its content for the purpose
+     * of misleading the user or hijacking touches. An appropriate response might be
+     * to drop the suspect touches or to take additional precautions to confirm the user's
+     * actual intent.
+     */
+    WINDOW_IS_OBSCURED = 1 << 0,
+    /**
+     * This flag indicates that the event has been generated by a gesture generator. It
+     * could be used, for example, to determine whether touch slop should be applied.
+     */
+    IS_GENERATED_GESTURE = 1 << 3,
+    /**
+     * Motion event is inconsistent with previously sent motion events.
+     */
+    TAINTED = 1 << 31,
+}
diff --git a/input/common/aidl/android/hardware/input/common/Meta.aidl b/input/common/aidl/android/hardware/input/common/Meta.aidl
new file mode 100644
index 0000000..9ccf11b
--- /dev/null
+++ b/input/common/aidl/android/hardware/input/common/Meta.aidl
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input.common;
+
+/**
+ * Meta key / modifier state
+ */
+@VintfStability
+@Backing(type="int")
+enum Meta {
+    NONE = 0,
+    /**
+     * One of the ALT meta keys is pressed.
+     */
+    ALT_ON = 1 << 1,
+    /**
+     * The left ALT meta key is pressed.
+     */
+    ALT_LEFT_ON = 1 << 4,
+    /**
+     * The right ALT meta key is pressed.
+     */
+    ALT_RIGHT_ON = 1 << 5,
+    /**
+     * One of the SHIFT meta keys is pressed.
+     */
+    SHIFT_ON = 1 << 0,
+    /**
+     * The left SHIFT meta key is pressed.
+     */
+    SHIFT_LEFT_ON = 1 << 6,
+    /**
+     * The right SHIFT meta key is pressed.
+     */
+    SHIFT_RIGHT_ON = 1 << 7,
+    /**
+     * The SYM meta key is pressed.
+     */
+    SYM_ON = 1 << 2,
+    /**
+     * The FUNCTION meta key is pressed.
+     */
+    FUNCTION_ON = 1 << 3,
+    /**
+     * One of the CTRL meta keys is pressed.
+     */
+    CTRL_ON = 1 << 12,
+    /**
+     * The left CTRL meta key is pressed.
+     */
+    CTRL_LEFT_ON = 1 << 13,
+    /**
+     * The right CTRL meta key is pressed.
+     */
+    CTRL_RIGHT_ON = 1 << 14,
+    /**
+     * One of the META meta keys is pressed.
+     */
+    META_ON = 1 << 16,
+    /**
+     * The left META meta key is pressed.
+     */
+    META_LEFT_ON = 1 << 17,
+    /**
+     * The right META meta key is pressed.
+     */
+    META_RIGHT_ON = 1 << 18,
+    /**
+     * The CAPS LOCK meta key is on.
+     */
+    CAPS_LOCK_ON = 1 << 20,
+    /**
+     * The NUM LOCK meta key is on.
+     */
+    NUM_LOCK_ON = 1 << 21,
+    /**
+     * The SCROLL LOCK meta key is on.
+     */
+    SCROLL_LOCK_ON = 1 << 22,
+}
diff --git a/input/common/aidl/android/hardware/input/common/MotionEvent.aidl b/input/common/aidl/android/hardware/input/common/MotionEvent.aidl
new file mode 100644
index 0000000..dfea703
--- /dev/null
+++ b/input/common/aidl/android/hardware/input/common/MotionEvent.aidl
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input.common;
+
+import android.hardware.input.common.Action;
+import android.hardware.input.common.Button;
+import android.hardware.input.common.EdgeFlag;
+import android.hardware.input.common.Flag;
+import android.hardware.input.common.Meta;
+import android.hardware.input.common.PointerCoords;
+import android.hardware.input.common.PointerProperties;
+import android.hardware.input.common.PolicyFlag;
+import android.hardware.input.common.Source;
+import android.hardware.input.common.VideoFrame;
+
+/**
+ * Analogous to Android's native MotionEvent / NotifyMotionArgs.
+ * Stores the basic information about pointer movements.
+ */
+@VintfStability
+parcelable MotionEvent {
+    /**
+     * The id of the device which produced this event.
+     */
+    int deviceId;
+    /**
+     * The source type of this event.
+     */
+    Source source;
+    /**
+     * The display id associated with this event.
+     */
+    int displayId;
+    /**
+     * Time when the initial touch down occurred, in nanoseconds.
+     */
+    long downTime;
+    /**
+     * Time when this event occurred, in nanoseconds.
+     */
+    long eventTime;
+    /**
+     * The kind of action being performed.
+     */
+    Action action;
+    /**
+     * For ACTION_POINTER_DOWN or ACTION_POINTER_UP, this contains the associated pointer index.
+     * The index may be used to get information about the pointer that has gone down or up.
+     */
+    byte actionIndex;
+    /**
+     * The button that has been modified during a press or release action.
+     */
+    Button actionButton;
+    /**
+     * The motion event flags.
+     */
+    Flag flags;
+    /**
+     * The motion event policy flags.
+     */
+    PolicyFlag policyFlags;
+    /**
+     * The edges, if any, that were touched by this motion event.
+     */
+    EdgeFlag edgeFlags;
+    /**
+     * The state of any meta / modifier keys that were in effect when the event was generated.
+     */
+    Meta metaState;
+    /**
+     * The state of buttons that are pressed.
+     */
+    Button buttonState;
+    /**
+     * The precision of the X coordinate being reported.
+     */
+    float xPrecision;
+    /**
+     * The precision of the Y coordinate being reported.
+     */
+    float yPrecision;
+    /**
+     * The properties of each pointer present in this motion event.
+     */
+    PointerProperties[] pointerProperties;
+    /**
+     * The coordinates of each pointer.
+     */
+    PointerCoords[] pointerCoords;
+    /**
+     * Device time at which the event occurred, in microseconds.
+     * Will wrap after a little over an hour.
+     */
+    int deviceTimestamp;
+    /**
+     * The video frames, if any, associated with the current or previous motion events.
+     */
+    VideoFrame[] frames;
+}
diff --git a/input/common/aidl/android/hardware/input/common/PointerCoords.aidl b/input/common/aidl/android/hardware/input/common/PointerCoords.aidl
new file mode 100644
index 0000000..56d9a74
--- /dev/null
+++ b/input/common/aidl/android/hardware/input/common/PointerCoords.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input.common;
+
+import android.hardware.input.common.Axis;
+
+/**
+ * Pointer coordinate data. Analogous to Android's PointerCoords.
+ */
+@VintfStability
+parcelable PointerCoords {
+    /**
+     * Bitfield of axes that are present in this structure.
+     * Each bit position matches an axis defined in Axis.aidl.
+     */
+    long bits;
+    /**
+     * The values corresponding to each non-zero axis. This vector only
+     * contains non-zero entries. If an axis that is not currently specified
+     * in "bits" is requested, a zero value is returned.
+     * There are only as many values stored here
+     * as there are non-zero bits in the "bits" field.
+     * The values are position-packed. So the first non-zero axis will be
+     * at position 0, the next non-zero axis will be at position 1, and so on.
+     */
+    float[] values;
+}
diff --git a/input/common/aidl/android/hardware/input/common/PointerProperties.aidl b/input/common/aidl/android/hardware/input/common/PointerProperties.aidl
new file mode 100644
index 0000000..38d815e
--- /dev/null
+++ b/input/common/aidl/android/hardware/input/common/PointerProperties.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input.common;
+
+import android.hardware.input.common.ToolType;
+
+/**
+ * Properties of a particular pointer. Analogous to Android's PointerProperties.
+ */
+@VintfStability
+parcelable PointerProperties {
+    /**
+     * A number identifying a specific pointer. When a pointer is lifted,
+     * this value may be reused by another new pointer, even during the
+     * same gesture. For example, if there are two pointers touching the screen
+     * at the same time, they might have pointer ID's of 0 and 1. If the
+     * pointer with id = 0 is lifted, while the pointer with id = 1 remains, and
+     * a new pointer is placed on the screen, then the new pointer may receive
+     * an id of 0. While a pointer is active, it is guaranteed to keep the same
+     * id.
+     */
+    int id;
+    /**
+     * Type of tool used to make contact, such as a finger or stylus, if known.
+     */
+    ToolType toolType;
+}
diff --git a/input/common/aidl/android/hardware/input/common/PolicyFlag.aidl b/input/common/aidl/android/hardware/input/common/PolicyFlag.aidl
new file mode 100644
index 0000000..c5edd0d
--- /dev/null
+++ b/input/common/aidl/android/hardware/input/common/PolicyFlag.aidl
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input.common;
+
+/**
+ * Policy flags.
+ * The values 1 << 4 through 1 << 23 are not currently used.
+ * When a new value is added, make sure it matches a value defined in Input.h
+ * and other relevant files in frameworks/base and frameworks/native.
+ */
+@VintfStability
+@Backing(type="int")
+enum PolicyFlag {
+    /**
+     * Event should wake the device
+     */
+    WAKE = 1 << 0,
+    /**
+     * Key is virtual, and should generate haptic feedback
+     */
+    VIRTUAL = 1 << 1,
+    /**
+     * Key is the special function modifier
+     */
+    FUNCTION = 1 << 2,
+    /**
+     * Key represents a special gesture that has been detected
+     * by the touch firmware or driver.
+     */
+    GESTURE = 1 << 3,
+    /**
+     * Event was injected
+     */
+    INJECTED = 1 << 24,
+    /**
+     * Event comes from a trusted source, such as a directly attached input
+     * device or an application with system-wide event injection permission.
+     */
+    TRUSTED = 1 << 25,
+    /**
+     * Event has passed through an input filter.
+     */
+    FILTERED = 1 << 26,
+    /**
+     * Disable automatic key repeating behaviour.
+     */
+    DISABLE_KEY_REPEAT = 1 << 27,
+    /**
+     * Device was in an interactive state when the event was intercepted
+     */
+    INTERACTIVE = 1 << 29,
+    /**
+     * Event should be dispatched to applications
+     */
+    PASS_TO_USER = 1 << 30,
+}
diff --git a/input/common/aidl/android/hardware/input/common/Source.aidl b/input/common/aidl/android/hardware/input/common/Source.aidl
new file mode 100644
index 0000000..7eb6d66
--- /dev/null
+++ b/input/common/aidl/android/hardware/input/common/Source.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input.common;
+
+import android.hardware.input.common.SourceClass;
+
+/**
+ * Input sources
+ */
+@VintfStability
+@Backing(type="int")
+enum Source {
+    UNKNOWN = 0,
+    KEYBOARD = (1 << 8) | SourceClass.BUTTON,
+    DPAD = (1 << 9) | SourceClass.BUTTON,
+    GAMEPAD = (1 << 10) | SourceClass.BUTTON,
+    TOUCHSCREEN = (1 << 12) | SourceClass.POINTER,
+    MOUSE = (1 << 13) | SourceClass.POINTER,
+    STYLUS = (1 << 14) | SourceClass.POINTER,
+    BLUETOOTH_STYLUS = (1 << 15) | STYLUS,
+    TRACKBALL = (1 << 16) | SourceClass.NAVIGATION,
+    MOUSE_RELATIVE = (1 << 17) | SourceClass.NAVIGATION,
+    TOUCHPAD = (1 << 20) | SourceClass.POSITION,
+    TOUCH_NAVIGATION = (1 << 21) | SourceClass.NONE,
+    ROTARY_ENCODER = (1 << 22) | SourceClass.NONE,
+    JOYSTICK = (1 << 24) | SourceClass.JOYSTICK,
+    SENSOR = (1 << 26) | SourceClass.NONE,
+    ANY = 0xFFFFFF00,
+}
diff --git a/input/common/aidl/android/hardware/input/common/SourceClass.aidl b/input/common/aidl/android/hardware/input/common/SourceClass.aidl
new file mode 100644
index 0000000..4315798
--- /dev/null
+++ b/input/common/aidl/android/hardware/input/common/SourceClass.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input.common;
+
+@VintfStability
+@Backing(type="byte")
+enum SourceClass {
+    NONE = 0 << 0,
+    BUTTON = 1 << 0,
+    POINTER = 1 << 1,
+    NAVIGATION = 1 << 2,
+    POSITION = 1 << 3,
+    JOYSTICK = 1 << 4,
+}
diff --git a/input/common/aidl/android/hardware/input/common/ToolType.aidl b/input/common/aidl/android/hardware/input/common/ToolType.aidl
new file mode 100644
index 0000000..cfa057d
--- /dev/null
+++ b/input/common/aidl/android/hardware/input/common/ToolType.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input.common;
+
+/**
+ * Tool type of a pointer
+ */
+@VintfStability
+@Backing(type="byte")
+enum ToolType {
+    UNKNOWN = 0,
+    FINGER = 1,
+    STYLUS = 2,
+    MOUSE = 3,
+    ERASER = 4,
+}
diff --git a/input/common/aidl/android/hardware/input/common/VideoFrame.aidl b/input/common/aidl/android/hardware/input/common/VideoFrame.aidl
new file mode 100644
index 0000000..409cee5
--- /dev/null
+++ b/input/common/aidl/android/hardware/input/common/VideoFrame.aidl
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input.common;
+
+/**
+ * Touch heatmap.
+ *
+ * The array is a 2-D row-major matrix with dimensions (height, width).
+ * The heatmap data is rotated when device orientation changes.
+ *
+ * Example:
+ *
+ * If the data in the array is:
+ * data[i] = i for i in 0 .. 59,
+ * then it can be represented as a 10 x 6 matrix:
+ *
+ *  <--   width   -->
+ *   0  1  2  3  4  5   ^
+ *   6  7  8  9 10 11   |
+ *  12 13 14 15 16 17   |
+ *  18    ...      23   |
+ *  24    ...      29   | height
+ *  30    ...      35   |
+ *  36    ...      41   |
+ *  42    ...      47   |
+ *  48    ...      53   |
+ *  54    ...      59   v
+ *
+ * Looking at the device in standard portrait orientation,
+ * the element "0" is the top left of the screen,
+ * "5" is at the top right, and "59" is the bottom right.
+ * Here height=10 and width=6.
+ *
+ * If the screen orientation changes to landscape (a 90 degree orientation
+ * change), the frame's dimensions will become 6 x 10
+ * and the data will look as follows:
+ * 54 48 42 36 30 24 18 12  6  0     ^
+ * ...                  13  7  1     |
+ * ...                  14  8  2     | height
+ * ...                  15  9  3     |
+ * ...                  16 10  4     |
+ * 59 53 47 41 35 29 23 17 11  5     v
+ * <--        width          -->
+ *
+ * Here the element "0" is at the physical top left of the unrotated screen.
+ *
+ * Since the coordinates of a MotionEvent are also adjusted based on the
+ * orientation, the rotation of the video frame data ensures that
+ * the axes for MotionEvent and VideoFrame data are consistent.
+ */
+@VintfStability
+parcelable VideoFrame {
+    /**
+     * Video frame data.
+     * Size of the data is height * width.
+     */
+    char[] data;
+    int height;
+    int width;
+    /**
+     * Time at which the frame was collected, in nanoseconds.
+     * Measured with the same clock that is used to populate MotionEvent times.
+     */
+    long timestamp;
+}
diff --git a/ir/aidl/Android.bp b/ir/aidl/Android.bp
index a623491..5dbf68f 100644
--- a/ir/aidl/Android.bp
+++ b/ir/aidl/Android.bp
@@ -35,8 +35,7 @@
         },
         ndk: {
             vndk: {
-                // TODO(b/206116595) enable this
-                enabled: false,
+                enabled: true,
             },
         },
     },
diff --git a/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/IConsumerIr.aidl b/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/IConsumerIr.aidl
index 056a8b1..07bf4b4 100644
--- a/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/IConsumerIr.aidl
+++ b/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/IConsumerIr.aidl
@@ -35,5 +35,5 @@
 @VintfStability
 interface IConsumerIr {
   android.hardware.ir.ConsumerIrFreqRange[] getCarrierFreqs();
-  void transmit(in int carrierFreq, in int[] pattern);
+  void transmit(in int carrierFreqHz, in int[] pattern);
 }
diff --git a/ir/aidl/android/hardware/ir/IConsumerIr.aidl b/ir/aidl/android/hardware/ir/IConsumerIr.aidl
index d14fa56..f6f9742 100644
--- a/ir/aidl/android/hardware/ir/IConsumerIr.aidl
+++ b/ir/aidl/android/hardware/ir/IConsumerIr.aidl
@@ -23,23 +23,21 @@
     /**
      * Enumerates which frequencies the IR transmitter supports.
      *
-     * Status OK (EX_NONE) on success.
-     *
      * @return - an array of all supported frequency ranges.
      */
     ConsumerIrFreqRange[] getCarrierFreqs();
 
     /**
      * Sends an IR pattern at a given frequency in HZ.
-     *
-     * The pattern is alternating series of carrier on and off periods measured in
-     * microseconds. The carrier should be turned off at the end of a transmit
-     * even if there are and odd number of entries in the pattern array.
-     *
      * This call must return when the transmit is complete or encounters an error.
      *
-     * Status OK (EX_NONE) on success.
-     * EX_UNSUPPORTED_OPERATION when the frequency is not supported.
+     * @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 carrierFreq, in int[] pattern);
+    void transmit(in int carrierFreqHz, in int[] pattern);
 }
diff --git a/ir/aidl/default/main.cpp b/ir/aidl/default/main.cpp
index 764aeaf..7c4a816 100644
--- a/ir/aidl/default/main.cpp
+++ b/ir/aidl/default/main.cpp
@@ -30,7 +30,7 @@
 
 class ConsumerIr : public BnConsumerIr {
     ::ndk::ScopedAStatus getCarrierFreqs(std::vector<ConsumerIrFreqRange>* _aidl_return) override;
-    ::ndk::ScopedAStatus transmit(int32_t in_carrierFreq,
+    ::ndk::ScopedAStatus transmit(int32_t in_carrierFreqHz,
                                   const std::vector<int32_t>& in_pattern) override;
 };
 
@@ -46,9 +46,9 @@
     return false;
 }
 
-::ndk::ScopedAStatus ConsumerIr::transmit(int32_t in_carrierFreq,
+::ndk::ScopedAStatus ConsumerIr::transmit(int32_t in_carrierFreqHz,
                                           const std::vector<int32_t>& in_pattern) {
-    if (isSupportedFreq(in_carrierFreq)) {
+    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));
diff --git a/keymaster/4.0/IKeymasterDevice.hal b/keymaster/4.0/IKeymasterDevice.hal
index dfde060..1c6ae47 100644
--- a/keymaster/4.0/IKeymasterDevice.hal
+++ b/keymaster/4.0/IKeymasterDevice.hal
@@ -1254,7 +1254,8 @@
      * o PaddingMode::RSA_PSS.  For PSS-padded signature operations, the PSS salt length must match
      *   the size of the PSS digest selected.  The digest specified with Tag::DIGEST in inputParams
      *   on begin() must be used as the PSS digest algorithm, MGF1 must be used as the mask
-     *   generation function and SHA1 must be used as the MGF1 digest algorithm.
+     *   generation function and the digest specified with Tag:DIGEST in inputParams must also be
+     *   used as the MGF1 digest algorithm.
      *
      * o PaddingMode::RSA_OAEP.  The digest specified with Tag::DIGEST in inputParams on begin is
      *   used as the OAEP digest algorithm, MGF1 must be used as the mask generation function and
diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
index 7676147..6412f3a 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -1712,6 +1712,7 @@
                     case PaddingMode::RSA_PSS:
                         EXPECT_GT(EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING), 0);
                         EXPECT_GT(EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, EVP_MD_size(md)), 0);
+                        EXPECT_GT(EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, md), 0);
                         break;
                     case PaddingMode::RSA_PKCS1_1_5_SIGN:
                         // PKCS1 is the default; don't need to set anything.
diff --git a/neuralnetworks/aidl/Android.bp b/neuralnetworks/aidl/Android.bp
index cbb6ce5..47f3b30 100644
--- a/neuralnetworks/aidl/Android.bp
+++ b/neuralnetworks/aidl/Android.bp
@@ -38,5 +38,6 @@
     versions: [
         "1",
         "2",
+        "3",
     ],
 }
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/.hash b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/.hash
new file mode 100644
index 0000000..3b9f018
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/.hash
@@ -0,0 +1 @@
+8c2c4ca2327e6f779dad6119c03d832ea4e1def1
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferDesc.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferDesc.aidl
index 295fde9..05cec76 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferDesc.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+parcelable BufferDesc {
+  int[] dimensions;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferRole.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferRole.aidl
index 295fde9..10a6b75 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferRole.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+parcelable BufferRole {
+  int modelIndex;
+  int ioIndex;
+  float probability;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Capabilities.aidl
similarity index 78%
rename from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/IFingerprint.aidl
rename to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Capabilities.aidl
index 5d3df6f..30877c0 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/IFingerprint.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Capabilities.aidl
@@ -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.biometrics.fingerprint;
+package android.hardware.neuralnetworks;
 @VintfStability
-interface IFingerprint {
-  android.hardware.biometrics.fingerprint.SensorProps[] getSensorProps();
-  android.hardware.biometrics.fingerprint.ISession createSession(in int sensorId, in int userId, in android.hardware.biometrics.fingerprint.ISessionCallback cb);
+parcelable Capabilities {
+  android.hardware.neuralnetworks.PerformanceInfo relaxedFloat32toFloat16PerformanceScalar;
+  android.hardware.neuralnetworks.PerformanceInfo relaxedFloat32toFloat16PerformanceTensor;
+  android.hardware.neuralnetworks.OperandPerformance[] operandPerformance;
+  android.hardware.neuralnetworks.PerformanceInfo ifPerformance;
+  android.hardware.neuralnetworks.PerformanceInfo whilePerformance;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DataLocation.aidl
similarity index 87%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DataLocation.aidl
index 295fde9..db49a38 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DataLocation.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+parcelable DataLocation {
+  int poolIndex;
+  long offset;
+  long length;
+  long padding;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceBuffer.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceBuffer.aidl
index 295fde9..7cdd6db 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceBuffer.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+parcelable DeviceBuffer {
+  android.hardware.neuralnetworks.IBuffer buffer;
+  int token;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceType.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceType.aidl
index 9c208c4..82fe8ae 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceType.aidl
@@ -31,13 +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.biometrics.fingerprint;
-@Backing(type="byte") @VintfStability
-enum FingerprintSensorType {
-  UNKNOWN = 0,
-  REAR = 1,
-  UNDER_DISPLAY_ULTRASONIC = 2,
-  UNDER_DISPLAY_OPTICAL = 3,
-  POWER_BUTTON = 4,
-  HOME_BUTTON = 5,
+package android.hardware.neuralnetworks;
+@Backing(type="int") @VintfStability
+enum DeviceType {
+  OTHER = 1,
+  CPU = 2,
+  GPU = 3,
+  ACCELERATOR = 4,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ErrorStatus.aidl
similarity index 82%
rename from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
rename to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ErrorStatus.aidl
index c51aa03..57d5d6e 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ErrorStatus.aidl
@@ -31,20 +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.biometrics.fingerprint;
-@Backing(type="byte") @VintfStability
-enum AcquiredInfo {
-  UNKNOWN = 0,
-  GOOD = 1,
-  PARTIAL = 2,
-  INSUFFICIENT = 3,
-  SENSOR_DIRTY = 4,
-  TOO_SLOW = 5,
-  TOO_FAST = 6,
-  VENDOR = 7,
-  START = 8,
-  TOO_DARK = 9,
-  TOO_BRIGHT = 10,
-  IMMOBILE = 11,
-  RETRYING_CAPTURE = 12,
+package android.hardware.neuralnetworks;
+@Backing(type="int") @VintfStability
+enum ErrorStatus {
+  NONE = 0,
+  DEVICE_UNAVAILABLE = 1,
+  GENERAL_FAILURE = 2,
+  OUTPUT_INSUFFICIENT_SIZE = 3,
+  INVALID_ARGUMENT = 4,
+  MISSED_DEADLINE_TRANSIENT = 5,
+  MISSED_DEADLINE_PERSISTENT = 6,
+  RESOURCE_EXHAUSTED_TRANSIENT = 7,
+  RESOURCE_EXHAUSTED_PERSISTENT = 8,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionPreference.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionPreference.aidl
index 9c208c4..4352d8f 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionPreference.aidl
@@ -31,13 +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.biometrics.fingerprint;
-@Backing(type="byte") @VintfStability
-enum FingerprintSensorType {
-  UNKNOWN = 0,
-  REAR = 1,
-  UNDER_DISPLAY_ULTRASONIC = 2,
-  UNDER_DISPLAY_OPTICAL = 3,
-  POWER_BUTTON = 4,
-  HOME_BUTTON = 5,
+package android.hardware.neuralnetworks;
+@Backing(type="int") @VintfStability
+enum ExecutionPreference {
+  LOW_POWER = 0,
+  FAST_SINGLE_ANSWER = 1,
+  SUSTAINED_SPEED = 2,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionResult.aidl
similarity index 88%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionResult.aidl
index 295fde9..44e9922 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionResult.aidl
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+parcelable ExecutionResult {
+  boolean outputSufficientSize;
+  android.hardware.neuralnetworks.OutputShape[] outputShapes;
+  android.hardware.neuralnetworks.Timing timing;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Extension.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Extension.aidl
index 295fde9..c47028d 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Extension.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+parcelable Extension {
+  String name;
+  android.hardware.neuralnetworks.ExtensionOperandTypeInformation[] operandTypes;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl
index 295fde9..6c287fd 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+parcelable ExtensionNameAndPrefix {
+  String name;
+  char prefix;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl
index 295fde9..a3680aa 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+parcelable ExtensionOperandTypeInformation {
+  char type;
+  boolean isTensor;
+  int byteSize;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FencedExecutionResult.aidl
similarity index 89%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FencedExecutionResult.aidl
index 295fde9..7952b34 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FencedExecutionResult.aidl
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+parcelable FencedExecutionResult {
+  android.hardware.neuralnetworks.IFencedExecutionCallback callback;
+  @nullable ParcelFileDescriptor syncFence;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FusedActivationFunc.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FusedActivationFunc.aidl
index 9c208c4..7e61bbb 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FusedActivationFunc.aidl
@@ -31,13 +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.biometrics.fingerprint;
-@Backing(type="byte") @VintfStability
-enum FingerprintSensorType {
-  UNKNOWN = 0,
-  REAR = 1,
-  UNDER_DISPLAY_ULTRASONIC = 2,
-  UNDER_DISPLAY_OPTICAL = 3,
-  POWER_BUTTON = 4,
-  HOME_BUTTON = 5,
+package android.hardware.neuralnetworks;
+@Backing(type="int") @VintfStability
+enum FusedActivationFunc {
+  NONE = 0,
+  RELU = 1,
+  RELU1 = 2,
+  RELU6 = 3,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBuffer.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBuffer.aidl
index 9c208c4..f10e7e2 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBuffer.aidl
@@ -31,13 +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.biometrics.fingerprint;
-@Backing(type="byte") @VintfStability
-enum FingerprintSensorType {
-  UNKNOWN = 0,
-  REAR = 1,
-  UNDER_DISPLAY_ULTRASONIC = 2,
-  UNDER_DISPLAY_OPTICAL = 3,
-  POWER_BUTTON = 4,
-  HOME_BUTTON = 5,
+package android.hardware.neuralnetworks;
+@VintfStability
+interface IBuffer {
+  void copyFrom(in android.hardware.neuralnetworks.Memory src, in int[] dimensions);
+  void copyTo(in android.hardware.neuralnetworks.Memory dst);
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBurst.aidl
similarity index 82%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBurst.aidl
index 295fde9..eb3d0b0 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBurst.aidl
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+interface IBurst {
+  android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in android.hardware.neuralnetworks.Request request, in long[] memoryIdentifierTokens, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs);
+  void releaseMemoryResource(in long memoryIdentifierToken);
 }
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IDevice.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IDevice.aidl
new file mode 100644
index 0000000..c9c67f2
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IDevice.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.neuralnetworks;
+@VintfStability
+interface IDevice {
+  android.hardware.neuralnetworks.DeviceBuffer allocate(in android.hardware.neuralnetworks.BufferDesc desc, in android.hardware.neuralnetworks.IPreparedModelParcel[] preparedModels, in android.hardware.neuralnetworks.BufferRole[] inputRoles, in android.hardware.neuralnetworks.BufferRole[] outputRoles);
+  android.hardware.neuralnetworks.Capabilities getCapabilities();
+  android.hardware.neuralnetworks.NumberOfCacheFiles getNumberOfCacheFilesNeeded();
+  android.hardware.neuralnetworks.Extension[] getSupportedExtensions();
+  boolean[] getSupportedOperations(in android.hardware.neuralnetworks.Model model);
+  android.hardware.neuralnetworks.DeviceType getType();
+  String getVersionString();
+  void prepareModel(in android.hardware.neuralnetworks.Model model, in android.hardware.neuralnetworks.ExecutionPreference preference, in android.hardware.neuralnetworks.Priority priority, in long deadlineNs, in ParcelFileDescriptor[] modelCache, in ParcelFileDescriptor[] dataCache, in byte[] token, in android.hardware.neuralnetworks.IPreparedModelCallback callback);
+  void prepareModelFromCache(in long deadlineNs, in ParcelFileDescriptor[] modelCache, in ParcelFileDescriptor[] dataCache, in byte[] token, in android.hardware.neuralnetworks.IPreparedModelCallback callback);
+  const int BYTE_SIZE_OF_CACHE_TOKEN = 32;
+  const int MAX_NUMBER_OF_CACHE_FILES = 32;
+  const int EXTENSION_TYPE_HIGH_BITS_PREFIX = 15;
+  const int EXTENSION_TYPE_LOW_BITS_TYPE = 16;
+  const int OPERAND_TYPE_BASE_MAX = 65535;
+  const int OPERATION_TYPE_BASE_MAX = 65535;
+}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/Error.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IFencedExecutionCallback.aidl
similarity index 85%
rename from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/Error.aidl
rename to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IFencedExecutionCallback.aidl
index af7bc3c..0bfb80a 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/Error.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IFencedExecutionCallback.aidl
@@ -31,16 +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.biometrics.fingerprint;
-@Backing(type="byte") @VintfStability
-enum Error {
-  UNKNOWN = 0,
-  HW_UNAVAILABLE = 1,
-  UNABLE_TO_PROCESS = 2,
-  TIMEOUT = 3,
-  NO_SPACE = 4,
-  CANCELED = 5,
-  UNABLE_TO_REMOVE = 6,
-  VENDOR = 7,
-  BAD_CALIBRATION = 8,
+package android.hardware.neuralnetworks;
+@VintfStability
+interface IFencedExecutionCallback {
+  android.hardware.neuralnetworks.ErrorStatus getExecutionInfo(out android.hardware.neuralnetworks.Timing timingLaunched, out android.hardware.neuralnetworks.Timing timingFenced);
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorProps.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModel.aidl
similarity index 70%
rename from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorProps.aidl
rename to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModel.aidl
index 782d289..fccb5dc 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorProps.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModel.aidl
@@ -31,14 +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.biometrics.fingerprint;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable SensorProps {
-  android.hardware.biometrics.common.CommonProps commonProps;
-  android.hardware.biometrics.fingerprint.FingerprintSensorType sensorType = android.hardware.biometrics.fingerprint.FingerprintSensorType.UNKNOWN;
-  android.hardware.biometrics.fingerprint.SensorLocation[] sensorLocations;
-  boolean supportsNavigationGestures;
-  boolean supportsDetectInteraction;
-  boolean halHandlesDisplayTouches;
-  boolean halControlsIllumination;
+interface IPreparedModel {
+  android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in android.hardware.neuralnetworks.Request request, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs);
+  android.hardware.neuralnetworks.FencedExecutionResult executeFenced(in android.hardware.neuralnetworks.Request request, in ParcelFileDescriptor[] waitFor, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs, in long durationNs);
+  android.hardware.neuralnetworks.IBurst configureExecutionBurst();
+  const long DEFAULT_LOOP_TIMEOUT_DURATION_NS = 2000000000;
+  const long MAXIMUM_LOOP_TIMEOUT_DURATION_NS = 15000000000;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelCallback.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelCallback.aidl
index 9c208c4..e0c763b 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelCallback.aidl
@@ -31,13 +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.biometrics.fingerprint;
-@Backing(type="byte") @VintfStability
-enum FingerprintSensorType {
-  UNKNOWN = 0,
-  REAR = 1,
-  UNDER_DISPLAY_ULTRASONIC = 2,
-  UNDER_DISPLAY_OPTICAL = 3,
-  POWER_BUTTON = 4,
-  HOME_BUTTON = 5,
+package android.hardware.neuralnetworks;
+@VintfStability
+interface IPreparedModelCallback {
+  void notify(in android.hardware.neuralnetworks.ErrorStatus status, in android.hardware.neuralnetworks.IPreparedModel preparedModel);
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelParcel.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelParcel.aidl
index 295fde9..dbedf12 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelParcel.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+parcelable IPreparedModelParcel {
+  android.hardware.neuralnetworks.IPreparedModel preparedModel;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Memory.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Memory.aidl
index 9c208c4..37fa102 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Memory.aidl
@@ -31,13 +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.biometrics.fingerprint;
-@Backing(type="byte") @VintfStability
-enum FingerprintSensorType {
-  UNKNOWN = 0,
-  REAR = 1,
-  UNDER_DISPLAY_ULTRASONIC = 2,
-  UNDER_DISPLAY_OPTICAL = 3,
-  POWER_BUTTON = 4,
-  HOME_BUTTON = 5,
+package android.hardware.neuralnetworks;
+@VintfStability
+union Memory {
+  android.hardware.common.Ashmem ashmem;
+  android.hardware.common.MappableFile mappableFile;
+  android.hardware.graphics.common.HardwareBuffer hardwareBuffer;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Model.aidl
similarity index 81%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Model.aidl
index c51aa03..30d8dda 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Model.aidl
@@ -31,20 +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.biometrics.fingerprint;
-@Backing(type="byte") @VintfStability
-enum AcquiredInfo {
-  UNKNOWN = 0,
-  GOOD = 1,
-  PARTIAL = 2,
-  INSUFFICIENT = 3,
-  SENSOR_DIRTY = 4,
-  TOO_SLOW = 5,
-  TOO_FAST = 6,
-  VENDOR = 7,
-  START = 8,
-  TOO_DARK = 9,
-  TOO_BRIGHT = 10,
-  IMMOBILE = 11,
-  RETRYING_CAPTURE = 12,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable Model {
+  android.hardware.neuralnetworks.Subgraph main;
+  android.hardware.neuralnetworks.Subgraph[] referenced;
+  byte[] operandValues;
+  android.hardware.neuralnetworks.Memory[] pools;
+  boolean relaxComputationFloat32toFloat16;
+  android.hardware.neuralnetworks.ExtensionNameAndPrefix[] extensionNameToPrefix;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl
index 295fde9..9314760 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+parcelable NumberOfCacheFiles {
+  int numModelCache;
+  int numDataCache;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operand.aidl
similarity index 77%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/IFingerprint.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operand.aidl
index 5d3df6f..1d9bdd8 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/IFingerprint.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operand.aidl
@@ -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.biometrics.fingerprint;
+package android.hardware.neuralnetworks;
 @VintfStability
-interface IFingerprint {
-  android.hardware.biometrics.fingerprint.SensorProps[] getSensorProps();
-  android.hardware.biometrics.fingerprint.ISession createSession(in int sensorId, in int userId, in android.hardware.biometrics.fingerprint.ISessionCallback cb);
+parcelable Operand {
+  android.hardware.neuralnetworks.OperandType type = android.hardware.neuralnetworks.OperandType.FLOAT32;
+  int[] dimensions;
+  float scale;
+  int zeroPoint;
+  android.hardware.neuralnetworks.OperandLifeTime lifetime = android.hardware.neuralnetworks.OperandLifeTime.TEMPORARY_VARIABLE;
+  android.hardware.neuralnetworks.DataLocation location;
+  @nullable android.hardware.neuralnetworks.OperandExtraParams extraParams;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandExtraParams.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandExtraParams.aidl
index 295fde9..14792cf 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandExtraParams.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+union OperandExtraParams {
+  android.hardware.neuralnetworks.SymmPerChannelQuantParams channelQuant;
+  byte[] extension;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandLifeTime.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandLifeTime.aidl
index 9c208c4..40adfb1 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandLifeTime.aidl
@@ -31,13 +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.biometrics.fingerprint;
-@Backing(type="byte") @VintfStability
-enum FingerprintSensorType {
-  UNKNOWN = 0,
-  REAR = 1,
-  UNDER_DISPLAY_ULTRASONIC = 2,
-  UNDER_DISPLAY_OPTICAL = 3,
-  POWER_BUTTON = 4,
-  HOME_BUTTON = 5,
+package android.hardware.neuralnetworks;
+@Backing(type="int") @VintfStability
+enum OperandLifeTime {
+  TEMPORARY_VARIABLE = 0,
+  SUBGRAPH_INPUT = 1,
+  SUBGRAPH_OUTPUT = 2,
+  CONSTANT_COPY = 3,
+  CONSTANT_POOL = 4,
+  NO_VALUE = 5,
+  SUBGRAPH = 6,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandPerformance.aidl
similarity index 86%
rename from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
rename to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandPerformance.aidl
index 9c208c4..ebb361b 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandPerformance.aidl
@@ -31,13 +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.biometrics.fingerprint;
-@Backing(type="byte") @VintfStability
-enum FingerprintSensorType {
-  UNKNOWN = 0,
-  REAR = 1,
-  UNDER_DISPLAY_ULTRASONIC = 2,
-  UNDER_DISPLAY_OPTICAL = 3,
-  POWER_BUTTON = 4,
-  HOME_BUTTON = 5,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable OperandPerformance {
+  android.hardware.neuralnetworks.OperandType type = android.hardware.neuralnetworks.OperandType.FLOAT32;
+  android.hardware.neuralnetworks.PerformanceInfo info;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandType.aidl
similarity index 78%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandType.aidl
index c51aa03..9f2c759 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandType.aidl
@@ -31,20 +31,23 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.biometrics.fingerprint;
-@Backing(type="byte") @VintfStability
-enum AcquiredInfo {
-  UNKNOWN = 0,
-  GOOD = 1,
-  PARTIAL = 2,
-  INSUFFICIENT = 3,
-  SENSOR_DIRTY = 4,
-  TOO_SLOW = 5,
-  TOO_FAST = 6,
-  VENDOR = 7,
-  START = 8,
-  TOO_DARK = 9,
-  TOO_BRIGHT = 10,
-  IMMOBILE = 11,
-  RETRYING_CAPTURE = 12,
+package android.hardware.neuralnetworks;
+@Backing(type="int") @VintfStability
+enum OperandType {
+  FLOAT32 = 0,
+  INT32 = 1,
+  UINT32 = 2,
+  TENSOR_FLOAT32 = 3,
+  TENSOR_INT32 = 4,
+  TENSOR_QUANT8_ASYMM = 5,
+  BOOL = 6,
+  TENSOR_QUANT16_SYMM = 7,
+  TENSOR_FLOAT16 = 8,
+  TENSOR_BOOL8 = 9,
+  FLOAT16 = 10,
+  TENSOR_QUANT8_SYMM_PER_CHANNEL = 11,
+  TENSOR_QUANT16_ASYMM = 12,
+  TENSOR_QUANT8_SYMM = 13,
+  TENSOR_QUANT8_ASYMM_SIGNED = 14,
+  SUBGRAPH = 15,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operation.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operation.aidl
index 295fde9..a4a3fbe 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operation.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+parcelable Operation {
+  android.hardware.neuralnetworks.OperationType type = android.hardware.neuralnetworks.OperationType.ADD;
+  int[] inputs;
+  int[] outputs;
 }
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperationType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperationType.aidl
new file mode 100644
index 0000000..34506c8
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperationType.aidl
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.neuralnetworks;
+@Backing(type="int") @VintfStability
+enum OperationType {
+  ADD = 0,
+  AVERAGE_POOL_2D = 1,
+  CONCATENATION = 2,
+  CONV_2D = 3,
+  DEPTHWISE_CONV_2D = 4,
+  DEPTH_TO_SPACE = 5,
+  DEQUANTIZE = 6,
+  EMBEDDING_LOOKUP = 7,
+  FLOOR = 8,
+  FULLY_CONNECTED = 9,
+  HASHTABLE_LOOKUP = 10,
+  L2_NORMALIZATION = 11,
+  L2_POOL_2D = 12,
+  LOCAL_RESPONSE_NORMALIZATION = 13,
+  LOGISTIC = 14,
+  LSH_PROJECTION = 15,
+  LSTM = 16,
+  MAX_POOL_2D = 17,
+  MUL = 18,
+  RELU = 19,
+  RELU1 = 20,
+  RELU6 = 21,
+  RESHAPE = 22,
+  RESIZE_BILINEAR = 23,
+  RNN = 24,
+  SOFTMAX = 25,
+  SPACE_TO_DEPTH = 26,
+  SVDF = 27,
+  TANH = 28,
+  BATCH_TO_SPACE_ND = 29,
+  DIV = 30,
+  MEAN = 31,
+  PAD = 32,
+  SPACE_TO_BATCH_ND = 33,
+  SQUEEZE = 34,
+  STRIDED_SLICE = 35,
+  SUB = 36,
+  TRANSPOSE = 37,
+  ABS = 38,
+  ARGMAX = 39,
+  ARGMIN = 40,
+  AXIS_ALIGNED_BBOX_TRANSFORM = 41,
+  BIDIRECTIONAL_SEQUENCE_LSTM = 42,
+  BIDIRECTIONAL_SEQUENCE_RNN = 43,
+  BOX_WITH_NMS_LIMIT = 44,
+  CAST = 45,
+  CHANNEL_SHUFFLE = 46,
+  DETECTION_POSTPROCESSING = 47,
+  EQUAL = 48,
+  EXP = 49,
+  EXPAND_DIMS = 50,
+  GATHER = 51,
+  GENERATE_PROPOSALS = 52,
+  GREATER = 53,
+  GREATER_EQUAL = 54,
+  GROUPED_CONV_2D = 55,
+  HEATMAP_MAX_KEYPOINT = 56,
+  INSTANCE_NORMALIZATION = 57,
+  LESS = 58,
+  LESS_EQUAL = 59,
+  LOG = 60,
+  LOGICAL_AND = 61,
+  LOGICAL_NOT = 62,
+  LOGICAL_OR = 63,
+  LOG_SOFTMAX = 64,
+  MAXIMUM = 65,
+  MINIMUM = 66,
+  NEG = 67,
+  NOT_EQUAL = 68,
+  PAD_V2 = 69,
+  POW = 70,
+  PRELU = 71,
+  QUANTIZE = 72,
+  QUANTIZED_16BIT_LSTM = 73,
+  RANDOM_MULTINOMIAL = 74,
+  REDUCE_ALL = 75,
+  REDUCE_ANY = 76,
+  REDUCE_MAX = 77,
+  REDUCE_MIN = 78,
+  REDUCE_PROD = 79,
+  REDUCE_SUM = 80,
+  ROI_ALIGN = 81,
+  ROI_POOLING = 82,
+  RSQRT = 83,
+  SELECT = 84,
+  SIN = 85,
+  SLICE = 86,
+  SPLIT = 87,
+  SQRT = 88,
+  TILE = 89,
+  TOPK_V2 = 90,
+  TRANSPOSE_CONV_2D = 91,
+  UNIDIRECTIONAL_SEQUENCE_LSTM = 92,
+  UNIDIRECTIONAL_SEQUENCE_RNN = 93,
+  RESIZE_NEAREST_NEIGHBOR = 94,
+  QUANTIZED_LSTM = 95,
+  IF = 96,
+  WHILE = 97,
+  ELU = 98,
+  HARD_SWISH = 99,
+  FILL = 100,
+  RANK = 101,
+  BATCH_MATMUL = 102,
+  PACK = 103,
+  MIRROR_PAD = 104,
+  REVERSE = 105,
+}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OutputShape.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OutputShape.aidl
index 295fde9..f733505 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OutputShape.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+parcelable OutputShape {
+  int[] dimensions;
+  boolean isSufficient;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/PerformanceInfo.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/PerformanceInfo.aidl
index 295fde9..04910f5 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/PerformanceInfo.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+parcelable PerformanceInfo {
+  float execTime;
+  float powerUsage;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Priority.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Priority.aidl
index 9c208c4..8f35709 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Priority.aidl
@@ -31,13 +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.biometrics.fingerprint;
-@Backing(type="byte") @VintfStability
-enum FingerprintSensorType {
-  UNKNOWN = 0,
-  REAR = 1,
-  UNDER_DISPLAY_ULTRASONIC = 2,
-  UNDER_DISPLAY_OPTICAL = 3,
-  POWER_BUTTON = 4,
-  HOME_BUTTON = 5,
+package android.hardware.neuralnetworks;
+@Backing(type="int") @VintfStability
+enum Priority {
+  LOW = 0,
+  MEDIUM = 1,
+  HIGH = 2,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Request.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Request.aidl
index 9c208c4..39ec7a9 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Request.aidl
@@ -31,13 +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.biometrics.fingerprint;
-@Backing(type="byte") @VintfStability
-enum FingerprintSensorType {
-  UNKNOWN = 0,
-  REAR = 1,
-  UNDER_DISPLAY_ULTRASONIC = 2,
-  UNDER_DISPLAY_OPTICAL = 3,
-  POWER_BUTTON = 4,
-  HOME_BUTTON = 5,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable Request {
+  android.hardware.neuralnetworks.RequestArgument[] inputs;
+  android.hardware.neuralnetworks.RequestArgument[] outputs;
+  android.hardware.neuralnetworks.RequestMemoryPool[] pools;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestArgument.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestArgument.aidl
index 295fde9..e3541c0 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestArgument.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+parcelable RequestArgument {
+  boolean hasNoValue;
+  android.hardware.neuralnetworks.DataLocation location;
+  int[] dimensions;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestMemoryPool.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestMemoryPool.aidl
index 295fde9..312f581 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestMemoryPool.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+union RequestMemoryPool {
+  android.hardware.neuralnetworks.Memory pool;
+  int token;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Subgraph.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Subgraph.aidl
index 9c208c4..b7d4451 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Subgraph.aidl
@@ -31,13 +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.biometrics.fingerprint;
-@Backing(type="byte") @VintfStability
-enum FingerprintSensorType {
-  UNKNOWN = 0,
-  REAR = 1,
-  UNDER_DISPLAY_ULTRASONIC = 2,
-  UNDER_DISPLAY_OPTICAL = 3,
-  POWER_BUTTON = 4,
-  HOME_BUTTON = 5,
+package android.hardware.neuralnetworks;
+@VintfStability
+parcelable Subgraph {
+  android.hardware.neuralnetworks.Operand[] operands;
+  android.hardware.neuralnetworks.Operation[] operations;
+  int[] inputIndexes;
+  int[] outputIndexes;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl
index 295fde9..02d68f9 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+parcelable SymmPerChannelQuantParams {
+  float[] scales;
+  int channelDim;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Timing.aidl
similarity index 86%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Timing.aidl
index 295fde9..bcc83cf 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Timing.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+parcelable Timing {
+  long timeOnDeviceNs;
+  long timeInDriverNs;
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IExecution.aidl
similarity index 84%
copy from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
copy to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IExecution.aidl
index 295fde9..ab5275e 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/2/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IExecution.aidl
@@ -31,12 +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.biometrics.fingerprint;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable SensorLocation {
-  int displayId;
-  int sensorLocationX;
-  int sensorLocationY;
-  int sensorRadius;
-  String display = "";
+interface IExecution {
+  android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in long deadlineNs);
+  android.hardware.neuralnetworks.FencedExecutionResult executeFenced(in ParcelFileDescriptor[] waitFor, in long deadlineNs, in long durationNs);
 }
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl
index fccb5dc..f899567 100644
--- a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl
@@ -37,6 +37,7 @@
   android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in android.hardware.neuralnetworks.Request request, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs);
   android.hardware.neuralnetworks.FencedExecutionResult executeFenced(in android.hardware.neuralnetworks.Request request, in ParcelFileDescriptor[] waitFor, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs, in long durationNs);
   android.hardware.neuralnetworks.IBurst configureExecutionBurst();
+  android.hardware.neuralnetworks.IExecution createReusableExecution(in android.hardware.neuralnetworks.Request request, in boolean measureTiming, in long loopTimeoutDurationNs);
   const long DEFAULT_LOOP_TIMEOUT_DURATION_NS = 2000000000;
   const long MAXIMUM_LOOP_TIMEOUT_DURATION_NS = 15000000000;
 }
diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/IBurst.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/IBurst.aidl
index decdc48..b089c49 100644
--- a/neuralnetworks/aidl/android/hardware/neuralnetworks/IBurst.aidl
+++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/IBurst.aidl
@@ -78,10 +78,10 @@
      *                runs from the time the driver sees the call to the executeSynchronously
      *                function to the time the driver returns from the function.
      * @param deadlineNs The time by which the execution is expected to complete. The time is
-     *                   measured in nanoseconds since epoch of the steady clock (as from
-     *                   std::chrono::steady_clock). If the execution cannot be finished by the
-     *                   deadline, the execution may be aborted. Passing -1 means the deadline is
-     *                   omitted. Other negative values are invalid.
+     *                   measured in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME,
+     *                   &ts) or ::android::base::boot_clock). If the execution cannot be finished
+     *                   by the deadline, the execution may be aborted. Passing -1 means the
+     *                   deadline is omitted. Other negative values are invalid.
      * @param loopTimeoutDurationNs The maximum amount of time in nanoseconds that should be spent
      *                              executing a {@link OperationType::WHILE} operation. If a loop
      *                              condition model does not output false within this duration, the
diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/IExecution.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/IExecution.aidl
new file mode 100644
index 0000000..3cb9c1a
--- /dev/null
+++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/IExecution.aidl
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.neuralnetworks;
+
+import android.hardware.neuralnetworks.ExecutionResult;
+import android.hardware.neuralnetworks.FencedExecutionResult;
+
+/**
+ * IExecution represents a reusable execution object with request and most other execution
+ * properties fixed. It is used to launch executions.
+ *
+ * At most one execution may occur on a reusable execution object at any given time, either by
+ * means of executeSynchronously or executeFenced.
+ *
+ * An IExecution object is used to control a set of executions on the same prepared model with
+ * the same request and properties. IExecution objects enable some optimizations:
+ * (1) An IExecution object can preserve resources between executions. For example, a driver can
+ *     map a memory object when the IExecution object is created and cache the mapping for reuse in
+ *     subsequent executions. Any cached resource can be released when the IExecution object is
+ *     destroyed.
+ * (2) Because an IExecution object may be used for at most one execution at a time, any transient
+ *     execution resources such as intermediate tensors can be allocated once when the IExecution
+ *     object is created and freed when the IExecution object is destroyed.
+ * (3) An IExecution object is created for a fixed request. This enables the implementation to apply
+ *     request-specific optimizations. For example, an implementation can avoid request validation
+ *     and conversions when the IExecution object is reused. An implementation may also choose to
+ *     specialize the dynamic tensor shapes in the IExecution object according to the request.
+ */
+@VintfStability
+interface IExecution {
+    /**
+     * Performs a synchronous execution on the reusable execution object.
+     *
+     * The execution is performed synchronously with respect to the caller. executeSynchronously
+     * must verify the inputs to the function are correct, and the usages of memory pools allocated
+     * by IDevice::allocate are valid. If there is an error, executeSynchronously must immediately
+     * return a service specific exception with the appropriate ErrorStatus value. If the inputs to
+     * the function are valid and there is no error, executeSynchronously must perform the
+     * execution, and must not return until the execution is complete.
+     *
+     * The caller must not change the content of any data object referenced by the 'request'
+     * provided in {@link IPreparedModel::createReusableExecution} (described by the
+     * {@link DataLocation} of a {@link RequestArgument}) until executeSynchronously returns.
+     * executeSynchronously must not change the content of any of the data objects corresponding to
+     * 'request' inputs.
+     *
+     * If the execution object was configured from a prepared model wherein all tensor operands have
+     * fully specified dimensions, and the inputs to the function are valid, and at execution time
+     * every operation's input operands have legal values, then the execution should complete
+     * successfully: there must be no failure unless the device itself is in a bad state.
+     *
+     * If the execution object was created with measureTiming being true and the execution is
+     * successful, the driver may report the timing information in the returning
+     * {@link ExecutionResult}. The duration runs from the time the driver sees the call to the time
+     * the driver returns from the function.
+     *
+     * executeSynchronously may be called with an optional deadline. If the execution is not able to
+     * be completed before the provided deadline, the execution may be aborted, and either
+     * {@link ErrorStatus::MISSED_DEADLINE_TRANSIENT} or {@link
+     * ErrorStatus::MISSED_DEADLINE_PERSISTENT} may be returned. The error due to an abort must be
+     * sent the same way as other errors, described above.
+     *
+     * @param deadlineNs The time by which the execution is expected to complete. The time is
+     *                   measured in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME,
+     *                   &ts) or ::android::base::boot_clock). If the execution cannot be finished
+     *                   by the deadline, the execution may be aborted. Passing -1 means the
+     *                   deadline is omitted. Other negative values are invalid.
+     * @return ExecutionResult parcelable, containing the status of the execution, output shapes
+     *     and timing information.
+     * @throws ServiceSpecificException with one of the following ErrorStatus values:
+     *     - DEVICE_UNAVAILABLE if driver is offline or busy
+     *     - GENERAL_FAILURE if there is an unspecified error
+     *     - INVALID_ARGUMENT if one of the input arguments is invalid
+     *     - MISSED_DEADLINE_* if the execution is aborted because it cannot be completed by the
+     *       deadline
+     *     - RESOURCE_EXHAUSTED_* if the task was aborted by the driver
+     */
+    ExecutionResult executeSynchronously(in long deadlineNs);
+
+    /**
+     * Launch a fenced asynchronous execution on the reusable execution object.
+     *
+     * The execution is performed asynchronously with respect to the caller. executeFenced must
+     * verify the inputs to the function are correct, and the usages of memory pools allocated by
+     * IDevice::allocate are valid. If there is an error, executeFenced must immediately return a
+     * service specific exception with the corresponding ErrorStatus. If the inputs to the function
+     * are valid and there is no error, executeFenced must dispatch an asynchronous task to perform
+     * the execution in the background, and immediately return a {@link FencedExecutionResult}
+     * containing two fields: a callback (which can be used by the client to query the duration and
+     * runtime error status) and a sync fence (which will be signaled once the execution is
+     * completed). If the task has finished before the call returns, syncFence file descriptor may
+     * be set to -1. The execution must wait for all the sync fences (if any) in waitFor to be
+     * signaled before starting the actual execution.
+     *
+     * When the asynchronous task has finished its execution, it must immediately signal the
+     * syncFence returned from the executeFenced call. After the syncFence is signaled, the task
+     * must not modify the content of any data object referenced by the 'request' provided in
+     * IPreparedModel::createReusableExecution (described by the {@link DataLocation} of a
+     * {@link RequestArgument}).
+     *
+     * executeFenced may be called with an optional deadline and an optional duration. If the
+     * execution is not able to be completed before the provided deadline or within the timeout
+     * duration (measured from when all sync fences in waitFor are signaled), whichever comes
+     * earlier, the execution may be aborted, and either
+     * {@link ErrorStatus::MISSED_DEADLINE_TRANSIENT} or {@link
+     * ErrorStatus::MISSED_DEADLINE_PERSISTENT} may be returned. The error due to an abort must be
+     * sent the same way as other errors, described above.
+     *
+     * If any of the sync fences in waitFor changes to error status after the executeFenced call
+     * succeeds, or the execution is aborted because it cannot finish before the deadline has been
+     * reached or the duration has elapsed, the driver must immediately set the returned syncFence
+     * to error status.
+     *
+     * @param waitFor A vector of sync fence file descriptors. Execution must not start until all
+     *                sync fences have been signaled.
+     * @param deadlineNs The time by which the execution is expected to complete. The time is
+     *                   measured in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME,
+     *                   &ts) or ::android::base::boot_clock). If the execution cannot be finished
+     *                   by the deadline, the execution may be aborted. Passing -1 means the
+     *                   deadline is omitted. Other negative values are invalid.
+     * @param durationNs The length of time in nanoseconds within which the execution is expected
+     *                   to complete after all sync fences in waitFor are signaled. If the
+     *                   execution cannot be finished within the duration, the execution may be
+     *                   aborted. Passing -1 means the duration is omitted. Other negative values
+     *                   are invalid.
+     * @return The FencedExecutionResult parcelable, containing IFencedExecutionCallback and the
+     *         sync fence.
+     * @throws ServiceSpecificException with one of the following ErrorStatus values:
+     *     - DEVICE_UNAVAILABLE if driver is offline or busy
+     *     - GENERAL_FAILURE if there is an unspecified error
+     *     - INVALID_ARGUMENT if one of the input arguments is invalid, including fences in error
+     *       states.
+     *     - MISSED_DEADLINE_* if the execution is aborted because it cannot be completed by the
+     *       deadline
+     *     - RESOURCE_EXHAUSTED_* if the task was aborted by the driver
+     */
+    FencedExecutionResult executeFenced(
+            in ParcelFileDescriptor[] waitFor, in long deadlineNs, in long durationNs);
+}
diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl
index 956b626..79053e5 100644
--- a/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl
+++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl
@@ -21,6 +21,7 @@
 import android.hardware.neuralnetworks.ExecutionResult;
 import android.hardware.neuralnetworks.FencedExecutionResult;
 import android.hardware.neuralnetworks.IBurst;
+import android.hardware.neuralnetworks.IExecution;
 import android.hardware.neuralnetworks.Request;
 
 /**
@@ -105,11 +106,12 @@
      * IDevice::allocate are valid. If there is an error, executeFenced must immediately return a
      * service specific exception with the corresponding ErrorStatus. If the inputs to the function
      * are valid and there is no error, executeFenced must dispatch an asynchronous task to perform
-     * the execution in the background, assign a sync fence that will be signaled once the execution
-     * is completed and immediately return a callback that can be used by the client to query the
-     * duration and runtime error status. If the task has finished before the call returns,
-     * syncFence file descriptor may be set to -1. The execution must wait for all the sync fences
-     * (if any) in waitFor to be signaled before starting the actual execution.
+     * the execution in the background, and immediately return a {@link FencedExecutionResult}
+     * containing two fields: a callback (which can be used by the client to query the duration and
+     * runtime error status) and a sync fence (which will be signaled once the execution is
+     * completed). If the task has finished before the call returns, syncFence file descriptor may
+     * be set to -1. The execution must wait for all the sync fences (if any) in waitFor to be
+     * signaled before starting the actual execution.
      *
      * When the asynchronous task has finished its execution, it must immediately signal the
      * syncFence returned from the executeFenced call. After the syncFence is signaled, the task
@@ -186,4 +188,36 @@
      *     - RESOURCE_EXHAUSTED_* if the task was aborted by the driver
      */
     IBurst configureExecutionBurst();
+
+    /**
+     * Create a reusable execution object to launch multiple executions with the same request and
+     * properties.
+     *
+     * createReusableExecution must verify the inputs to the function are correct, and the usages of
+     * memory pools allocated by IDevice::allocate are valid. If there is an error,
+     * createReusableExecution must immediately return a service specific exception with the
+     * appropriate ErrorStatus value. If the inputs to the function are valid and there is no error,
+     * createReusableExecution must construct a reusable execution.
+     *
+     * @param request The input and output information on which the prepared model is to be
+     *                executed.
+     * @param measure Specifies whether or not to measure duration of the execution.
+     * @param loopTimeoutDurationNs The maximum amount of time in nanoseconds that should be spent
+     *                              executing a {@link OperationType::WHILE} operation. If a loop
+     *                              condition model does not output false within this duration, the
+     *                              computation performed on the returned reusable execution object
+     *                              must be aborted. If -1 is provided, the maximum amount
+     *                              of time is {@link DEFAULT_LOOP_TIMEOUT_DURATION_NS}. Other
+     *                              negative values are invalid. When provided, the duration must
+     *                              not exceed {@link MAXIMUM_LOOP_TIMEOUT_DURATION_NS}.
+     * @return execution An IExecution object representing a reusable execution that has been
+     *                   specialized for a fixed request.
+     * @throws ServiceSpecificException with one of the following ErrorStatus values:
+     *     - DEVICE_UNAVAILABLE if driver is offline or busy
+     *     - GENERAL_FAILURE if there is an unspecified error
+     *     - INVALID_ARGUMENT if one of the input arguments is invalid
+     *     - RESOURCE_EXHAUSTED_* if the task was aborted by the driver
+     */
+    IExecution createReusableExecution(
+            in Request request, in boolean measureTiming, in long loopTimeoutDurationNs);
 }
diff --git a/neuralnetworks/aidl/utils/Android.bp b/neuralnetworks/aidl/utils/Android.bp
index e356104..3faa613 100644
--- a/neuralnetworks/aidl/utils/Android.bp
+++ b/neuralnetworks/aidl/utils/Android.bp
@@ -26,7 +26,14 @@
 cc_defaults {
     name: "neuralnetworks_utils_hal_aidl_defaults",
     defaults: ["neuralnetworks_utils_defaults"],
-    srcs: ["src/*"],
+    srcs: [
+        // AIDL utils that a driver may depend on.
+        "src/BufferTracker.cpp",
+        "src/Conversions.cpp",
+        "src/HalUtils.cpp",
+        "src/Utils.cpp",
+        "src/ValidateHal.cpp",
+    ],
     local_include_dirs: ["include/nnapi/hal/aidl/"],
     export_include_dirs: ["include"],
     cflags: ["-Wthread-safety"],
@@ -47,6 +54,7 @@
     },
 }
 
+// Deprecated. Remove once all modules depending on this are migrated away.
 cc_library_static {
     name: "neuralnetworks_utils_hal_aidl_v1",
     defaults: ["neuralnetworks_utils_hal_aidl_defaults"],
@@ -56,19 +64,25 @@
 }
 
 cc_library_static {
-    name: "neuralnetworks_utils_hal_aidl_v2",
-    defaults: ["neuralnetworks_utils_hal_aidl_defaults"],
-    shared_libs: [
-        "android.hardware.neuralnetworks-V2-ndk",
-    ],
-}
-
-cc_library_static {
     name: "neuralnetworks_utils_hal_aidl",
     defaults: ["neuralnetworks_utils_hal_aidl_defaults"],
-    shared_libs: [
-        "android.hardware.neuralnetworks-V3-ndk",
+    srcs: [
+        // Additional AIDL utils for the runtime.
+        "src/Assertions.cpp",
+        "src/Buffer.cpp",
+        "src/Burst.cpp",
+        "src/Callbacks.cpp",
+        "src/Device.cpp",
+        "src/Execution.cpp",
+        "src/InvalidDevice.cpp",
+        "src/PreparedModel.cpp",
+        "src/ProtectCallback.cpp",
+        "src/Service.cpp",
     ],
+    shared_libs: [
+        "android.hardware.neuralnetworks-V4-ndk",
+    ],
+    cflags: ["-DNN_AIDL_V4_OR_ABOVE"],
 }
 
 // A cc_defaults that includes the latest non-experimental AIDL utilities and other AIDL libraries
@@ -79,9 +93,10 @@
     static_libs: [
         "android.hardware.common-V2-ndk",
         "android.hardware.graphics.common-V3-ndk",
-        "android.hardware.neuralnetworks-V3-ndk",
+        "android.hardware.neuralnetworks-V4-ndk",
         "neuralnetworks_utils_hal_aidl",
     ],
+    cflags: ["-DNN_AIDL_V4_OR_ABOVE"],
 }
 
 cc_test {
diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Callbacks.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Callbacks.h
index 168264b..960be2b 100644
--- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Callbacks.h
+++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Callbacks.h
@@ -36,6 +36,8 @@
   public:
     using Data = nn::GeneralResult<nn::SharedPreparedModel>;
 
+    PreparedModelCallback(nn::Version featureLevel) : kFeatureLevel(featureLevel) {}
+
     ndk::ScopedAStatus notify(ErrorStatus status,
                               const std::shared_ptr<IPreparedModel>& preparedModel) override;
 
@@ -44,6 +46,7 @@
     Data get();
 
   private:
+    const nn::Version kFeatureLevel;
     hal::utils::TransferValue<Data> mData;
 };
 
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/include/nnapi/hal/aidl/Execution.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Execution.h
index a77ea98..14802b9 100644
--- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Execution.h
+++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Execution.h
@@ -17,6 +17,8 @@
 #ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_EXECUTION_H
 #define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_EXECUTION_H
 
+#include <aidl/android/hardware/neuralnetworks/IExecution.h>
+
 #include <nnapi/IExecution.h>
 #include <nnapi/Result.h>
 #include <nnapi/Types.h>
@@ -33,17 +35,22 @@
 
 namespace aidl::android::hardware::neuralnetworks::utils {
 
-class Execution final : public nn::IExecution, public std::enable_shared_from_this<Execution> {
+// A reusable execution implementation with a cached Request, internally it is still passing the
+// request to the driver in every computation.
+class ExecutionWithCachedRequest final
+    : public nn::IExecution,
+      public std::enable_shared_from_this<ExecutionWithCachedRequest> {
     struct PrivateConstructorTag {};
 
   public:
-    static nn::GeneralResult<std::shared_ptr<const Execution>> create(
+    static nn::GeneralResult<std::shared_ptr<const ExecutionWithCachedRequest>> create(
             std::shared_ptr<const PreparedModel> preparedModel, Request request,
             hal::utils::RequestRelocation relocation, bool measure, int64_t loopTimeoutDuration);
 
-    Execution(PrivateConstructorTag tag, std::shared_ptr<const PreparedModel> preparedModel,
-              Request request, hal::utils::RequestRelocation relocation, bool measure,
-              int64_t loopTimeoutDuration);
+    ExecutionWithCachedRequest(PrivateConstructorTag tag,
+                               std::shared_ptr<const PreparedModel> preparedModel, Request request,
+                               hal::utils::RequestRelocation relocation, bool measure,
+                               int64_t loopTimeoutDuration);
 
     nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> compute(
             const nn::OptionalTimePoint& deadline) const override;
@@ -60,6 +67,30 @@
     const int64_t kLoopTimeoutDuration;
 };
 
+// A reusable execution implementation that is backed by an actual AIDL IExecution object.
+class Execution final : public nn::IExecution, public std::enable_shared_from_this<Execution> {
+    struct PrivateConstructorTag {};
+
+  public:
+    static nn::GeneralResult<std::shared_ptr<const Execution>> create(
+            std::shared_ptr<aidl_hal::IExecution> execution,
+            hal::utils::RequestRelocation relocation);
+
+    Execution(PrivateConstructorTag tag, std::shared_ptr<aidl_hal::IExecution> execution,
+              hal::utils::RequestRelocation relocation);
+
+    nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> compute(
+            const nn::OptionalTimePoint& deadline) const override;
+
+    nn::GeneralResult<std::pair<nn::SyncFence, nn::ExecuteFencedInfoCallback>> computeFenced(
+            const std::vector<nn::SyncFence>& waitFor, const nn::OptionalTimePoint& deadline,
+            const nn::OptionalDuration& timeoutDurationAfterFence) const override;
+
+  private:
+    const std::shared_ptr<aidl_hal::IExecution> kExecution;
+    const hal::utils::RequestRelocation kRelocation;
+};
+
 }  // namespace aidl::android::hardware::neuralnetworks::utils
 
 #endif  // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_EXECUTION_H
diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/HalInterfaces.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/HalInterfaces.h
index 3fb443c..205d428 100644
--- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/HalInterfaces.h
+++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/HalInterfaces.h
@@ -61,6 +61,11 @@
 #include <aidl/android/hardware/neuralnetworks/SymmPerChannelQuantParams.h>
 #include <aidl/android/hardware/neuralnetworks/Timing.h>
 
+#ifdef NN_AIDL_V4_OR_ABOVE
+#include <aidl/android/hardware/neuralnetworks/BnExecution.h>
+#include <aidl/android/hardware/neuralnetworks/IExecution.h>
+#endif  // NN_AIDL_V4_OR_ABOVE
+
 namespace android::nn {
 
 namespace aidl_hal = ::aidl::android::hardware::neuralnetworks;
diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/PreparedModel.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/PreparedModel.h
index 4035764..24cd681 100644
--- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/PreparedModel.h
+++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/PreparedModel.h
@@ -41,10 +41,11 @@
 
   public:
     static nn::GeneralResult<std::shared_ptr<const PreparedModel>> create(
-            std::shared_ptr<aidl_hal::IPreparedModel> preparedModel);
+            std::shared_ptr<aidl_hal::IPreparedModel> preparedModel, nn::Version featureLevel);
 
     PreparedModel(PrivateConstructorTag tag,
-                  std::shared_ptr<aidl_hal::IPreparedModel> preparedModel);
+                  std::shared_ptr<aidl_hal::IPreparedModel> preparedModel,
+                  nn::Version featureLevel);
 
     nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> execute(
             const nn::Request& request, nn::MeasureTiming measure,
@@ -78,6 +79,7 @@
 
   private:
     const std::shared_ptr<aidl_hal::IPreparedModel> kPreparedModel;
+    const nn::Version kFeatureLevel;
 };
 
 }  // namespace aidl::android::hardware::neuralnetworks::utils
diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h
index a27487e..beca38b 100644
--- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h
+++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h
@@ -38,6 +38,8 @@
             return nn::kVersionFeatureLevel6;
         case 3:
             return nn::kVersionFeatureLevel7;
+        case 4:
+            return nn::kVersionFeatureLevel8;
         default:
             return std::nullopt;
     }
diff --git a/neuralnetworks/aidl/utils/src/Callbacks.cpp b/neuralnetworks/aidl/utils/src/Callbacks.cpp
index 8084970..554f3fa 100644
--- a/neuralnetworks/aidl/utils/src/Callbacks.cpp
+++ b/neuralnetworks/aidl/utils/src/Callbacks.cpp
@@ -38,16 +38,17 @@
 // nn::kVersionFeatureLevel5. On failure, this function returns with the appropriate
 // nn::GeneralError.
 nn::GeneralResult<nn::SharedPreparedModel> prepareModelCallback(
-        ErrorStatus status, const std::shared_ptr<IPreparedModel>& preparedModel) {
+        ErrorStatus status, const std::shared_ptr<IPreparedModel>& preparedModel,
+        nn::Version featureLevel) {
     HANDLE_STATUS_AIDL(status) << "model preparation failed with " << toString(status);
-    return NN_TRY(PreparedModel::create(preparedModel));
+    return NN_TRY(PreparedModel::create(preparedModel, featureLevel));
 }
 
 }  // namespace
 
 ndk::ScopedAStatus PreparedModelCallback::notify(
         ErrorStatus status, const std::shared_ptr<IPreparedModel>& preparedModel) {
-    mData.put(prepareModelCallback(status, preparedModel));
+    mData.put(prepareModelCallback(status, preparedModel, kFeatureLevel));
     return ndk::ScopedAStatus::ok();
 }
 
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/aidl/utils/src/Device.cpp b/neuralnetworks/aidl/utils/src/Device.cpp
index 5b7ec4e..bad10ed 100644
--- a/neuralnetworks/aidl/utils/src/Device.cpp
+++ b/neuralnetworks/aidl/utils/src/Device.cpp
@@ -229,7 +229,7 @@
     const auto aidlDataCache = NN_TRY(convert(dataCache));
     const auto aidlToken = NN_TRY(convert(token));
 
-    const auto cb = ndk::SharedRefBase::make<PreparedModelCallback>();
+    const auto cb = ndk::SharedRefBase::make<PreparedModelCallback>(kFeatureLevel);
     const auto scoped = kDeathHandler.protectCallback(cb.get());
 
     const auto ret = kDevice->prepareModel(aidlModel, aidlPreference, aidlPriority, aidlDeadline,
@@ -247,7 +247,7 @@
     const auto aidlDataCache = NN_TRY(convert(dataCache));
     const auto aidlToken = NN_TRY(convert(token));
 
-    const auto cb = ndk::SharedRefBase::make<PreparedModelCallback>();
+    const auto cb = ndk::SharedRefBase::make<PreparedModelCallback>(kFeatureLevel);
     const auto scoped = kDeathHandler.protectCallback(cb.get());
 
     const auto ret = kDevice->prepareModelFromCache(aidlDeadline, aidlModelCache, aidlDataCache,
diff --git a/neuralnetworks/aidl/utils/src/Execution.cpp b/neuralnetworks/aidl/utils/src/Execution.cpp
index 94edd90..c4add63 100644
--- a/neuralnetworks/aidl/utils/src/Execution.cpp
+++ b/neuralnetworks/aidl/utils/src/Execution.cpp
@@ -35,36 +35,39 @@
 
 namespace aidl::android::hardware::neuralnetworks::utils {
 
-nn::GeneralResult<std::shared_ptr<const Execution>> Execution::create(
-        std::shared_ptr<const PreparedModel> preparedModel, Request request,
-        hal::utils::RequestRelocation relocation, bool measure, int64_t loopTimeoutDuration) {
+nn::GeneralResult<std::shared_ptr<const ExecutionWithCachedRequest>>
+ExecutionWithCachedRequest::create(std::shared_ptr<const PreparedModel> preparedModel,
+                                   Request request, hal::utils::RequestRelocation relocation,
+                                   bool measure, int64_t loopTimeoutDuration) {
     if (preparedModel == nullptr) {
-        return NN_ERROR() << "aidl::utils::Execution::create must have non-null preparedModel";
+        return NN_ERROR() << "aidl::utils::ExecutionWithCachedRequest::create must have non-null "
+                             "preparedModel";
     }
 
-    return std::make_shared<const Execution>(PrivateConstructorTag{}, std::move(preparedModel),
-                                             std::move(request), std::move(relocation), measure,
-                                             loopTimeoutDuration);
+    return std::make_shared<const ExecutionWithCachedRequest>(
+            PrivateConstructorTag{}, std::move(preparedModel), std::move(request),
+            std::move(relocation), measure, loopTimeoutDuration);
 }
 
-Execution::Execution(PrivateConstructorTag /*tag*/,
-                     std::shared_ptr<const PreparedModel> preparedModel, Request request,
-                     hal::utils::RequestRelocation relocation, bool measure,
-                     int64_t loopTimeoutDuration)
+ExecutionWithCachedRequest::ExecutionWithCachedRequest(
+        PrivateConstructorTag /*tag*/, std::shared_ptr<const PreparedModel> preparedModel,
+        Request request, hal::utils::RequestRelocation relocation, bool measure,
+        int64_t loopTimeoutDuration)
     : kPreparedModel(std::move(preparedModel)),
       kRequest(std::move(request)),
       kRelocation(std::move(relocation)),
       kMeasure(measure),
       kLoopTimeoutDuration(loopTimeoutDuration) {}
 
-nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> Execution::compute(
-        const nn::OptionalTimePoint& deadline) const {
+nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>>
+ExecutionWithCachedRequest::compute(const nn::OptionalTimePoint& deadline) const {
     const auto aidlDeadline = NN_TRY(convert(deadline));
     return kPreparedModel->executeInternal(kRequest, kMeasure, aidlDeadline, kLoopTimeoutDuration,
                                            kRelocation);
 }
 
-nn::GeneralResult<std::pair<nn::SyncFence, nn::ExecuteFencedInfoCallback>> Execution::computeFenced(
+nn::GeneralResult<std::pair<nn::SyncFence, nn::ExecuteFencedInfoCallback>>
+ExecutionWithCachedRequest::computeFenced(
         const std::vector<nn::SyncFence>& waitFor, const nn::OptionalTimePoint& deadline,
         const nn::OptionalDuration& timeoutDurationAfterFence) const {
     const auto aidlWaitFor = NN_TRY(convert(waitFor));
@@ -75,4 +78,18 @@
                                                  aidlTimeoutDurationAfterFence, kRelocation);
 }
 
+nn::GeneralResult<std::shared_ptr<const Execution>> Execution::create(
+        std::shared_ptr<aidl_hal::IExecution> execution, hal::utils::RequestRelocation relocation) {
+    if (execution == nullptr) {
+        return NN_ERROR() << "aidl::utils::Execution::create must have non-null execution";
+    }
+
+    return std::make_shared<const Execution>(PrivateConstructorTag{}, std::move(execution),
+                                             std::move(relocation));
+}
+
+Execution::Execution(PrivateConstructorTag /*tag*/, std::shared_ptr<aidl_hal::IExecution> execution,
+                     hal::utils::RequestRelocation relocation)
+    : kExecution(std::move(execution)), kRelocation(std::move(relocation)) {}
+
 }  // namespace aidl::android::hardware::neuralnetworks::utils
diff --git a/neuralnetworks/aidl/utils/src/PreparedModel.cpp b/neuralnetworks/aidl/utils/src/PreparedModel.cpp
index f25c2c8..6d1de56 100644
--- a/neuralnetworks/aidl/utils/src/PreparedModel.cpp
+++ b/neuralnetworks/aidl/utils/src/PreparedModel.cpp
@@ -54,21 +54,77 @@
     return std::make_pair(NN_TRY(nn::convert(timingLaunched)), NN_TRY(nn::convert(timingFenced)));
 }
 
+nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> handleExecutionResult(
+        const ExecutionResult& result, const hal::utils::RequestRelocation& relocation) {
+    if (!result.outputSufficientSize) {
+        auto canonicalOutputShapes =
+                nn::convert(result.outputShapes).value_or(std::vector<nn::OutputShape>{});
+        return NN_ERROR(nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE, std::move(canonicalOutputShapes))
+               << "execution failed with " << nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE;
+    }
+    auto [outputShapes, timing] =
+            NN_TRY(convertExecutionResults(result.outputShapes, result.timing));
+
+    if (relocation.output) {
+        relocation.output->flush();
+    }
+    return std::make_pair(std::move(outputShapes), timing);
+}
+
+nn::GeneralResult<std::pair<nn::SyncFence, nn::ExecuteFencedInfoCallback>>
+handleFencedExecutionResult(const FencedExecutionResult& result,
+                            const hal::utils::RequestRelocation& relocation) {
+    auto resultSyncFence = nn::SyncFence::createAsSignaled();
+    if (result.syncFence.get() != -1) {
+        resultSyncFence = nn::SyncFence::create(NN_TRY(nn::convert(result.syncFence))).value();
+    }
+
+    auto callback = result.callback;
+    if (callback == nullptr) {
+        return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "callback is null";
+    }
+
+    // If computeFenced required the request memory to be moved into shared memory, block here until
+    // the fenced execution has completed and flush the memory back.
+    if (relocation.output) {
+        const auto state = resultSyncFence.syncWait({});
+        if (state != nn::SyncFence::FenceState::SIGNALED) {
+            return NN_ERROR() << "syncWait failed with " << state;
+        }
+        relocation.output->flush();
+    }
+
+    // Create callback which can be used to retrieve the execution error status and timings.
+    nn::ExecuteFencedInfoCallback resultCallback =
+            [callback]() -> nn::GeneralResult<std::pair<nn::Timing, nn::Timing>> {
+        ErrorStatus errorStatus;
+        Timing timingLaunched;
+        Timing timingFenced;
+        const auto ret = callback->getExecutionInfo(&timingLaunched, &timingFenced, &errorStatus);
+        HANDLE_ASTATUS(ret) << "fenced execution callback getExecutionInfo failed";
+        return convertFencedExecutionResults(errorStatus, timingLaunched, timingFenced);
+    };
+
+    return std::make_pair(std::move(resultSyncFence), std::move(resultCallback));
+}
+
 }  // namespace
 
 nn::GeneralResult<std::shared_ptr<const PreparedModel>> PreparedModel::create(
-        std::shared_ptr<aidl_hal::IPreparedModel> preparedModel) {
+        std::shared_ptr<aidl_hal::IPreparedModel> preparedModel, nn::Version featureLevel) {
     if (preparedModel == nullptr) {
         return NN_ERROR()
                << "aidl_hal::utils::PreparedModel::create must have non-null preparedModel";
     }
 
-    return std::make_shared<const PreparedModel>(PrivateConstructorTag{}, std::move(preparedModel));
+    return std::make_shared<const PreparedModel>(PrivateConstructorTag{}, std::move(preparedModel),
+                                                 featureLevel);
 }
 
 PreparedModel::PreparedModel(PrivateConstructorTag /*tag*/,
-                             std::shared_ptr<aidl_hal::IPreparedModel> preparedModel)
-    : kPreparedModel(std::move(preparedModel)) {}
+                             std::shared_ptr<aidl_hal::IPreparedModel> preparedModel,
+                             nn::Version featureLevel)
+    : kPreparedModel(std::move(preparedModel)), kFeatureLevel(featureLevel) {}
 
 nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> PreparedModel::execute(
         const nn::Request& request, nn::MeasureTiming measure,
@@ -101,19 +157,7 @@
     const auto ret = kPreparedModel->executeSynchronously(request, measure, deadline,
                                                           loopTimeoutDuration, &executionResult);
     HANDLE_ASTATUS(ret) << "executeSynchronously failed";
-    if (!executionResult.outputSufficientSize) {
-        auto canonicalOutputShapes =
-                nn::convert(executionResult.outputShapes).value_or(std::vector<nn::OutputShape>{});
-        return NN_ERROR(nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE, std::move(canonicalOutputShapes))
-               << "execution failed with " << nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE;
-    }
-    auto [outputShapes, timing] =
-            NN_TRY(convertExecutionResults(executionResult.outputShapes, executionResult.timing));
-
-    if (relocation.output) {
-        relocation.output->flush();
-    }
-    return std::make_pair(std::move(outputShapes), timing);
+    return handleExecutionResult(executionResult, relocation);
 }
 
 nn::GeneralResult<std::pair<nn::SyncFence, nn::ExecuteFencedInfoCallback>>
@@ -154,39 +198,7 @@
             kPreparedModel->executeFenced(request, waitFor, measure, deadline, loopTimeoutDuration,
                                           timeoutDurationAfterFence, &result);
     HANDLE_ASTATUS(ret) << "executeFenced failed";
-
-    auto resultSyncFence = nn::SyncFence::createAsSignaled();
-    if (result.syncFence.get() != -1) {
-        resultSyncFence = nn::SyncFence::create(NN_TRY(nn::convert(result.syncFence))).value();
-    }
-
-    auto callback = result.callback;
-    if (callback == nullptr) {
-        return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "callback is null";
-    }
-
-    // If executeFenced required the request memory to be moved into shared memory, block here until
-    // the fenced execution has completed and flush the memory back.
-    if (relocation.output) {
-        const auto state = resultSyncFence.syncWait({});
-        if (state != nn::SyncFence::FenceState::SIGNALED) {
-            return NN_ERROR() << "syncWait failed with " << state;
-        }
-        relocation.output->flush();
-    }
-
-    // Create callback which can be used to retrieve the execution error status and timings.
-    nn::ExecuteFencedInfoCallback resultCallback =
-            [callback]() -> nn::GeneralResult<std::pair<nn::Timing, nn::Timing>> {
-        ErrorStatus errorStatus;
-        Timing timingLaunched;
-        Timing timingFenced;
-        const auto ret = callback->getExecutionInfo(&timingLaunched, &timingFenced, &errorStatus);
-        HANDLE_ASTATUS(ret) << "fenced execution callback getExecutionInfo failed";
-        return convertFencedExecutionResults(errorStatus, timingLaunched, timingFenced);
-    };
-
-    return std::make_pair(std::move(resultSyncFence), std::move(resultCallback));
+    return handleFencedExecutionResult(result, relocation);
 }
 
 nn::GeneralResult<nn::SharedExecution> PreparedModel::createReusableExecution(
@@ -202,8 +214,18 @@
     auto aidlRequest = NN_TRY(convert(requestInShared));
     auto aidlMeasure = NN_TRY(convert(measure));
     auto aidlLoopTimeoutDuration = NN_TRY(convert(loopTimeoutDuration));
-    return Execution::create(shared_from_this(), std::move(aidlRequest), std::move(relocation),
-                             aidlMeasure, aidlLoopTimeoutDuration);
+
+    if (kFeatureLevel.level >= nn::Version::Level::FEATURE_LEVEL_8) {
+        std::shared_ptr<IExecution> execution;
+        const auto ret = kPreparedModel->createReusableExecution(
+                aidlRequest, aidlMeasure, aidlLoopTimeoutDuration, &execution);
+        HANDLE_ASTATUS(ret) << "createReusableExecution failed";
+        return Execution::create(std::move(execution), std::move(relocation));
+    }
+
+    return ExecutionWithCachedRequest::create(shared_from_this(), std::move(aidlRequest),
+                                              std::move(relocation), aidlMeasure,
+                                              aidlLoopTimeoutDuration);
 }
 
 nn::GeneralResult<nn::SharedBurst> PreparedModel::configureExecutionBurst() const {
@@ -218,4 +240,36 @@
     return resource;
 }
 
+nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> Execution::compute(
+        const nn::OptionalTimePoint& deadline) const {
+    const auto aidlDeadline = NN_TRY(convert(deadline));
+
+    if (kRelocation.input) {
+        kRelocation.input->flush();
+    }
+
+    ExecutionResult executionResult;
+    auto ret = kExecution->executeSynchronously(aidlDeadline, &executionResult);
+    HANDLE_ASTATUS(ret) << "executeSynchronously failed";
+    return handleExecutionResult(executionResult, kRelocation);
+}
+
+nn::GeneralResult<std::pair<nn::SyncFence, nn::ExecuteFencedInfoCallback>> Execution::computeFenced(
+        const std::vector<nn::SyncFence>& waitFor, const nn::OptionalTimePoint& deadline,
+        const nn::OptionalDuration& timeoutDurationAfterFence) const {
+    const auto aidlWaitFor = NN_TRY(convert(waitFor));
+    const auto aidlDeadline = NN_TRY(convert(deadline));
+    const auto aidlTimeoutDurationAfterFence = NN_TRY(convert(timeoutDurationAfterFence));
+
+    if (kRelocation.input) {
+        kRelocation.input->flush();
+    }
+
+    FencedExecutionResult result;
+    const auto ret = kExecution->executeFenced(aidlWaitFor, aidlDeadline,
+                                               aidlTimeoutDurationAfterFence, &result);
+    HANDLE_ASTATUS(ret) << "executeFenced failed";
+    return handleFencedExecutionResult(result, kRelocation);
+}
+
 }  // namespace aidl::android::hardware::neuralnetworks::utils
diff --git a/neuralnetworks/aidl/utils/test/DeviceTest.cpp b/neuralnetworks/aidl/utils/test/DeviceTest.cpp
index 0366e7d..fb13af8 100644
--- a/neuralnetworks/aidl/utils/test/DeviceTest.cpp
+++ b/neuralnetworks/aidl/utils/test/DeviceTest.cpp
@@ -17,6 +17,7 @@
 #include "MockBuffer.h"
 #include "MockDevice.h"
 #include "MockPreparedModel.h"
+#include "TestUtils.h"
 
 #include <aidl/android/hardware/neuralnetworks/BnDevice.h>
 #include <android/binder_auto_utils.h>
@@ -146,26 +147,7 @@
     return ndk::ScopedAStatus::fromStatus(STATUS_DEAD_OBJECT);
 };
 
-class DeviceTest : public ::testing::TestWithParam<nn::Version> {
-  protected:
-    const nn::Version kVersion = GetParam();
-};
-
-std::string printDeviceTest(const testing::TestParamInfo<nn::Version>& info) {
-    const nn::Version version = info.param;
-    CHECK(!version.runtimeOnlyFeatures);
-    switch (version.level) {
-        case nn::Version::Level::FEATURE_LEVEL_5:
-            return "v1";
-        case nn::Version::Level::FEATURE_LEVEL_6:
-            return "v2";
-        case nn::Version::Level::FEATURE_LEVEL_7:
-            return "v3";
-        default:
-            LOG(FATAL) << "Invalid AIDL version: " << version;
-            return "invalid";
-    }
-}
+class DeviceTest : public VersionedAidlUtilsTestBase {};
 
 }  // namespace
 
@@ -894,9 +876,6 @@
     EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
 }
 
-INSTANTIATE_TEST_SUITE_P(TestDevice, DeviceTest,
-                         ::testing::Values(nn::kVersionFeatureLevel5, nn::kVersionFeatureLevel6,
-                                           nn::kVersionFeatureLevel7),
-                         printDeviceTest);
+INSTANTIATE_VERSIONED_AIDL_UTILS_TEST(DeviceTest, kAllAidlVersions);
 
 }  // namespace aidl::android::hardware::neuralnetworks::utils
diff --git a/neuralnetworks/aidl/utils/test/ExecutionTest.cpp b/neuralnetworks/aidl/utils/test/ExecutionTest.cpp
new file mode 100644
index 0000000..8519290
--- /dev/null
+++ b/neuralnetworks/aidl/utils/test/ExecutionTest.cpp
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "MockExecution.h"
+#include "MockFencedExecutionCallback.h"
+
+#include <aidl/android/hardware/neuralnetworks/IFencedExecutionCallback.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <nnapi/IExecution.h>
+#include <nnapi/TypeUtils.h>
+#include <nnapi/Types.h>
+#include <nnapi/hal/aidl/Execution.h>
+
+#include <functional>
+#include <memory>
+
+namespace aidl::android::hardware::neuralnetworks::utils {
+namespace {
+
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::Invoke;
+using ::testing::InvokeWithoutArgs;
+using ::testing::SetArgPointee;
+
+const std::shared_ptr<IExecution> kInvalidExecution;
+constexpr auto kNoTiming = Timing{.timeOnDeviceNs = -1, .timeInDriverNs = -1};
+
+constexpr auto makeStatusOk = [] { return ndk::ScopedAStatus::ok(); };
+
+constexpr auto makeGeneralFailure = [] {
+    return ndk::ScopedAStatus::fromServiceSpecificError(
+            static_cast<int32_t>(ErrorStatus::GENERAL_FAILURE));
+};
+constexpr auto makeGeneralTransportFailure = [] {
+    return ndk::ScopedAStatus::fromStatus(STATUS_NO_MEMORY);
+};
+constexpr auto makeDeadObjectFailure = [] {
+    return ndk::ScopedAStatus::fromStatus(STATUS_DEAD_OBJECT);
+};
+
+auto makeFencedExecutionResult(const std::shared_ptr<MockFencedExecutionCallback>& callback) {
+    return [callback](const std::vector<ndk::ScopedFileDescriptor>& /*waitFor*/,
+                      int64_t /*deadline*/, int64_t /*duration*/,
+                      FencedExecutionResult* fencedExecutionResult) {
+        *fencedExecutionResult = FencedExecutionResult{.callback = callback,
+                                                       .syncFence = ndk::ScopedFileDescriptor(-1)};
+        return ndk::ScopedAStatus::ok();
+    };
+}
+
+}  // namespace
+
+TEST(ExecutionTest, invalidExecution) {
+    // run test
+    const auto result = Execution::create(kInvalidExecution, {});
+
+    // verify result
+    ASSERT_FALSE(result.has_value());
+    EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
+}
+
+TEST(ExecutionTest, executeSync) {
+    // setup call
+    const auto mockExecution = MockExecution::create();
+    const auto execution = Execution::create(mockExecution, {}).value();
+    const auto mockExecutionResult = ExecutionResult{
+            .outputSufficientSize = true,
+            .outputShapes = {},
+            .timing = kNoTiming,
+    };
+    EXPECT_CALL(*mockExecution, executeSynchronously(_, _))
+            .Times(1)
+            .WillOnce(
+                    DoAll(SetArgPointee<1>(mockExecutionResult), InvokeWithoutArgs(makeStatusOk)));
+
+    // run test
+    const auto result = execution->compute({});
+
+    // verify result
+    EXPECT_TRUE(result.has_value())
+            << "Failed with " << result.error().code << ": " << result.error().message;
+}
+
+TEST(ExecutionTest, executeSyncError) {
+    // setup test
+    const auto mockExecution = MockExecution::create();
+    const auto execution = Execution::create(mockExecution, {}).value();
+    EXPECT_CALL(*mockExecution, executeSynchronously(_, _))
+            .Times(1)
+            .WillOnce(Invoke(makeGeneralFailure));
+
+    // run test
+    const auto result = execution->compute({});
+
+    // verify result
+    ASSERT_FALSE(result.has_value());
+    EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
+}
+
+TEST(ExecutionTest, executeSyncTransportFailure) {
+    // setup test
+    const auto mockExecution = MockExecution::create();
+    const auto execution = Execution::create(mockExecution, {}).value();
+    EXPECT_CALL(*mockExecution, executeSynchronously(_, _))
+            .Times(1)
+            .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure));
+
+    // run test
+    const auto result = execution->compute({});
+
+    // verify result
+    ASSERT_FALSE(result.has_value());
+    EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
+}
+
+TEST(ExecutionTest, executeSyncDeadObject) {
+    // setup test
+    const auto mockExecution = MockExecution::create();
+    const auto execution = Execution::create(mockExecution, {}).value();
+    EXPECT_CALL(*mockExecution, executeSynchronously(_, _))
+            .Times(1)
+            .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure));
+
+    // run test
+    const auto result = execution->compute({});
+
+    // verify result
+    ASSERT_FALSE(result.has_value());
+    EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
+}
+
+TEST(ExecutionTest, executeFenced) {
+    // setup call
+    const auto mockExecution = MockExecution::create();
+    const auto execution = Execution::create(mockExecution, {}).value();
+    const auto mockCallback = MockFencedExecutionCallback::create();
+    EXPECT_CALL(*mockCallback, getExecutionInfo(_, _, _))
+            .Times(1)
+            .WillOnce(DoAll(SetArgPointee<0>(kNoTiming), SetArgPointee<1>(kNoTiming),
+                            SetArgPointee<2>(ErrorStatus::NONE), Invoke(makeStatusOk)));
+    EXPECT_CALL(*mockExecution, executeFenced(_, _, _, _))
+            .Times(1)
+            .WillOnce(Invoke(makeFencedExecutionResult(mockCallback)));
+
+    // run test
+    const auto result = execution->computeFenced({}, {}, {});
+
+    // verify result
+    ASSERT_TRUE(result.has_value())
+            << "Failed with " << result.error().code << ": " << result.error().message;
+    const auto& [syncFence, callback] = result.value();
+    EXPECT_EQ(syncFence.syncWait({}), nn::SyncFence::FenceState::SIGNALED);
+    ASSERT_NE(callback, nullptr);
+
+    // get results from callback
+    const auto callbackResult = callback();
+    ASSERT_TRUE(callbackResult.has_value()) << "Failed with " << callbackResult.error().code << ": "
+                                            << callbackResult.error().message;
+}
+
+TEST(ExecutionTest, executeFencedCallbackError) {
+    // setup call
+    const auto mockExecution = MockExecution::create();
+    const auto execution = Execution::create(mockExecution, {}).value();
+    const auto mockCallback = MockFencedExecutionCallback::create();
+    EXPECT_CALL(*mockCallback, getExecutionInfo(_, _, _))
+            .Times(1)
+            .WillOnce(Invoke(DoAll(SetArgPointee<0>(kNoTiming), SetArgPointee<1>(kNoTiming),
+                                   SetArgPointee<2>(ErrorStatus::GENERAL_FAILURE),
+                                   Invoke(makeStatusOk))));
+    EXPECT_CALL(*mockExecution, executeFenced(_, _, _, _))
+            .Times(1)
+            .WillOnce(Invoke(makeFencedExecutionResult(mockCallback)));
+
+    // run test
+    const auto result = execution->computeFenced({}, {}, {});
+
+    // verify result
+    ASSERT_TRUE(result.has_value())
+            << "Failed with " << result.error().code << ": " << result.error().message;
+    const auto& [syncFence, callback] = result.value();
+    EXPECT_NE(syncFence.syncWait({}), nn::SyncFence::FenceState::ACTIVE);
+    ASSERT_NE(callback, nullptr);
+
+    // verify callback failure
+    const auto callbackResult = callback();
+    ASSERT_FALSE(callbackResult.has_value());
+    EXPECT_EQ(callbackResult.error().code, nn::ErrorStatus::GENERAL_FAILURE);
+}
+
+TEST(ExecutionTest, executeFencedError) {
+    // setup test
+    const auto mockExecution = MockExecution::create();
+    const auto execution = Execution::create(mockExecution, {}).value();
+    EXPECT_CALL(*mockExecution, executeFenced(_, _, _, _))
+            .Times(1)
+            .WillOnce(InvokeWithoutArgs(makeGeneralFailure));
+
+    // run test
+    const auto result = execution->computeFenced({}, {}, {});
+
+    // verify result
+    ASSERT_FALSE(result.has_value());
+    EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
+}
+
+TEST(ExecutionTest, executeFencedTransportFailure) {
+    // setup test
+    const auto mockExecution = MockExecution::create();
+    const auto execution = Execution::create(mockExecution, {}).value();
+    EXPECT_CALL(*mockExecution, executeFenced(_, _, _, _))
+            .Times(1)
+            .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure));
+
+    // run test
+    const auto result = execution->computeFenced({}, {}, {});
+
+    // verify result
+    ASSERT_FALSE(result.has_value());
+    EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
+}
+
+TEST(ExecutionTest, executeFencedDeadObject) {
+    // setup test
+    const auto mockExecution = MockExecution::create();
+    const auto execution = Execution::create(mockExecution, {}).value();
+    EXPECT_CALL(*mockExecution, executeFenced(_, _, _, _))
+            .Times(1)
+            .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure));
+
+    // run test
+    const auto result = execution->computeFenced({}, {}, {});
+
+    // verify result
+    ASSERT_FALSE(result.has_value());
+    EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
+}
+
+}  // namespace aidl::android::hardware::neuralnetworks::utils
diff --git a/neuralnetworks/aidl/utils/test/MockExecution.h b/neuralnetworks/aidl/utils/test/MockExecution.h
new file mode 100644
index 0000000..216f569
--- /dev/null
+++ b/neuralnetworks/aidl/utils/test/MockExecution.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_AIDL_UTILS_TEST_MOCK_EXECUTION_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_MOCK_EXECUTION_H
+
+#include <aidl/android/hardware/neuralnetworks/BnExecution.h>
+#include <android/binder_interface_utils.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/Status.h>
+
+namespace aidl::android::hardware::neuralnetworks::utils {
+
+class MockExecution final : public BnExecution {
+  public:
+    static std::shared_ptr<MockExecution> create();
+
+    MOCK_METHOD(ndk::ScopedAStatus, executeSynchronously,
+                (int64_t deadline, ExecutionResult* executionResult), (override));
+    MOCK_METHOD(ndk::ScopedAStatus, executeFenced,
+                (const std::vector<ndk::ScopedFileDescriptor>& waitFor, int64_t deadline,
+                 int64_t duration, FencedExecutionResult* fencedExecutionResult),
+                (override));
+};
+
+inline std::shared_ptr<MockExecution> MockExecution::create() {
+    return ndk::SharedRefBase::make<MockExecution>();
+}
+
+}  // namespace aidl::android::hardware::neuralnetworks::utils
+
+#endif  // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_MOCK_EXECUTION_H
diff --git a/neuralnetworks/aidl/utils/test/MockPreparedModel.h b/neuralnetworks/aidl/utils/test/MockPreparedModel.h
index a4ae2b7..0ed9af9 100644
--- a/neuralnetworks/aidl/utils/test/MockPreparedModel.h
+++ b/neuralnetworks/aidl/utils/test/MockPreparedModel.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_MOCK_PREPARED_MODEL_H
 #define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_MOCK_PREPARED_MODEL_H
 
+#include <aidl/android/hardware/neuralnetworks/BnExecution.h>
 #include <aidl/android/hardware/neuralnetworks/BnPreparedModel.h>
 #include <android/binder_interface_utils.h>
 #include <gmock/gmock.h>
@@ -41,6 +42,10 @@
                 (override));
     MOCK_METHOD(ndk::ScopedAStatus, configureExecutionBurst, (std::shared_ptr<IBurst> * burst),
                 (override));
+    MOCK_METHOD(ndk::ScopedAStatus, createReusableExecution,
+                (const Request& request, bool measureTiming, int64_t loopTimeoutDuration,
+                 std::shared_ptr<IExecution>* execution),
+                (override));
 };
 
 inline std::shared_ptr<MockPreparedModel> MockPreparedModel::create() {
diff --git a/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp b/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp
index 8bb5c90..8cfb7c1 100644
--- a/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp
+++ b/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp
@@ -15,8 +15,10 @@
  */
 
 #include "MockBurst.h"
+#include "MockExecution.h"
 #include "MockFencedExecutionCallback.h"
 #include "MockPreparedModel.h"
+#include "TestUtils.h"
 
 #include <aidl/android/hardware/neuralnetworks/IFencedExecutionCallback.h>
 #include <gmock/gmock.h>
@@ -66,21 +68,23 @@
     };
 }
 
+class PreparedModelTest : public VersionedAidlUtilsTestBase {};
+
 }  // namespace
 
-TEST(PreparedModelTest, invalidPreparedModel) {
+TEST_P(PreparedModelTest, invalidPreparedModel) {
     // run test
-    const auto result = PreparedModel::create(kInvalidPreparedModel);
+    const auto result = PreparedModel::create(kInvalidPreparedModel, kVersion);
 
     // verify result
     ASSERT_FALSE(result.has_value());
     EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
 }
 
-TEST(PreparedModelTest, executeSync) {
+TEST_P(PreparedModelTest, executeSync) {
     // setup call
     const auto mockPreparedModel = MockPreparedModel::create();
-    const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
     const auto mockExecutionResult = ExecutionResult{
             .outputSufficientSize = true,
             .outputShapes = {},
@@ -99,10 +103,10 @@
             << "Failed with " << result.error().code << ": " << result.error().message;
 }
 
-TEST(PreparedModelTest, executeSyncError) {
+TEST_P(PreparedModelTest, executeSyncError) {
     // setup test
     const auto mockPreparedModel = MockPreparedModel::create();
-    const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
     EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _))
             .Times(1)
             .WillOnce(Invoke(makeGeneralFailure));
@@ -115,10 +119,10 @@
     EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
 }
 
-TEST(PreparedModelTest, executeSyncTransportFailure) {
+TEST_P(PreparedModelTest, executeSyncTransportFailure) {
     // setup test
     const auto mockPreparedModel = MockPreparedModel::create();
-    const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
     EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _))
             .Times(1)
             .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure));
@@ -131,10 +135,10 @@
     EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
 }
 
-TEST(PreparedModelTest, executeSyncDeadObject) {
+TEST_P(PreparedModelTest, executeSyncDeadObject) {
     // setup test
     const auto mockPreparedModel = MockPreparedModel::create();
-    const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
     EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _))
             .Times(1)
             .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure));
@@ -147,10 +151,10 @@
     EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
 }
 
-TEST(PreparedModelTest, executeFenced) {
+TEST_P(PreparedModelTest, executeFenced) {
     // setup call
     const auto mockPreparedModel = MockPreparedModel::create();
-    const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
     const auto mockCallback = MockFencedExecutionCallback::create();
     EXPECT_CALL(*mockCallback, getExecutionInfo(_, _, _))
             .Times(1)
@@ -176,10 +180,10 @@
                                             << callbackResult.error().message;
 }
 
-TEST(PreparedModelTest, executeFencedCallbackError) {
+TEST_P(PreparedModelTest, executeFencedCallbackError) {
     // setup call
     const auto mockPreparedModel = MockPreparedModel::create();
-    const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
     const auto mockCallback = MockFencedExecutionCallback::create();
     EXPECT_CALL(*mockCallback, getExecutionInfo(_, _, _))
             .Times(1)
@@ -206,10 +210,10 @@
     EXPECT_EQ(callbackResult.error().code, nn::ErrorStatus::GENERAL_FAILURE);
 }
 
-TEST(PreparedModelTest, executeFencedError) {
+TEST_P(PreparedModelTest, executeFencedError) {
     // setup test
     const auto mockPreparedModel = MockPreparedModel::create();
-    const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
     EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _))
             .Times(1)
             .WillOnce(InvokeWithoutArgs(makeGeneralFailure));
@@ -222,10 +226,10 @@
     EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
 }
 
-TEST(PreparedModelTest, executeFencedTransportFailure) {
+TEST_P(PreparedModelTest, executeFencedTransportFailure) {
     // setup test
     const auto mockPreparedModel = MockPreparedModel::create();
-    const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
     EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _))
             .Times(1)
             .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure));
@@ -238,10 +242,10 @@
     EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
 }
 
-TEST(PreparedModelTest, executeFencedDeadObject) {
+TEST_P(PreparedModelTest, executeFencedDeadObject) {
     // setup test
     const auto mockPreparedModel = MockPreparedModel::create();
-    const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
     EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _))
             .Times(1)
             .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure));
@@ -254,11 +258,13 @@
     EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
 }
 
-TEST(PreparedModelTest, reusableExecuteSync) {
+TEST_P(PreparedModelTest, reusableExecuteSync) {
+    if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return;
+
     // setup call
     const uint32_t kNumberOfComputations = 2;
     const auto mockPreparedModel = MockPreparedModel::create();
-    const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
     const auto mockExecutionResult = ExecutionResult{
             .outputSufficientSize = true,
             .outputShapes = {},
@@ -283,10 +289,12 @@
     }
 }
 
-TEST(PreparedModelTest, reusableExecuteSyncError) {
+TEST_P(PreparedModelTest, reusableExecuteSyncError) {
+    if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return;
+
     // setup test
     const auto mockPreparedModel = MockPreparedModel::create();
-    const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
     EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _))
             .Times(1)
             .WillOnce(Invoke(makeGeneralFailure));
@@ -303,10 +311,12 @@
     EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE);
 }
 
-TEST(PreparedModelTest, reusableExecuteSyncTransportFailure) {
+TEST_P(PreparedModelTest, reusableExecuteSyncTransportFailure) {
+    if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return;
+
     // setup test
     const auto mockPreparedModel = MockPreparedModel::create();
-    const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
     EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _))
             .Times(1)
             .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure));
@@ -323,10 +333,12 @@
     EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE);
 }
 
-TEST(PreparedModelTest, reusableExecuteSyncDeadObject) {
+TEST_P(PreparedModelTest, reusableExecuteSyncDeadObject) {
+    if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return;
+
     // setup test
     const auto mockPreparedModel = MockPreparedModel::create();
-    const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
     EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _))
             .Times(1)
             .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure));
@@ -343,11 +355,13 @@
     EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::DEAD_OBJECT);
 }
 
-TEST(PreparedModelTest, reusableExecuteFenced) {
+TEST_P(PreparedModelTest, reusableExecuteFenced) {
+    if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return;
+
     // setup call
     const uint32_t kNumberOfComputations = 2;
     const auto mockPreparedModel = MockPreparedModel::create();
-    const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
     const auto mockCallback = MockFencedExecutionCallback::create();
     EXPECT_CALL(*mockCallback, getExecutionInfo(_, _, _))
             .Times(kNumberOfComputations)
@@ -379,10 +393,12 @@
     }
 }
 
-TEST(PreparedModelTest, reusableExecuteFencedCallbackError) {
+TEST_P(PreparedModelTest, reusableExecuteFencedCallbackError) {
+    if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return;
+
     // setup call
     const auto mockPreparedModel = MockPreparedModel::create();
-    const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
     const auto mockCallback = MockFencedExecutionCallback::create();
     EXPECT_CALL(*mockCallback, getExecutionInfo(_, _, _))
             .Times(1)
@@ -413,10 +429,12 @@
     EXPECT_EQ(callbackResult.error().code, nn::ErrorStatus::GENERAL_FAILURE);
 }
 
-TEST(PreparedModelTest, reusableExecuteFencedError) {
+TEST_P(PreparedModelTest, reusableExecuteFencedError) {
+    if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return;
+
     // setup test
     const auto mockPreparedModel = MockPreparedModel::create();
-    const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
     EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _))
             .Times(1)
             .WillOnce(InvokeWithoutArgs(makeGeneralFailure));
@@ -433,10 +451,12 @@
     EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE);
 }
 
-TEST(PreparedModelTest, reusableExecuteFencedTransportFailure) {
+TEST_P(PreparedModelTest, reusableExecuteFencedTransportFailure) {
+    if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return;
+
     // setup test
     const auto mockPreparedModel = MockPreparedModel::create();
-    const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
     EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _))
             .Times(1)
             .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure));
@@ -453,10 +473,12 @@
     EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE);
 }
 
-TEST(PreparedModelTest, reusableExecuteFencedDeadObject) {
+TEST_P(PreparedModelTest, reusableExecuteFencedDeadObject) {
+    if (kVersion.level >= nn::Version::Level::FEATURE_LEVEL_8) return;
+
     // setup test
     const auto mockPreparedModel = MockPreparedModel::create();
-    const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
     EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _))
             .Times(1)
             .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure));
@@ -473,14 +495,14 @@
     EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::DEAD_OBJECT);
 }
 
-TEST(PreparedModelTest, configureExecutionBurst) {
+TEST_P(PreparedModelTest, configureExecutionBurst) {
     // setup test
     const auto mockPreparedModel = MockPreparedModel::create();
     const auto mockBurst = ndk::SharedRefBase::make<MockBurst>();
     EXPECT_CALL(*mockPreparedModel, configureExecutionBurst(_))
             .Times(1)
             .WillOnce(DoAll(SetArgPointee<0>(mockBurst), Invoke(makeStatusOk)));
-    const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
 
     // run test
     const auto result = preparedModel->configureExecutionBurst();
@@ -491,13 +513,13 @@
     EXPECT_NE(result.value(), nullptr);
 }
 
-TEST(PreparedModelTest, configureExecutionBurstError) {
+TEST_P(PreparedModelTest, configureExecutionBurstError) {
     // setup test
     const auto mockPreparedModel = MockPreparedModel::create();
     EXPECT_CALL(*mockPreparedModel, configureExecutionBurst(_))
             .Times(1)
             .WillOnce(InvokeWithoutArgs(makeGeneralFailure));
-    const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
 
     // run test
     const auto result = preparedModel->configureExecutionBurst();
@@ -507,13 +529,13 @@
     EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
 }
 
-TEST(PreparedModelTest, configureExecutionBurstTransportFailure) {
+TEST_P(PreparedModelTest, configureExecutionBurstTransportFailure) {
     // setup test
     const auto mockPreparedModel = MockPreparedModel::create();
     EXPECT_CALL(*mockPreparedModel, configureExecutionBurst(_))
             .Times(1)
             .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure));
-    const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
 
     // run test
     const auto result = preparedModel->configureExecutionBurst();
@@ -523,13 +545,13 @@
     EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
 }
 
-TEST(PreparedModelTest, configureExecutionBurstDeadObject) {
+TEST_P(PreparedModelTest, configureExecutionBurstDeadObject) {
     // setup test
     const auto mockPreparedModel = MockPreparedModel::create();
     EXPECT_CALL(*mockPreparedModel, configureExecutionBurst(_))
             .Times(1)
             .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure));
-    const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
 
     // run test
     const auto result = preparedModel->configureExecutionBurst();
@@ -539,10 +561,84 @@
     EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
 }
 
-TEST(PreparedModelTest, getUnderlyingResource) {
+TEST_P(PreparedModelTest, createReusableExecution) {
+    if (kVersion.level < nn::Version::Level::FEATURE_LEVEL_8) return;
+
     // setup test
     const auto mockPreparedModel = MockPreparedModel::create();
-    const auto preparedModel = PreparedModel::create(mockPreparedModel).value();
+    const auto mockExecution = ndk::SharedRefBase::make<MockExecution>();
+    EXPECT_CALL(*mockPreparedModel, createReusableExecution(_, _, _, _))
+            .Times(1)
+            .WillOnce(DoAll(SetArgPointee<3>(mockExecution), Invoke(makeStatusOk)));
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
+
+    // run test
+    const auto result = preparedModel->createReusableExecution({}, {}, {});
+
+    // verify result
+    ASSERT_TRUE(result.has_value())
+            << "Failed with " << result.error().code << ": " << result.error().message;
+    EXPECT_NE(result.value(), nullptr);
+}
+
+TEST_P(PreparedModelTest, createReusableExecutionError) {
+    if (kVersion.level < nn::Version::Level::FEATURE_LEVEL_8) return;
+
+    // setup test
+    const auto mockPreparedModel = MockPreparedModel::create();
+    EXPECT_CALL(*mockPreparedModel, createReusableExecution(_, _, _, _))
+            .Times(1)
+            .WillOnce(InvokeWithoutArgs(makeGeneralFailure));
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
+
+    // run test
+    const auto result = preparedModel->createReusableExecution({}, {}, {});
+
+    // verify result
+    ASSERT_FALSE(result.has_value());
+    EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
+}
+
+TEST_P(PreparedModelTest, createReusableExecutionTransportFailure) {
+    if (kVersion.level < nn::Version::Level::FEATURE_LEVEL_8) return;
+
+    // setup test
+    const auto mockPreparedModel = MockPreparedModel::create();
+    EXPECT_CALL(*mockPreparedModel, createReusableExecution(_, _, _, _))
+            .Times(1)
+            .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure));
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
+
+    // run test
+    const auto result = preparedModel->createReusableExecution({}, {}, {});
+
+    // verify result
+    ASSERT_FALSE(result.has_value());
+    EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE);
+}
+
+TEST_P(PreparedModelTest, createReusableExecutionDeadObject) {
+    if (kVersion.level < nn::Version::Level::FEATURE_LEVEL_8) return;
+
+    // setup test
+    const auto mockPreparedModel = MockPreparedModel::create();
+    EXPECT_CALL(*mockPreparedModel, createReusableExecution(_, _, _, _))
+            .Times(1)
+            .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure));
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
+
+    // run test
+    const auto result = preparedModel->createReusableExecution({}, {}, {});
+
+    // verify result
+    ASSERT_FALSE(result.has_value());
+    EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
+}
+
+TEST_P(PreparedModelTest, getUnderlyingResource) {
+    // setup test
+    const auto mockPreparedModel = MockPreparedModel::create();
+    const auto preparedModel = PreparedModel::create(mockPreparedModel, kVersion).value();
 
     // run test
     const auto resource = preparedModel->getUnderlyingResource();
@@ -554,4 +650,6 @@
     EXPECT_EQ(maybeMock->get(), mockPreparedModel.get());
 }
 
+INSTANTIATE_VERSIONED_AIDL_UTILS_TEST(PreparedModelTest, kAllAidlVersions);
+
 }  // namespace aidl::android::hardware::neuralnetworks::utils
diff --git a/neuralnetworks/aidl/utils/test/TestUtils.cpp b/neuralnetworks/aidl/utils/test/TestUtils.cpp
new file mode 100644
index 0000000..9abec88
--- /dev/null
+++ b/neuralnetworks/aidl/utils/test/TestUtils.cpp
@@ -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.
+ */
+
+#include "TestUtils.h"
+
+#include <android-base/logging.h>
+#include <gtest/gtest.h>
+#include <nnapi/TypeUtils.h>
+#include <nnapi/Types.h>
+#include <nnapi/hal/CommonUtils.h>
+#include <string>
+
+namespace aidl::android::hardware::neuralnetworks::utils {
+
+std::string printTestVersion(const testing::TestParamInfo<nn::Version>& info) {
+    switch (info.param.level) {
+        case nn::Version::Level::FEATURE_LEVEL_5:
+            return "v1";
+        case nn::Version::Level::FEATURE_LEVEL_6:
+            return "v2";
+        case nn::Version::Level::FEATURE_LEVEL_7:
+            return "v3";
+        case nn::Version::Level::FEATURE_LEVEL_8:
+            return "v4";
+        default:
+            LOG(FATAL) << "Invalid AIDL version: " << info.param;
+            return "invalid";
+    }
+}
+
+}  // namespace aidl::android::hardware::neuralnetworks::utils
diff --git a/neuralnetworks/aidl/utils/test/TestUtils.h b/neuralnetworks/aidl/utils/test/TestUtils.h
new file mode 100644
index 0000000..23f734a
--- /dev/null
+++ b/neuralnetworks/aidl/utils/test/TestUtils.h
@@ -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.
+ */
+
+#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_TEST_UTILS_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_TEST_UTILS_H
+
+#include <gtest/gtest.h>
+#include <nnapi/Types.h>
+#include <nnapi/hal/CommonUtils.h>
+#include <string>
+
+namespace aidl::android::hardware::neuralnetworks::utils {
+
+class VersionedAidlUtilsTestBase : public ::testing::TestWithParam<nn::Version> {
+  protected:
+    const nn::Version kVersion = GetParam();
+};
+
+std::string printTestVersion(const testing::TestParamInfo<nn::Version>& info);
+
+inline const auto kAllAidlVersions =
+        ::testing::Values(nn::kVersionFeatureLevel5, nn::kVersionFeatureLevel6,
+                          nn::kVersionFeatureLevel7, nn::kVersionFeatureLevel8);
+
+#define INSTANTIATE_VERSIONED_AIDL_UTILS_TEST(TestSuite, versions) \
+    INSTANTIATE_TEST_SUITE_P(Versioned, TestSuite, versions, printTestVersion)
+
+}  // namespace aidl::android::hardware::neuralnetworks::utils
+
+#endif  // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_TEST_TEST_UTILS_H
diff --git a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp
index cd5475c..b3e9c63 100644
--- a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp
+++ b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp
@@ -208,6 +208,11 @@
         return ndk::ScopedAStatus::fromServiceSpecificError(
                 static_cast<int32_t>(ErrorStatus::GENERAL_FAILURE));
     }
+    ndk::ScopedAStatus createReusableExecution(const aidl_hal::Request&, bool, int64_t,
+                                               std::shared_ptr<aidl_hal::IExecution>*) override {
+        return ndk::ScopedAStatus::fromServiceSpecificError(
+                static_cast<int32_t>(ErrorStatus::GENERAL_FAILURE));
+    }
 };
 
 template <typename... Args>
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/Execution.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Execution.h
new file mode 100644
index 0000000..6a9ac57
--- /dev/null
+++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Execution.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_EXECUTION_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_EXECUTION_H
+
+#include "nnapi/hal/aidl/Adapter.h"
+
+#include <aidl/android/hardware/neuralnetworks/BnExecution.h>
+#include <aidl/android/hardware/neuralnetworks/ExecutionResult.h>
+#include <aidl/android/hardware/neuralnetworks/FencedExecutionResult.h>
+#include <aidl/android/hardware/neuralnetworks/IExecution.h>
+#include <aidl/android/hardware/neuralnetworks/Request.h>
+#include <android/binder_auto_utils.h>
+#include <nnapi/IExecution.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::IExecution to BnExecution.
+class Execution : public BnExecution {
+  public:
+    explicit Execution(::android::nn::SharedExecution execution);
+
+    ndk::ScopedAStatus executeSynchronously(int64_t deadlineNs,
+                                            ExecutionResult* executionResult) override;
+    ndk::ScopedAStatus executeFenced(const std::vector<ndk::ScopedFileDescriptor>& waitFor,
+                                     int64_t deadlineNs, int64_t durationNs,
+                                     FencedExecutionResult* fencedExecutionResult) override;
+
+  protected:
+    const ::android::nn::SharedExecution kExecution;
+};
+
+}  // namespace aidl::android::hardware::neuralnetworks::adapter
+
+#endif  // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_EXECUTION_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..f92b0bc
--- /dev/null
+++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/PreparedModel.h
@@ -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.
+ */
+
+#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/IExecution.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;
+    ndk::ScopedAStatus createReusableExecution(const Request& request, bool measureTiming,
+                                               int64_t loopTimeoutDurationNs,
+                                               std::shared_ptr<IExecution>* execution) 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..5cab62c
--- /dev/null
+++ b/neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp
@@ -0,0 +1,324 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "Execution.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/IExecution.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)};
+}
+
+nn::GeneralResult<nn::SharedExecution> createReusableExecution(
+        const nn::IPreparedModel& preparedModel, const Request& request, bool measureTiming,
+        int64_t loopTimeoutDurationNs) {
+    const auto nnRequest = NN_TRY(convertInput(request));
+    const auto nnMeasureTiming = measureTiming ? nn::MeasureTiming::YES : nn::MeasureTiming::NO;
+    const auto nnLoopTimeoutDuration = NN_TRY(makeOptionalDuration(loopTimeoutDurationNs));
+    return preparedModel.createReusableExecution(nnRequest, nnMeasureTiming, nnLoopTimeoutDuration);
+}
+
+nn::ExecutionResult<ExecutionResult> executeSynchronously(const nn::IExecution& execution,
+                                                          int64_t deadlineNs) {
+    const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs));
+
+    const auto result = execution.compute(nnDeadline);
+
+    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::IExecution& execution, const std::vector<ndk::ScopedFileDescriptor>& waitFor,
+        int64_t deadlineNs, int64_t durationNs) {
+    const auto nnWaitFor = NN_TRY(convertSyncFences(waitFor));
+    const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs));
+    const auto nnDuration = NN_TRY(makeOptionalDuration(durationNs));
+
+    auto [syncFence, executeFencedInfoCallback] =
+            NN_TRY(execution.computeFenced(nnWaitFor, nnDeadline, 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;
+}
+
+ndk::ScopedAStatus PreparedModel::createReusableExecution(const Request& request,
+                                                          bool measureTiming,
+                                                          int64_t loopTimeoutDurationNs,
+                                                          std::shared_ptr<IExecution>* execution) {
+    auto result = adapter::createReusableExecution(*kPreparedModel, request, measureTiming,
+                                                   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());
+    }
+    *execution = ndk::SharedRefBase::make<Execution>(std::move(result).value());
+    return ndk::ScopedAStatus::ok();
+}
+
+Execution::Execution(nn::SharedExecution execution) : kExecution(std::move(execution)) {
+    CHECK(kExecution != nullptr);
+}
+
+ndk::ScopedAStatus Execution::executeSynchronously(int64_t deadlineNs,
+                                                   ExecutionResult* executionResult) {
+    auto result = adapter::executeSynchronously(*kExecution, deadlineNs);
+    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 Execution::executeFenced(const std::vector<ndk::ScopedFileDescriptor>& waitFor,
+                                            int64_t deadlineNs, int64_t durationNs,
+                                            FencedExecutionResult* executionResult) {
+    auto result = adapter::executeFenced(*kExecution, waitFor, deadlineNs, 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();
+}
+
+}  // 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/radio/1.5/vts/functional/radio_hidl_hal_api.cpp b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
index d108951..152858f 100644
--- a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
@@ -1271,8 +1271,12 @@
     EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
 
     int32_t firstApiLevel = android::base::GetIntProperty<int32_t>("ro.product.first_api_level", 0);
+    int32_t boardApiLevel = android::base::GetIntProperty<int32_t>("ro.board.first_api_level", 0);
     // Allow devices shipping with Radio::1_5 and Android 11 to not support barring info.
-    if (firstApiLevel > 0 && firstApiLevel <= 30) {
+    // b/212384410 Some GRF targets lauched with S release but with vendor R release
+    // do not support getBarringInfo API. Allow these devices to not support barring info.
+    if ((firstApiLevel > 0 && firstApiLevel <= 30) ||
+        (boardApiLevel > 0 && boardApiLevel <= 30)) {
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
                                      {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
         // Early exit for devices that don't support barring info.
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl
index 6982d40..980b042 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl
@@ -47,4 +47,7 @@
   EMERGENCY = 512,
   MCX = 1024,
   XCAP = 2048,
+  VSIM = 4096,
+  BIP = 8192,
+  ENTERPRISE = 16384,
 }
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 b0cc1eb..0ffa1f7 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
@@ -38,4 +38,5 @@
   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 android.hardware.radio.data.DataProfileInfo dataProfileInfo);
+  oneway void slicingConfigChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.SlicingConfig slicingConfig);
 }
diff --git a/radio/aidl/android/hardware/radio/data/ApnTypes.aidl b/radio/aidl/android/hardware/radio/data/ApnTypes.aidl
index e780d8e..ae103fc 100644
--- a/radio/aidl/android/hardware/radio/data/ApnTypes.aidl
+++ b/radio/aidl/android/hardware/radio/data/ApnTypes.aidl
@@ -73,4 +73,16 @@
      * APN type for XCAP
      */
     XCAP = 1 << 11,
+    /**
+     * APN type for VSIM.
+     */
+    VSIM = 1 << 12,
+    /**
+     * APN type for BIP.
+     */
+    BIP = 1 << 13,
+    /**
+     * APN type for ENTERPRISE
+     */
+    ENTERPRISE = 1 << 14
 }
diff --git a/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl b/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl
index 1772c88..938c695 100644
--- a/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl
+++ b/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl
@@ -21,6 +21,7 @@
 import android.hardware.radio.data.KeepaliveStatus;
 import android.hardware.radio.data.PcoDataInfo;
 import android.hardware.radio.data.SetupDataCallResult;
+import android.hardware.radio.data.SlicingConfig;
 
 /**
  * Interface declaring unsolicited radio indications for data APIs.
@@ -72,4 +73,17 @@
      * @param dataProfileInfo Data profile info.
      */
     void unthrottleApn(in RadioIndicationType type, in DataProfileInfo dataProfileInfo);
+
+    /**
+     * Indicates the current slicing configuration including URSP rules and NSSAIs
+     * (configured, allowed and rejected). URSP stands for UE route selection policy and is defined
+     * in 3GPP TS 24.526 Section 4.2. An NSSAI is a collection of network slices. Each network slice
+     * is identified by an S-NSSAI and is represented by the struct SliceInfo. NSSAI and S-NSSAI
+     * are defined in 3GPP TS 24.501.
+     *
+     * @param type Type of radio indication
+     * @param slicingConfig Current slicing configuration
+     *
+     */
+    void slicingConfigChanged(in RadioIndicationType type, in SlicingConfig slicingConfig);
 }
diff --git a/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp b/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp
index 1d367d2..602bb39 100644
--- a/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp
+++ b/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp
@@ -85,4 +85,11 @@
     return {};
 }
 
+Return<void> RadioIndication::slicingConfigChanged(V1_0::RadioIndicationType type,
+                                                   const V1_6::SlicingConfig& slicingConfig) {
+    LOG_CALL << type;
+    dataCb()->slicingConfigChanged(toAidl(type), toAidl(slicingConfig));
+    return {};
+}
+
 }  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h
index c668af5..6cfd59c 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h
@@ -186,6 +186,8 @@
             V1_0::RadioIndicationType type,
             const hidl_vec<V1_6::SetupDataCallResult>& dcList) override;
     Return<void> unthrottleApn(V1_0::RadioIndicationType type, const hidl_string& apn) override;
+    Return<void> slicingConfigChanged(V1_0::RadioIndicationType type,
+                                      const V1_6::SlicingConfig& slicingConfig);
     Return<void> currentLinkCapacityEstimate_1_6(V1_0::RadioIndicationType type,
                                                  const V1_6::LinkCapacityEstimate& lce) override;
     Return<void> currentSignalStrength_1_6(V1_0::RadioIndicationType type,
diff --git a/radio/aidl/vts/radio_data_indication.cpp b/radio/aidl/vts/radio_data_indication.cpp
index 4d3c539..61e079e 100644
--- a/radio/aidl/vts/radio_data_indication.cpp
+++ b/radio/aidl/vts/radio_data_indication.cpp
@@ -37,3 +37,8 @@
                                                       const DataProfileInfo& /*dataProfileInfo*/) {
     return ndk::ScopedAStatus::ok();
 }
+
+ndk::ScopedAStatus RadioDataIndication::slicingConfigChanged(
+        RadioIndicationType /*type*/, const SlicingConfig& /*slicingConfig*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_data_utils.h b/radio/aidl/vts/radio_data_utils.h
index 50c7878..fb91ef6 100644
--- a/radio/aidl/vts/radio_data_utils.h
+++ b/radio/aidl/vts/radio_data_utils.h
@@ -95,6 +95,8 @@
 
     virtual ndk::ScopedAStatus unthrottleApn(RadioIndicationType type,
                                              const DataProfileInfo& dataProfile) override;
+    virtual ndk::ScopedAStatus slicingConfigChanged(RadioIndicationType type,
+                                                    const SlicingConfig& slicingConfig) override;
 };
 
 // The main test class for Radio AIDL Data.
diff --git a/security/dice/aidl/Android.bp b/security/dice/aidl/Android.bp
index af9dd33..01bc91e 100644
--- a/security/dice/aidl/Android.bp
+++ b/security/dice/aidl/Android.bp
@@ -41,6 +41,10 @@
         },
         rust: {
             enabled: true,
+            apex_available: [
+                "//apex_available:platform",
+                "com.android.compos",
+            ],
         },
     },
     //     versions: ["1"],
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/BccHandover.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/BccHandover.aidl
index ab50c36..8baca94 100644
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/BccHandover.aidl
+++ b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/BccHandover.aidl
@@ -35,7 +35,7 @@
 /* @hide */
 @RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
 parcelable BccHandover {
-  byte[] cdiAttest;
-  byte[] cdiSeal;
+  byte[32] cdiAttest;
+  byte[32] cdiSeal;
   android.hardware.security.dice.Bcc bcc;
 }
diff --git a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/InputValues.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/InputValues.aidl
index 79583fb..e43c429 100644
--- a/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/InputValues.aidl
+++ b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/InputValues.aidl
@@ -35,10 +35,10 @@
 /* @hide */
 @RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
 parcelable InputValues {
-  byte[] codeHash;
+  byte[64] codeHash;
   android.hardware.security.dice.Config config;
-  byte[] authorityHash;
+  byte[64] authorityHash;
   @nullable byte[] authorityDescriptor;
   android.hardware.security.dice.Mode mode = android.hardware.security.dice.Mode.NOT_INITIALIZED;
-  byte[] hidden;
+  byte[64] hidden;
 }
diff --git a/security/dice/aidl/android/hardware/security/dice/BccHandover.aidl b/security/dice/aidl/android/hardware/security/dice/BccHandover.aidl
index d522cef..6ca862c 100644
--- a/security/dice/aidl/android/hardware/security/dice/BccHandover.aidl
+++ b/security/dice/aidl/android/hardware/security/dice/BccHandover.aidl
@@ -27,13 +27,13 @@
 @RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
 parcelable BccHandover {
     /**
-     * CDI_attest. Must a exactly 32 bytes of data.
+     * CDI_attest. Must be exactly 32 bytes of data.
      */
-    byte[] cdiAttest;
+    byte[32] cdiAttest;
     /**
-     * CDI_seal. Must a exactly 32 bytes of data.
+     * CDI_seal. Must be exactly 32 bytes of data.
      */
-    byte[] cdiSeal;
+    byte[32] cdiSeal;
     /**
      * CBOR encoded BCC.
      *
diff --git a/security/dice/aidl/android/hardware/security/dice/InputValues.aidl b/security/dice/aidl/android/hardware/security/dice/InputValues.aidl
index e44ef22..711d523 100644
--- a/security/dice/aidl/android/hardware/security/dice/InputValues.aidl
+++ b/security/dice/aidl/android/hardware/security/dice/InputValues.aidl
@@ -34,7 +34,7 @@
     /**
      * The target code hash. Must be exactly 64 bytes.
      */
-    byte[] codeHash;
+    byte[64] codeHash;
     /**
      * The configuration data.
      */
@@ -42,7 +42,7 @@
     /**
      * The authority hash. Must be exactly 64 bytes. Must be all zero if unused.
      */
-    byte[] authorityHash;
+    byte[64] authorityHash;
     /**
      * Optional free form authorityDescriptor.
      */
@@ -54,5 +54,5 @@
     /**
      * Optional hidden values. Must be exactly 64 bytes. Must be all zero if unused.
      */
-    byte[] hidden;
+    byte[64] hidden;
 }
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
index ce83044..ca89555 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
@@ -227,7 +227,8 @@
      * o PaddingMode::RSA_PSS.  For PSS-padded signature operations, the PSS salt length must match
      *   the size of the PSS digest selected.  The digest specified with Tag::DIGEST in params
      *   on begin() must be used as the PSS digest algorithm, MGF1 must be used as the mask
-     *   generation function and SHA1 must be used as the MGF1 digest algorithm.
+     *   generation function and the digest specified with Tag:DIGEST in params on begin() must also
+     *   be used as the MGF1 digest algorithm.
      *
      * -- ECDSA keys --
      *
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 02462fc..374f2da 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -812,6 +812,7 @@
         if (padding == PaddingMode::RSA_PSS) {
             EXPECT_GT(EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING), 0);
             EXPECT_GT(EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, EVP_MD_size(md)), 0);
+            EXPECT_GT(EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, md), 0);
         }
 
         ASSERT_EQ(1, EVP_DigestVerifyUpdate(&digest_ctx,
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index dd3719b..340010f 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -4608,8 +4608,10 @@
     auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
 
     // Try various message lengths; all should work.
-    for (size_t i = 0; i < 32; ++i) {
-        string message(i, 'a');
+    for (size_t i = 0; i <= 48; i++) {
+        SCOPED_TRACE(testing::Message() << "i = " << i);
+        // Edge case: '\t' (0x09) is also a valid PKCS7 padding character.
+        string message(i, '\t');
         string ciphertext = EncryptMessage(message, params);
         EXPECT_EQ(i + 16 - (i % 16), ciphertext.size());
         string plaintext = DecryptMessage(ciphertext, params);
@@ -4633,7 +4635,7 @@
     auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
 
     // Try various message lengths; all should fail
-    for (size_t i = 0; i < 32; ++i) {
+    for (size_t i = 0; i <= 48; i++) {
         string message(i, 'a');
         EXPECT_EQ(ErrorCode::INCOMPATIBLE_PADDING_MODE, Begin(KeyPurpose::ENCRYPT, params));
     }
@@ -5818,8 +5820,8 @@
 
     ASSERT_GT(key_blob_.size(), 0U);
 
-    // Two-block message.
-    string message = "1234567890123456";
+    // Four-block message.
+    string message = "12345678901234561234567890123456";
     vector<uint8_t> iv1;
     string ciphertext1 = EncryptMessage(message, BlockMode::CBC, PaddingMode::NONE, &iv1);
     EXPECT_EQ(message.size(), ciphertext1.size());
@@ -5979,8 +5981,10 @@
                                                  .Padding(PaddingMode::PKCS7)));
 
     // Try various message lengths; all should work.
-    for (size_t i = 0; i < 32; ++i) {
-        string message(i, 'a');
+    for (size_t i = 0; i <= 32; i++) {
+        SCOPED_TRACE(testing::Message() << "i = " << i);
+        // Edge case: '\t' (0x09) is also a valid PKCS7 padding character, albeit not for 3DES.
+        string message(i, '\t');
         vector<uint8_t> iv;
         string ciphertext = EncryptMessage(message, BlockMode::CBC, PaddingMode::PKCS7, &iv);
         EXPECT_EQ(i + 8 - (i % 8), ciphertext.size());
@@ -6002,7 +6006,7 @@
                                                  .Padding(PaddingMode::NONE)));
 
     // Try various message lengths; all should fail.
-    for (size_t i = 0; i < 32; ++i) {
+    for (size_t i = 0; i <= 32; i++) {
         auto begin_params =
                 AuthorizationSetBuilder().BlockMode(BlockMode::CBC).Padding(PaddingMode::PKCS7);
         EXPECT_EQ(ErrorCode::INCOMPATIBLE_PADDING_MODE, Begin(KeyPurpose::ENCRYPT, begin_params));
@@ -6033,6 +6037,7 @@
                                 .Authorization(TAG_NONCE, iv);
 
     for (size_t i = 0; i < kMaxPaddingCorruptionRetries; ++i) {
+        SCOPED_TRACE(testing::Message() << "i = " << i);
         ++ciphertext[ciphertext.size() / 2];
         EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
         string plaintext;
diff --git a/sensors/aidl/Android.bp b/sensors/aidl/Android.bp
index fd1ac44..92b7ad0 100644
--- a/sensors/aidl/Android.bp
+++ b/sensors/aidl/Android.bp
@@ -1,4 +1,11 @@
-// This is the expected build file, but it may not be right in all cases
+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.sensors",
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
index 186b2be..c92ab1a 100644
--- 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
@@ -51,6 +51,7 @@
     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;
@@ -75,6 +76,16 @@
       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;
diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorType.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorType.aidl
index 4f3b5b2..3d7ab45 100644
--- a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorType.aidl
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorType.aidl
@@ -70,5 +70,6 @@
   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/Event.aidl b/sensors/aidl/android/hardware/sensors/Event.aidl
index 6ef9acb..fd6a8cc 100644
--- a/sensors/aidl/android/hardware/sensors/Event.aidl
+++ b/sensors/aidl/android/hardware/sensors/Event.aidl
@@ -127,6 +127,11 @@
          */
         Data data;
 
+        /**
+         * SensorType::HEAD_TRACKER
+         */
+        HeadTracker headTracker;
+
         @FixedSize
         @VintfStability
         parcelable Vec4 {
@@ -156,6 +161,46 @@
             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 {
diff --git a/sensors/aidl/android/hardware/sensors/SensorType.aidl b/sensors/aidl/android/hardware/sensors/SensorType.aidl
index 95c7a6a..01e6bee 100644
--- a/sensors/aidl/android/hardware/sensors/SensorType.aidl
+++ b/sensors/aidl/android/hardware/sensors/SensorType.aidl
@@ -142,6 +142,10 @@
      * 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.
      */
@@ -634,6 +638,35 @@
     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.
      */
diff --git a/sensors/aidl/default/multihal/Android.bp b/sensors/aidl/default/multihal/Android.bp
new file mode 100644
index 0000000..eee1062
--- /dev/null
+++ b/sensors/aidl/default/multihal/Android.bp
@@ -0,0 +1,58 @@
+//
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // 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: "android.hardware.sensors@aidl-multihal",
+    vendor: true,
+    header_libs: [
+        "android.hardware.sensors@2.X-multihal.header",
+        "android.hardware.sensors@2.X-shared-utils",
+    ],
+    shared_libs: [
+        "libfmq",
+        "libpower",
+        "libbase",
+        "libbinder_ndk",
+        "android.hardware.sensors@1.0",
+        "android.hardware.sensors@2.0",
+        "android.hardware.sensors@2.1",
+        "android.hardware.sensors-V1-ndk",
+    ],
+    export_include_dirs: ["include"],
+    srcs: [
+        "HalProxyAidl.cpp",
+        "ConvertUtils.cpp",
+    ],
+    visibility: [
+        ":__subpackages__",
+        "//hardware/interfaces/sensors/aidl/multihal:__subpackages__",
+        "//hardware/interfaces/tests/extension/sensors:__subpackages__",
+    ],
+    static_libs: [
+        "android.hardware.sensors@1.0-convert",
+        "android.hardware.sensors@2.X-multihal",
+        "libaidlcommonsupport",
+    ],
+}
diff --git a/sensors/aidl/default/multihal/ConvertUtils.cpp b/sensors/aidl/default/multihal/ConvertUtils.cpp
new file mode 100644
index 0000000..509bbb0
--- /dev/null
+++ b/sensors/aidl/default/multihal/ConvertUtils.cpp
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "ConvertUtils.h"
+#include <android-base/logging.h>
+#include <log/log.h>
+
+using AidlSensorInfo = ::aidl::android::hardware::sensors::SensorInfo;
+using AidlSensorType = ::aidl::android::hardware::sensors::SensorType;
+using AidlEvent = ::aidl::android::hardware::sensors::Event;
+using AidlSensorStatus = ::aidl::android::hardware::sensors::SensorStatus;
+using ::aidl::android::hardware::sensors::AdditionalInfo;
+using ::aidl::android::hardware::sensors::DynamicSensorInfo;
+using ::android::hardware::sensors::V1_0::MetaDataEventType;
+using V1_0SensorStatus = ::android::hardware::sensors::V1_0::SensorStatus;
+using ::android::hardware::sensors::V1_0::AdditionalInfoType;
+using V2_1SensorInfo = ::android::hardware::sensors::V2_1::SensorInfo;
+using V2_1Event = ::android::hardware::sensors::V2_1::Event;
+using V2_1SensorType = ::android::hardware::sensors::V2_1::SensorType;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace implementation {
+
+AidlSensorInfo convertSensorInfo(const V2_1SensorInfo& sensorInfo) {
+    AidlSensorInfo aidlSensorInfo;
+    aidlSensorInfo.sensorHandle = sensorInfo.sensorHandle;
+    aidlSensorInfo.name = sensorInfo.name;
+    aidlSensorInfo.vendor = sensorInfo.vendor;
+    aidlSensorInfo.version = sensorInfo.version;
+    aidlSensorInfo.type = (AidlSensorType)sensorInfo.type;
+    aidlSensorInfo.typeAsString = sensorInfo.typeAsString;
+    aidlSensorInfo.maxRange = sensorInfo.maxRange;
+    aidlSensorInfo.resolution = sensorInfo.resolution;
+    aidlSensorInfo.power = sensorInfo.power;
+    aidlSensorInfo.minDelayUs = sensorInfo.minDelay;
+    aidlSensorInfo.fifoReservedEventCount = sensorInfo.fifoReservedEventCount;
+    aidlSensorInfo.fifoMaxEventCount = sensorInfo.fifoMaxEventCount;
+    aidlSensorInfo.requiredPermission = sensorInfo.requiredPermission;
+    aidlSensorInfo.maxDelayUs = sensorInfo.maxDelay;
+    aidlSensorInfo.flags = sensorInfo.flags;
+    return aidlSensorInfo;
+}
+
+void convertToHidlEvent(const AidlEvent& aidlEvent, V2_1Event* hidlEvent) {
+    hidlEvent->timestamp = aidlEvent.timestamp;
+    hidlEvent->sensorHandle = aidlEvent.sensorHandle;
+    hidlEvent->sensorType = (V2_1SensorType)aidlEvent.sensorType;
+
+    switch (aidlEvent.sensorType) {
+        case AidlSensorType::META_DATA:
+            hidlEvent->u.meta.what =
+                    (MetaDataEventType)aidlEvent.payload.get<Event::EventPayload::meta>().what;
+            break;
+        case AidlSensorType::ACCELEROMETER:
+        case AidlSensorType::MAGNETIC_FIELD:
+        case AidlSensorType::ORIENTATION:
+        case AidlSensorType::GYROSCOPE:
+        case AidlSensorType::GRAVITY:
+        case AidlSensorType::LINEAR_ACCELERATION:
+            hidlEvent->u.vec3.x = aidlEvent.payload.get<Event::EventPayload::vec3>().x;
+            hidlEvent->u.vec3.y = aidlEvent.payload.get<Event::EventPayload::vec3>().y;
+            hidlEvent->u.vec3.z = aidlEvent.payload.get<Event::EventPayload::vec3>().z;
+            break;
+        case AidlSensorType::GAME_ROTATION_VECTOR:
+            hidlEvent->u.vec4.x = aidlEvent.payload.get<Event::EventPayload::vec4>().x;
+            hidlEvent->u.vec4.y = aidlEvent.payload.get<Event::EventPayload::vec4>().y;
+            hidlEvent->u.vec4.z = aidlEvent.payload.get<Event::EventPayload::vec4>().z;
+            hidlEvent->u.vec4.w = aidlEvent.payload.get<Event::EventPayload::vec4>().w;
+            break;
+        case AidlSensorType::ROTATION_VECTOR:
+        case AidlSensorType::GEOMAGNETIC_ROTATION_VECTOR:
+            std::copy(aidlEvent.payload.get<Event::EventPayload::data>().values.data(),
+                      aidlEvent.payload.get<Event::EventPayload::data>().values.data() + 5,
+                      hidlEvent->u.data.data());
+            break;
+        case AidlSensorType::ACCELEROMETER_UNCALIBRATED:
+        case AidlSensorType::MAGNETIC_FIELD_UNCALIBRATED:
+        case AidlSensorType::GYROSCOPE_UNCALIBRATED:
+            hidlEvent->u.uncal.x = aidlEvent.payload.get<Event::EventPayload::uncal>().x;
+            hidlEvent->u.uncal.y = aidlEvent.payload.get<Event::EventPayload::uncal>().y;
+            hidlEvent->u.uncal.z = aidlEvent.payload.get<Event::EventPayload::uncal>().z;
+            hidlEvent->u.uncal.x_bias = aidlEvent.payload.get<Event::EventPayload::uncal>().xBias;
+            hidlEvent->u.uncal.y_bias = aidlEvent.payload.get<Event::EventPayload::uncal>().yBias;
+            hidlEvent->u.uncal.z_bias = aidlEvent.payload.get<Event::EventPayload::uncal>().zBias;
+            break;
+        case AidlSensorType::DEVICE_ORIENTATION:
+        case AidlSensorType::LIGHT:
+        case AidlSensorType::PRESSURE:
+        case AidlSensorType::PROXIMITY:
+        case AidlSensorType::RELATIVE_HUMIDITY:
+        case AidlSensorType::AMBIENT_TEMPERATURE:
+        case AidlSensorType::SIGNIFICANT_MOTION:
+        case AidlSensorType::STEP_DETECTOR:
+        case AidlSensorType::TILT_DETECTOR:
+        case AidlSensorType::WAKE_GESTURE:
+        case AidlSensorType::GLANCE_GESTURE:
+        case AidlSensorType::PICK_UP_GESTURE:
+        case AidlSensorType::WRIST_TILT_GESTURE:
+        case AidlSensorType::STATIONARY_DETECT:
+        case AidlSensorType::MOTION_DETECT:
+        case AidlSensorType::HEART_BEAT:
+        case AidlSensorType::LOW_LATENCY_OFFBODY_DETECT:
+        case AidlSensorType::HINGE_ANGLE:
+            hidlEvent->u.scalar = aidlEvent.payload.get<Event::EventPayload::scalar>();
+            break;
+        case AidlSensorType::STEP_COUNTER:
+            hidlEvent->u.stepCount = aidlEvent.payload.get<AidlEvent::EventPayload::stepCount>();
+            break;
+        case AidlSensorType::HEART_RATE:
+            hidlEvent->u.heartRate.bpm =
+                    aidlEvent.payload.get<AidlEvent::EventPayload::heartRate>().bpm;
+            hidlEvent->u.heartRate.status =
+                    (V1_0SensorStatus)aidlEvent.payload.get<Event::EventPayload::heartRate>()
+                            .status;
+            break;
+        case AidlSensorType::POSE_6DOF:
+            std::copy(std::begin(aidlEvent.payload.get<AidlEvent::EventPayload::pose6DOF>().values),
+                      std::end(aidlEvent.payload.get<AidlEvent::EventPayload::pose6DOF>().values),
+                      hidlEvent->u.pose6DOF.data());
+            break;
+        case AidlSensorType::DYNAMIC_SENSOR_META:
+            hidlEvent->u.dynamic.connected =
+                    aidlEvent.payload.get<Event::EventPayload::dynamic>().connected;
+            hidlEvent->u.dynamic.sensorHandle =
+                    aidlEvent.payload.get<Event::EventPayload::dynamic>().sensorHandle;
+            std::copy(
+                    std::begin(
+                            aidlEvent.payload.get<AidlEvent::EventPayload::dynamic>().uuid.values),
+                    std::end(aidlEvent.payload.get<AidlEvent::EventPayload::dynamic>().uuid.values),
+                    hidlEvent->u.dynamic.uuid.data());
+            break;
+        case AidlSensorType::ADDITIONAL_INFO: {
+            const AdditionalInfo& additionalInfo =
+                    aidlEvent.payload.get<AidlEvent::EventPayload::additional>();
+            hidlEvent->u.additional.type = (AdditionalInfoType)additionalInfo.type;
+            hidlEvent->u.additional.serial = additionalInfo.serial;
+
+            switch (additionalInfo.payload.getTag()) {
+                case AdditionalInfo::AdditionalInfoPayload::Tag::dataInt32: {
+                    const auto& aidlData =
+                            additionalInfo.payload
+                                    .get<AdditionalInfo::AdditionalInfoPayload::dataInt32>()
+                                    .values;
+                    std::copy(std::begin(aidlData), std::end(aidlData),
+                              hidlEvent->u.additional.u.data_int32.data());
+                    break;
+                }
+                case AdditionalInfo::AdditionalInfoPayload::Tag::dataFloat: {
+                    const auto& aidlData =
+                            additionalInfo.payload
+                                    .get<AdditionalInfo::AdditionalInfoPayload::dataFloat>()
+                                    .values;
+                    std::copy(std::begin(aidlData), std::end(aidlData),
+                              hidlEvent->u.additional.u.data_float.data());
+                    break;
+                }
+                default:
+                    ALOGE("Invalid sensor additioanl info tag: %d",
+                          additionalInfo.payload.getTag());
+                    break;
+            }
+            break;
+        }
+        default:
+            CHECK_GE((int32_t)aidlEvent.sensorType, (int32_t)SensorType::DEVICE_PRIVATE_BASE);
+            std::copy(std::begin(aidlEvent.payload.get<AidlEvent::EventPayload::data>().values),
+                      std::end(aidlEvent.payload.get<AidlEvent::EventPayload::data>().values),
+                      hidlEvent->u.data.data());
+            break;
+    }
+}
+
+void convertToAidlEvent(const V2_1Event& hidlEvent, AidlEvent* aidlEvent) {
+    aidlEvent->timestamp = hidlEvent.timestamp;
+    aidlEvent->sensorHandle = hidlEvent.sensorHandle;
+    aidlEvent->sensorType = (AidlSensorType)hidlEvent.sensorType;
+    switch (hidlEvent.sensorType) {
+        case V2_1SensorType::META_DATA: {
+            AidlEvent::EventPayload::MetaData meta;
+            meta.what = (Event::EventPayload::MetaData::MetaDataEventType)hidlEvent.u.meta.what;
+            aidlEvent->payload.set<Event::EventPayload::meta>(meta);
+            break;
+        }
+        case V2_1SensorType::ACCELEROMETER:
+        case V2_1SensorType::MAGNETIC_FIELD:
+        case V2_1SensorType::ORIENTATION:
+        case V2_1SensorType::GYROSCOPE:
+        case V2_1SensorType::GRAVITY:
+        case V2_1SensorType::LINEAR_ACCELERATION: {
+            AidlEvent::EventPayload::Vec3 vec3;
+            vec3.x = hidlEvent.u.vec3.x;
+            vec3.y = hidlEvent.u.vec3.y;
+            vec3.z = hidlEvent.u.vec3.z;
+            aidlEvent->payload.set<Event::EventPayload::vec3>(vec3);
+            break;
+        }
+        case V2_1SensorType::GAME_ROTATION_VECTOR: {
+            AidlEvent::EventPayload::Vec4 vec4;
+            vec4.x = hidlEvent.u.vec4.x;
+            vec4.y = hidlEvent.u.vec4.y;
+            vec4.z = hidlEvent.u.vec4.z;
+            vec4.w = hidlEvent.u.vec4.w;
+            aidlEvent->payload.set<Event::EventPayload::vec4>(vec4);
+            break;
+        }
+        case V2_1SensorType::ROTATION_VECTOR:
+        case V2_1SensorType::GEOMAGNETIC_ROTATION_VECTOR: {
+            AidlEvent::EventPayload::Data data;
+            std::copy(hidlEvent.u.data.data(), hidlEvent.u.data.data() + 5,
+                      std::begin(data.values));
+            aidlEvent->payload.set<Event::EventPayload::data>(data);
+            break;
+        }
+        case V2_1SensorType::MAGNETIC_FIELD_UNCALIBRATED:
+        case V2_1SensorType::GYROSCOPE_UNCALIBRATED:
+        case V2_1SensorType::ACCELEROMETER_UNCALIBRATED: {
+            AidlEvent::EventPayload::Uncal uncal;
+            uncal.x = hidlEvent.u.uncal.x;
+            uncal.y = hidlEvent.u.uncal.y;
+            uncal.z = hidlEvent.u.uncal.z;
+            uncal.xBias = hidlEvent.u.uncal.x_bias;
+            uncal.yBias = hidlEvent.u.uncal.y_bias;
+            uncal.zBias = hidlEvent.u.uncal.z_bias;
+            aidlEvent->payload.set<Event::EventPayload::uncal>(uncal);
+            break;
+        }
+        case V2_1SensorType::DEVICE_ORIENTATION:
+        case V2_1SensorType::LIGHT:
+        case V2_1SensorType::PRESSURE:
+        case V2_1SensorType::PROXIMITY:
+        case V2_1SensorType::RELATIVE_HUMIDITY:
+        case V2_1SensorType::AMBIENT_TEMPERATURE:
+        case V2_1SensorType::SIGNIFICANT_MOTION:
+        case V2_1SensorType::STEP_DETECTOR:
+        case V2_1SensorType::TILT_DETECTOR:
+        case V2_1SensorType::WAKE_GESTURE:
+        case V2_1SensorType::GLANCE_GESTURE:
+        case V2_1SensorType::PICK_UP_GESTURE:
+        case V2_1SensorType::WRIST_TILT_GESTURE:
+        case V2_1SensorType::STATIONARY_DETECT:
+        case V2_1SensorType::MOTION_DETECT:
+        case V2_1SensorType::HEART_BEAT:
+        case V2_1SensorType::LOW_LATENCY_OFFBODY_DETECT:
+        case V2_1SensorType::HINGE_ANGLE:
+            aidlEvent->payload.set<Event::EventPayload::scalar>(hidlEvent.u.scalar);
+            break;
+        case V2_1SensorType::STEP_COUNTER:
+            aidlEvent->payload.set<Event::EventPayload::stepCount>(hidlEvent.u.stepCount);
+            break;
+        case V2_1SensorType::HEART_RATE: {
+            AidlEvent::EventPayload::HeartRate heartRate;
+            heartRate.bpm = hidlEvent.u.heartRate.bpm;
+            heartRate.status = (SensorStatus)hidlEvent.u.heartRate.status;
+            aidlEvent->payload.set<Event::EventPayload::heartRate>(heartRate);
+            break;
+        }
+        case V2_1SensorType::POSE_6DOF: {
+            AidlEvent::EventPayload::Pose6Dof pose6Dof;
+            std::copy(hidlEvent.u.pose6DOF.data(),
+                      hidlEvent.u.pose6DOF.data() + hidlEvent.u.pose6DOF.size(),
+                      std::begin(pose6Dof.values));
+            aidlEvent->payload.set<Event::EventPayload::pose6DOF>(pose6Dof);
+            break;
+        }
+        case V2_1SensorType::DYNAMIC_SENSOR_META: {
+            DynamicSensorInfo dynamicSensorInfo;
+            dynamicSensorInfo.connected = hidlEvent.u.dynamic.connected;
+            dynamicSensorInfo.sensorHandle = hidlEvent.u.dynamic.sensorHandle;
+            std::copy(hidlEvent.u.dynamic.uuid.data(),
+                      hidlEvent.u.dynamic.uuid.data() + hidlEvent.u.dynamic.uuid.size(),
+                      std::begin(dynamicSensorInfo.uuid.values));
+            aidlEvent->payload.set<Event::EventPayload::dynamic>(dynamicSensorInfo);
+            break;
+        }
+        case V2_1SensorType::ADDITIONAL_INFO: {
+            AdditionalInfo additionalInfo;
+            additionalInfo.type = (AdditionalInfo::AdditionalInfoType)hidlEvent.u.additional.type;
+            additionalInfo.serial = hidlEvent.u.additional.serial;
+
+            AdditionalInfo::AdditionalInfoPayload::Int32Values int32Values;
+            std::copy(hidlEvent.u.additional.u.data_int32.data(),
+                      hidlEvent.u.additional.u.data_int32.data() +
+                              hidlEvent.u.additional.u.data_int32.size(),
+                      std::begin(int32Values.values));
+            additionalInfo.payload.set<AdditionalInfo::AdditionalInfoPayload::dataInt32>(
+                    int32Values);
+            aidlEvent->payload.set<Event::EventPayload::additional>(additionalInfo);
+            break;
+        }
+        default: {
+            CHECK_GE((int32_t)hidlEvent.sensorType, (int32_t)V2_1SensorType::DEVICE_PRIVATE_BASE);
+            AidlEvent::EventPayload::Data data;
+            std::copy(hidlEvent.u.data.data(), hidlEvent.u.data.data() + hidlEvent.u.data.size(),
+                      std::begin(data.values));
+            aidlEvent->payload.set<Event::EventPayload::data>(data);
+            break;
+        }
+    }
+}
+
+}  // namespace implementation
+}  // namespace sensors
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/sensors/aidl/default/multihal/HalProxyAidl.cpp b/sensors/aidl/default/multihal/HalProxyAidl.cpp
new file mode 100644
index 0000000..64805e6
--- /dev/null
+++ b/sensors/aidl/default/multihal/HalProxyAidl.cpp
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "HalProxyAidl.h"
+#include <aidlcommonsupport/NativeHandle.h>
+#include <fmq/AidlMessageQueue.h>
+#include <hidl/Status.h>
+#include "ConvertUtils.h"
+#include "EventMessageQueueWrapperAidl.h"
+#include "ISensorsCallbackWrapperAidl.h"
+#include "WakeLockMessageQueueWrapperAidl.h"
+#include "convertV2_1.h"
+
+using ::aidl::android::hardware::common::fmq::MQDescriptor;
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::aidl::android::hardware::sensors::ISensors;
+using ::aidl::android::hardware::sensors::ISensorsCallback;
+using ::android::hardware::sensors::V2_1::implementation::convertToOldEvent;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace implementation {
+
+static binder_status_t resultToBinderStatus(::android::hardware::sensors::V1_0::Result result) {
+    switch (result) {
+        case ::android::hardware::sensors::V1_0::Result::OK:
+            return STATUS_OK;
+        case ::android::hardware::sensors::V1_0::Result::PERMISSION_DENIED:
+            return STATUS_PERMISSION_DENIED;
+        case ::android::hardware::sensors::V1_0::Result::NO_MEMORY:
+            return STATUS_NO_MEMORY;
+        case ::android::hardware::sensors::V1_0::Result::BAD_VALUE:
+            return STATUS_BAD_VALUE;
+        case ::android::hardware::sensors::V1_0::Result::INVALID_OPERATION:
+            return STATUS_INVALID_OPERATION;
+    }
+}
+
+static ::android::hardware::sensors::V1_0::RateLevel convertRateLevel(
+        ISensors::RateLevel rateLevel) {
+    switch (rateLevel) {
+        case ISensors::RateLevel::STOP:
+            return ::android::hardware::sensors::V1_0::RateLevel::STOP;
+        case ISensors::RateLevel::NORMAL:
+            return ::android::hardware::sensors::V1_0::RateLevel::NORMAL;
+        case ISensors::RateLevel::FAST:
+            return ::android::hardware::sensors::V1_0::RateLevel::FAST;
+        case ISensors::RateLevel::VERY_FAST:
+            return ::android::hardware::sensors::V1_0::RateLevel::VERY_FAST;
+    }
+}
+
+static ::android::hardware::sensors::V1_0::OperationMode convertOperationMode(
+        ISensors::OperationMode operationMode) {
+    switch (operationMode) {
+        case ISensors::OperationMode::NORMAL:
+            return ::android::hardware::sensors::V1_0::OperationMode::NORMAL;
+        case ISensors::OperationMode::DATA_INJECTION:
+            return ::android::hardware::sensors::V1_0::OperationMode::DATA_INJECTION;
+    }
+}
+
+static ::android::hardware::sensors::V1_0::SharedMemType convertSharedMemType(
+        ISensors::SharedMemInfo::SharedMemType sharedMemType) {
+    switch (sharedMemType) {
+        case ISensors::SharedMemInfo::SharedMemType::ASHMEM:
+            return ::android::hardware::sensors::V1_0::SharedMemType::ASHMEM;
+        case ISensors::SharedMemInfo::SharedMemType::GRALLOC:
+            return ::android::hardware::sensors::V1_0::SharedMemType::GRALLOC;
+    }
+}
+
+static ::android::hardware::sensors::V1_0::SharedMemFormat convertSharedMemFormat(
+        ISensors::SharedMemInfo::SharedMemFormat sharedMemFormat) {
+    switch (sharedMemFormat) {
+        case ISensors::SharedMemInfo::SharedMemFormat::SENSORS_EVENT:
+            return ::android::hardware::sensors::V1_0::SharedMemFormat::SENSORS_EVENT;
+    }
+}
+
+static ::android::hardware::sensors::V1_0::SharedMemInfo convertSharedMemInfo(
+        const ISensors::SharedMemInfo& sharedMemInfo) {
+    ::android::hardware::sensors::V1_0::SharedMemInfo v1SharedMemInfo;
+    v1SharedMemInfo.type = convertSharedMemType(sharedMemInfo.type);
+    v1SharedMemInfo.format = convertSharedMemFormat(sharedMemInfo.format);
+    v1SharedMemInfo.size = sharedMemInfo.size;
+    v1SharedMemInfo.memoryHandle =
+            ::android::hardware::hidl_handle(::android::makeFromAidl(sharedMemInfo.memoryHandle));
+    return v1SharedMemInfo;
+}
+
+::ndk::ScopedAStatus HalProxyAidl::activate(int32_t in_sensorHandle, bool in_enabled) {
+    return ndk::ScopedAStatus::fromStatus(
+            resultToBinderStatus(HalProxy::activate(in_sensorHandle, in_enabled)));
+}
+
+::ndk::ScopedAStatus HalProxyAidl::batch(int32_t in_sensorHandle, int64_t in_samplingPeriodNs,
+                                         int64_t in_maxReportLatencyNs) {
+    return ndk::ScopedAStatus::fromStatus(resultToBinderStatus(
+            HalProxy::batch(in_sensorHandle, in_samplingPeriodNs, in_maxReportLatencyNs)));
+}
+
+::ndk::ScopedAStatus HalProxyAidl::configDirectReport(int32_t in_sensorHandle,
+                                                      int32_t in_channelHandle,
+                                                      ISensors::RateLevel in_rate,
+                                                      int32_t* _aidl_return) {
+    binder_status_t binderStatus;
+    HalProxy::configDirectReport(
+            in_sensorHandle, in_channelHandle, convertRateLevel(in_rate),
+            [&binderStatus, _aidl_return](::android::hardware::sensors::V1_0::Result result,
+                                          int32_t reportToken) {
+                binderStatus = resultToBinderStatus(result);
+                *_aidl_return = reportToken;
+            });
+    return ndk::ScopedAStatus::fromStatus(binderStatus);
+}
+
+::ndk::ScopedAStatus HalProxyAidl::flush(int32_t in_sensorHandle) {
+    return ndk::ScopedAStatus::fromStatus(resultToBinderStatus(HalProxy::flush(in_sensorHandle)));
+}
+
+::ndk::ScopedAStatus HalProxyAidl::getSensorsList(
+        std::vector<::aidl::android::hardware::sensors::SensorInfo>* _aidl_return) {
+    for (const auto& sensor : HalProxy::getSensors()) {
+        _aidl_return->push_back(convertSensorInfo(sensor.second));
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus HalProxyAidl::initialize(
+        const MQDescriptor<::aidl::android::hardware::sensors::Event, SynchronizedReadWrite>&
+                in_eventQueueDescriptor,
+        const MQDescriptor<int32_t, SynchronizedReadWrite>& in_wakeLockDescriptor,
+        const std::shared_ptr<ISensorsCallback>& in_sensorsCallback) {
+    ::android::sp<::android::hardware::sensors::V2_1::implementation::ISensorsCallbackWrapperBase>
+            dynamicCallback = new ISensorsCallbackWrapperAidl(in_sensorsCallback);
+
+    auto aidlEventQueue =
+            std::make_unique<::android::AidlMessageQueue<::aidl::android::hardware::sensors::Event,
+                                                         SynchronizedReadWrite>>(
+                    in_eventQueueDescriptor, true /* resetPointers */);
+    std::unique_ptr<
+            ::android::hardware::sensors::V2_1::implementation::EventMessageQueueWrapperBase>
+            eventQueue = std::make_unique<EventMessageQueueWrapperAidl>(aidlEventQueue);
+
+    auto aidlWakeLockQueue =
+            std::make_unique<::android::AidlMessageQueue<int32_t, SynchronizedReadWrite>>(
+                    in_wakeLockDescriptor, true /* resetPointers */);
+    std::unique_ptr<
+            ::android::hardware::sensors::V2_1::implementation::WakeLockMessageQueueWrapperBase>
+            wakeLockQueue = std::make_unique<WakeLockMessageQueueWrapperAidl>(aidlWakeLockQueue);
+
+    return ndk::ScopedAStatus::fromStatus(
+            resultToBinderStatus(initializeCommon(eventQueue, wakeLockQueue, dynamicCallback)));
+}
+
+::ndk::ScopedAStatus HalProxyAidl::injectSensorData(
+        const ::aidl::android::hardware::sensors::Event& in_event) {
+    ::android::hardware::sensors::V2_1::Event hidlEvent;
+    convertToHidlEvent(in_event, &hidlEvent);
+    return ndk::ScopedAStatus::fromStatus(
+            resultToBinderStatus(HalProxy::injectSensorData(convertToOldEvent(hidlEvent))));
+}
+
+::ndk::ScopedAStatus HalProxyAidl::registerDirectChannel(const ISensors::SharedMemInfo& in_mem,
+                                                         int32_t* _aidl_return) {
+    binder_status_t binderStatus;
+    ::android::hardware::sensors::V1_0::SharedMemInfo sharedMemInfo = convertSharedMemInfo(in_mem);
+
+    HalProxy::registerDirectChannel(
+            sharedMemInfo,
+            [&binderStatus, _aidl_return](::android::hardware::sensors::V1_0::Result result,
+                                          int32_t reportToken) {
+                binderStatus = resultToBinderStatus(result);
+                *_aidl_return = reportToken;
+            });
+
+    native_handle_delete(
+            const_cast<native_handle_t*>(sharedMemInfo.memoryHandle.getNativeHandle()));
+    return ndk::ScopedAStatus::fromStatus(binderStatus);
+}
+
+::ndk::ScopedAStatus HalProxyAidl::setOperationMode(
+        ::aidl::android::hardware::sensors::ISensors::OperationMode in_mode) {
+    return ndk::ScopedAStatus::fromStatus(
+            resultToBinderStatus(HalProxy::setOperationMode(convertOperationMode(in_mode))));
+}
+
+::ndk::ScopedAStatus HalProxyAidl::unregisterDirectChannel(int32_t in_channelHandle) {
+    return ndk::ScopedAStatus::fromStatus(
+            resultToBinderStatus(HalProxy::unregisterDirectChannel(in_channelHandle)));
+}
+
+}  // namespace implementation
+}  // namespace sensors
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
\ No newline at end of file
diff --git a/sensors/aidl/default/multihal/include/ConvertUtils.h b/sensors/aidl/default/multihal/include/ConvertUtils.h
new file mode 100644
index 0000000..91dfabd
--- /dev/null
+++ b/sensors/aidl/default/multihal/include/ConvertUtils.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 <aidl/android/hardware/sensors/BnSensors.h>
+#include <android/hardware/sensors/2.1/types.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace implementation {
+
+/**
+ * Generates an AIDL SensorInfo instance from the passed HIDL V2.1 SensorInfo instance.
+ */
+::aidl::android::hardware::sensors::SensorInfo convertSensorInfo(
+        const ::android::hardware::sensors::V2_1::SensorInfo& sensorInfo);
+
+/**
+ * Populates a HIDL V2.1 Event instance based on an AIDL Event instance.
+ */
+void convertToHidlEvent(const ::aidl::android::hardware::sensors::Event& aidlEvent,
+                        ::android::hardware::sensors::V2_1::Event* hidlEvent);
+
+/**
+ * Populates an AIDL Event instance based on a HIDL V2.1 Event instance.
+ */
+void convertToAidlEvent(const ::android::hardware::sensors::V2_1::Event& hidlEvent,
+                        ::aidl::android::hardware::sensors::Event* aidlEvent);
+
+}  // namespace implementation
+}  // namespace sensors
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
\ No newline at end of file
diff --git a/sensors/aidl/default/multihal/include/EventMessageQueueWrapperAidl.h b/sensors/aidl/default/multihal/include/EventMessageQueueWrapperAidl.h
new file mode 100644
index 0000000..3eaa1d4
--- /dev/null
+++ b/sensors/aidl/default/multihal/include/EventMessageQueueWrapperAidl.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/sensors/2.1/types.h>
+#include <fmq/AidlMessageQueue.h>
+#include "ConvertUtils.h"
+#include "EventMessageQueueWrapper.h"
+#include "ISensorsWrapper.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace implementation {
+
+class EventMessageQueueWrapperAidl
+    : public ::android::hardware::sensors::V2_1::implementation::EventMessageQueueWrapperBase {
+  public:
+    EventMessageQueueWrapperAidl(
+            std::unique_ptr<::android::AidlMessageQueue<
+                    ::aidl::android::hardware::sensors::Event,
+                    ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>>& queue)
+        : mQueue(std::move(queue)) {}
+
+    virtual std::atomic<uint32_t>* getEventFlagWord() override {
+        return mQueue->getEventFlagWord();
+    }
+
+    virtual size_t availableToRead() override { return mQueue->availableToRead(); }
+
+    size_t availableToWrite() override { return mQueue->availableToWrite(); }
+
+    virtual bool read(::android::hardware::sensors::V2_1::Event* events,
+                      size_t numToRead) override {
+        bool success = mQueue->read(mIntermediateEventBuffer.data(), numToRead);
+        for (int i = 0; i < numToRead; ++i) {
+            convertToHidlEvent(mIntermediateEventBuffer[i], &events[i]);
+        }
+        return success;
+    }
+
+    bool write(const ::android::hardware::sensors::V2_1::Event* events,
+               size_t numToWrite) override {
+        for (int i = 0; i < numToWrite; ++i) {
+            convertToAidlEvent(events[i], &mIntermediateEventBuffer[i]);
+        }
+        return mQueue->write(mIntermediateEventBuffer.data(), numToWrite);
+    }
+
+    virtual bool write(
+            const std::vector<::android::hardware::sensors::V2_1::Event>& events) override {
+        for (int i = 0; i < events.size(); ++i) {
+            convertToAidlEvent(events[i], &mIntermediateEventBuffer[i]);
+        }
+        return mQueue->write(mIntermediateEventBuffer.data(), events.size());
+    }
+
+    bool writeBlocking(const ::android::hardware::sensors::V2_1::Event* events, size_t count,
+                       uint32_t readNotification, uint32_t writeNotification, int64_t timeOutNanos,
+                       ::android::hardware::EventFlag* evFlag) override {
+        for (int i = 0; i < count; ++i) {
+            convertToAidlEvent(events[i], &mIntermediateEventBuffer[i]);
+        }
+        return mQueue->writeBlocking(mIntermediateEventBuffer.data(), count, readNotification,
+                                     writeNotification, timeOutNanos, evFlag);
+    }
+
+    size_t getQuantumCount() override { return mQueue->getQuantumCount(); }
+
+  private:
+    std::unique_ptr<::android::AidlMessageQueue<
+            ::aidl::android::hardware::sensors::Event,
+            ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>>
+            mQueue;
+    std::array<::aidl::android::hardware::sensors::Event,
+               ::android::hardware::sensors::V2_1::implementation::MAX_RECEIVE_BUFFER_EVENT_COUNT>
+            mIntermediateEventBuffer;
+};
+
+}  // namespace implementation
+}  // namespace sensors
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/sensors/aidl/default/multihal/include/HalProxyAidl.h b/sensors/aidl/default/multihal/include/HalProxyAidl.h
new file mode 100644
index 0000000..7401726
--- /dev/null
+++ b/sensors/aidl/default/multihal/include/HalProxyAidl.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/sensors/BnSensors.h>
+#include "HalProxy.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace implementation {
+
+class HalProxyAidl : public ::android::hardware::sensors::V2_1::implementation::HalProxy,
+                     public ::aidl::android::hardware::sensors::BnSensors {
+    ::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;
+};
+
+}  // namespace implementation
+}  // namespace sensors
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/sensors/aidl/default/multihal/include/ISensorsCallbackWrapperAidl.h b/sensors/aidl/default/multihal/include/ISensorsCallbackWrapperAidl.h
new file mode 100644
index 0000000..6ef6c63
--- /dev/null
+++ b/sensors/aidl/default/multihal/include/ISensorsCallbackWrapperAidl.h
@@ -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.
+ */
+
+#pragma once
+
+#include "ConvertUtils.h"
+#include "ISensorsCallbackWrapper.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace implementation {
+
+static std::vector<::aidl::android::hardware::sensors::SensorInfo> convertToAidlSensorInfos(
+        const ::android::hardware::hidl_vec<::android::hardware::sensors::V2_1::SensorInfo>&
+                sensorInfos) {
+    std::vector<::aidl::android::hardware::sensors::SensorInfo> aidlSensorInfos;
+    for (const auto& sensorInfo : sensorInfos) {
+        aidlSensorInfos.push_back(convertSensorInfo(sensorInfo));
+    }
+    return aidlSensorInfos;
+}
+
+class ISensorsCallbackWrapperAidl
+    : public ::android::hardware::sensors::V2_1::implementation::ISensorsCallbackWrapperBase {
+  public:
+    ISensorsCallbackWrapperAidl(
+            std::shared_ptr<::aidl::android::hardware::sensors::ISensorsCallback> sensorsCallback)
+        : mSensorsCallback(sensorsCallback) {}
+
+    ::android::hardware::Return<void> onDynamicSensorsConnected(
+            const ::android::hardware::hidl_vec<::android::hardware::sensors::V2_1::SensorInfo>&
+                    sensorInfos) override {
+        mSensorsCallback->onDynamicSensorsConnected(convertToAidlSensorInfos(sensorInfos));
+        return ::android::hardware::Void();
+    }
+
+    ::android::hardware::Return<void> onDynamicSensorsDisconnected(
+            const ::android::hardware::hidl_vec<int32_t>& sensorHandles) override {
+        mSensorsCallback->onDynamicSensorsDisconnected(sensorHandles);
+        return ::android::hardware::Void();
+    }
+
+  private:
+    std::shared_ptr<::aidl::android::hardware::sensors::ISensorsCallback> mSensorsCallback;
+};
+
+}  // namespace implementation
+}  // namespace sensors
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
\ No newline at end of file
diff --git a/sensors/aidl/default/multihal/include/WakeLockMessageQueueWrapperAidl.h b/sensors/aidl/default/multihal/include/WakeLockMessageQueueWrapperAidl.h
new file mode 100644
index 0000000..6be0b69
--- /dev/null
+++ b/sensors/aidl/default/multihal/include/WakeLockMessageQueueWrapperAidl.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 <android/hardware/sensors/2.1/types.h>
+#include <fmq/AidlMessageQueue.h>
+#include "WakeLockMessageQueueWrapper.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace implementation {
+
+class WakeLockMessageQueueWrapperAidl
+    : public ::android::hardware::sensors::V2_1::implementation::WakeLockMessageQueueWrapperBase {
+  public:
+    WakeLockMessageQueueWrapperAidl(
+            std::unique_ptr<::android::AidlMessageQueue<
+                    int32_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>>& queue)
+        : mQueue(std::move(queue)) {}
+
+    virtual std::atomic<uint32_t>* getEventFlagWord() override {
+        return mQueue->getEventFlagWord();
+    }
+
+    bool readBlocking(uint32_t* wakeLocks, size_t numToRead, uint32_t readNotification,
+                      uint32_t writeNotification, int64_t timeOutNanos,
+                      ::android::hardware::EventFlag* evFlag) override {
+        return mQueue->readBlocking(reinterpret_cast<int32_t*>(wakeLocks), numToRead,
+                                    readNotification, writeNotification, timeOutNanos, evFlag);
+    }
+
+    bool write(const uint32_t* wakeLock) override {
+        return mQueue->write(reinterpret_cast<const int32_t*>(wakeLock));
+    }
+
+  private:
+    std::unique_ptr<::android::AidlMessageQueue<
+            int32_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>>
+            mQueue;
+};
+
+}  // namespace implementation
+}  // namespace sensors
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/sensors/aidl/multihal/Android.bp b/sensors/aidl/multihal/Android.bp
new file mode 100644
index 0000000..6d35daf
--- /dev/null
+++ b/sensors/aidl/multihal/Android.bp
@@ -0,0 +1,59 @@
+//
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // 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.sensors-service.multihal",
+    vendor: true,
+    relative_install_path: "hw",
+    srcs: [
+        "service.cpp",
+    ],
+    header_libs: [
+        "android.hardware.sensors@2.X-multihal.header",
+        "android.hardware.sensors@2.X-shared-utils",
+    ],
+    init_rc: ["android.hardware.sensors-service-multihal.rc"],
+    vintf_fragments: ["android.hardware.sensors-multihal.xml"],
+    shared_libs: [
+        "android.hardware.sensors@2.0-ScopedWakelock",
+        "android.hardware.sensors@2.0",
+        "android.hardware.sensors@2.1",
+        "android.hardware.sensors-V1-ndk",
+        "libbase",
+        "libcutils",
+        "libfmq",
+        "liblog",
+        "libpower",
+        "libutils",
+        "libbinder_ndk",
+        "libhidlbase",
+    ],
+    static_libs: [
+        "libaidlcommonsupport",
+        "android.hardware.sensors@1.0-convert",
+        "android.hardware.sensors@2.X-multihal",
+        "android.hardware.sensors@aidl-multihal",
+    ],
+}
diff --git a/sensors/aidl/multihal/OWNERS b/sensors/aidl/multihal/OWNERS
new file mode 100644
index 0000000..e955670
--- /dev/null
+++ b/sensors/aidl/multihal/OWNERS
@@ -0,0 +1,3 @@
+arthuri@google.com
+bduddie@google.com
+stange@google.com
\ No newline at end of file
diff --git a/sensors/aidl/multihal/android.hardware.sensors-multihal.xml b/sensors/aidl/multihal/android.hardware.sensors-multihal.xml
new file mode 100644
index 0000000..d78edff
--- /dev/null
+++ b/sensors/aidl/multihal/android.hardware.sensors-multihal.xml
@@ -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.
+  -->
+
+<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/multihal/android.hardware.sensors-service-multihal.rc b/sensors/aidl/multihal/android.hardware.sensors-service-multihal.rc
new file mode 100644
index 0000000..3f91a0a
--- /dev/null
+++ b/sensors/aidl/multihal/android.hardware.sensors-service-multihal.rc
@@ -0,0 +1,7 @@
+service vendor.sensors-hal-multihal /vendor/bin/hw/android.hardware.sensors-service.multihal
+    class hal
+    user system
+    group system wakelock context_hub
+    task_profiles ServiceCapacityLow
+    capabilities BLOCK_SUSPEND
+    rlimit rtprio 10 10
\ No newline at end of file
diff --git a/sensors/aidl/multihal/service.cpp b/sensors/aidl/multihal/service.cpp
new file mode 100644
index 0000000..11c108a
--- /dev/null
+++ b/sensors/aidl/multihal/service.cpp
@@ -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.
+ */
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include "HalProxyAidl.h"
+
+using ::aidl::android::hardware::sensors::implementation::HalProxyAidl;
+
+int main() {
+    ABinderProcess_setThreadPoolMaxThreadCount(0);
+
+    // Make a default multihal sensors service
+    auto halProxy = ndk::SharedRefBase::make<HalProxyAidl>();
+    const std::string halProxyName = std::string() + HalProxyAidl::descriptor + "/default";
+    binder_status_t status =
+            AServiceManager_addService(halProxy->asBinder().get(), halProxyName.c_str());
+    CHECK_EQ(status, STATUS_OK);
+
+    ABinderProcess_joinThreadPool();
+    return EXIT_FAILURE;  // should not reach
+}
diff --git a/sensors/aidl/vts/Android.bp b/sensors/aidl/vts/Android.bp
index 5a519a5..b5a5f15 100644
--- a/sensors/aidl/vts/Android.bp
+++ b/sensors/aidl/vts/Android.bp
@@ -34,6 +34,7 @@
     shared_libs: [
         "libbinder",
         "libbinder_ndk",
+        "libvndksupport",
         "libfmq",
         "android.hardware.common-V2-ndk",
         "android.hardware.common.fmq-V1-ndk",
@@ -41,6 +42,7 @@
     static_libs: [
         "android.hardware.sensors-V1-ndk",
         "VtsHalSensorsTargetTestUtils",
+        "libaidlcommonsupport",
     ],
     test_suites: [
         "general-tests",
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
index 33645b2..1bc7263 100644
--- a/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp
+++ b/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp
@@ -26,6 +26,7 @@
 #include <utils/SystemClock.h>
 
 #include "SensorsAidlEnvironment.h"
+#include "SensorsAidlTestSharedMemory.h"
 #include "sensors-vts-utils/SensorsVtsEnvironmentBase.h"
 
 #include <cinttypes>
@@ -43,6 +44,9 @@
 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) {
@@ -97,6 +101,24 @@
     }
 }
 
+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:
@@ -286,6 +308,24 @@
     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; }
@@ -313,6 +353,18 @@
 
     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);
 
@@ -334,6 +386,19 @@
     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));
@@ -850,12 +915,141 @@
     }
 }
 
+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) {
-    // TODO(b/195593357): Implement this
+    verifyDirectChannel(ISensors::SharedMemInfo::SharedMemType::ASHMEM);
 }
 
 TEST_P(SensorsAidlTest, DirectChannelGralloc) {
-    // TODO(b/195593357): Implement this
+    verifyDirectChannel(ISensors::SharedMemInfo::SharedMemType::GRALLOC);
 }
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SensorsAidlTest);
diff --git a/sensors/common/default/2.X/multihal/HalProxy.cpp b/sensors/common/default/2.X/multihal/HalProxy.cpp
index f5fc066..73b0594 100644
--- a/sensors/common/default/2.X/multihal/HalProxy.cpp
+++ b/sensors/common/default/2.X/multihal/HalProxy.cpp
@@ -176,7 +176,13 @@
     std::unique_ptr<EventMessageQueueWrapperBase> queue =
             std::make_unique<EventMessageQueueWrapperV2_1>(eventQueue);
 
-    return initializeCommon(queue, wakeLockDescriptor, dynamicCallback);
+    // Create the Wake Lock FMQ from the wakeLockDescriptor. Reset the read/write positions.
+    auto hidlWakeLockQueue =
+            std::make_unique<WakeLockMessageQueue>(wakeLockDescriptor, true /* resetPointers */);
+    std::unique_ptr<WakeLockMessageQueueWrapperBase> wakeLockQueue =
+            std::make_unique<WakeLockMessageQueueWrapperHidl>(hidlWakeLockQueue);
+
+    return initializeCommon(queue, wakeLockQueue, dynamicCallback);
 }
 
 Return<Result> HalProxy::initialize(
@@ -192,12 +198,18 @@
     std::unique_ptr<EventMessageQueueWrapperBase> queue =
             std::make_unique<EventMessageQueueWrapperV1_0>(eventQueue);
 
-    return initializeCommon(queue, wakeLockDescriptor, dynamicCallback);
+    // Create the Wake Lock FMQ from the wakeLockDescriptor. Reset the read/write positions.
+    auto hidlWakeLockQueue =
+            std::make_unique<WakeLockMessageQueue>(wakeLockDescriptor, true /* resetPointers */);
+    std::unique_ptr<WakeLockMessageQueueWrapperBase> wakeLockQueue =
+            std::make_unique<WakeLockMessageQueueWrapperHidl>(hidlWakeLockQueue);
+
+    return initializeCommon(queue, wakeLockQueue, dynamicCallback);
 }
 
 Return<Result> HalProxy::initializeCommon(
         std::unique_ptr<EventMessageQueueWrapperBase>& eventQueue,
-        const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor,
+        std::unique_ptr<WakeLockMessageQueueWrapperBase>& wakeLockQueue,
         const sp<ISensorsCallbackWrapperBase>& sensorsCallback) {
     Result result = Result::OK;
 
@@ -222,8 +234,7 @@
 
     // 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<WakeLockMessageQueue>(wakeLockDescriptor, true /* resetPointers */);
+    mWakeLockQueue = std::move(wakeLockQueue);
 
     if (mEventQueueFlag != nullptr) {
         EventFlag::deleteEventFlag(&mEventQueueFlag);
diff --git a/sensors/common/default/2.X/multihal/include/HalProxy.h b/sensors/common/default/2.X/multihal/include/HalProxy.h
index 35d7c8b..6174528 100644
--- a/sensors/common/default/2.X/multihal/include/HalProxy.h
+++ b/sensors/common/default/2.X/multihal/include/HalProxy.h
@@ -23,6 +23,7 @@
 #include "V2_0/ScopedWakelock.h"
 #include "V2_0/SubHal.h"
 #include "V2_1/SubHal.h"
+#include "WakeLockMessageQueueWrapper.h"
 #include "convertV2_1.h"
 
 #include <android/hardware/sensors/2.1/ISensors.h>
@@ -98,10 +99,9 @@
             const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor,
             const sp<V2_0::ISensorsCallback>& sensorsCallback);
 
-    Return<Result> initializeCommon(
-            std::unique_ptr<EventMessageQueueWrapperBase>& eventQueue,
-            const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor,
-            const sp<ISensorsCallbackWrapperBase>& sensorsCallback);
+    Return<Result> initializeCommon(std::unique_ptr<EventMessageQueueWrapperBase>& eventQueue,
+                                    std::unique_ptr<WakeLockMessageQueueWrapperBase>& wakeLockQueue,
+                                    const sp<ISensorsCallbackWrapperBase>& sensorsCallback);
 
     Return<Result> batch(int32_t sensorHandle, int64_t samplingPeriodNs,
                          int64_t maxReportLatencyNs);
@@ -141,6 +141,8 @@
 
     void decrementRefCountAndMaybeReleaseWakelock(size_t delta, int64_t timeoutStart = -1) override;
 
+    const std::map<int32_t, SensorInfo>& getSensors() { return mSensors; }
+
   private:
     using EventMessageQueueV2_1 = MessageQueue<V2_1::Event, kSynchronizedReadWrite>;
     using EventMessageQueueV2_0 = MessageQueue<V1_0::Event, kSynchronizedReadWrite>;
@@ -154,7 +156,7 @@
     /**
      * The Wake Lock FMQ that is read to determine when the framework has handled WAKE_UP events
      */
-    std::unique_ptr<WakeLockMessageQueue> mWakeLockQueue;
+    std::unique_ptr<WakeLockMessageQueueWrapperBase> mWakeLockQueue;
 
     /**
      * Event Flag to signal to the framework when sensor events are available to be read and to
diff --git a/sensors/common/utils/WakeLockMessageQueueWrapper.h b/sensors/common/utils/WakeLockMessageQueueWrapper.h
new file mode 100644
index 0000000..3a219cf
--- /dev/null
+++ b/sensors/common/utils/WakeLockMessageQueueWrapper.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.
+ */
+
+#pragma once
+
+#include "convertV2_1.h"
+
+#include <android/hardware/sensors/2.1/types.h>
+#include <fmq/MessageQueue.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <log/log.h>
+
+#include <atomic>
+
+namespace android {
+namespace hardware {
+namespace sensors {
+namespace V2_1 {
+namespace implementation {
+
+class WakeLockMessageQueueWrapperBase {
+  public:
+    virtual ~WakeLockMessageQueueWrapperBase() {}
+
+    virtual std::atomic<uint32_t>* getEventFlagWord() = 0;
+    virtual bool readBlocking(uint32_t* events, size_t numToRead, uint32_t readNotification,
+                              uint32_t writeNotification, int64_t timeOutNanos,
+                              ::android::hardware::EventFlag* evFlag = nullptr) = 0;
+    virtual bool write(const uint32_t* wakeLock) = 0;
+};
+
+class WakeLockMessageQueueWrapperHidl : public WakeLockMessageQueueWrapperBase {
+  public:
+    WakeLockMessageQueueWrapperHidl(
+            std::unique_ptr<::android::hardware::MessageQueue<uint32_t, kSynchronizedReadWrite>>&
+                    queue)
+        : mQueue(std::move(queue)) {}
+
+    std::atomic<uint32_t>* getEventFlagWord() override { return mQueue->getEventFlagWord(); }
+
+    bool readBlocking(uint32_t* wakeLocks, size_t numToRead, uint32_t readNotification,
+                      uint32_t writeNotification, int64_t timeOutNanos,
+                      ::android::hardware::EventFlag* evFlag) override {
+        return mQueue->readBlocking(wakeLocks, numToRead, readNotification, writeNotification,
+                                    timeOutNanos, evFlag);
+    }
+
+    bool write(const uint32_t* wakeLock) override { return mQueue->write(wakeLock); }
+
+  private:
+    std::unique_ptr<::android::hardware::MessageQueue<uint32_t, kSynchronizedReadWrite>> mQueue;
+};
+
+}  // namespace implementation
+}  // namespace V2_1
+}  // namespace sensors
+}  // namespace hardware
+}  // namespace android
diff --git a/tv/tuner/1.0/default/Lnb.cpp b/tv/tuner/1.0/default/Lnb.cpp
index 6025339..c770e91 100644
--- a/tv/tuner/1.0/default/Lnb.cpp
+++ b/tv/tuner/1.0/default/Lnb.cpp
@@ -33,9 +33,10 @@
 
 Lnb::~Lnb() {}
 
-Return<Result> Lnb::setCallback(const sp<ILnbCallback>& /* callback */) {
+Return<Result> Lnb::setCallback(const sp<ILnbCallback>& callback) {
     ALOGV("%s", __FUNCTION__);
 
+    mCallback = callback;
     return Result::SUCCESS;
 }
 
@@ -57,9 +58,16 @@
     return Result::SUCCESS;
 }
 
-Return<Result> Lnb::sendDiseqcMessage(const hidl_vec<uint8_t>& /* diseqcMessage */) {
+Return<Result> Lnb::sendDiseqcMessage(const hidl_vec<uint8_t>& diseqcMessage) {
     ALOGV("%s", __FUNCTION__);
 
+    if (mCallback != nullptr) {
+        // The correct implementation should be to return the response from the
+        // device via onDiseqcMessage(). The below implementation is only to enable
+        // testing for LnbCallbacks.
+        ALOGV("[hidl] %s - this is for test purpose only, and must be replaced!", __FUNCTION__);
+        mCallback->onDiseqcMessage(diseqcMessage);
+    }
     return Result::SUCCESS;
 }
 
diff --git a/tv/tuner/1.0/default/Lnb.h b/tv/tuner/1.0/default/Lnb.h
index 1e97214..c14bbd8 100644
--- a/tv/tuner/1.0/default/Lnb.h
+++ b/tv/tuner/1.0/default/Lnb.h
@@ -57,6 +57,7 @@
   private:
     int mId;
     virtual ~Lnb();
+    sp<ILnbCallback> mCallback;
 };
 
 }  // namespace implementation
diff --git a/tv/tuner/1.1/default/Lnb.cpp b/tv/tuner/1.1/default/Lnb.cpp
index 044727f..5dd0147 100644
--- a/tv/tuner/1.1/default/Lnb.cpp
+++ b/tv/tuner/1.1/default/Lnb.cpp
@@ -33,9 +33,10 @@
 
 Lnb::~Lnb() {}
 
-Return<Result> Lnb::setCallback(const sp<ILnbCallback>& /* callback */) {
+Return<Result> Lnb::setCallback(const sp<ILnbCallback>& callback) {
     ALOGV("%s", __FUNCTION__);
 
+    mCallback = callback;
     return Result::SUCCESS;
 }
 
@@ -57,9 +58,16 @@
     return Result::SUCCESS;
 }
 
-Return<Result> Lnb::sendDiseqcMessage(const hidl_vec<uint8_t>& /* diseqcMessage */) {
+Return<Result> Lnb::sendDiseqcMessage(const hidl_vec<uint8_t>& diseqcMessage) {
     ALOGV("%s", __FUNCTION__);
 
+    if (mCallback != nullptr) {
+        // The correct implementation should be to return the response from the
+        // device via onDiseqcMessage(). The below implementation is only to enable
+        // testing for LnbCallbacks.
+        ALOGV("[hidl] %s - this is for test purpose only, and must be replaced!", __FUNCTION__);
+        mCallback->onDiseqcMessage(diseqcMessage);
+    }
     return Result::SUCCESS;
 }
 
diff --git a/tv/tuner/1.1/default/Lnb.h b/tv/tuner/1.1/default/Lnb.h
index 70a8e41..b34ca39 100644
--- a/tv/tuner/1.1/default/Lnb.h
+++ b/tv/tuner/1.1/default/Lnb.h
@@ -51,6 +51,7 @@
   private:
     int mId;
     virtual ~Lnb();
+    sp<ILnbCallback> mCallback;
 };
 
 }  // namespace implementation
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/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl
index f6788ee..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
@@ -49,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/default/Lnb.cpp b/tv/tuner/aidl/default/Lnb.cpp
index 35d2da6..f9343ae 100644
--- a/tv/tuner/aidl/default/Lnb.cpp
+++ b/tv/tuner/aidl/default/Lnb.cpp
@@ -34,9 +34,11 @@
 
 Lnb::~Lnb() {}
 
-::ndk::ScopedAStatus Lnb::setCallback(const std::shared_ptr<ILnbCallback>& /* in_callback */) {
+::ndk::ScopedAStatus Lnb::setCallback(const std::shared_ptr<ILnbCallback>& in_callback) {
     ALOGV("%s", __FUNCTION__);
 
+    mCallback = in_callback;
+
     return ::ndk::ScopedAStatus::ok();
 }
 
@@ -58,9 +60,17 @@
     return ::ndk::ScopedAStatus::ok();
 }
 
-::ndk::ScopedAStatus Lnb::sendDiseqcMessage(const std::vector<uint8_t>& /* in_diseqcMessage */) {
+::ndk::ScopedAStatus Lnb::sendDiseqcMessage(const std::vector<uint8_t>& in_diseqcMessage) {
     ALOGV("%s", __FUNCTION__);
 
+    if (mCallback != nullptr) {
+        // The correct implementation should be to return the response from the
+        // device via onDiseqcMessage(). The below implementation is only to enable
+        // testing for LnbCallbacks.
+        ALOGV("[aidl] %s - this is for test purpose only, and must be replaced!", __FUNCTION__);
+        mCallback->onDiseqcMessage(in_diseqcMessage);
+    }
+
     return ::ndk::ScopedAStatus::ok();
 }
 
diff --git a/tv/tuner/aidl/default/Lnb.h b/tv/tuner/aidl/default/Lnb.h
index bfe3097..464f9a4 100644
--- a/tv/tuner/aidl/default/Lnb.h
+++ b/tv/tuner/aidl/default/Lnb.h
@@ -44,6 +44,7 @@
   private:
     int mId;
     virtual ~Lnb();
+    std::shared_ptr<ILnbCallback> mCallback;
 };
 
 }  // namespace tuner
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/wifi/1.5/default/hidl_struct_util.h b/wifi/1.5/default/hidl_struct_util.h
deleted file mode 100644
index 352f213..0000000
--- a/wifi/1.5/default/hidl_struct_util.h
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 HIDL_STRUCT_UTIL_H_
-#define HIDL_STRUCT_UTIL_H_
-
-#include <vector>
-
-#include <android/hardware/wifi/1.0/IWifiChip.h>
-#include <android/hardware/wifi/1.0/types.h>
-#include <android/hardware/wifi/1.2/types.h>
-#include <android/hardware/wifi/1.3/types.h>
-#include <android/hardware/wifi/1.4/IWifiChipEventCallback.h>
-#include <android/hardware/wifi/1.4/types.h>
-#include <android/hardware/wifi/1.5/IWifiChip.h>
-#include <android/hardware/wifi/1.5/types.h>
-
-#include "wifi_legacy_hal.h"
-
-/**
- * This file contains a bunch of functions to convert structs from the legacy
- * HAL to HIDL and vice versa.
- * TODO(b/32093047): Add unit tests for these conversion methods in the VTS test
- * suite.
- */
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_5 {
-namespace implementation {
-namespace hidl_struct_util {
-using namespace android::hardware::wifi::V1_0;
-
-// Chip conversion methods.
-bool convertLegacyFeaturesToHidlChipCapabilities(
-    uint64_t legacy_feature_set, uint32_t legacy_logger_feature_set,
-    uint32_t* hidl_caps);
-bool convertLegacyDebugRingBufferStatusToHidl(
-    const legacy_hal::wifi_ring_buffer_status& legacy_status,
-    WifiDebugRingBufferStatus* hidl_status);
-bool convertLegacyVectorOfDebugRingBufferStatusToHidl(
-    const std::vector<legacy_hal::wifi_ring_buffer_status>& legacy_status_vec,
-    std::vector<WifiDebugRingBufferStatus>* hidl_status_vec);
-bool convertLegacyWakeReasonStatsToHidl(
-    const legacy_hal::WakeReasonStats& legacy_stats,
-    WifiDebugHostWakeReasonStats* hidl_stats);
-legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy(
-    V1_1::IWifiChip::TxPowerScenario hidl_scenario);
-legacy_hal::wifi_latency_mode convertHidlLatencyModeToLegacy(
-    V1_3::IWifiChip::LatencyMode hidl_latency_mode);
-legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy_1_2(
-    V1_2::IWifiChip::TxPowerScenario hidl_scenario);
-bool convertLegacyWifiMacInfosToHidl(
-    const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos,
-    std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo>*
-        hidl_radio_mode_infos);
-legacy_hal::wifi_interface_type convertHidlIfaceTypeToLegacy(
-    IfaceType hidl_interface_type);
-legacy_hal::wifi_multi_sta_use_case convertHidlMultiStaUseCaseToLegacy(
-    IWifiChip::MultiStaUseCase use_case);
-bool convertHidlCoexUnsafeChannelToLegacy(
-    const IWifiChip::CoexUnsafeChannel& hidl_unsafe_channel,
-    legacy_hal::wifi_coex_unsafe_channel* legacy_unsafe_channel);
-bool convertHidlVectorOfCoexUnsafeChannelToLegacy(
-    const std::vector<IWifiChip::CoexUnsafeChannel>& hidl_unsafe_channels,
-    std::vector<legacy_hal::wifi_coex_unsafe_channel>* legacy_unsafe_channels);
-
-// STA iface conversion methods.
-bool convertLegacyFeaturesToHidlStaCapabilities(
-    uint64_t legacy_feature_set, uint32_t legacy_logger_feature_set,
-    uint32_t* hidl_caps);
-bool convertLegacyApfCapabilitiesToHidl(
-    const legacy_hal::PacketFilterCapabilities& legacy_caps,
-    StaApfPacketFilterCapabilities* hidl_caps);
-bool convertLegacyGscanCapabilitiesToHidl(
-    const legacy_hal::wifi_gscan_capabilities& legacy_caps,
-    StaBackgroundScanCapabilities* hidl_caps);
-legacy_hal::wifi_band convertHidlWifiBandToLegacy(V1_0::WifiBand band);
-bool convertHidlGscanParamsToLegacy(
-    const StaBackgroundScanParameters& hidl_scan_params,
-    legacy_hal::wifi_scan_cmd_params* legacy_scan_params);
-// |has_ie_data| indicates whether or not the wifi_scan_result includes 802.11
-// Information Elements (IEs)
-bool convertLegacyGscanResultToHidl(
-    const legacy_hal::wifi_scan_result& legacy_scan_result, bool has_ie_data,
-    StaScanResult* hidl_scan_result);
-// |cached_results| is assumed to not include IEs.
-bool convertLegacyVectorOfCachedGscanResultsToHidl(
-    const std::vector<legacy_hal::wifi_cached_scan_results>&
-        legacy_cached_scan_results,
-    std::vector<StaScanData>* hidl_scan_datas);
-bool convertLegacyLinkLayerStatsToHidl(
-    const legacy_hal::LinkLayerStats& legacy_stats,
-    StaLinkLayerStats* hidl_stats);
-bool convertLegacyRoamingCapabilitiesToHidl(
-    const legacy_hal::wifi_roaming_capabilities& legacy_caps,
-    StaRoamingCapabilities* hidl_caps);
-bool convertHidlRoamingConfigToLegacy(
-    const StaRoamingConfig& hidl_config,
-    legacy_hal::wifi_roaming_config* legacy_config);
-legacy_hal::fw_roaming_state_t convertHidlRoamingStateToLegacy(
-    StaRoamingState state);
-bool convertLegacyVectorOfDebugTxPacketFateToHidl(
-    const std::vector<legacy_hal::wifi_tx_report>& legacy_fates,
-    std::vector<WifiDebugTxPacketFateReport>* hidl_fates);
-bool convertLegacyVectorOfDebugRxPacketFateToHidl(
-    const std::vector<legacy_hal::wifi_rx_report>& legacy_fates,
-    std::vector<WifiDebugRxPacketFateReport>* hidl_fates);
-
-// NAN iface conversion methods.
-void convertToWifiNanStatus(legacy_hal::NanStatusType type, const char* str,
-                            size_t max_len, WifiNanStatus* wifiNanStatus);
-bool convertHidlNanEnableRequestToLegacy(
-    const V1_4::NanEnableRequest& hidl_request,
-    legacy_hal::NanEnableRequest* legacy_request);
-bool convertHidlNanConfigRequestToLegacy(
-    const V1_4::NanConfigRequest& hidl_request,
-    legacy_hal::NanConfigRequest* legacy_request);
-bool convertHidlNanEnableRequest_1_4ToLegacy(
-    const V1_4::NanEnableRequest& hidl_request1,
-    const NanConfigRequestSupplemental& hidl_request2,
-    legacy_hal::NanEnableRequest* legacy_request);
-bool convertHidlNanConfigRequest_1_4ToLegacy(
-    const V1_4::NanConfigRequest& hidl_request1,
-    const NanConfigRequestSupplemental& hidl_request2,
-    legacy_hal::NanConfigRequest* legacy_request);
-bool convertHidlNanEnableRequest_1_5ToLegacy(
-    const V1_4::NanEnableRequest& hidl_request1,
-    const NanConfigRequestSupplemental& hidl_request2,
-    legacy_hal::NanEnableRequest* legacy_request);
-bool convertHidlNanConfigRequest_1_5ToLegacy(
-    const V1_4::NanConfigRequest& hidl_request1,
-    const NanConfigRequestSupplemental& hidl_request2,
-    legacy_hal::NanConfigRequest* legacy_request);
-bool convertHidlNanPublishRequestToLegacy(
-    const NanPublishRequest& hidl_request,
-    legacy_hal::NanPublishRequest* legacy_request);
-bool convertHidlNanSubscribeRequestToLegacy(
-    const NanSubscribeRequest& hidl_request,
-    legacy_hal::NanSubscribeRequest* legacy_request);
-bool convertHidlNanTransmitFollowupRequestToLegacy(
-    const NanTransmitFollowupRequest& hidl_request,
-    legacy_hal::NanTransmitFollowupRequest* legacy_request);
-bool convertHidlNanDataPathInitiatorRequestToLegacy(
-    const NanInitiateDataPathRequest& hidl_request,
-    legacy_hal::NanDataPathInitiatorRequest* legacy_request);
-bool convertHidlNanDataPathIndicationResponseToLegacy(
-    const NanRespondToDataPathIndicationRequest& hidl_response,
-    legacy_hal::NanDataPathIndicationResponse* legacy_response);
-bool convertLegacyNanResponseHeaderToHidl(
-    const legacy_hal::NanResponseMsg& legacy_response,
-    WifiNanStatus* wifiNanStatus);
-bool convertLegacyNanCapabilitiesResponseToHidl(
-    const legacy_hal::NanCapabilities& legacy_response,
-    NanCapabilities* hidl_response);
-bool convertLegacyNanMatchIndToHidl(const legacy_hal::NanMatchInd& legacy_ind,
-                                    NanMatchInd* hidl_ind);
-bool convertLegacyNanFollowupIndToHidl(
-    const legacy_hal::NanFollowupInd& legacy_ind,
-    NanFollowupReceivedInd* hidl_ind);
-bool convertLegacyNanDataPathRequestIndToHidl(
-    const legacy_hal::NanDataPathRequestInd& legacy_ind,
-    NanDataPathRequestInd* hidl_ind);
-bool convertLegacyNanDataPathConfirmIndToHidl(
-    const legacy_hal::NanDataPathConfirmInd& legacy_ind,
-    V1_2::NanDataPathConfirmInd* hidl_ind);
-bool convertLegacyNanDataPathScheduleUpdateIndToHidl(
-    const legacy_hal::NanDataPathScheduleUpdateInd& legacy_ind,
-    V1_2::NanDataPathScheduleUpdateInd* hidl_ind);
-
-// RTT controller conversion methods.
-bool convertHidlVectorOfRttConfigToLegacy(
-    const std::vector<V1_4::RttConfig>& hidl_configs,
-    std::vector<legacy_hal::wifi_rtt_config>* legacy_configs);
-bool convertHidlRttLciInformationToLegacy(
-    const RttLciInformation& hidl_info,
-    legacy_hal::wifi_lci_information* legacy_info);
-bool convertHidlRttLcrInformationToLegacy(
-    const RttLcrInformation& hidl_info,
-    legacy_hal::wifi_lcr_information* legacy_info);
-bool convertHidlRttResponderToLegacy(
-    const V1_4::RttResponder& hidl_responder,
-    legacy_hal::wifi_rtt_responder* legacy_responder);
-bool convertHidlWifiChannelInfoToLegacy(
-    const WifiChannelInfo& hidl_info,
-    legacy_hal::wifi_channel_info* legacy_info);
-bool convertLegacyRttResponderToHidl(
-    const legacy_hal::wifi_rtt_responder& legacy_responder,
-    V1_4::RttResponder* hidl_responder);
-bool convertLegacyRttCapabilitiesToHidl(
-    const legacy_hal::wifi_rtt_capabilities& legacy_capabilities,
-    V1_4::RttCapabilities* hidl_capabilities);
-bool convertLegacyVectorOfRttResultToHidl(
-    const std::vector<const legacy_hal::wifi_rtt_result*>& legacy_results,
-    std::vector<V1_4::RttResult>* hidl_results);
-uint32_t convertHidlWifiBandToLegacyMacBand(V1_5::WifiBand band);
-uint32_t convertHidlWifiIfaceModeToLegacy(uint32_t hidl_iface_mask);
-uint32_t convertHidlUsableChannelFilterToLegacy(uint32_t hidl_filter_mask);
-bool convertLegacyWifiUsableChannelsToHidl(
-    const std::vector<legacy_hal::wifi_usable_channel>& legacy_usable_channels,
-    std::vector<V1_5::WifiUsableChannel>* hidl_usable_channels);
-bool convertLegacyPeerInfoStatsToHidl(
-    const legacy_hal::WifiPeerInfo& legacy_peer_info_stats,
-    StaPeerInfo* hidl_peer_info_stats);
-bool convertLegacyWifiRateInfoToHidl(const legacy_hal::wifi_rate& legacy_rate,
-                                     V1_4::WifiRateInfo* hidl_rate);
-}  // namespace hidl_struct_util
-}  // namespace implementation
-}  // namespace V1_5
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // HIDL_STRUCT_UTIL_H_
diff --git a/wifi/1.5/default/tests/mock_wifi_legacy_hal.h b/wifi/1.5/default/tests/mock_wifi_legacy_hal.h
deleted file mode 100644
index 826b35f..0000000
--- a/wifi/1.5/default/tests/mock_wifi_legacy_hal.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 MOCK_WIFI_LEGACY_HAL_H_
-#define MOCK_WIFI_LEGACY_HAL_H_
-
-#include <gmock/gmock.h>
-
-#include "wifi_legacy_hal.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_5 {
-namespace implementation {
-namespace legacy_hal {
-
-class MockWifiLegacyHal : public WifiLegacyHal {
-   public:
-    MockWifiLegacyHal(
-        const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
-        const wifi_hal_fn& fn, bool is_primary);
-    MOCK_METHOD0(initialize, wifi_error());
-    MOCK_METHOD0(start, wifi_error());
-    MOCK_METHOD2(stop, wifi_error(std::unique_lock<std::recursive_mutex>*,
-                                  const std::function<void()>&));
-    MOCK_METHOD2(setDfsFlag, wifi_error(const std::string&, bool));
-    MOCK_METHOD2(registerRadioModeChangeCallbackHandler,
-                 wifi_error(const std::string&,
-                            const on_radio_mode_change_callback&));
-    MOCK_METHOD1(getFirmwareVersion, std::pair<wifi_error, std::string>(
-                                         const std::string& iface_name));
-    MOCK_METHOD1(getDriverVersion, std::pair<wifi_error, std::string>(
-                                       const std::string& iface_name));
-
-    MOCK_METHOD2(selectTxPowerScenario,
-                 wifi_error(const std::string& iface_name,
-                            wifi_power_scenario scenario));
-    MOCK_METHOD1(resetTxPowerScenario,
-                 wifi_error(const std::string& iface_name));
-    MOCK_METHOD2(nanRegisterCallbackHandlers,
-                 wifi_error(const std::string&, const NanCallbackHandlers&));
-    MOCK_METHOD2(nanDisableRequest,
-                 wifi_error(const std::string&, transaction_id));
-    MOCK_METHOD3(nanDataInterfaceDelete,
-                 wifi_error(const std::string&, transaction_id,
-                            const std::string&));
-    MOCK_METHOD2(createVirtualInterface,
-                 wifi_error(const std::string& ifname,
-                            wifi_interface_type iftype));
-    MOCK_METHOD1(deleteVirtualInterface, wifi_error(const std::string& ifname));
-    MOCK_METHOD0(waitForDriverReady, wifi_error());
-};
-}  // namespace legacy_hal
-}  // namespace implementation
-}  // namespace V1_5
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // MOCK_WIFI_LEGACY_HAL_H_
diff --git a/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp b/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp
deleted file mode 100644
index 32da55e..0000000
--- a/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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-base/macros.h>
-#include <cutils/properties.h>
-#include <gmock/gmock.h>
-
-#undef NAN  // This is weird, NAN is defined in bionic/libc/include/math.h:38
-#include "wifi_nan_iface.h"
-
-#include "mock_interface_tool.h"
-#include "mock_wifi_feature_flags.h"
-#include "mock_wifi_iface_util.h"
-#include "mock_wifi_legacy_hal.h"
-
-using testing::NiceMock;
-using testing::Return;
-using testing::Test;
-
-namespace {
-constexpr char kIfaceName[] = "mockWlan0";
-}  // namespace
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_5 {
-namespace implementation {
-
-using android::hardware::wifi::V1_2::NanDataPathConfirmInd;
-
-bool CaptureIfaceEventHandlers(
-    const std::string& /* iface_name*/,
-    iface_util::IfaceEventHandlers in_iface_event_handlers,
-    iface_util::IfaceEventHandlers* out_iface_event_handlers) {
-    *out_iface_event_handlers = in_iface_event_handlers;
-    return true;
-}
-
-class MockNanIfaceEventCallback : public IWifiNanIfaceEventCallback {
-   public:
-    MockNanIfaceEventCallback() = default;
-
-    MOCK_METHOD3(
-        notifyCapabilitiesResponse,
-        Return<void>(uint16_t, const WifiNanStatus&,
-                     const android::hardware::wifi::V1_0::NanCapabilities&));
-    MOCK_METHOD2(notifyEnableResponse,
-                 Return<void>(uint16_t, const WifiNanStatus&));
-    MOCK_METHOD2(notifyConfigResponse,
-                 Return<void>(uint16_t, const WifiNanStatus&));
-    MOCK_METHOD2(notifyDisableResponse,
-                 Return<void>(uint16_t, const WifiNanStatus&));
-    MOCK_METHOD3(notifyStartPublishResponse,
-                 Return<void>(uint16_t, const WifiNanStatus&, uint8_t));
-    MOCK_METHOD2(notifyStopPublishResponse,
-                 Return<void>(uint16_t, const WifiNanStatus&));
-    MOCK_METHOD3(notifyStartSubscribeResponse,
-                 Return<void>(uint16_t, const WifiNanStatus&, uint8_t));
-    MOCK_METHOD2(notifyStopSubscribeResponse,
-                 Return<void>(uint16_t, const WifiNanStatus&));
-    MOCK_METHOD2(notifyTransmitFollowupResponse,
-                 Return<void>(uint16_t, const WifiNanStatus&));
-    MOCK_METHOD2(notifyCreateDataInterfaceResponse,
-                 Return<void>(uint16_t, const WifiNanStatus&));
-    MOCK_METHOD2(notifyDeleteDataInterfaceResponse,
-                 Return<void>(uint16_t, const WifiNanStatus&));
-    MOCK_METHOD3(notifyInitiateDataPathResponse,
-                 Return<void>(uint16_t, const WifiNanStatus&, uint32_t));
-    MOCK_METHOD2(notifyRespondToDataPathIndicationResponse,
-                 Return<void>(uint16_t, const WifiNanStatus&));
-    MOCK_METHOD2(notifyTerminateDataPathResponse,
-                 Return<void>(uint16_t, const WifiNanStatus&));
-    MOCK_METHOD1(eventClusterEvent, Return<void>(const NanClusterEventInd&));
-    MOCK_METHOD1(eventDisabled, Return<void>(const WifiNanStatus&));
-    MOCK_METHOD2(eventPublishTerminated,
-                 Return<void>(uint8_t, const WifiNanStatus&));
-    MOCK_METHOD2(eventSubscribeTerminated,
-                 Return<void>(uint8_t, const WifiNanStatus&));
-    MOCK_METHOD1(eventMatch, Return<void>(const NanMatchInd&));
-    MOCK_METHOD2(eventMatchExpired, Return<void>(uint8_t, uint32_t));
-    MOCK_METHOD1(eventFollowupReceived,
-                 Return<void>(const NanFollowupReceivedInd&));
-    MOCK_METHOD2(eventTransmitFollowup,
-                 Return<void>(uint16_t, const WifiNanStatus&));
-    MOCK_METHOD1(eventDataPathRequest,
-                 Return<void>(const NanDataPathRequestInd&));
-    MOCK_METHOD1(
-        eventDataPathConfirm,
-        Return<void>(
-            const android::hardware::wifi::V1_0::NanDataPathConfirmInd&));
-    MOCK_METHOD1(eventDataPathTerminated, Return<void>(uint32_t));
-    MOCK_METHOD1(eventDataPathConfirm_1_2,
-                 Return<void>(const NanDataPathConfirmInd&));
-    MOCK_METHOD1(eventDataPathScheduleUpdate,
-                 Return<void>(const NanDataPathScheduleUpdateInd&));
-    MOCK_METHOD3(notifyCapabilitiesResponse_1_5,
-                 Return<void>(uint16_t, const WifiNanStatus&,
-                              const NanCapabilities&));
-};
-
-class WifiNanIfaceTest : public Test {
-   protected:
-    legacy_hal::wifi_hal_fn fake_func_table_;
-    std::shared_ptr<NiceMock<wifi_system::MockInterfaceTool>> iface_tool_{
-        new NiceMock<wifi_system::MockInterfaceTool>};
-    std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
-        new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_,
-                                                    fake_func_table_, true)};
-    std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{
-        new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_, legacy_hal_)};
-};
-
-TEST_F(WifiNanIfaceTest, IfacEventHandlers_OnStateToggleOffOn) {
-    iface_util::IfaceEventHandlers captured_iface_event_handlers = {};
-    EXPECT_CALL(*legacy_hal_,
-                nanRegisterCallbackHandlers(testing::_, testing::_))
-        .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
-    EXPECT_CALL(*iface_util_,
-                registerIfaceEventHandlers(testing::_, testing::_))
-        .WillOnce(testing::Invoke(
-            bind(CaptureIfaceEventHandlers, std::placeholders::_1,
-                 std::placeholders::_2, &captured_iface_event_handlers)));
-    sp<WifiNanIface> nan_iface =
-        new WifiNanIface(kIfaceName, false, legacy_hal_, iface_util_);
-
-    // Register a mock nan event callback.
-    sp<NiceMock<MockNanIfaceEventCallback>> mock_event_callback{
-        new NiceMock<MockNanIfaceEventCallback>};
-    nan_iface->registerEventCallback(
-        mock_event_callback, [](const WifiStatus& status) {
-            ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-        });
-    // Ensure that the eventDisabled() function in mock callback will be
-    // invoked.
-    WifiNanStatus expected_nan_status = {
-        NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""};
-    EXPECT_CALL(*mock_event_callback, eventDisabled(expected_nan_status))
-        .Times(1);
-
-    // Trigger the iface state toggle callback.
-    captured_iface_event_handlers.on_state_toggle_off_on(kIfaceName);
-}
-}  // namespace implementation
-}  // namespace V1_5
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.5/default/wifi_chip.h b/wifi/1.5/default/wifi_chip.h
deleted file mode 100644
index bd40ead..0000000
--- a/wifi/1.5/default/wifi_chip.h
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 WIFI_CHIP_H_
-#define WIFI_CHIP_H_
-
-#include <list>
-#include <map>
-#include <mutex>
-
-#include <android-base/macros.h>
-#include <android/hardware/wifi/1.4/IWifiRttController.h>
-#include <android/hardware/wifi/1.5/IWifiChip.h>
-
-#include "hidl_callback_util.h"
-#include "ringbuffer.h"
-#include "wifi_ap_iface.h"
-#include "wifi_feature_flags.h"
-#include "wifi_legacy_hal.h"
-#include "wifi_mode_controller.h"
-#include "wifi_nan_iface.h"
-#include "wifi_p2p_iface.h"
-#include "wifi_rtt_controller.h"
-#include "wifi_sta_iface.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_5 {
-namespace implementation {
-using namespace android::hardware::wifi::V1_0;
-
-/**
- * HIDL interface object used to control a Wifi HAL chip instance.
- * Since there is only a single chip instance used today, there is no
- * identifying handle information stored here.
- */
-class WifiChip : public V1_5::IWifiChip {
-   public:
-    WifiChip(ChipId chip_id, bool is_primary,
-             const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
-             const std::weak_ptr<mode_controller::WifiModeController>
-                 mode_controller,
-             const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
-             const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
-             const std::function<void(const std::string&)>&
-                 subsystemCallbackHandler);
-    // HIDL does not provide a built-in mechanism to let the server invalidate
-    // a HIDL interface object after creation. If any client process holds onto
-    // a reference to the object in their context, any method calls on that
-    // reference will continue to be directed to the server.
-    //
-    // However Wifi HAL needs to control the lifetime of these objects. So, add
-    // a public |invalidate| method to |WifiChip| and it's child objects. This
-    // will be used to mark an object invalid when either:
-    // a) Wifi HAL is stopped, or
-    // b) Wifi Chip is reconfigured.
-    //
-    // All HIDL method implementations should check if the object is still
-    // marked valid before processing them.
-    void invalidate();
-    bool isValid();
-    std::set<sp<V1_4::IWifiChipEventCallback>> getEventCallbacks();
-
-    // HIDL methods exposed.
-    Return<void> getId(getId_cb hidl_status_cb) override;
-    // Deprecated support for this callback
-    Return<void> registerEventCallback(
-        const sp<V1_0::IWifiChipEventCallback>& event_callback,
-        registerEventCallback_cb hidl_status_cb) override;
-    Return<void> getCapabilities(getCapabilities_cb hidl_status_cb) override;
-    Return<void> getAvailableModes(
-        getAvailableModes_cb hidl_status_cb) override;
-    Return<void> configureChip(ChipModeId mode_id,
-                               configureChip_cb hidl_status_cb) override;
-    Return<void> getMode(getMode_cb hidl_status_cb) override;
-    Return<void> requestChipDebugInfo(
-        requestChipDebugInfo_cb hidl_status_cb) override;
-    Return<void> requestDriverDebugDump(
-        requestDriverDebugDump_cb hidl_status_cb) override;
-    Return<void> requestFirmwareDebugDump(
-        requestFirmwareDebugDump_cb hidl_status_cb) override;
-    Return<void> createApIface(createApIface_cb hidl_status_cb) override;
-    Return<void> createBridgedApIface(
-        createBridgedApIface_cb hidl_status_cb) override;
-    Return<void> getApIfaceNames(getApIfaceNames_cb hidl_status_cb) override;
-    Return<void> getApIface(const hidl_string& ifname,
-                            getApIface_cb hidl_status_cb) override;
-    Return<void> removeApIface(const hidl_string& ifname,
-                               removeApIface_cb hidl_status_cb) override;
-    Return<void> removeIfaceInstanceFromBridgedApIface(
-        const hidl_string& brIfaceName, const hidl_string& ifaceInstanceName,
-        removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) override;
-    Return<void> createNanIface(createNanIface_cb hidl_status_cb) override;
-    Return<void> getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) override;
-    Return<void> getNanIface(const hidl_string& ifname,
-                             getNanIface_cb hidl_status_cb) override;
-    Return<void> removeNanIface(const hidl_string& ifname,
-                                removeNanIface_cb hidl_status_cb) override;
-    Return<void> createP2pIface(createP2pIface_cb hidl_status_cb) override;
-    Return<void> getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) override;
-    Return<void> getP2pIface(const hidl_string& ifname,
-                             getP2pIface_cb hidl_status_cb) override;
-    Return<void> removeP2pIface(const hidl_string& ifname,
-                                removeP2pIface_cb hidl_status_cb) override;
-    Return<void> createStaIface(createStaIface_cb hidl_status_cb) override;
-    Return<void> getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) override;
-    Return<void> getStaIface(const hidl_string& ifname,
-                             getStaIface_cb hidl_status_cb) override;
-    Return<void> removeStaIface(const hidl_string& ifname,
-                                removeStaIface_cb hidl_status_cb) override;
-    Return<void> createRttController(
-        const sp<IWifiIface>& bound_iface,
-        createRttController_cb hidl_status_cb) override;
-    Return<void> getDebugRingBuffersStatus(
-        getDebugRingBuffersStatus_cb hidl_status_cb) override;
-    Return<void> startLoggingToDebugRingBuffer(
-        const hidl_string& ring_name,
-        WifiDebugRingBufferVerboseLevel verbose_level,
-        uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes,
-        startLoggingToDebugRingBuffer_cb hidl_status_cb) override;
-    Return<void> forceDumpToDebugRingBuffer(
-        const hidl_string& ring_name,
-        forceDumpToDebugRingBuffer_cb hidl_status_cb) override;
-    Return<void> flushRingBufferToFile(
-        flushRingBufferToFile_cb hidl_status_cb) override;
-    Return<void> stopLoggingToDebugRingBuffer(
-        stopLoggingToDebugRingBuffer_cb hidl_status_cb) override;
-    Return<void> getDebugHostWakeReasonStats(
-        getDebugHostWakeReasonStats_cb hidl_status_cb) override;
-    Return<void> enableDebugErrorAlerts(
-        bool enable, enableDebugErrorAlerts_cb hidl_status_cb) override;
-    Return<void> selectTxPowerScenario(
-        V1_1::IWifiChip::TxPowerScenario scenario,
-        selectTxPowerScenario_cb hidl_status_cb) override;
-    Return<void> resetTxPowerScenario(
-        resetTxPowerScenario_cb hidl_status_cb) override;
-    Return<void> setLatencyMode(LatencyMode mode,
-                                setLatencyMode_cb hidl_status_cb) override;
-    Return<void> registerEventCallback_1_2(
-        const sp<V1_2::IWifiChipEventCallback>& event_callback,
-        registerEventCallback_1_2_cb hidl_status_cb) override;
-    Return<void> selectTxPowerScenario_1_2(
-        TxPowerScenario scenario,
-        selectTxPowerScenario_cb hidl_status_cb) override;
-    Return<void> getCapabilities_1_3(
-        getCapabilities_cb hidl_status_cb) override;
-    Return<void> getCapabilities_1_5(
-        getCapabilities_1_5_cb hidl_status_cb) override;
-    Return<void> debug(const hidl_handle& handle,
-                       const hidl_vec<hidl_string>& options) override;
-    Return<void> createRttController_1_4(
-        const sp<IWifiIface>& bound_iface,
-        createRttController_1_4_cb hidl_status_cb) override;
-    Return<void> registerEventCallback_1_4(
-        const sp<V1_4::IWifiChipEventCallback>& event_callback,
-        registerEventCallback_1_4_cb hidl_status_cb) override;
-    Return<void> setMultiStaPrimaryConnection(
-        const hidl_string& ifname,
-        setMultiStaPrimaryConnection_cb hidl_status_cb) override;
-    Return<void> setMultiStaUseCase(
-        MultiStaUseCase use_case,
-        setMultiStaUseCase_cb hidl_status_cb) override;
-    Return<void> setCoexUnsafeChannels(
-        const hidl_vec<CoexUnsafeChannel>& unsafe_channels,
-        hidl_bitfield<IfaceType> restrictions,
-        setCoexUnsafeChannels_cb hidl_status_cb) override;
-    Return<void> setCountryCode(const hidl_array<int8_t, 2>& code,
-                                setCountryCode_cb _hidl_cb) override;
-    Return<void> getUsableChannels(
-        WifiBand band, hidl_bitfield<WifiIfaceMode> ifaceModeMask,
-        hidl_bitfield<UsableChannelFilter> filterMask,
-        getUsableChannels_cb _hidl_cb) override;
-    Return<void> triggerSubsystemRestart(
-        triggerSubsystemRestart_cb hidl_status_cb) override;
-
-   private:
-    void invalidateAndRemoveAllIfaces();
-    // When a STA iface is removed any dependent NAN-ifaces/RTT-controllers are
-    // invalidated & removed.
-    void invalidateAndRemoveDependencies(const std::string& removed_iface_name);
-
-    // Corresponding worker functions for the HIDL methods.
-    std::pair<WifiStatus, ChipId> getIdInternal();
-    // Deprecated support for this callback
-    WifiStatus registerEventCallbackInternal(
-        const sp<V1_0::IWifiChipEventCallback>& event_callback);
-    std::pair<WifiStatus, uint32_t> getCapabilitiesInternal();
-    std::pair<WifiStatus, std::vector<ChipMode>> getAvailableModesInternal();
-    WifiStatus configureChipInternal(
-        std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id);
-    std::pair<WifiStatus, uint32_t> getModeInternal();
-    std::pair<WifiStatus, IWifiChip::ChipDebugInfo>
-    requestChipDebugInfoInternal();
-    std::pair<WifiStatus, std::vector<uint8_t>>
-    requestDriverDebugDumpInternal();
-    std::pair<WifiStatus, std::vector<uint8_t>>
-    requestFirmwareDebugDumpInternal();
-    sp<WifiApIface> newWifiApIface(std::string& ifname);
-    WifiStatus createVirtualApInterface(const std::string& apVirtIf);
-    std::pair<WifiStatus, sp<V1_5::IWifiApIface>> createApIfaceInternal();
-    std::pair<WifiStatus, sp<V1_5::IWifiApIface>>
-    createBridgedApIfaceInternal();
-    std::pair<WifiStatus, std::vector<hidl_string>> getApIfaceNamesInternal();
-    std::pair<WifiStatus, sp<V1_5::IWifiApIface>> getApIfaceInternal(
-        const std::string& ifname);
-    WifiStatus removeApIfaceInternal(const std::string& ifname);
-    WifiStatus removeIfaceInstanceFromBridgedApIfaceInternal(
-        const std::string& brIfaceName, const std::string& ifInstanceName);
-    std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> createNanIfaceInternal();
-    std::pair<WifiStatus, std::vector<hidl_string>> getNanIfaceNamesInternal();
-    std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> getNanIfaceInternal(
-        const std::string& ifname);
-    WifiStatus removeNanIfaceInternal(const std::string& ifname);
-    std::pair<WifiStatus, sp<IWifiP2pIface>> createP2pIfaceInternal();
-    std::pair<WifiStatus, std::vector<hidl_string>> getP2pIfaceNamesInternal();
-    std::pair<WifiStatus, sp<IWifiP2pIface>> getP2pIfaceInternal(
-        const std::string& ifname);
-    WifiStatus removeP2pIfaceInternal(const std::string& ifname);
-    std::pair<WifiStatus, sp<V1_5::IWifiStaIface>> createStaIfaceInternal();
-    std::pair<WifiStatus, std::vector<hidl_string>> getStaIfaceNamesInternal();
-    std::pair<WifiStatus, sp<V1_5::IWifiStaIface>> getStaIfaceInternal(
-        const std::string& ifname);
-    WifiStatus removeStaIfaceInternal(const std::string& ifname);
-    std::pair<WifiStatus, sp<V1_0::IWifiRttController>>
-    createRttControllerInternal(const sp<IWifiIface>& bound_iface);
-    std::pair<WifiStatus, std::vector<WifiDebugRingBufferStatus>>
-    getDebugRingBuffersStatusInternal();
-    WifiStatus startLoggingToDebugRingBufferInternal(
-        const hidl_string& ring_name,
-        WifiDebugRingBufferVerboseLevel verbose_level,
-        uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes);
-    WifiStatus forceDumpToDebugRingBufferInternal(const hidl_string& ring_name);
-    WifiStatus flushRingBufferToFileInternal();
-    WifiStatus stopLoggingToDebugRingBufferInternal();
-    std::pair<WifiStatus, WifiDebugHostWakeReasonStats>
-    getDebugHostWakeReasonStatsInternal();
-    WifiStatus enableDebugErrorAlertsInternal(bool enable);
-    WifiStatus selectTxPowerScenarioInternal(
-        V1_1::IWifiChip::TxPowerScenario scenario);
-    WifiStatus resetTxPowerScenarioInternal();
-    WifiStatus setLatencyModeInternal(LatencyMode mode);
-    WifiStatus registerEventCallbackInternal_1_2(
-        const sp<V1_2::IWifiChipEventCallback>& event_callback);
-    WifiStatus selectTxPowerScenarioInternal_1_2(TxPowerScenario scenario);
-    std::pair<WifiStatus, uint32_t> getCapabilitiesInternal_1_3();
-    std::pair<WifiStatus, uint32_t> getCapabilitiesInternal_1_5();
-    std::pair<WifiStatus, sp<V1_4::IWifiRttController>>
-    createRttControllerInternal_1_4(const sp<IWifiIface>& bound_iface);
-    WifiStatus registerEventCallbackInternal_1_4(
-        const sp<V1_4::IWifiChipEventCallback>& event_callback);
-    WifiStatus setMultiStaPrimaryConnectionInternal(const std::string& ifname);
-    WifiStatus setMultiStaUseCaseInternal(MultiStaUseCase use_case);
-    WifiStatus setCoexUnsafeChannelsInternal(
-        std::vector<CoexUnsafeChannel> unsafe_channels, uint32_t restrictions);
-    WifiStatus setCountryCodeInternal(const std::array<int8_t, 2>& code);
-    std::pair<WifiStatus, std::vector<WifiUsableChannel>>
-    getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask,
-                              uint32_t filterMask);
-    WifiStatus handleChipConfiguration(
-        std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id);
-    WifiStatus registerDebugRingBufferCallback();
-    WifiStatus registerRadioModeChangeCallback();
-
-    std::vector<V1_4::IWifiChip::ChipIfaceCombination>
-    getCurrentModeIfaceCombinations();
-    std::map<IfaceType, size_t> getCurrentIfaceCombination();
-    std::vector<std::map<IfaceType, size_t>> expandIfaceCombinations(
-        const V1_4::IWifiChip::ChipIfaceCombination& combination);
-    bool canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces(
-        const std::map<IfaceType, size_t>& expanded_combo,
-        IfaceType requested_type);
-    bool canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(
-        IfaceType requested_type);
-    bool canExpandedIfaceComboSupportIfaceCombo(
-        const std::map<IfaceType, size_t>& expanded_combo,
-        const std::map<IfaceType, size_t>& req_combo);
-    bool canCurrentModeSupportIfaceCombo(
-        const std::map<IfaceType, size_t>& req_combo);
-    bool canCurrentModeSupportIfaceOfType(IfaceType requested_type);
-    bool isValidModeId(ChipModeId mode_id);
-    bool isStaApConcurrencyAllowedInCurrentMode();
-    bool isDualStaConcurrencyAllowedInCurrentMode();
-    uint32_t startIdxOfApIface();
-    std::string getFirstActiveWlanIfaceName();
-    std::string allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx);
-    std::string allocateApIfaceName();
-    std::vector<std::string> allocateBridgedApInstanceNames();
-    std::string allocateStaIfaceName();
-    bool writeRingbufferFilesInternal();
-    std::string getWlanIfaceNameWithType(IfaceType type, unsigned idx);
-    void invalidateAndClearBridgedApAll();
-    void invalidateAndClearBridgedAp(const std::string& br_name);
-    bool findUsingNameFromBridgedApInstances(const std::string& name);
-    WifiStatus triggerSubsystemRestartInternal();
-
-    ChipId chip_id_;
-    std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
-    std::weak_ptr<mode_controller::WifiModeController> mode_controller_;
-    std::shared_ptr<iface_util::WifiIfaceUtil> iface_util_;
-    std::vector<sp<WifiApIface>> ap_ifaces_;
-    std::vector<sp<WifiNanIface>> nan_ifaces_;
-    std::vector<sp<WifiP2pIface>> p2p_ifaces_;
-    std::vector<sp<WifiStaIface>> sta_ifaces_;
-    std::vector<sp<WifiRttController>> rtt_controllers_;
-    std::map<std::string, Ringbuffer> ringbuffer_map_;
-    bool is_valid_;
-    // Members pertaining to chip configuration.
-    uint32_t current_mode_id_;
-    std::mutex lock_t;
-    std::vector<V1_4::IWifiChip::ChipMode> modes_;
-    // The legacy ring buffer callback API has only a global callback
-    // registration mechanism. Use this to check if we have already
-    // registered a callback.
-    bool debug_ring_buffer_cb_registered_;
-    hidl_callback_util::HidlCallbackHandler<V1_4::IWifiChipEventCallback>
-        event_cb_handler_;
-
-    const std::function<void(const std::string&)> subsystemCallbackHandler_;
-    std::map<std::string, std::vector<std::string>> br_ifaces_ap_instances_;
-    DISALLOW_COPY_AND_ASSIGN(WifiChip);
-};
-
-}  // namespace implementation
-}  // namespace V1_5
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WIFI_CHIP_H_
diff --git a/wifi/1.5/default/wifi_legacy_hal.cpp b/wifi/1.5/default/wifi_legacy_hal.cpp
deleted file mode 100644
index 5074252..0000000
--- a/wifi/1.5/default/wifi_legacy_hal.cpp
+++ /dev/null
@@ -1,1725 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 <array>
-#include <chrono>
-
-#include <android-base/logging.h>
-#include <cutils/properties.h>
-#include <net/if.h>
-
-#include "hidl_sync_util.h"
-#include "wifi_legacy_hal.h"
-#include "wifi_legacy_hal_stubs.h"
-
-namespace {
-// Constants ported over from the legacy HAL calling code
-// (com_android_server_wifi_WifiNative.cpp). This will all be thrown
-// away when this shim layer is replaced by the real vendor
-// implementation.
-static constexpr uint32_t kMaxVersionStringLength = 256;
-static constexpr uint32_t kMaxCachedGscanResults = 64;
-static constexpr uint32_t kMaxGscanFrequenciesForBand = 64;
-static constexpr uint32_t kLinkLayerStatsDataMpduSizeThreshold = 128;
-static constexpr uint32_t kMaxWakeReasonStatsArraySize = 32;
-static constexpr uint32_t kMaxRingBuffers = 10;
-static constexpr uint32_t kMaxWifiUsableChannels = 256;
-// need a long timeout (1000ms) for chips that unload their driver.
-static constexpr uint32_t kMaxStopCompleteWaitMs = 1000;
-static constexpr char kDriverPropName[] = "wlan.driver.status";
-
-// Helper function to create a non-const char* for legacy Hal API's.
-std::vector<char> makeCharVec(const std::string& str) {
-    std::vector<char> vec(str.size() + 1);
-    vec.assign(str.begin(), str.end());
-    vec.push_back('\0');
-    return vec;
-}
-}  // namespace
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_5 {
-namespace implementation {
-namespace legacy_hal {
-
-// Legacy HAL functions accept "C" style function pointers, so use global
-// functions to pass to the legacy HAL function and store the corresponding
-// std::function methods to be invoked.
-//
-// Callback to be invoked once |stop| is complete
-std::function<void(wifi_handle handle)> on_stop_complete_internal_callback;
-void onAsyncStopComplete(wifi_handle handle) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_stop_complete_internal_callback) {
-        on_stop_complete_internal_callback(handle);
-        // Invalidate this callback since we don't want this firing again.
-        on_stop_complete_internal_callback = nullptr;
-    }
-}
-
-// Callback to be invoked for driver dump.
-std::function<void(char*, int)> on_driver_memory_dump_internal_callback;
-void onSyncDriverMemoryDump(char* buffer, int buffer_size) {
-    if (on_driver_memory_dump_internal_callback) {
-        on_driver_memory_dump_internal_callback(buffer, buffer_size);
-    }
-}
-
-// Callback to be invoked for firmware dump.
-std::function<void(char*, int)> on_firmware_memory_dump_internal_callback;
-void onSyncFirmwareMemoryDump(char* buffer, int buffer_size) {
-    if (on_firmware_memory_dump_internal_callback) {
-        on_firmware_memory_dump_internal_callback(buffer, buffer_size);
-    }
-}
-
-// Callback to be invoked for Gscan events.
-std::function<void(wifi_request_id, wifi_scan_event)>
-    on_gscan_event_internal_callback;
-void onAsyncGscanEvent(wifi_request_id id, wifi_scan_event event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_gscan_event_internal_callback) {
-        on_gscan_event_internal_callback(id, event);
-    }
-}
-
-// Callback to be invoked for Gscan full results.
-std::function<void(wifi_request_id, wifi_scan_result*, uint32_t)>
-    on_gscan_full_result_internal_callback;
-void onAsyncGscanFullResult(wifi_request_id id, wifi_scan_result* result,
-                            uint32_t buckets_scanned) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_gscan_full_result_internal_callback) {
-        on_gscan_full_result_internal_callback(id, result, buckets_scanned);
-    }
-}
-
-// Callback to be invoked for link layer stats results.
-std::function<void((wifi_request_id, wifi_iface_stat*, int, wifi_radio_stat*))>
-    on_link_layer_stats_result_internal_callback;
-void onSyncLinkLayerStatsResult(wifi_request_id id, wifi_iface_stat* iface_stat,
-                                int num_radios, wifi_radio_stat* radio_stat) {
-    if (on_link_layer_stats_result_internal_callback) {
-        on_link_layer_stats_result_internal_callback(id, iface_stat, num_radios,
-                                                     radio_stat);
-    }
-}
-
-// Callback to be invoked for rssi threshold breach.
-std::function<void((wifi_request_id, uint8_t*, int8_t))>
-    on_rssi_threshold_breached_internal_callback;
-void onAsyncRssiThresholdBreached(wifi_request_id id, uint8_t* bssid,
-                                  int8_t rssi) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_rssi_threshold_breached_internal_callback) {
-        on_rssi_threshold_breached_internal_callback(id, bssid, rssi);
-    }
-}
-
-// Callback to be invoked for ring buffer data indication.
-std::function<void(char*, char*, int, wifi_ring_buffer_status*)>
-    on_ring_buffer_data_internal_callback;
-void onAsyncRingBufferData(char* ring_name, char* buffer, int buffer_size,
-                           wifi_ring_buffer_status* status) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_ring_buffer_data_internal_callback) {
-        on_ring_buffer_data_internal_callback(ring_name, buffer, buffer_size,
-                                              status);
-    }
-}
-
-// Callback to be invoked for error alert indication.
-std::function<void(wifi_request_id, char*, int, int)>
-    on_error_alert_internal_callback;
-void onAsyncErrorAlert(wifi_request_id id, char* buffer, int buffer_size,
-                       int err_code) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_error_alert_internal_callback) {
-        on_error_alert_internal_callback(id, buffer, buffer_size, err_code);
-    }
-}
-
-// Callback to be invoked for radio mode change indication.
-std::function<void(wifi_request_id, uint32_t, wifi_mac_info*)>
-    on_radio_mode_change_internal_callback;
-void onAsyncRadioModeChange(wifi_request_id id, uint32_t num_macs,
-                            wifi_mac_info* mac_infos) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_radio_mode_change_internal_callback) {
-        on_radio_mode_change_internal_callback(id, num_macs, mac_infos);
-    }
-}
-
-// Callback to be invoked to report subsystem restart
-std::function<void(const char*)> on_subsystem_restart_internal_callback;
-void onAsyncSubsystemRestart(const char* error) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_subsystem_restart_internal_callback) {
-        on_subsystem_restart_internal_callback(error);
-    }
-}
-
-// Callback to be invoked for rtt results results.
-std::function<void(wifi_request_id, unsigned num_results,
-                   wifi_rtt_result* rtt_results[])>
-    on_rtt_results_internal_callback;
-void onAsyncRttResults(wifi_request_id id, unsigned num_results,
-                       wifi_rtt_result* rtt_results[]) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_rtt_results_internal_callback) {
-        on_rtt_results_internal_callback(id, num_results, rtt_results);
-        on_rtt_results_internal_callback = nullptr;
-    }
-}
-
-// Callbacks for the various NAN operations.
-// NOTE: These have very little conversions to perform before invoking the user
-// callbacks.
-// So, handle all of them here directly to avoid adding an unnecessary layer.
-std::function<void(transaction_id, const NanResponseMsg&)>
-    on_nan_notify_response_user_callback;
-void onAysncNanNotifyResponse(transaction_id id, NanResponseMsg* msg) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_notify_response_user_callback && msg) {
-        on_nan_notify_response_user_callback(id, *msg);
-    }
-}
-
-std::function<void(const NanPublishRepliedInd&)>
-    on_nan_event_publish_replied_user_callback;
-void onAysncNanEventPublishReplied(NanPublishRepliedInd* /* event */) {
-    LOG(ERROR) << "onAysncNanEventPublishReplied triggered";
-}
-
-std::function<void(const NanPublishTerminatedInd&)>
-    on_nan_event_publish_terminated_user_callback;
-void onAysncNanEventPublishTerminated(NanPublishTerminatedInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_publish_terminated_user_callback && event) {
-        on_nan_event_publish_terminated_user_callback(*event);
-    }
-}
-
-std::function<void(const NanMatchInd&)> on_nan_event_match_user_callback;
-void onAysncNanEventMatch(NanMatchInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_match_user_callback && event) {
-        on_nan_event_match_user_callback(*event);
-    }
-}
-
-std::function<void(const NanMatchExpiredInd&)>
-    on_nan_event_match_expired_user_callback;
-void onAysncNanEventMatchExpired(NanMatchExpiredInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_match_expired_user_callback && event) {
-        on_nan_event_match_expired_user_callback(*event);
-    }
-}
-
-std::function<void(const NanSubscribeTerminatedInd&)>
-    on_nan_event_subscribe_terminated_user_callback;
-void onAysncNanEventSubscribeTerminated(NanSubscribeTerminatedInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_subscribe_terminated_user_callback && event) {
-        on_nan_event_subscribe_terminated_user_callback(*event);
-    }
-}
-
-std::function<void(const NanFollowupInd&)> on_nan_event_followup_user_callback;
-void onAysncNanEventFollowup(NanFollowupInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_followup_user_callback && event) {
-        on_nan_event_followup_user_callback(*event);
-    }
-}
-
-std::function<void(const NanDiscEngEventInd&)>
-    on_nan_event_disc_eng_event_user_callback;
-void onAysncNanEventDiscEngEvent(NanDiscEngEventInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_disc_eng_event_user_callback && event) {
-        on_nan_event_disc_eng_event_user_callback(*event);
-    }
-}
-
-std::function<void(const NanDisabledInd&)> on_nan_event_disabled_user_callback;
-void onAysncNanEventDisabled(NanDisabledInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_disabled_user_callback && event) {
-        on_nan_event_disabled_user_callback(*event);
-    }
-}
-
-std::function<void(const NanTCAInd&)> on_nan_event_tca_user_callback;
-void onAysncNanEventTca(NanTCAInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_tca_user_callback && event) {
-        on_nan_event_tca_user_callback(*event);
-    }
-}
-
-std::function<void(const NanBeaconSdfPayloadInd&)>
-    on_nan_event_beacon_sdf_payload_user_callback;
-void onAysncNanEventBeaconSdfPayload(NanBeaconSdfPayloadInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_beacon_sdf_payload_user_callback && event) {
-        on_nan_event_beacon_sdf_payload_user_callback(*event);
-    }
-}
-
-std::function<void(const NanDataPathRequestInd&)>
-    on_nan_event_data_path_request_user_callback;
-void onAysncNanEventDataPathRequest(NanDataPathRequestInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_data_path_request_user_callback && event) {
-        on_nan_event_data_path_request_user_callback(*event);
-    }
-}
-std::function<void(const NanDataPathConfirmInd&)>
-    on_nan_event_data_path_confirm_user_callback;
-void onAysncNanEventDataPathConfirm(NanDataPathConfirmInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_data_path_confirm_user_callback && event) {
-        on_nan_event_data_path_confirm_user_callback(*event);
-    }
-}
-
-std::function<void(const NanDataPathEndInd&)>
-    on_nan_event_data_path_end_user_callback;
-void onAysncNanEventDataPathEnd(NanDataPathEndInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_data_path_end_user_callback && event) {
-        on_nan_event_data_path_end_user_callback(*event);
-    }
-}
-
-std::function<void(const NanTransmitFollowupInd&)>
-    on_nan_event_transmit_follow_up_user_callback;
-void onAysncNanEventTransmitFollowUp(NanTransmitFollowupInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_transmit_follow_up_user_callback && event) {
-        on_nan_event_transmit_follow_up_user_callback(*event);
-    }
-}
-
-std::function<void(const NanRangeRequestInd&)>
-    on_nan_event_range_request_user_callback;
-void onAysncNanEventRangeRequest(NanRangeRequestInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_range_request_user_callback && event) {
-        on_nan_event_range_request_user_callback(*event);
-    }
-}
-
-std::function<void(const NanRangeReportInd&)>
-    on_nan_event_range_report_user_callback;
-void onAysncNanEventRangeReport(NanRangeReportInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_range_report_user_callback && event) {
-        on_nan_event_range_report_user_callback(*event);
-    }
-}
-
-std::function<void(const NanDataPathScheduleUpdateInd&)>
-    on_nan_event_schedule_update_user_callback;
-void onAsyncNanEventScheduleUpdate(NanDataPathScheduleUpdateInd* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_nan_event_schedule_update_user_callback && event) {
-        on_nan_event_schedule_update_user_callback(*event);
-    }
-}
-
-// Callbacks for the various TWT operations.
-std::function<void(const TwtSetupResponse&)>
-    on_twt_event_setup_response_callback;
-void onAsyncTwtEventSetupResponse(TwtSetupResponse* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_twt_event_setup_response_callback && event) {
-        on_twt_event_setup_response_callback(*event);
-    }
-}
-
-std::function<void(const TwtTeardownCompletion&)>
-    on_twt_event_teardown_completion_callback;
-void onAsyncTwtEventTeardownCompletion(TwtTeardownCompletion* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_twt_event_teardown_completion_callback && event) {
-        on_twt_event_teardown_completion_callback(*event);
-    }
-}
-
-std::function<void(const TwtInfoFrameReceived&)>
-    on_twt_event_info_frame_received_callback;
-void onAsyncTwtEventInfoFrameReceived(TwtInfoFrameReceived* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_twt_event_info_frame_received_callback && event) {
-        on_twt_event_info_frame_received_callback(*event);
-    }
-}
-
-std::function<void(const TwtDeviceNotify&)> on_twt_event_device_notify_callback;
-void onAsyncTwtEventDeviceNotify(TwtDeviceNotify* event) {
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (on_twt_event_device_notify_callback && event) {
-        on_twt_event_device_notify_callback(*event);
-    }
-}
-
-// End of the free-standing "C" style callbacks.
-
-WifiLegacyHal::WifiLegacyHal(
-    const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
-    const wifi_hal_fn& fn, bool is_primary)
-    : global_func_table_(fn),
-      global_handle_(nullptr),
-      awaiting_event_loop_termination_(false),
-      is_started_(false),
-      iface_tool_(iface_tool),
-      is_primary_(is_primary) {}
-
-wifi_error WifiLegacyHal::initialize() {
-    LOG(DEBUG) << "Initialize legacy HAL";
-    // this now does nothing, since HAL function table is provided
-    // to the constructor
-    return WIFI_SUCCESS;
-}
-
-wifi_error WifiLegacyHal::start() {
-    // Ensure that we're starting in a good state.
-    CHECK(global_func_table_.wifi_initialize && !global_handle_ &&
-          iface_name_to_handle_.empty() && !awaiting_event_loop_termination_);
-    if (is_started_) {
-        LOG(DEBUG) << "Legacy HAL already started";
-        return WIFI_SUCCESS;
-    }
-    LOG(DEBUG) << "Waiting for the driver ready";
-    wifi_error status = global_func_table_.wifi_wait_for_driver_ready();
-    if (status == WIFI_ERROR_TIMED_OUT || status == WIFI_ERROR_UNKNOWN) {
-        LOG(ERROR) << "Failed or timed out awaiting driver ready";
-        return status;
-    }
-
-    if (is_primary_) {
-        property_set(kDriverPropName, "ok");
-
-        if (!iface_tool_.lock()->SetWifiUpState(true)) {
-            LOG(ERROR) << "Failed to set WiFi interface up";
-            return WIFI_ERROR_UNKNOWN;
-        }
-    }
-
-    LOG(DEBUG) << "Starting legacy HAL";
-    status = global_func_table_.wifi_initialize(&global_handle_);
-    if (status != WIFI_SUCCESS || !global_handle_) {
-        LOG(ERROR) << "Failed to retrieve global handle";
-        return status;
-    }
-    std::thread(&WifiLegacyHal::runEventLoop, this).detach();
-    status = retrieveIfaceHandles();
-    if (status != WIFI_SUCCESS || iface_name_to_handle_.empty()) {
-        LOG(ERROR) << "Failed to retrieve wlan interface handle";
-        return status;
-    }
-    LOG(DEBUG) << "Legacy HAL start complete";
-    is_started_ = true;
-    return WIFI_SUCCESS;
-}
-
-wifi_error WifiLegacyHal::stop(
-    /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
-    const std::function<void()>& on_stop_complete_user_callback) {
-    if (!is_started_) {
-        LOG(DEBUG) << "Legacy HAL already stopped";
-        on_stop_complete_user_callback();
-        return WIFI_SUCCESS;
-    }
-    LOG(DEBUG) << "Stopping legacy HAL";
-    on_stop_complete_internal_callback = [on_stop_complete_user_callback,
-                                          this](wifi_handle handle) {
-        CHECK_EQ(global_handle_, handle) << "Handle mismatch";
-        LOG(INFO) << "Legacy HAL stop complete callback received";
-        // Invalidate all the internal pointers now that the HAL is
-        // stopped.
-        invalidate();
-        if (is_primary_) iface_tool_.lock()->SetWifiUpState(false);
-        on_stop_complete_user_callback();
-        is_started_ = false;
-    };
-    awaiting_event_loop_termination_ = true;
-    global_func_table_.wifi_cleanup(global_handle_, onAsyncStopComplete);
-    const auto status = stop_wait_cv_.wait_for(
-        *lock, std::chrono::milliseconds(kMaxStopCompleteWaitMs),
-        [this] { return !awaiting_event_loop_termination_; });
-    if (!status) {
-        LOG(ERROR) << "Legacy HAL stop failed or timed out";
-        return WIFI_ERROR_UNKNOWN;
-    }
-    LOG(DEBUG) << "Legacy HAL stop complete";
-    return WIFI_SUCCESS;
-}
-
-bool WifiLegacyHal::isStarted() { return is_started_; }
-
-wifi_error WifiLegacyHal::waitForDriverReady() {
-    return global_func_table_.wifi_wait_for_driver_ready();
-}
-
-std::pair<wifi_error, std::string> WifiLegacyHal::getDriverVersion(
-    const std::string& iface_name) {
-    std::array<char, kMaxVersionStringLength> buffer;
-    buffer.fill(0);
-    wifi_error status = global_func_table_.wifi_get_driver_version(
-        getIfaceHandle(iface_name), buffer.data(), buffer.size());
-    return {status, buffer.data()};
-}
-
-std::pair<wifi_error, std::string> WifiLegacyHal::getFirmwareVersion(
-    const std::string& iface_name) {
-    std::array<char, kMaxVersionStringLength> buffer;
-    buffer.fill(0);
-    wifi_error status = global_func_table_.wifi_get_firmware_version(
-        getIfaceHandle(iface_name), buffer.data(), buffer.size());
-    return {status, buffer.data()};
-}
-
-std::pair<wifi_error, std::vector<uint8_t>>
-WifiLegacyHal::requestDriverMemoryDump(const std::string& iface_name) {
-    std::vector<uint8_t> driver_dump;
-    on_driver_memory_dump_internal_callback = [&driver_dump](char* buffer,
-                                                             int buffer_size) {
-        driver_dump.insert(driver_dump.end(),
-                           reinterpret_cast<uint8_t*>(buffer),
-                           reinterpret_cast<uint8_t*>(buffer) + buffer_size);
-    };
-    wifi_error status = global_func_table_.wifi_get_driver_memory_dump(
-        getIfaceHandle(iface_name), {onSyncDriverMemoryDump});
-    on_driver_memory_dump_internal_callback = nullptr;
-    return {status, std::move(driver_dump)};
-}
-
-std::pair<wifi_error, std::vector<uint8_t>>
-WifiLegacyHal::requestFirmwareMemoryDump(const std::string& iface_name) {
-    std::vector<uint8_t> firmware_dump;
-    on_firmware_memory_dump_internal_callback =
-        [&firmware_dump](char* buffer, int buffer_size) {
-            firmware_dump.insert(
-                firmware_dump.end(), reinterpret_cast<uint8_t*>(buffer),
-                reinterpret_cast<uint8_t*>(buffer) + buffer_size);
-        };
-    wifi_error status = global_func_table_.wifi_get_firmware_memory_dump(
-        getIfaceHandle(iface_name), {onSyncFirmwareMemoryDump});
-    on_firmware_memory_dump_internal_callback = nullptr;
-    return {status, std::move(firmware_dump)};
-}
-
-std::pair<wifi_error, uint64_t> WifiLegacyHal::getSupportedFeatureSet(
-    const std::string& iface_name) {
-    feature_set set = 0, chip_set = 0;
-    wifi_error status = WIFI_SUCCESS;
-
-    static_assert(sizeof(set) == sizeof(uint64_t),
-                  "Some feature_flags can not be represented in output");
-    wifi_interface_handle iface_handle = getIfaceHandle(iface_name);
-
-    global_func_table_.wifi_get_chip_feature_set(
-        global_handle_, &chip_set); /* ignore error, chip_set will stay 0 */
-
-    if (iface_handle) {
-        status = global_func_table_.wifi_get_supported_feature_set(iface_handle,
-                                                                   &set);
-    }
-    return {status, static_cast<uint64_t>(set | chip_set)};
-}
-
-std::pair<wifi_error, PacketFilterCapabilities>
-WifiLegacyHal::getPacketFilterCapabilities(const std::string& iface_name) {
-    PacketFilterCapabilities caps;
-    wifi_error status = global_func_table_.wifi_get_packet_filter_capabilities(
-        getIfaceHandle(iface_name), &caps.version, &caps.max_len);
-    return {status, caps};
-}
-
-wifi_error WifiLegacyHal::setPacketFilter(const std::string& iface_name,
-                                          const std::vector<uint8_t>& program) {
-    return global_func_table_.wifi_set_packet_filter(
-        getIfaceHandle(iface_name), program.data(), program.size());
-}
-
-std::pair<wifi_error, std::vector<uint8_t>>
-WifiLegacyHal::readApfPacketFilterData(const std::string& iface_name) {
-    PacketFilterCapabilities caps;
-    wifi_error status = global_func_table_.wifi_get_packet_filter_capabilities(
-        getIfaceHandle(iface_name), &caps.version, &caps.max_len);
-    if (status != WIFI_SUCCESS) {
-        return {status, {}};
-    }
-
-    // Size the buffer to read the entire program & work memory.
-    std::vector<uint8_t> buffer(caps.max_len);
-
-    status = global_func_table_.wifi_read_packet_filter(
-        getIfaceHandle(iface_name), /*src_offset=*/0, buffer.data(),
-        buffer.size());
-    return {status, move(buffer)};
-}
-
-std::pair<wifi_error, wifi_gscan_capabilities>
-WifiLegacyHal::getGscanCapabilities(const std::string& iface_name) {
-    wifi_gscan_capabilities caps;
-    wifi_error status = global_func_table_.wifi_get_gscan_capabilities(
-        getIfaceHandle(iface_name), &caps);
-    return {status, caps};
-}
-
-wifi_error WifiLegacyHal::startGscan(
-    const std::string& iface_name, wifi_request_id id,
-    const wifi_scan_cmd_params& params,
-    const std::function<void(wifi_request_id)>& on_failure_user_callback,
-    const on_gscan_results_callback& on_results_user_callback,
-    const on_gscan_full_result_callback& on_full_result_user_callback) {
-    // If there is already an ongoing background scan, reject new scan requests.
-    if (on_gscan_event_internal_callback ||
-        on_gscan_full_result_internal_callback) {
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-
-    // This callback will be used to either trigger |on_results_user_callback|
-    // or |on_failure_user_callback|.
-    on_gscan_event_internal_callback =
-        [iface_name, on_failure_user_callback, on_results_user_callback, this](
-            wifi_request_id id, wifi_scan_event event) {
-            switch (event) {
-                case WIFI_SCAN_RESULTS_AVAILABLE:
-                case WIFI_SCAN_THRESHOLD_NUM_SCANS:
-                case WIFI_SCAN_THRESHOLD_PERCENT: {
-                    wifi_error status;
-                    std::vector<wifi_cached_scan_results> cached_scan_results;
-                    std::tie(status, cached_scan_results) =
-                        getGscanCachedResults(iface_name);
-                    if (status == WIFI_SUCCESS) {
-                        on_results_user_callback(id, cached_scan_results);
-                        return;
-                    }
-                    FALLTHROUGH_INTENDED;
-                }
-                // Fall through if failed. Failure to retrieve cached scan
-                // results should trigger a background scan failure.
-                case WIFI_SCAN_FAILED:
-                    on_failure_user_callback(id);
-                    on_gscan_event_internal_callback = nullptr;
-                    on_gscan_full_result_internal_callback = nullptr;
-                    return;
-            }
-            LOG(FATAL) << "Unexpected gscan event received: " << event;
-        };
-
-    on_gscan_full_result_internal_callback = [on_full_result_user_callback](
-                                                 wifi_request_id id,
-                                                 wifi_scan_result* result,
-                                                 uint32_t buckets_scanned) {
-        if (result) {
-            on_full_result_user_callback(id, result, buckets_scanned);
-        }
-    };
-
-    wifi_scan_result_handler handler = {onAsyncGscanFullResult,
-                                        onAsyncGscanEvent};
-    wifi_error status = global_func_table_.wifi_start_gscan(
-        id, getIfaceHandle(iface_name), params, handler);
-    if (status != WIFI_SUCCESS) {
-        on_gscan_event_internal_callback = nullptr;
-        on_gscan_full_result_internal_callback = nullptr;
-    }
-    return status;
-}
-
-wifi_error WifiLegacyHal::stopGscan(const std::string& iface_name,
-                                    wifi_request_id id) {
-    // If there is no an ongoing background scan, reject stop requests.
-    // TODO(b/32337212): This needs to be handled by the HIDL object because we
-    // need to return the NOT_STARTED error code.
-    if (!on_gscan_event_internal_callback &&
-        !on_gscan_full_result_internal_callback) {
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-    wifi_error status =
-        global_func_table_.wifi_stop_gscan(id, getIfaceHandle(iface_name));
-    // If the request Id is wrong, don't stop the ongoing background scan. Any
-    // other error should be treated as the end of background scan.
-    if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
-        on_gscan_event_internal_callback = nullptr;
-        on_gscan_full_result_internal_callback = nullptr;
-    }
-    return status;
-}
-
-std::pair<wifi_error, std::vector<uint32_t>>
-WifiLegacyHal::getValidFrequenciesForBand(const std::string& iface_name,
-                                          wifi_band band) {
-    static_assert(sizeof(uint32_t) >= sizeof(wifi_channel),
-                  "Wifi Channel cannot be represented in output");
-    std::vector<uint32_t> freqs;
-    freqs.resize(kMaxGscanFrequenciesForBand);
-    int32_t num_freqs = 0;
-    wifi_error status = global_func_table_.wifi_get_valid_channels(
-        getIfaceHandle(iface_name), band, freqs.size(),
-        reinterpret_cast<wifi_channel*>(freqs.data()), &num_freqs);
-    CHECK(num_freqs >= 0 &&
-          static_cast<uint32_t>(num_freqs) <= kMaxGscanFrequenciesForBand);
-    freqs.resize(num_freqs);
-    return {status, std::move(freqs)};
-}
-
-wifi_error WifiLegacyHal::setDfsFlag(const std::string& iface_name,
-                                     bool dfs_on) {
-    return global_func_table_.wifi_set_nodfs_flag(getIfaceHandle(iface_name),
-                                                  dfs_on ? 0 : 1);
-}
-
-wifi_error WifiLegacyHal::enableLinkLayerStats(const std::string& iface_name,
-                                               bool debug) {
-    wifi_link_layer_params params;
-    params.mpdu_size_threshold = kLinkLayerStatsDataMpduSizeThreshold;
-    params.aggressive_statistics_gathering = debug;
-    return global_func_table_.wifi_set_link_stats(getIfaceHandle(iface_name),
-                                                  params);
-}
-
-wifi_error WifiLegacyHal::disableLinkLayerStats(const std::string& iface_name) {
-    // TODO: Do we care about these responses?
-    uint32_t clear_mask_rsp;
-    uint8_t stop_rsp;
-    return global_func_table_.wifi_clear_link_stats(
-        getIfaceHandle(iface_name), 0xFFFFFFFF, &clear_mask_rsp, 1, &stop_rsp);
-}
-
-std::pair<wifi_error, LinkLayerStats> WifiLegacyHal::getLinkLayerStats(
-    const std::string& iface_name) {
-    LinkLayerStats link_stats{};
-    LinkLayerStats* link_stats_ptr = &link_stats;
-
-    on_link_layer_stats_result_internal_callback =
-        [&link_stats_ptr](wifi_request_id /* id */,
-                          wifi_iface_stat* iface_stats_ptr, int num_radios,
-                          wifi_radio_stat* radio_stats_ptr) {
-            wifi_radio_stat* l_radio_stats_ptr;
-            wifi_peer_info* l_peer_info_stats_ptr;
-
-            if (iface_stats_ptr != nullptr) {
-                link_stats_ptr->iface = *iface_stats_ptr;
-                l_peer_info_stats_ptr = iface_stats_ptr->peer_info;
-                for (uint32_t i = 0; i < iface_stats_ptr->num_peers; i++) {
-                    WifiPeerInfo peer;
-                    peer.peer_info = *l_peer_info_stats_ptr;
-                    if (l_peer_info_stats_ptr->num_rate > 0) {
-                        /* Copy the rate stats */
-                        peer.rate_stats.assign(
-                            l_peer_info_stats_ptr->rate_stats,
-                            l_peer_info_stats_ptr->rate_stats +
-                                l_peer_info_stats_ptr->num_rate);
-                    }
-                    peer.peer_info.num_rate = 0;
-                    link_stats_ptr->peers.push_back(peer);
-                    l_peer_info_stats_ptr =
-                        (wifi_peer_info*)((u8*)l_peer_info_stats_ptr +
-                                          sizeof(wifi_peer_info) +
-                                          (sizeof(wifi_rate_stat) *
-                                           l_peer_info_stats_ptr->num_rate));
-                }
-                link_stats_ptr->iface.num_peers = 0;
-            } else {
-                LOG(ERROR) << "Invalid iface stats in link layer stats";
-            }
-            if (num_radios <= 0 || radio_stats_ptr == nullptr) {
-                LOG(ERROR) << "Invalid radio stats in link layer stats";
-                return;
-            }
-            l_radio_stats_ptr = radio_stats_ptr;
-            for (int i = 0; i < num_radios; i++) {
-                LinkLayerRadioStats radio;
-
-                radio.stats = *l_radio_stats_ptr;
-                // Copy over the tx level array to the separate vector.
-                if (l_radio_stats_ptr->num_tx_levels > 0 &&
-                    l_radio_stats_ptr->tx_time_per_levels != nullptr) {
-                    radio.tx_time_per_levels.assign(
-                        l_radio_stats_ptr->tx_time_per_levels,
-                        l_radio_stats_ptr->tx_time_per_levels +
-                            l_radio_stats_ptr->num_tx_levels);
-                }
-                radio.stats.num_tx_levels = 0;
-                radio.stats.tx_time_per_levels = nullptr;
-                /* Copy over the channel stat to separate vector */
-                if (l_radio_stats_ptr->num_channels > 0) {
-                    /* Copy the channel stats */
-                    radio.channel_stats.assign(
-                        l_radio_stats_ptr->channels,
-                        l_radio_stats_ptr->channels +
-                            l_radio_stats_ptr->num_channels);
-                }
-                link_stats_ptr->radios.push_back(radio);
-                l_radio_stats_ptr =
-                    (wifi_radio_stat*)((u8*)l_radio_stats_ptr +
-                                       sizeof(wifi_radio_stat) +
-                                       (sizeof(wifi_channel_stat) *
-                                        l_radio_stats_ptr->num_channels));
-            }
-        };
-
-    wifi_error status = global_func_table_.wifi_get_link_stats(
-        0, getIfaceHandle(iface_name), {onSyncLinkLayerStatsResult});
-    on_link_layer_stats_result_internal_callback = nullptr;
-    return {status, link_stats};
-}
-
-wifi_error WifiLegacyHal::startRssiMonitoring(
-    const std::string& iface_name, wifi_request_id id, int8_t max_rssi,
-    int8_t min_rssi,
-    const on_rssi_threshold_breached_callback&
-        on_threshold_breached_user_callback) {
-    if (on_rssi_threshold_breached_internal_callback) {
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-    on_rssi_threshold_breached_internal_callback =
-        [on_threshold_breached_user_callback](wifi_request_id id,
-                                              uint8_t* bssid_ptr, int8_t rssi) {
-            if (!bssid_ptr) {
-                return;
-            }
-            std::array<uint8_t, 6> bssid_arr;
-            // |bssid_ptr| pointer is assumed to have 6 bytes for the mac
-            // address.
-            std::copy(bssid_ptr, bssid_ptr + 6, std::begin(bssid_arr));
-            on_threshold_breached_user_callback(id, bssid_arr, rssi);
-        };
-    wifi_error status = global_func_table_.wifi_start_rssi_monitoring(
-        id, getIfaceHandle(iface_name), max_rssi, min_rssi,
-        {onAsyncRssiThresholdBreached});
-    if (status != WIFI_SUCCESS) {
-        on_rssi_threshold_breached_internal_callback = nullptr;
-    }
-    return status;
-}
-
-wifi_error WifiLegacyHal::stopRssiMonitoring(const std::string& iface_name,
-                                             wifi_request_id id) {
-    if (!on_rssi_threshold_breached_internal_callback) {
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-    wifi_error status = global_func_table_.wifi_stop_rssi_monitoring(
-        id, getIfaceHandle(iface_name));
-    // If the request Id is wrong, don't stop the ongoing rssi monitoring. Any
-    // other error should be treated as the end of background scan.
-    if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
-        on_rssi_threshold_breached_internal_callback = nullptr;
-    }
-    return status;
-}
-
-std::pair<wifi_error, wifi_roaming_capabilities>
-WifiLegacyHal::getRoamingCapabilities(const std::string& iface_name) {
-    wifi_roaming_capabilities caps;
-    wifi_error status = global_func_table_.wifi_get_roaming_capabilities(
-        getIfaceHandle(iface_name), &caps);
-    return {status, caps};
-}
-
-wifi_error WifiLegacyHal::configureRoaming(const std::string& iface_name,
-                                           const wifi_roaming_config& config) {
-    wifi_roaming_config config_internal = config;
-    return global_func_table_.wifi_configure_roaming(getIfaceHandle(iface_name),
-                                                     &config_internal);
-}
-
-wifi_error WifiLegacyHal::enableFirmwareRoaming(const std::string& iface_name,
-                                                fw_roaming_state_t state) {
-    return global_func_table_.wifi_enable_firmware_roaming(
-        getIfaceHandle(iface_name), state);
-}
-
-wifi_error WifiLegacyHal::configureNdOffload(const std::string& iface_name,
-                                             bool enable) {
-    return global_func_table_.wifi_configure_nd_offload(
-        getIfaceHandle(iface_name), enable);
-}
-
-wifi_error WifiLegacyHal::startSendingOffloadedPacket(
-    const std::string& iface_name, uint32_t cmd_id, uint16_t ether_type,
-    const std::vector<uint8_t>& ip_packet_data,
-    const std::array<uint8_t, 6>& src_address,
-    const std::array<uint8_t, 6>& dst_address, uint32_t period_in_ms) {
-    std::vector<uint8_t> ip_packet_data_internal(ip_packet_data);
-    std::vector<uint8_t> src_address_internal(
-        src_address.data(), src_address.data() + src_address.size());
-    std::vector<uint8_t> dst_address_internal(
-        dst_address.data(), dst_address.data() + dst_address.size());
-    return global_func_table_.wifi_start_sending_offloaded_packet(
-        cmd_id, getIfaceHandle(iface_name), ether_type,
-        ip_packet_data_internal.data(), ip_packet_data_internal.size(),
-        src_address_internal.data(), dst_address_internal.data(), period_in_ms);
-}
-
-wifi_error WifiLegacyHal::stopSendingOffloadedPacket(
-    const std::string& iface_name, uint32_t cmd_id) {
-    return global_func_table_.wifi_stop_sending_offloaded_packet(
-        cmd_id, getIfaceHandle(iface_name));
-}
-
-wifi_error WifiLegacyHal::selectTxPowerScenario(const std::string& iface_name,
-                                                wifi_power_scenario scenario) {
-    return global_func_table_.wifi_select_tx_power_scenario(
-        getIfaceHandle(iface_name), scenario);
-}
-
-wifi_error WifiLegacyHal::resetTxPowerScenario(const std::string& iface_name) {
-    return global_func_table_.wifi_reset_tx_power_scenario(
-        getIfaceHandle(iface_name));
-}
-
-wifi_error WifiLegacyHal::setLatencyMode(const std::string& iface_name,
-                                         wifi_latency_mode mode) {
-    return global_func_table_.wifi_set_latency_mode(getIfaceHandle(iface_name),
-                                                    mode);
-}
-
-wifi_error WifiLegacyHal::setThermalMitigationMode(wifi_thermal_mode mode,
-                                                   uint32_t completion_window) {
-    return global_func_table_.wifi_set_thermal_mitigation_mode(
-        global_handle_, mode, completion_window);
-}
-
-wifi_error WifiLegacyHal::setDscpToAccessCategoryMapping(
-    uint32_t start, uint32_t end, uint32_t access_category) {
-    return global_func_table_.wifi_map_dscp_access_category(
-        global_handle_, start, end, access_category);
-}
-
-wifi_error WifiLegacyHal::resetDscpToAccessCategoryMapping() {
-    return global_func_table_.wifi_reset_dscp_mapping(global_handle_);
-}
-
-std::pair<wifi_error, uint32_t> WifiLegacyHal::getLoggerSupportedFeatureSet(
-    const std::string& iface_name) {
-    uint32_t supported_feature_flags = 0;
-    wifi_error status = WIFI_SUCCESS;
-
-    wifi_interface_handle iface_handle = getIfaceHandle(iface_name);
-
-    if (iface_handle) {
-        status = global_func_table_.wifi_get_logger_supported_feature_set(
-            iface_handle, &supported_feature_flags);
-    }
-    return {status, supported_feature_flags};
-}
-
-wifi_error WifiLegacyHal::startPktFateMonitoring(
-    const std::string& iface_name) {
-    return global_func_table_.wifi_start_pkt_fate_monitoring(
-        getIfaceHandle(iface_name));
-}
-
-std::pair<wifi_error, std::vector<wifi_tx_report>> WifiLegacyHal::getTxPktFates(
-    const std::string& iface_name) {
-    std::vector<wifi_tx_report> tx_pkt_fates;
-    tx_pkt_fates.resize(MAX_FATE_LOG_LEN);
-    size_t num_fates = 0;
-    wifi_error status = global_func_table_.wifi_get_tx_pkt_fates(
-        getIfaceHandle(iface_name), tx_pkt_fates.data(), tx_pkt_fates.size(),
-        &num_fates);
-    CHECK(num_fates <= MAX_FATE_LOG_LEN);
-    tx_pkt_fates.resize(num_fates);
-    return {status, std::move(tx_pkt_fates)};
-}
-
-std::pair<wifi_error, std::vector<wifi_rx_report>> WifiLegacyHal::getRxPktFates(
-    const std::string& iface_name) {
-    std::vector<wifi_rx_report> rx_pkt_fates;
-    rx_pkt_fates.resize(MAX_FATE_LOG_LEN);
-    size_t num_fates = 0;
-    wifi_error status = global_func_table_.wifi_get_rx_pkt_fates(
-        getIfaceHandle(iface_name), rx_pkt_fates.data(), rx_pkt_fates.size(),
-        &num_fates);
-    CHECK(num_fates <= MAX_FATE_LOG_LEN);
-    rx_pkt_fates.resize(num_fates);
-    return {status, std::move(rx_pkt_fates)};
-}
-
-std::pair<wifi_error, WakeReasonStats> WifiLegacyHal::getWakeReasonStats(
-    const std::string& iface_name) {
-    WakeReasonStats stats;
-    stats.cmd_event_wake_cnt.resize(kMaxWakeReasonStatsArraySize);
-    stats.driver_fw_local_wake_cnt.resize(kMaxWakeReasonStatsArraySize);
-
-    // This legacy struct needs separate memory to store the variable sized wake
-    // reason types.
-    stats.wake_reason_cnt.cmd_event_wake_cnt =
-        reinterpret_cast<int32_t*>(stats.cmd_event_wake_cnt.data());
-    stats.wake_reason_cnt.cmd_event_wake_cnt_sz =
-        stats.cmd_event_wake_cnt.size();
-    stats.wake_reason_cnt.cmd_event_wake_cnt_used = 0;
-    stats.wake_reason_cnt.driver_fw_local_wake_cnt =
-        reinterpret_cast<int32_t*>(stats.driver_fw_local_wake_cnt.data());
-    stats.wake_reason_cnt.driver_fw_local_wake_cnt_sz =
-        stats.driver_fw_local_wake_cnt.size();
-    stats.wake_reason_cnt.driver_fw_local_wake_cnt_used = 0;
-
-    wifi_error status = global_func_table_.wifi_get_wake_reason_stats(
-        getIfaceHandle(iface_name), &stats.wake_reason_cnt);
-
-    CHECK(
-        stats.wake_reason_cnt.cmd_event_wake_cnt_used >= 0 &&
-        static_cast<uint32_t>(stats.wake_reason_cnt.cmd_event_wake_cnt_used) <=
-            kMaxWakeReasonStatsArraySize);
-    stats.cmd_event_wake_cnt.resize(
-        stats.wake_reason_cnt.cmd_event_wake_cnt_used);
-    stats.wake_reason_cnt.cmd_event_wake_cnt = nullptr;
-
-    CHECK(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used >= 0 &&
-          static_cast<uint32_t>(
-              stats.wake_reason_cnt.driver_fw_local_wake_cnt_used) <=
-              kMaxWakeReasonStatsArraySize);
-    stats.driver_fw_local_wake_cnt.resize(
-        stats.wake_reason_cnt.driver_fw_local_wake_cnt_used);
-    stats.wake_reason_cnt.driver_fw_local_wake_cnt = nullptr;
-
-    return {status, stats};
-}
-
-wifi_error WifiLegacyHal::registerRingBufferCallbackHandler(
-    const std::string& iface_name,
-    const on_ring_buffer_data_callback& on_user_data_callback) {
-    if (on_ring_buffer_data_internal_callback) {
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-    on_ring_buffer_data_internal_callback =
-        [on_user_data_callback](char* ring_name, char* buffer, int buffer_size,
-                                wifi_ring_buffer_status* status) {
-            if (status && buffer) {
-                std::vector<uint8_t> buffer_vector(
-                    reinterpret_cast<uint8_t*>(buffer),
-                    reinterpret_cast<uint8_t*>(buffer) + buffer_size);
-                on_user_data_callback(ring_name, buffer_vector, *status);
-            }
-        };
-    wifi_error status = global_func_table_.wifi_set_log_handler(
-        0, getIfaceHandle(iface_name), {onAsyncRingBufferData});
-    if (status != WIFI_SUCCESS) {
-        on_ring_buffer_data_internal_callback = nullptr;
-    }
-    return status;
-}
-
-wifi_error WifiLegacyHal::deregisterRingBufferCallbackHandler(
-    const std::string& iface_name) {
-    if (!on_ring_buffer_data_internal_callback) {
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-    on_ring_buffer_data_internal_callback = nullptr;
-    return global_func_table_.wifi_reset_log_handler(
-        0, getIfaceHandle(iface_name));
-}
-
-std::pair<wifi_error, std::vector<wifi_ring_buffer_status>>
-WifiLegacyHal::getRingBuffersStatus(const std::string& iface_name) {
-    std::vector<wifi_ring_buffer_status> ring_buffers_status;
-    ring_buffers_status.resize(kMaxRingBuffers);
-    uint32_t num_rings = kMaxRingBuffers;
-    wifi_error status = global_func_table_.wifi_get_ring_buffers_status(
-        getIfaceHandle(iface_name), &num_rings, ring_buffers_status.data());
-    CHECK(num_rings <= kMaxRingBuffers);
-    ring_buffers_status.resize(num_rings);
-    return {status, std::move(ring_buffers_status)};
-}
-
-wifi_error WifiLegacyHal::startRingBufferLogging(const std::string& iface_name,
-                                                 const std::string& ring_name,
-                                                 uint32_t verbose_level,
-                                                 uint32_t max_interval_sec,
-                                                 uint32_t min_data_size) {
-    return global_func_table_.wifi_start_logging(
-        getIfaceHandle(iface_name), verbose_level, 0, max_interval_sec,
-        min_data_size, makeCharVec(ring_name).data());
-}
-
-wifi_error WifiLegacyHal::getRingBufferData(const std::string& iface_name,
-                                            const std::string& ring_name) {
-    return global_func_table_.wifi_get_ring_data(getIfaceHandle(iface_name),
-                                                 makeCharVec(ring_name).data());
-}
-
-wifi_error WifiLegacyHal::registerErrorAlertCallbackHandler(
-    const std::string& iface_name,
-    const on_error_alert_callback& on_user_alert_callback) {
-    if (on_error_alert_internal_callback) {
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-    on_error_alert_internal_callback = [on_user_alert_callback](
-                                           wifi_request_id id, char* buffer,
-                                           int buffer_size, int err_code) {
-        if (buffer) {
-            CHECK(id == 0);
-            on_user_alert_callback(
-                err_code,
-                std::vector<uint8_t>(
-                    reinterpret_cast<uint8_t*>(buffer),
-                    reinterpret_cast<uint8_t*>(buffer) + buffer_size));
-        }
-    };
-    wifi_error status = global_func_table_.wifi_set_alert_handler(
-        0, getIfaceHandle(iface_name), {onAsyncErrorAlert});
-    if (status != WIFI_SUCCESS) {
-        on_error_alert_internal_callback = nullptr;
-    }
-    return status;
-}
-
-wifi_error WifiLegacyHal::deregisterErrorAlertCallbackHandler(
-    const std::string& iface_name) {
-    if (!on_error_alert_internal_callback) {
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-    on_error_alert_internal_callback = nullptr;
-    return global_func_table_.wifi_reset_alert_handler(
-        0, getIfaceHandle(iface_name));
-}
-
-wifi_error WifiLegacyHal::registerRadioModeChangeCallbackHandler(
-    const std::string& iface_name,
-    const on_radio_mode_change_callback& on_user_change_callback) {
-    if (on_radio_mode_change_internal_callback) {
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-    on_radio_mode_change_internal_callback = [on_user_change_callback](
-                                                 wifi_request_id /* id */,
-                                                 uint32_t num_macs,
-                                                 wifi_mac_info* mac_infos_arr) {
-        if (num_macs > 0 && mac_infos_arr) {
-            std::vector<WifiMacInfo> mac_infos_vec;
-            for (uint32_t i = 0; i < num_macs; i++) {
-                WifiMacInfo mac_info;
-                mac_info.wlan_mac_id = mac_infos_arr[i].wlan_mac_id;
-                mac_info.mac_band = mac_infos_arr[i].mac_band;
-                for (int32_t j = 0; j < mac_infos_arr[i].num_iface; j++) {
-                    WifiIfaceInfo iface_info;
-                    iface_info.name = mac_infos_arr[i].iface_info[j].iface_name;
-                    iface_info.channel = mac_infos_arr[i].iface_info[j].channel;
-                    mac_info.iface_infos.push_back(iface_info);
-                }
-                mac_infos_vec.push_back(mac_info);
-            }
-            on_user_change_callback(mac_infos_vec);
-        }
-    };
-    wifi_error status = global_func_table_.wifi_set_radio_mode_change_handler(
-        0, getIfaceHandle(iface_name), {onAsyncRadioModeChange});
-    if (status != WIFI_SUCCESS) {
-        on_radio_mode_change_internal_callback = nullptr;
-    }
-    return status;
-}
-
-wifi_error WifiLegacyHal::registerSubsystemRestartCallbackHandler(
-    const on_subsystem_restart_callback& on_restart_callback) {
-    if (on_subsystem_restart_internal_callback) {
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-    on_subsystem_restart_internal_callback =
-        [on_restart_callback](const char* error) {
-            on_restart_callback(error);
-        };
-    wifi_error status = global_func_table_.wifi_set_subsystem_restart_handler(
-        global_handle_, {onAsyncSubsystemRestart});
-    if (status != WIFI_SUCCESS) {
-        on_subsystem_restart_internal_callback = nullptr;
-    }
-    return status;
-}
-
-wifi_error WifiLegacyHal::startRttRangeRequest(
-    const std::string& iface_name, wifi_request_id id,
-    const std::vector<wifi_rtt_config>& rtt_configs,
-    const on_rtt_results_callback& on_results_user_callback) {
-    if (on_rtt_results_internal_callback) {
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-
-    on_rtt_results_internal_callback =
-        [on_results_user_callback](wifi_request_id id, unsigned num_results,
-                                   wifi_rtt_result* rtt_results[]) {
-            if (num_results > 0 && !rtt_results) {
-                LOG(ERROR) << "Unexpected nullptr in RTT results";
-                return;
-            }
-            std::vector<const wifi_rtt_result*> rtt_results_vec;
-            std::copy_if(rtt_results, rtt_results + num_results,
-                         back_inserter(rtt_results_vec),
-                         [](wifi_rtt_result* rtt_result) {
-                             return rtt_result != nullptr;
-                         });
-            on_results_user_callback(id, rtt_results_vec);
-        };
-
-    std::vector<wifi_rtt_config> rtt_configs_internal(rtt_configs);
-    wifi_error status = global_func_table_.wifi_rtt_range_request(
-        id, getIfaceHandle(iface_name), rtt_configs.size(),
-        rtt_configs_internal.data(), {onAsyncRttResults});
-    if (status != WIFI_SUCCESS) {
-        on_rtt_results_internal_callback = nullptr;
-    }
-    return status;
-}
-
-wifi_error WifiLegacyHal::cancelRttRangeRequest(
-    const std::string& iface_name, wifi_request_id id,
-    const std::vector<std::array<uint8_t, 6>>& mac_addrs) {
-    if (!on_rtt_results_internal_callback) {
-        return WIFI_ERROR_NOT_AVAILABLE;
-    }
-    static_assert(sizeof(mac_addr) == sizeof(std::array<uint8_t, 6>),
-                  "MAC address size mismatch");
-    // TODO: How do we handle partial cancels (i.e only a subset of enabled mac
-    // addressed are cancelled).
-    std::vector<std::array<uint8_t, 6>> mac_addrs_internal(mac_addrs);
-    wifi_error status = global_func_table_.wifi_rtt_range_cancel(
-        id, getIfaceHandle(iface_name), mac_addrs.size(),
-        reinterpret_cast<mac_addr*>(mac_addrs_internal.data()));
-    // If the request Id is wrong, don't stop the ongoing range request. Any
-    // other error should be treated as the end of rtt ranging.
-    if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
-        on_rtt_results_internal_callback = nullptr;
-    }
-    return status;
-}
-
-std::pair<wifi_error, wifi_rtt_capabilities> WifiLegacyHal::getRttCapabilities(
-    const std::string& iface_name) {
-    wifi_rtt_capabilities rtt_caps;
-    wifi_error status = global_func_table_.wifi_get_rtt_capabilities(
-        getIfaceHandle(iface_name), &rtt_caps);
-    return {status, rtt_caps};
-}
-
-std::pair<wifi_error, wifi_rtt_responder> WifiLegacyHal::getRttResponderInfo(
-    const std::string& iface_name) {
-    wifi_rtt_responder rtt_responder;
-    wifi_error status = global_func_table_.wifi_rtt_get_responder_info(
-        getIfaceHandle(iface_name), &rtt_responder);
-    return {status, rtt_responder};
-}
-
-wifi_error WifiLegacyHal::enableRttResponder(
-    const std::string& iface_name, wifi_request_id id,
-    const wifi_channel_info& channel_hint, uint32_t max_duration_secs,
-    const wifi_rtt_responder& info) {
-    wifi_rtt_responder info_internal(info);
-    return global_func_table_.wifi_enable_responder(
-        id, getIfaceHandle(iface_name), channel_hint, max_duration_secs,
-        &info_internal);
-}
-
-wifi_error WifiLegacyHal::disableRttResponder(const std::string& iface_name,
-                                              wifi_request_id id) {
-    return global_func_table_.wifi_disable_responder(
-        id, getIfaceHandle(iface_name));
-}
-
-wifi_error WifiLegacyHal::setRttLci(const std::string& iface_name,
-                                    wifi_request_id id,
-                                    const wifi_lci_information& info) {
-    wifi_lci_information info_internal(info);
-    return global_func_table_.wifi_set_lci(id, getIfaceHandle(iface_name),
-                                           &info_internal);
-}
-
-wifi_error WifiLegacyHal::setRttLcr(const std::string& iface_name,
-                                    wifi_request_id id,
-                                    const wifi_lcr_information& info) {
-    wifi_lcr_information info_internal(info);
-    return global_func_table_.wifi_set_lcr(id, getIfaceHandle(iface_name),
-                                           &info_internal);
-}
-
-wifi_error WifiLegacyHal::nanRegisterCallbackHandlers(
-    const std::string& iface_name, const NanCallbackHandlers& user_callbacks) {
-    on_nan_notify_response_user_callback = user_callbacks.on_notify_response;
-    on_nan_event_publish_terminated_user_callback =
-        user_callbacks.on_event_publish_terminated;
-    on_nan_event_match_user_callback = user_callbacks.on_event_match;
-    on_nan_event_match_expired_user_callback =
-        user_callbacks.on_event_match_expired;
-    on_nan_event_subscribe_terminated_user_callback =
-        user_callbacks.on_event_subscribe_terminated;
-    on_nan_event_followup_user_callback = user_callbacks.on_event_followup;
-    on_nan_event_disc_eng_event_user_callback =
-        user_callbacks.on_event_disc_eng_event;
-    on_nan_event_disabled_user_callback = user_callbacks.on_event_disabled;
-    on_nan_event_tca_user_callback = user_callbacks.on_event_tca;
-    on_nan_event_beacon_sdf_payload_user_callback =
-        user_callbacks.on_event_beacon_sdf_payload;
-    on_nan_event_data_path_request_user_callback =
-        user_callbacks.on_event_data_path_request;
-    on_nan_event_data_path_confirm_user_callback =
-        user_callbacks.on_event_data_path_confirm;
-    on_nan_event_data_path_end_user_callback =
-        user_callbacks.on_event_data_path_end;
-    on_nan_event_transmit_follow_up_user_callback =
-        user_callbacks.on_event_transmit_follow_up;
-    on_nan_event_range_request_user_callback =
-        user_callbacks.on_event_range_request;
-    on_nan_event_range_report_user_callback =
-        user_callbacks.on_event_range_report;
-    on_nan_event_schedule_update_user_callback =
-        user_callbacks.on_event_schedule_update;
-
-    return global_func_table_.wifi_nan_register_handler(
-        getIfaceHandle(iface_name),
-        {onAysncNanNotifyResponse, onAysncNanEventPublishReplied,
-         onAysncNanEventPublishTerminated, onAysncNanEventMatch,
-         onAysncNanEventMatchExpired, onAysncNanEventSubscribeTerminated,
-         onAysncNanEventFollowup, onAysncNanEventDiscEngEvent,
-         onAysncNanEventDisabled, onAysncNanEventTca,
-         onAysncNanEventBeaconSdfPayload, onAysncNanEventDataPathRequest,
-         onAysncNanEventDataPathConfirm, onAysncNanEventDataPathEnd,
-         onAysncNanEventTransmitFollowUp, onAysncNanEventRangeRequest,
-         onAysncNanEventRangeReport, onAsyncNanEventScheduleUpdate});
-}
-
-wifi_error WifiLegacyHal::nanEnableRequest(const std::string& iface_name,
-                                           transaction_id id,
-                                           const NanEnableRequest& msg) {
-    NanEnableRequest msg_internal(msg);
-    return global_func_table_.wifi_nan_enable_request(
-        id, getIfaceHandle(iface_name), &msg_internal);
-}
-
-wifi_error WifiLegacyHal::nanDisableRequest(const std::string& iface_name,
-                                            transaction_id id) {
-    return global_func_table_.wifi_nan_disable_request(
-        id, getIfaceHandle(iface_name));
-}
-
-wifi_error WifiLegacyHal::nanPublishRequest(const std::string& iface_name,
-                                            transaction_id id,
-                                            const NanPublishRequest& msg) {
-    NanPublishRequest msg_internal(msg);
-    return global_func_table_.wifi_nan_publish_request(
-        id, getIfaceHandle(iface_name), &msg_internal);
-}
-
-wifi_error WifiLegacyHal::nanPublishCancelRequest(
-    const std::string& iface_name, transaction_id id,
-    const NanPublishCancelRequest& msg) {
-    NanPublishCancelRequest msg_internal(msg);
-    return global_func_table_.wifi_nan_publish_cancel_request(
-        id, getIfaceHandle(iface_name), &msg_internal);
-}
-
-wifi_error WifiLegacyHal::nanSubscribeRequest(const std::string& iface_name,
-                                              transaction_id id,
-                                              const NanSubscribeRequest& msg) {
-    NanSubscribeRequest msg_internal(msg);
-    return global_func_table_.wifi_nan_subscribe_request(
-        id, getIfaceHandle(iface_name), &msg_internal);
-}
-
-wifi_error WifiLegacyHal::nanSubscribeCancelRequest(
-    const std::string& iface_name, transaction_id id,
-    const NanSubscribeCancelRequest& msg) {
-    NanSubscribeCancelRequest msg_internal(msg);
-    return global_func_table_.wifi_nan_subscribe_cancel_request(
-        id, getIfaceHandle(iface_name), &msg_internal);
-}
-
-wifi_error WifiLegacyHal::nanTransmitFollowupRequest(
-    const std::string& iface_name, transaction_id id,
-    const NanTransmitFollowupRequest& msg) {
-    NanTransmitFollowupRequest msg_internal(msg);
-    return global_func_table_.wifi_nan_transmit_followup_request(
-        id, getIfaceHandle(iface_name), &msg_internal);
-}
-
-wifi_error WifiLegacyHal::nanStatsRequest(const std::string& iface_name,
-                                          transaction_id id,
-                                          const NanStatsRequest& msg) {
-    NanStatsRequest msg_internal(msg);
-    return global_func_table_.wifi_nan_stats_request(
-        id, getIfaceHandle(iface_name), &msg_internal);
-}
-
-wifi_error WifiLegacyHal::nanConfigRequest(const std::string& iface_name,
-                                           transaction_id id,
-                                           const NanConfigRequest& msg) {
-    NanConfigRequest msg_internal(msg);
-    return global_func_table_.wifi_nan_config_request(
-        id, getIfaceHandle(iface_name), &msg_internal);
-}
-
-wifi_error WifiLegacyHal::nanTcaRequest(const std::string& iface_name,
-                                        transaction_id id,
-                                        const NanTCARequest& msg) {
-    NanTCARequest msg_internal(msg);
-    return global_func_table_.wifi_nan_tca_request(
-        id, getIfaceHandle(iface_name), &msg_internal);
-}
-
-wifi_error WifiLegacyHal::nanBeaconSdfPayloadRequest(
-    const std::string& iface_name, transaction_id id,
-    const NanBeaconSdfPayloadRequest& msg) {
-    NanBeaconSdfPayloadRequest msg_internal(msg);
-    return global_func_table_.wifi_nan_beacon_sdf_payload_request(
-        id, getIfaceHandle(iface_name), &msg_internal);
-}
-
-std::pair<wifi_error, NanVersion> WifiLegacyHal::nanGetVersion() {
-    NanVersion version;
-    wifi_error status =
-        global_func_table_.wifi_nan_get_version(global_handle_, &version);
-    return {status, version};
-}
-
-wifi_error WifiLegacyHal::nanGetCapabilities(const std::string& iface_name,
-                                             transaction_id id) {
-    return global_func_table_.wifi_nan_get_capabilities(
-        id, getIfaceHandle(iface_name));
-}
-
-wifi_error WifiLegacyHal::nanDataInterfaceCreate(
-    const std::string& iface_name, transaction_id id,
-    const std::string& data_iface_name) {
-    return global_func_table_.wifi_nan_data_interface_create(
-        id, getIfaceHandle(iface_name), makeCharVec(data_iface_name).data());
-}
-
-wifi_error WifiLegacyHal::nanDataInterfaceDelete(
-    const std::string& iface_name, transaction_id id,
-    const std::string& data_iface_name) {
-    return global_func_table_.wifi_nan_data_interface_delete(
-        id, getIfaceHandle(iface_name), makeCharVec(data_iface_name).data());
-}
-
-wifi_error WifiLegacyHal::nanDataRequestInitiator(
-    const std::string& iface_name, transaction_id id,
-    const NanDataPathInitiatorRequest& msg) {
-    NanDataPathInitiatorRequest msg_internal(msg);
-    return global_func_table_.wifi_nan_data_request_initiator(
-        id, getIfaceHandle(iface_name), &msg_internal);
-}
-
-wifi_error WifiLegacyHal::nanDataIndicationResponse(
-    const std::string& iface_name, transaction_id id,
-    const NanDataPathIndicationResponse& msg) {
-    NanDataPathIndicationResponse msg_internal(msg);
-    return global_func_table_.wifi_nan_data_indication_response(
-        id, getIfaceHandle(iface_name), &msg_internal);
-}
-
-typedef struct {
-    u8 num_ndp_instances;
-    NanDataPathId ndp_instance_id;
-} NanDataPathEndSingleNdpIdRequest;
-
-wifi_error WifiLegacyHal::nanDataEnd(const std::string& iface_name,
-                                     transaction_id id,
-                                     uint32_t ndpInstanceId) {
-    NanDataPathEndSingleNdpIdRequest msg;
-    msg.num_ndp_instances = 1;
-    msg.ndp_instance_id = ndpInstanceId;
-    wifi_error status = global_func_table_.wifi_nan_data_end(
-        id, getIfaceHandle(iface_name), (NanDataPathEndRequest*)&msg);
-    return status;
-}
-
-wifi_error WifiLegacyHal::setCountryCode(const std::string& iface_name,
-                                         std::array<int8_t, 2> code) {
-    std::string code_str(code.data(), code.data() + code.size());
-    return global_func_table_.wifi_set_country_code(getIfaceHandle(iface_name),
-                                                    code_str.c_str());
-}
-
-wifi_error WifiLegacyHal::retrieveIfaceHandles() {
-    wifi_interface_handle* iface_handles = nullptr;
-    int num_iface_handles = 0;
-    wifi_error status = global_func_table_.wifi_get_ifaces(
-        global_handle_, &num_iface_handles, &iface_handles);
-    if (status != WIFI_SUCCESS) {
-        LOG(ERROR) << "Failed to enumerate interface handles";
-        return status;
-    }
-    iface_name_to_handle_.clear();
-    for (int i = 0; i < num_iface_handles; ++i) {
-        std::array<char, IFNAMSIZ> iface_name_arr = {};
-        status = global_func_table_.wifi_get_iface_name(
-            iface_handles[i], iface_name_arr.data(), iface_name_arr.size());
-        if (status != WIFI_SUCCESS) {
-            LOG(WARNING) << "Failed to get interface handle name";
-            continue;
-        }
-        // Assuming the interface name is null terminated since the legacy HAL
-        // API does not return a size.
-        std::string iface_name(iface_name_arr.data());
-        LOG(INFO) << "Adding interface handle for " << iface_name;
-        iface_name_to_handle_[iface_name] = iface_handles[i];
-    }
-    return WIFI_SUCCESS;
-}
-
-wifi_interface_handle WifiLegacyHal::getIfaceHandle(
-    const std::string& iface_name) {
-    const auto iface_handle_iter = iface_name_to_handle_.find(iface_name);
-    if (iface_handle_iter == iface_name_to_handle_.end()) {
-        LOG(ERROR) << "Unknown iface name: " << iface_name;
-        return nullptr;
-    }
-    return iface_handle_iter->second;
-}
-
-void WifiLegacyHal::runEventLoop() {
-    LOG(DEBUG) << "Starting legacy HAL event loop";
-    global_func_table_.wifi_event_loop(global_handle_);
-    const auto lock = hidl_sync_util::acquireGlobalLock();
-    if (!awaiting_event_loop_termination_) {
-        LOG(FATAL)
-            << "Legacy HAL event loop terminated, but HAL was not stopping";
-    }
-    LOG(DEBUG) << "Legacy HAL event loop terminated";
-    awaiting_event_loop_termination_ = false;
-    stop_wait_cv_.notify_one();
-}
-
-std::pair<wifi_error, std::vector<wifi_cached_scan_results>>
-WifiLegacyHal::getGscanCachedResults(const std::string& iface_name) {
-    std::vector<wifi_cached_scan_results> cached_scan_results;
-    cached_scan_results.resize(kMaxCachedGscanResults);
-    int32_t num_results = 0;
-    wifi_error status = global_func_table_.wifi_get_cached_gscan_results(
-        getIfaceHandle(iface_name), true /* always flush */,
-        cached_scan_results.size(), cached_scan_results.data(), &num_results);
-    CHECK(num_results >= 0 &&
-          static_cast<uint32_t>(num_results) <= kMaxCachedGscanResults);
-    cached_scan_results.resize(num_results);
-    // Check for invalid IE lengths in these cached scan results and correct it.
-    for (auto& cached_scan_result : cached_scan_results) {
-        int num_scan_results = cached_scan_result.num_results;
-        for (int i = 0; i < num_scan_results; i++) {
-            auto& scan_result = cached_scan_result.results[i];
-            if (scan_result.ie_length > 0) {
-                LOG(DEBUG) << "Cached scan result has non-zero IE length "
-                           << scan_result.ie_length;
-                scan_result.ie_length = 0;
-            }
-        }
-    }
-    return {status, std::move(cached_scan_results)};
-}
-
-wifi_error WifiLegacyHal::createVirtualInterface(const std::string& ifname,
-                                                 wifi_interface_type iftype) {
-    // Create the interface if it doesn't exist. If interface already exist,
-    // Vendor Hal should return WIFI_SUCCESS.
-    wifi_error status = global_func_table_.wifi_virtual_interface_create(
-        global_handle_, ifname.c_str(), iftype);
-    return handleVirtualInterfaceCreateOrDeleteStatus(ifname, status);
-}
-
-wifi_error WifiLegacyHal::deleteVirtualInterface(const std::string& ifname) {
-    // Delete the interface if it was created dynamically.
-    wifi_error status = global_func_table_.wifi_virtual_interface_delete(
-        global_handle_, ifname.c_str());
-    return handleVirtualInterfaceCreateOrDeleteStatus(ifname, status);
-}
-
-wifi_error WifiLegacyHal::handleVirtualInterfaceCreateOrDeleteStatus(
-    const std::string& ifname, wifi_error status) {
-    if (status == WIFI_SUCCESS) {
-        // refresh list of handlers now.
-        status = retrieveIfaceHandles();
-    } else if (status == WIFI_ERROR_NOT_SUPPORTED) {
-        // Vendor hal does not implement this API. Such vendor implementations
-        // are expected to create / delete interface by other means.
-
-        // check if interface exists.
-        if (if_nametoindex(ifname.c_str())) {
-            status = retrieveIfaceHandles();
-        }
-    }
-    return status;
-}
-
-wifi_error WifiLegacyHal::getSupportedIfaceName(uint32_t iface_type,
-                                                std::string& ifname) {
-    std::array<char, IFNAMSIZ> buffer;
-
-    wifi_error res = global_func_table_.wifi_get_supported_iface_name(
-        global_handle_, (uint32_t)iface_type, buffer.data(), buffer.size());
-    if (res == WIFI_SUCCESS) ifname = buffer.data();
-
-    return res;
-}
-
-wifi_error WifiLegacyHal::multiStaSetPrimaryConnection(
-    const std::string& ifname) {
-    return global_func_table_.wifi_multi_sta_set_primary_connection(
-        global_handle_, getIfaceHandle(ifname));
-}
-
-wifi_error WifiLegacyHal::multiStaSetUseCase(wifi_multi_sta_use_case use_case) {
-    return global_func_table_.wifi_multi_sta_set_use_case(global_handle_,
-                                                          use_case);
-}
-
-wifi_error WifiLegacyHal::setCoexUnsafeChannels(
-    std::vector<wifi_coex_unsafe_channel> unsafe_channels,
-    uint32_t restrictions) {
-    return global_func_table_.wifi_set_coex_unsafe_channels(
-        global_handle_, unsafe_channels.size(), unsafe_channels.data(),
-        restrictions);
-}
-
-wifi_error WifiLegacyHal::setVoipMode(const std::string& iface_name,
-                                      wifi_voip_mode mode) {
-    return global_func_table_.wifi_set_voip_mode(getIfaceHandle(iface_name),
-                                                 mode);
-}
-
-wifi_error WifiLegacyHal::twtRegisterHandler(
-    const std::string& iface_name, const TwtCallbackHandlers& user_callbacks) {
-    on_twt_event_setup_response_callback = user_callbacks.on_setup_response;
-    on_twt_event_teardown_completion_callback =
-        user_callbacks.on_teardown_completion;
-    on_twt_event_info_frame_received_callback =
-        user_callbacks.on_info_frame_received;
-    on_twt_event_device_notify_callback = user_callbacks.on_device_notify;
-
-    return global_func_table_.wifi_twt_register_handler(
-        getIfaceHandle(iface_name),
-        {onAsyncTwtEventSetupResponse, onAsyncTwtEventTeardownCompletion,
-         onAsyncTwtEventInfoFrameReceived, onAsyncTwtEventDeviceNotify});
-}
-
-std::pair<wifi_error, TwtCapabilitySet> WifiLegacyHal::twtGetCapability(
-    const std::string& iface_name) {
-    TwtCapabilitySet capSet;
-    wifi_error status = global_func_table_.wifi_twt_get_capability(
-        getIfaceHandle(iface_name), &capSet);
-    return {status, capSet};
-}
-
-wifi_error WifiLegacyHal::twtSetupRequest(const std::string& iface_name,
-                                          const TwtSetupRequest& msg) {
-    TwtSetupRequest msgInternal(msg);
-    return global_func_table_.wifi_twt_setup_request(getIfaceHandle(iface_name),
-                                                     &msgInternal);
-}
-
-wifi_error WifiLegacyHal::twtTearDownRequest(const std::string& iface_name,
-                                             const TwtTeardownRequest& msg) {
-    TwtTeardownRequest msgInternal(msg);
-    return global_func_table_.wifi_twt_teardown_request(
-        getIfaceHandle(iface_name), &msgInternal);
-}
-
-wifi_error WifiLegacyHal::twtInfoFrameRequest(const std::string& iface_name,
-                                              const TwtInfoFrameRequest& msg) {
-    TwtInfoFrameRequest msgInternal(msg);
-    return global_func_table_.wifi_twt_info_frame_request(
-        getIfaceHandle(iface_name), &msgInternal);
-}
-
-std::pair<wifi_error, TwtStats> WifiLegacyHal::twtGetStats(
-    const std::string& iface_name, uint8_t configId) {
-    TwtStats stats;
-    wifi_error status = global_func_table_.wifi_twt_get_stats(
-        getIfaceHandle(iface_name), configId, &stats);
-    return {status, stats};
-}
-
-wifi_error WifiLegacyHal::twtClearStats(const std::string& iface_name,
-                                        uint8_t configId) {
-    return global_func_table_.wifi_twt_clear_stats(getIfaceHandle(iface_name),
-                                                   configId);
-}
-
-wifi_error WifiLegacyHal::setDtimConfig(const std::string& iface_name,
-                                        uint32_t multiplier) {
-    return global_func_table_.wifi_set_dtim_config(getIfaceHandle(iface_name),
-                                                   multiplier);
-}
-
-std::pair<wifi_error, std::vector<wifi_usable_channel>>
-WifiLegacyHal::getUsableChannels(uint32_t band_mask, uint32_t iface_mode_mask,
-                                 uint32_t filter_mask) {
-    std::vector<wifi_usable_channel> channels;
-    channels.resize(kMaxWifiUsableChannels);
-    uint32_t size = 0;
-    wifi_error status = global_func_table_.wifi_get_usable_channels(
-        global_handle_, band_mask, iface_mode_mask, filter_mask,
-        channels.size(), &size,
-        reinterpret_cast<wifi_usable_channel*>(channels.data()));
-    CHECK(size >= 0 && size <= kMaxWifiUsableChannels);
-    channels.resize(size);
-    return {status, std::move(channels)};
-}
-
-wifi_error WifiLegacyHal::triggerSubsystemRestart() {
-    return global_func_table_.wifi_trigger_subsystem_restart(global_handle_);
-}
-
-void WifiLegacyHal::invalidate() {
-    global_handle_ = nullptr;
-    iface_name_to_handle_.clear();
-    on_driver_memory_dump_internal_callback = nullptr;
-    on_firmware_memory_dump_internal_callback = nullptr;
-    on_gscan_event_internal_callback = nullptr;
-    on_gscan_full_result_internal_callback = nullptr;
-    on_link_layer_stats_result_internal_callback = nullptr;
-    on_rssi_threshold_breached_internal_callback = nullptr;
-    on_ring_buffer_data_internal_callback = nullptr;
-    on_error_alert_internal_callback = nullptr;
-    on_radio_mode_change_internal_callback = nullptr;
-    on_subsystem_restart_internal_callback = nullptr;
-    on_rtt_results_internal_callback = nullptr;
-    on_nan_notify_response_user_callback = nullptr;
-    on_nan_event_publish_terminated_user_callback = nullptr;
-    on_nan_event_match_user_callback = nullptr;
-    on_nan_event_match_expired_user_callback = nullptr;
-    on_nan_event_subscribe_terminated_user_callback = nullptr;
-    on_nan_event_followup_user_callback = nullptr;
-    on_nan_event_disc_eng_event_user_callback = nullptr;
-    on_nan_event_disabled_user_callback = nullptr;
-    on_nan_event_tca_user_callback = nullptr;
-    on_nan_event_beacon_sdf_payload_user_callback = nullptr;
-    on_nan_event_data_path_request_user_callback = nullptr;
-    on_nan_event_data_path_confirm_user_callback = nullptr;
-    on_nan_event_data_path_end_user_callback = nullptr;
-    on_nan_event_transmit_follow_up_user_callback = nullptr;
-    on_nan_event_range_request_user_callback = nullptr;
-    on_nan_event_range_report_user_callback = nullptr;
-    on_nan_event_schedule_update_user_callback = nullptr;
-    on_twt_event_setup_response_callback = nullptr;
-    on_twt_event_teardown_completion_callback = nullptr;
-    on_twt_event_info_frame_received_callback = nullptr;
-    on_twt_event_device_notify_callback = nullptr;
-}
-
-}  // namespace legacy_hal
-}  // namespace implementation
-}  // namespace V1_5
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.5/default/wifi_nan_iface.cpp b/wifi/1.5/default/wifi_nan_iface.cpp
deleted file mode 100644
index 0cc6cd5..0000000
--- a/wifi/1.5/default/wifi_nan_iface.cpp
+++ /dev/null
@@ -1,1003 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 "hidl_return_util.h"
-#include "hidl_struct_util.h"
-#include "wifi_nan_iface.h"
-#include "wifi_status_util.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_5 {
-namespace implementation {
-using hidl_return_util::validateAndCall;
-
-WifiNanIface::WifiNanIface(
-    const std::string& ifname, bool is_dedicated_iface,
-    const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
-    const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
-    : ifname_(ifname),
-      is_dedicated_iface_(is_dedicated_iface),
-      legacy_hal_(legacy_hal),
-      iface_util_(iface_util),
-      is_valid_(true) {
-    if (is_dedicated_iface_) {
-        // If using a dedicated iface, set the iface up first.
-        if (!iface_util_.lock()->setUpState(ifname_, true)) {
-            // Fatal failure, invalidate the iface object.
-            invalidate();
-            return;
-        }
-    }
-    // Register all the callbacks here. these should be valid for the lifetime
-    // of the object. Whenever the mode changes legacy HAL will remove
-    // all of these callbacks.
-    legacy_hal::NanCallbackHandlers callback_handlers;
-    android::wp<WifiNanIface> weak_ptr_this(this);
-
-    // Callback for response.
-    callback_handlers
-        .on_notify_response = [weak_ptr_this](
-                                  legacy_hal::transaction_id id,
-                                  const legacy_hal::NanResponseMsg& msg) {
-        const auto shared_ptr_this = weak_ptr_this.promote();
-        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-            LOG(ERROR) << "Callback invoked on an invalid object";
-            return;
-        }
-        WifiNanStatus wifiNanStatus;
-        if (!hidl_struct_util::convertLegacyNanResponseHeaderToHidl(
-                msg, &wifiNanStatus)) {
-            LOG(ERROR) << "Failed to convert nan response header";
-            return;
-        }
-
-        switch (msg.response_type) {
-            case legacy_hal::NAN_RESPONSE_ENABLED: {
-                for (const auto& callback :
-                     shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->notifyEnableResponse(id, wifiNanStatus)
-                             .isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_RESPONSE_DISABLED: {
-                for (const auto& callback :
-                     shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->notifyDisableResponse(id, wifiNanStatus)
-                             .isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_RESPONSE_PUBLISH: {
-                for (const auto& callback :
-                     shared_ptr_this->getEventCallbacks()) {
-                    if (!callback
-                             ->notifyStartPublishResponse(
-                                 id, wifiNanStatus,
-                                 msg.body.publish_response.publish_id)
-                             .isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_RESPONSE_PUBLISH_CANCEL: {
-                for (const auto& callback :
-                     shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->notifyStopPublishResponse(id, wifiNanStatus)
-                             .isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_RESPONSE_TRANSMIT_FOLLOWUP: {
-                for (const auto& callback :
-                     shared_ptr_this->getEventCallbacks()) {
-                    if (!callback
-                             ->notifyTransmitFollowupResponse(id, wifiNanStatus)
-                             .isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_RESPONSE_SUBSCRIBE: {
-                for (const auto& callback :
-                     shared_ptr_this->getEventCallbacks()) {
-                    if (!callback
-                             ->notifyStartSubscribeResponse(
-                                 id, wifiNanStatus,
-                                 msg.body.subscribe_response.subscribe_id)
-                             .isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_RESPONSE_SUBSCRIBE_CANCEL: {
-                for (const auto& callback :
-                     shared_ptr_this->getEventCallbacks()) {
-                    if (!callback
-                             ->notifyStopSubscribeResponse(id, wifiNanStatus)
-                             .isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_RESPONSE_CONFIG: {
-                for (const auto& callback :
-                     shared_ptr_this->getEventCallbacks()) {
-                    if (!callback->notifyConfigResponse(id, wifiNanStatus)
-                             .isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_GET_CAPABILITIES: {
-                NanCapabilities hidl_struct;
-                if (!hidl_struct_util::
-                        convertLegacyNanCapabilitiesResponseToHidl(
-                            msg.body.nan_capabilities, &hidl_struct)) {
-                    LOG(ERROR) << "Failed to convert nan capabilities response";
-                    return;
-                }
-                for (const auto& callback :
-                     shared_ptr_this->getEventCallbacks_1_5()) {
-                    if (!callback
-                             ->notifyCapabilitiesResponse_1_5(id, wifiNanStatus,
-                                                              hidl_struct)
-                             .isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_DP_INTERFACE_CREATE: {
-                for (const auto& callback :
-                     shared_ptr_this->getEventCallbacks()) {
-                    if (!callback
-                             ->notifyCreateDataInterfaceResponse(id,
-                                                                 wifiNanStatus)
-                             .isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_DP_INTERFACE_DELETE: {
-                for (const auto& callback :
-                     shared_ptr_this->getEventCallbacks()) {
-                    if (!callback
-                             ->notifyDeleteDataInterfaceResponse(id,
-                                                                 wifiNanStatus)
-                             .isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_DP_INITIATOR_RESPONSE: {
-                for (const auto& callback :
-                     shared_ptr_this->getEventCallbacks()) {
-                    if (!callback
-                             ->notifyInitiateDataPathResponse(
-                                 id, wifiNanStatus,
-                                 msg.body.data_request_response.ndp_instance_id)
-                             .isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_DP_RESPONDER_RESPONSE: {
-                for (const auto& callback :
-                     shared_ptr_this->getEventCallbacks()) {
-                    if (!callback
-                             ->notifyRespondToDataPathIndicationResponse(
-                                 id, wifiNanStatus)
-                             .isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_DP_END: {
-                for (const auto& callback :
-                     shared_ptr_this->getEventCallbacks()) {
-                    if (!callback
-                             ->notifyTerminateDataPathResponse(id,
-                                                               wifiNanStatus)
-                             .isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-                break;
-            }
-            case legacy_hal::NAN_RESPONSE_BEACON_SDF_PAYLOAD:
-            /* fall through */
-            case legacy_hal::NAN_RESPONSE_TCA:
-            /* fall through */
-            case legacy_hal::NAN_RESPONSE_STATS:
-            /* fall through */
-            case legacy_hal::NAN_RESPONSE_ERROR:
-            /* fall through */
-            default:
-                LOG(ERROR) << "Unknown or unhandled response type: "
-                           << msg.response_type;
-                return;
-        }
-    };
-
-    callback_handlers.on_event_disc_eng_event =
-        [weak_ptr_this](const legacy_hal::NanDiscEngEventInd& msg) {
-            const auto shared_ptr_this = weak_ptr_this.promote();
-            if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                LOG(ERROR) << "Callback invoked on an invalid object";
-                return;
-            }
-            NanClusterEventInd hidl_struct;
-            // event types defined identically - hence can be cast
-            hidl_struct.eventType = (NanClusterEventType)msg.event_type;
-            hidl_struct.addr = msg.data.mac_addr.addr;
-
-            for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                if (!callback->eventClusterEvent(hidl_struct).isOk()) {
-                    LOG(ERROR) << "Failed to invoke the callback";
-                }
-            }
-        };
-
-    callback_handlers.on_event_disabled =
-        [weak_ptr_this](const legacy_hal::NanDisabledInd& msg) {
-            const auto shared_ptr_this = weak_ptr_this.promote();
-            if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                LOG(ERROR) << "Callback invoked on an invalid object";
-                return;
-            }
-            WifiNanStatus status;
-            hidl_struct_util::convertToWifiNanStatus(
-                msg.reason, msg.nan_reason, sizeof(msg.nan_reason), &status);
-
-            for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                if (!callback->eventDisabled(status).isOk()) {
-                    LOG(ERROR) << "Failed to invoke the callback";
-                }
-            }
-        };
-
-    callback_handlers.on_event_publish_terminated =
-        [weak_ptr_this](const legacy_hal::NanPublishTerminatedInd& msg) {
-            const auto shared_ptr_this = weak_ptr_this.promote();
-            if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                LOG(ERROR) << "Callback invoked on an invalid object";
-                return;
-            }
-            WifiNanStatus status;
-            hidl_struct_util::convertToWifiNanStatus(
-                msg.reason, msg.nan_reason, sizeof(msg.nan_reason), &status);
-
-            for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                if (!callback->eventPublishTerminated(msg.publish_id, status)
-                         .isOk()) {
-                    LOG(ERROR) << "Failed to invoke the callback";
-                }
-            }
-        };
-
-    callback_handlers.on_event_subscribe_terminated =
-        [weak_ptr_this](const legacy_hal::NanSubscribeTerminatedInd& msg) {
-            const auto shared_ptr_this = weak_ptr_this.promote();
-            if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                LOG(ERROR) << "Callback invoked on an invalid object";
-                return;
-            }
-            WifiNanStatus status;
-            hidl_struct_util::convertToWifiNanStatus(
-                msg.reason, msg.nan_reason, sizeof(msg.nan_reason), &status);
-
-            for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                if (!callback
-                         ->eventSubscribeTerminated(msg.subscribe_id, status)
-                         .isOk()) {
-                    LOG(ERROR) << "Failed to invoke the callback";
-                }
-            }
-        };
-
-    callback_handlers.on_event_match =
-        [weak_ptr_this](const legacy_hal::NanMatchInd& msg) {
-            const auto shared_ptr_this = weak_ptr_this.promote();
-            if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                LOG(ERROR) << "Callback invoked on an invalid object";
-                return;
-            }
-            NanMatchInd hidl_struct;
-            if (!hidl_struct_util::convertLegacyNanMatchIndToHidl(
-                    msg, &hidl_struct)) {
-                LOG(ERROR) << "Failed to convert nan capabilities response";
-                return;
-            }
-
-            for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                if (!callback->eventMatch(hidl_struct).isOk()) {
-                    LOG(ERROR) << "Failed to invoke the callback";
-                }
-            }
-        };
-
-    callback_handlers.on_event_match_expired =
-        [weak_ptr_this](const legacy_hal::NanMatchExpiredInd& msg) {
-            const auto shared_ptr_this = weak_ptr_this.promote();
-            if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                LOG(ERROR) << "Callback invoked on an invalid object";
-                return;
-            }
-            for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                if (!callback
-                         ->eventMatchExpired(msg.publish_subscribe_id,
-                                             msg.requestor_instance_id)
-                         .isOk()) {
-                    LOG(ERROR) << "Failed to invoke the callback";
-                }
-            }
-        };
-
-    callback_handlers.on_event_followup =
-        [weak_ptr_this](const legacy_hal::NanFollowupInd& msg) {
-            const auto shared_ptr_this = weak_ptr_this.promote();
-            if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                LOG(ERROR) << "Callback invoked on an invalid object";
-                return;
-            }
-            NanFollowupReceivedInd hidl_struct;
-            if (!hidl_struct_util::convertLegacyNanFollowupIndToHidl(
-                    msg, &hidl_struct)) {
-                LOG(ERROR) << "Failed to convert nan capabilities response";
-                return;
-            }
-
-            for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                if (!callback->eventFollowupReceived(hidl_struct).isOk()) {
-                    LOG(ERROR) << "Failed to invoke the callback";
-                }
-            }
-        };
-
-    callback_handlers.on_event_transmit_follow_up =
-        [weak_ptr_this](const legacy_hal::NanTransmitFollowupInd& msg) {
-            const auto shared_ptr_this = weak_ptr_this.promote();
-            if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                LOG(ERROR) << "Callback invoked on an invalid object";
-                return;
-            }
-            WifiNanStatus status;
-            hidl_struct_util::convertToWifiNanStatus(
-                msg.reason, msg.nan_reason, sizeof(msg.nan_reason), &status);
-
-            for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                if (!callback->eventTransmitFollowup(msg.id, status).isOk()) {
-                    LOG(ERROR) << "Failed to invoke the callback";
-                }
-            }
-        };
-
-    callback_handlers.on_event_data_path_request =
-        [weak_ptr_this](const legacy_hal::NanDataPathRequestInd& msg) {
-            const auto shared_ptr_this = weak_ptr_this.promote();
-            if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                LOG(ERROR) << "Callback invoked on an invalid object";
-                return;
-            }
-            NanDataPathRequestInd hidl_struct;
-            if (!hidl_struct_util::convertLegacyNanDataPathRequestIndToHidl(
-                    msg, &hidl_struct)) {
-                LOG(ERROR) << "Failed to convert nan capabilities response";
-                return;
-            }
-
-            for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                if (!callback->eventDataPathRequest(hidl_struct).isOk()) {
-                    LOG(ERROR) << "Failed to invoke the callback";
-                }
-            }
-        };
-
-    callback_handlers.on_event_data_path_confirm =
-        [weak_ptr_this](const legacy_hal::NanDataPathConfirmInd& msg) {
-            const auto shared_ptr_this = weak_ptr_this.promote();
-            if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                LOG(ERROR) << "Callback invoked on an invalid object";
-                return;
-            }
-            V1_2::NanDataPathConfirmInd hidl_struct;
-            if (!hidl_struct_util::convertLegacyNanDataPathConfirmIndToHidl(
-                    msg, &hidl_struct)) {
-                LOG(ERROR) << "Failed to convert nan capabilities response";
-                return;
-            }
-
-            for (const auto& callback :
-                 shared_ptr_this->getEventCallbacks_1_2()) {
-                if (!callback->eventDataPathConfirm_1_2(hidl_struct).isOk()) {
-                    LOG(ERROR) << "Failed to invoke the callback";
-                }
-            }
-        };
-
-    callback_handlers.on_event_data_path_end =
-        [weak_ptr_this](const legacy_hal::NanDataPathEndInd& msg) {
-            const auto shared_ptr_this = weak_ptr_this.promote();
-            if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                LOG(ERROR) << "Callback invoked on an invalid object";
-                return;
-            }
-            for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                for (int i = 0; i < msg.num_ndp_instances; ++i) {
-                    if (!callback
-                             ->eventDataPathTerminated(msg.ndp_instance_id[i])
-                             .isOk()) {
-                        LOG(ERROR) << "Failed to invoke the callback";
-                    }
-                }
-            }
-        };
-
-    callback_handlers.on_event_beacon_sdf_payload =
-        [weak_ptr_this](const legacy_hal::NanBeaconSdfPayloadInd& /* msg */) {
-            LOG(ERROR) << "on_event_beacon_sdf_payload - should not be called";
-        };
-
-    callback_handlers.on_event_range_request =
-        [weak_ptr_this](const legacy_hal::NanRangeRequestInd& /* msg */) {
-            LOG(ERROR) << "on_event_range_request - should not be called";
-        };
-
-    callback_handlers.on_event_range_report =
-        [weak_ptr_this](const legacy_hal::NanRangeReportInd& /* msg */) {
-            LOG(ERROR) << "on_event_range_report - should not be called";
-        };
-
-    callback_handlers
-        .on_event_schedule_update = [weak_ptr_this](
-                                        const legacy_hal::
-                                            NanDataPathScheduleUpdateInd& msg) {
-        const auto shared_ptr_this = weak_ptr_this.promote();
-        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-            LOG(ERROR) << "Callback invoked on an invalid object";
-            return;
-        }
-        V1_2::NanDataPathScheduleUpdateInd hidl_struct;
-        if (!hidl_struct_util::convertLegacyNanDataPathScheduleUpdateIndToHidl(
-                msg, &hidl_struct)) {
-            LOG(ERROR) << "Failed to convert nan capabilities response";
-            return;
-        }
-
-        for (const auto& callback : shared_ptr_this->getEventCallbacks_1_2()) {
-            if (!callback->eventDataPathScheduleUpdate(hidl_struct).isOk()) {
-                LOG(ERROR) << "Failed to invoke the callback";
-            }
-        }
-    };
-
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->nanRegisterCallbackHandlers(ifname_,
-                                                        callback_handlers);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        LOG(ERROR) << "Failed to register nan callbacks. Invalidating object";
-        invalidate();
-    }
-
-    // Register for iface state toggle events.
-    iface_util::IfaceEventHandlers event_handlers = {};
-    event_handlers.on_state_toggle_off_on =
-        [weak_ptr_this](const std::string& /* iface_name */) {
-            const auto shared_ptr_this = weak_ptr_this.promote();
-            if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                LOG(ERROR) << "Callback invoked on an invalid object";
-                return;
-            }
-            // Tell framework that NAN has been disabled.
-            WifiNanStatus status = {
-                NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""};
-            for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                if (!callback->eventDisabled(status).isOk()) {
-                    LOG(ERROR) << "Failed to invoke the callback";
-                }
-            }
-        };
-    iface_util_.lock()->registerIfaceEventHandlers(ifname_, event_handlers);
-}
-
-void WifiNanIface::invalidate() {
-    if (!isValid()) {
-        return;
-    }
-    // send commands to HAL to actually disable and destroy interfaces
-    legacy_hal_.lock()->nanDisableRequest(ifname_, 0xFFFF);
-    legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFE, "aware_data0");
-    legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFD, "aware_data1");
-    iface_util_.lock()->unregisterIfaceEventHandlers(ifname_);
-    legacy_hal_.reset();
-    event_cb_handler_.invalidate();
-    event_cb_handler_1_2_.invalidate();
-    event_cb_handler_1_5_.invalidate();
-    is_valid_ = false;
-    if (is_dedicated_iface_) {
-        // If using a dedicated iface, set the iface down.
-        iface_util_.lock()->setUpState(ifname_, false);
-    }
-}
-
-bool WifiNanIface::isValid() { return is_valid_; }
-
-std::string WifiNanIface::getName() { return ifname_; }
-
-std::set<sp<V1_0::IWifiNanIfaceEventCallback>>
-WifiNanIface::getEventCallbacks() {
-    return event_cb_handler_.getCallbacks();
-}
-
-std::set<sp<V1_2::IWifiNanIfaceEventCallback>>
-WifiNanIface::getEventCallbacks_1_2() {
-    return event_cb_handler_1_2_.getCallbacks();
-}
-
-std::set<sp<IWifiNanIfaceEventCallback>> WifiNanIface::getEventCallbacks_1_5() {
-    return event_cb_handler_1_5_.getCallbacks();
-}
-
-Return<void> WifiNanIface::getName(getName_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::getNameInternal, hidl_status_cb);
-}
-
-Return<void> WifiNanIface::getType(getType_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::getTypeInternal, hidl_status_cb);
-}
-
-Return<void> WifiNanIface::registerEventCallback(
-    const sp<V1_0::IWifiNanIfaceEventCallback>& callback,
-    registerEventCallback_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::registerEventCallbackInternal,
-                           hidl_status_cb, callback);
-}
-
-Return<void> WifiNanIface::getCapabilitiesRequest(
-    uint16_t cmd_id, getCapabilitiesRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::getCapabilitiesRequestInternal,
-                           hidl_status_cb, cmd_id);
-}
-
-Return<void> WifiNanIface::enableRequest(uint16_t cmd_id,
-                                         const V1_0::NanEnableRequest& msg,
-                                         enableRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::enableRequestInternal, hidl_status_cb,
-                           cmd_id, msg);
-}
-
-Return<void> WifiNanIface::configRequest(uint16_t cmd_id,
-                                         const V1_0::NanConfigRequest& msg,
-                                         configRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::configRequestInternal, hidl_status_cb,
-                           cmd_id, msg);
-}
-
-Return<void> WifiNanIface::disableRequest(uint16_t cmd_id,
-                                          disableRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::disableRequestInternal,
-                           hidl_status_cb, cmd_id);
-}
-
-Return<void> WifiNanIface::startPublishRequest(
-    uint16_t cmd_id, const NanPublishRequest& msg,
-    startPublishRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::startPublishRequestInternal,
-                           hidl_status_cb, cmd_id, msg);
-}
-
-Return<void> WifiNanIface::stopPublishRequest(
-    uint16_t cmd_id, uint8_t sessionId, stopPublishRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::stopPublishRequestInternal,
-                           hidl_status_cb, cmd_id, sessionId);
-}
-
-Return<void> WifiNanIface::startSubscribeRequest(
-    uint16_t cmd_id, const NanSubscribeRequest& msg,
-    startSubscribeRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::startSubscribeRequestInternal,
-                           hidl_status_cb, cmd_id, msg);
-}
-
-Return<void> WifiNanIface::stopSubscribeRequest(
-    uint16_t cmd_id, uint8_t sessionId,
-    stopSubscribeRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::stopSubscribeRequestInternal,
-                           hidl_status_cb, cmd_id, sessionId);
-}
-
-Return<void> WifiNanIface::transmitFollowupRequest(
-    uint16_t cmd_id, const NanTransmitFollowupRequest& msg,
-    transmitFollowupRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::transmitFollowupRequestInternal,
-                           hidl_status_cb, cmd_id, msg);
-}
-
-Return<void> WifiNanIface::createDataInterfaceRequest(
-    uint16_t cmd_id, const hidl_string& iface_name,
-    createDataInterfaceRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::createDataInterfaceRequestInternal,
-                           hidl_status_cb, cmd_id, iface_name);
-}
-
-Return<void> WifiNanIface::deleteDataInterfaceRequest(
-    uint16_t cmd_id, const hidl_string& iface_name,
-    deleteDataInterfaceRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::deleteDataInterfaceRequestInternal,
-                           hidl_status_cb, cmd_id, iface_name);
-}
-
-Return<void> WifiNanIface::initiateDataPathRequest(
-    uint16_t cmd_id, const NanInitiateDataPathRequest& msg,
-    initiateDataPathRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::initiateDataPathRequestInternal,
-                           hidl_status_cb, cmd_id, msg);
-}
-
-Return<void> WifiNanIface::respondToDataPathIndicationRequest(
-    uint16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg,
-    respondToDataPathIndicationRequest_cb hidl_status_cb) {
-    return validateAndCall(
-        this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-        &WifiNanIface::respondToDataPathIndicationRequestInternal,
-        hidl_status_cb, cmd_id, msg);
-}
-
-Return<void> WifiNanIface::terminateDataPathRequest(
-    uint16_t cmd_id, uint32_t ndpInstanceId,
-    terminateDataPathRequest_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::terminateDataPathRequestInternal,
-                           hidl_status_cb, cmd_id, ndpInstanceId);
-}
-
-Return<void> WifiNanIface::registerEventCallback_1_2(
-    const sp<V1_2::IWifiNanIfaceEventCallback>& callback,
-    registerEventCallback_1_2_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::registerEventCallback_1_2Internal,
-                           hidl_status_cb, callback);
-}
-
-Return<void> WifiNanIface::enableRequest_1_2(
-    uint16_t cmd_id, const V1_0::NanEnableRequest& msg1,
-    const V1_2::NanConfigRequestSupplemental& msg2,
-    enableRequest_1_2_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::enableRequest_1_2Internal,
-                           hidl_status_cb, cmd_id, msg1, msg2);
-}
-
-Return<void> WifiNanIface::configRequest_1_2(
-    uint16_t cmd_id, const V1_0::NanConfigRequest& msg1,
-    const V1_2::NanConfigRequestSupplemental& msg2,
-    configRequest_1_2_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::configRequest_1_2Internal,
-                           hidl_status_cb, cmd_id, msg1, msg2);
-}
-
-Return<void> WifiNanIface::enableRequest_1_4(
-    uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
-    const V1_2::NanConfigRequestSupplemental& msg2,
-    enableRequest_1_4_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::enableRequest_1_4Internal,
-                           hidl_status_cb, cmd_id, msg1, msg2);
-}
-
-Return<void> WifiNanIface::configRequest_1_4(
-    uint16_t cmd_id, const V1_4::NanConfigRequest& msg1,
-    const V1_2::NanConfigRequestSupplemental& msg2,
-    configRequest_1_4_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::configRequest_1_4Internal,
-                           hidl_status_cb, cmd_id, msg1, msg2);
-}
-
-Return<void> WifiNanIface::registerEventCallback_1_5(
-    const sp<IWifiNanIfaceEventCallback>& callback,
-    registerEventCallback_1_5_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::registerEventCallback_1_5Internal,
-                           hidl_status_cb, callback);
-}
-
-Return<void> WifiNanIface::enableRequest_1_5(
-    uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
-    const NanConfigRequestSupplemental& msg2,
-    enableRequest_1_5_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::enableRequest_1_5Internal,
-                           hidl_status_cb, cmd_id, msg1, msg2);
-}
-
-Return<void> WifiNanIface::configRequest_1_5(
-    uint16_t cmd_id, const V1_4::NanConfigRequest& msg1,
-    const NanConfigRequestSupplemental& msg2,
-    configRequest_1_5_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::configRequest_1_5Internal,
-                           hidl_status_cb, cmd_id, msg1, msg2);
-}
-
-Return<void> WifiNanIface::getCapabilitiesRequest_1_5(
-    uint16_t cmd_id, getCapabilitiesRequest_1_5_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiNanIface::getCapabilitiesRequest_1_5Internal,
-                           hidl_status_cb, cmd_id);
-}
-
-std::pair<WifiStatus, std::string> WifiNanIface::getNameInternal() {
-    return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_};
-}
-
-std::pair<WifiStatus, IfaceType> WifiNanIface::getTypeInternal() {
-    return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::NAN};
-}
-
-WifiStatus WifiNanIface::registerEventCallbackInternal(
-    const sp<V1_0::IWifiNanIfaceEventCallback>& callback) {
-    if (!event_cb_handler_.addCallback(callback)) {
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-WifiStatus WifiNanIface::getCapabilitiesRequestInternal(uint16_t /* cmd_id */) {
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus WifiNanIface::enableRequestInternal(
-    uint16_t /* cmd_id */, const V1_0::NanEnableRequest& /* msg */) {
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus WifiNanIface::configRequestInternal(
-    uint16_t /* cmd_id */, const V1_0::NanConfigRequest& /* msg */) {
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus WifiNanIface::disableRequestInternal(uint16_t cmd_id) {
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->nanDisableRequest(ifname_, cmd_id);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiNanIface::startPublishRequestInternal(
-    uint16_t cmd_id, const NanPublishRequest& msg) {
-    legacy_hal::NanPublishRequest legacy_msg;
-    if (!hidl_struct_util::convertHidlNanPublishRequestToLegacy(msg,
-                                                                &legacy_msg)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->nanPublishRequest(ifname_, cmd_id, legacy_msg);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiNanIface::stopPublishRequestInternal(uint16_t cmd_id,
-                                                    uint8_t sessionId) {
-    legacy_hal::NanPublishCancelRequest legacy_msg;
-    legacy_msg.publish_id = sessionId;
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->nanPublishCancelRequest(ifname_, cmd_id,
-                                                    legacy_msg);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiNanIface::startSubscribeRequestInternal(
-    uint16_t cmd_id, const NanSubscribeRequest& msg) {
-    legacy_hal::NanSubscribeRequest legacy_msg;
-    if (!hidl_struct_util::convertHidlNanSubscribeRequestToLegacy(
-            msg, &legacy_msg)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->nanSubscribeRequest(ifname_, cmd_id, legacy_msg);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiNanIface::stopSubscribeRequestInternal(uint16_t cmd_id,
-                                                      uint8_t sessionId) {
-    legacy_hal::NanSubscribeCancelRequest legacy_msg;
-    legacy_msg.subscribe_id = sessionId;
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->nanSubscribeCancelRequest(ifname_, cmd_id,
-                                                      legacy_msg);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiNanIface::transmitFollowupRequestInternal(
-    uint16_t cmd_id, const NanTransmitFollowupRequest& msg) {
-    legacy_hal::NanTransmitFollowupRequest legacy_msg;
-    if (!hidl_struct_util::convertHidlNanTransmitFollowupRequestToLegacy(
-            msg, &legacy_msg)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->nanTransmitFollowupRequest(ifname_, cmd_id,
-                                                       legacy_msg);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiNanIface::createDataInterfaceRequestInternal(
-    uint16_t cmd_id, const std::string& iface_name) {
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->nanDataInterfaceCreate(ifname_, cmd_id, iface_name);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-WifiStatus WifiNanIface::deleteDataInterfaceRequestInternal(
-    uint16_t cmd_id, const std::string& iface_name) {
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, cmd_id, iface_name);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-WifiStatus WifiNanIface::initiateDataPathRequestInternal(
-    uint16_t cmd_id, const NanInitiateDataPathRequest& msg) {
-    legacy_hal::NanDataPathInitiatorRequest legacy_msg;
-    if (!hidl_struct_util::convertHidlNanDataPathInitiatorRequestToLegacy(
-            msg, &legacy_msg)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->nanDataRequestInitiator(ifname_, cmd_id,
-                                                    legacy_msg);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-WifiStatus WifiNanIface::respondToDataPathIndicationRequestInternal(
-    uint16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg) {
-    legacy_hal::NanDataPathIndicationResponse legacy_msg;
-    if (!hidl_struct_util::convertHidlNanDataPathIndicationResponseToLegacy(
-            msg, &legacy_msg)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->nanDataIndicationResponse(ifname_, cmd_id,
-                                                      legacy_msg);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-WifiStatus WifiNanIface::terminateDataPathRequestInternal(
-    uint16_t cmd_id, uint32_t ndpInstanceId) {
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->nanDataEnd(ifname_, cmd_id, ndpInstanceId);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiNanIface::registerEventCallback_1_2Internal(
-    const sp<V1_2::IWifiNanIfaceEventCallback>& callback) {
-    sp<V1_0::IWifiNanIfaceEventCallback> callback_1_0 = callback;
-    if (!event_cb_handler_.addCallback(callback_1_0)) {
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    if (!event_cb_handler_1_2_.addCallback(callback)) {
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-WifiStatus WifiNanIface::enableRequest_1_2Internal(
-    uint16_t /* cmd_id */, const V1_0::NanEnableRequest& /* msg1 */,
-    const V1_2::NanConfigRequestSupplemental& /* msg2 */) {
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus WifiNanIface::configRequest_1_2Internal(
-    uint16_t /* cmd_id */, const V1_0::NanConfigRequest& /* msg1 */,
-    const V1_2::NanConfigRequestSupplemental& /* msg2 */) {
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus WifiNanIface::enableRequest_1_4Internal(
-    uint16_t /* cmd_id */, const V1_4::NanEnableRequest& /* msg1 */,
-    const V1_2::NanConfigRequestSupplemental& /* msg2 */) {
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus WifiNanIface::configRequest_1_4Internal(
-    uint16_t /* cmd_id */, const V1_4::NanConfigRequest& /* msg1 */,
-    const V1_2::NanConfigRequestSupplemental& /* msg2 */) {
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus WifiNanIface::registerEventCallback_1_5Internal(
-    const sp<IWifiNanIfaceEventCallback>& callback) {
-    sp<V1_0::IWifiNanIfaceEventCallback> callback_1_0 = callback;
-    if (!event_cb_handler_.addCallback(callback_1_0)) {
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    sp<V1_2::IWifiNanIfaceEventCallback> callback_1_2 = callback;
-    if (!event_cb_handler_1_2_.addCallback(callback_1_2)) {
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    if (!event_cb_handler_1_5_.addCallback(callback)) {
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-WifiStatus WifiNanIface::getCapabilitiesRequest_1_5Internal(uint16_t cmd_id) {
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->nanGetCapabilities(ifname_, cmd_id);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiNanIface::enableRequest_1_5Internal(
-    uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
-    const NanConfigRequestSupplemental& msg2) {
-    legacy_hal::NanEnableRequest legacy_msg;
-    if (!hidl_struct_util::convertHidlNanEnableRequest_1_5ToLegacy(
-            msg1, msg2, &legacy_msg)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->nanEnableRequest(ifname_, cmd_id, legacy_msg);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiNanIface::configRequest_1_5Internal(
-    uint16_t cmd_id, const V1_4::NanConfigRequest& msg1,
-    const NanConfigRequestSupplemental& msg2) {
-    legacy_hal::NanConfigRequest legacy_msg;
-    if (!hidl_struct_util::convertHidlNanConfigRequest_1_5ToLegacy(
-            msg1, msg2, &legacy_msg)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->nanConfigRequest(ifname_, cmd_id, legacy_msg);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-}  // namespace implementation
-}  // namespace V1_5
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.5/default/wifi_nan_iface.h b/wifi/1.5/default/wifi_nan_iface.h
deleted file mode 100644
index fb9c047..0000000
--- a/wifi/1.5/default/wifi_nan_iface.h
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 WIFI_NAN_IFACE_H_
-#define WIFI_NAN_IFACE_H_
-
-#include <android-base/macros.h>
-#include <android/hardware/wifi/1.5/IWifiNanIface.h>
-#include <android/hardware/wifi/1.5/IWifiNanIfaceEventCallback.h>
-
-#include "hidl_callback_util.h"
-#include "wifi_iface_util.h"
-#include "wifi_legacy_hal.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_5 {
-namespace implementation {
-using namespace android::hardware::wifi::V1_0;
-using namespace android::hardware::wifi::V1_2;
-
-/**
- * HIDL interface object used to control a NAN Iface instance.
- */
-class WifiNanIface : public V1_5::IWifiNanIface {
-   public:
-    WifiNanIface(const std::string& ifname, bool is_dedicated_iface,
-                 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
-                 const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
-    // Refer to |WifiChip::invalidate()|.
-    void invalidate();
-    bool isValid();
-    std::string getName();
-
-    // HIDL methods exposed.
-    Return<void> getName(getName_cb hidl_status_cb) override;
-    Return<void> getType(getType_cb hidl_status_cb) override;
-    Return<void> registerEventCallback(
-        const sp<V1_0::IWifiNanIfaceEventCallback>& callback,
-        registerEventCallback_cb hidl_status_cb) override;
-    Return<void> getCapabilitiesRequest(
-        uint16_t cmd_id, getCapabilitiesRequest_cb hidl_status_cb) override;
-    Return<void> enableRequest(uint16_t cmd_id,
-                               const V1_0::NanEnableRequest& msg,
-                               enableRequest_cb hidl_status_cb) override;
-    Return<void> configRequest(uint16_t cmd_id,
-                               const V1_0::NanConfigRequest& msg,
-                               configRequest_cb hidl_status_cb) override;
-    Return<void> disableRequest(uint16_t cmd_id,
-                                disableRequest_cb hidl_status_cb) override;
-    Return<void> startPublishRequest(
-        uint16_t cmd_id, const NanPublishRequest& msg,
-        startPublishRequest_cb hidl_status_cb) override;
-    Return<void> stopPublishRequest(
-        uint16_t cmd_id, uint8_t sessionId,
-        stopPublishRequest_cb hidl_status_cb) override;
-    Return<void> startSubscribeRequest(
-        uint16_t cmd_id, const NanSubscribeRequest& msg,
-        startSubscribeRequest_cb hidl_status_cb) override;
-    Return<void> stopSubscribeRequest(
-        uint16_t cmd_id, uint8_t sessionId,
-        stopSubscribeRequest_cb hidl_status_cb) override;
-    Return<void> transmitFollowupRequest(
-        uint16_t cmd_id, const NanTransmitFollowupRequest& msg,
-        transmitFollowupRequest_cb hidl_status_cb) override;
-    Return<void> createDataInterfaceRequest(
-        uint16_t cmd_id, const hidl_string& iface_name,
-        createDataInterfaceRequest_cb hidl_status_cb) override;
-    Return<void> deleteDataInterfaceRequest(
-        uint16_t cmd_id, const hidl_string& iface_name,
-        deleteDataInterfaceRequest_cb hidl_status_cb) override;
-    Return<void> initiateDataPathRequest(
-        uint16_t cmd_id, const NanInitiateDataPathRequest& msg,
-        initiateDataPathRequest_cb hidl_status_cb) override;
-    Return<void> respondToDataPathIndicationRequest(
-        uint16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg,
-        respondToDataPathIndicationRequest_cb hidl_status_cb) override;
-    Return<void> terminateDataPathRequest(
-        uint16_t cmd_id, uint32_t ndpInstanceId,
-        terminateDataPathRequest_cb hidl_status_cb) override;
-
-    Return<void> registerEventCallback_1_2(
-        const sp<V1_2::IWifiNanIfaceEventCallback>& callback,
-        registerEventCallback_1_2_cb hidl_status_cb) override;
-    Return<void> enableRequest_1_2(
-        uint16_t cmd_id, const V1_0::NanEnableRequest& msg1,
-        const V1_2::NanConfigRequestSupplemental& msg2,
-        enableRequest_1_2_cb hidl_status_cb) override;
-    Return<void> configRequest_1_2(
-        uint16_t cmd_id, const V1_0::NanConfigRequest& msg1,
-        const V1_2::NanConfigRequestSupplemental& msg2,
-        configRequest_1_2_cb hidl_status_cb) override;
-    Return<void> enableRequest_1_4(
-        uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
-        const V1_2::NanConfigRequestSupplemental& msg2,
-        enableRequest_1_4_cb hidl_status_cb) override;
-    Return<void> configRequest_1_4(
-        uint16_t cmd_id, const V1_4::NanConfigRequest& msg1,
-        const V1_2::NanConfigRequestSupplemental& msg2,
-        configRequest_1_4_cb hidl_status_cb) override;
-    Return<void> registerEventCallback_1_5(
-        const sp<IWifiNanIfaceEventCallback>& callback,
-        registerEventCallback_1_5_cb hidl_status_cb) override;
-    Return<void> enableRequest_1_5(
-        uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
-        const NanConfigRequestSupplemental& msg2,
-        enableRequest_1_4_cb hidl_status_cb) override;
-    Return<void> configRequest_1_5(
-        uint16_t cmd_id, const V1_4::NanConfigRequest& msg1,
-        const NanConfigRequestSupplemental& msg2,
-        configRequest_1_4_cb hidl_status_cb) override;
-    Return<void> getCapabilitiesRequest_1_5(
-        uint16_t cmd_id, getCapabilitiesRequest_cb hidl_status_cb) override;
-
-   private:
-    // Corresponding worker functions for the HIDL methods.
-    std::pair<WifiStatus, std::string> getNameInternal();
-    std::pair<WifiStatus, IfaceType> getTypeInternal();
-    WifiStatus registerEventCallbackInternal(
-        const sp<V1_0::IWifiNanIfaceEventCallback>& callback);
-    WifiStatus getCapabilitiesRequestInternal(uint16_t cmd_id);
-    WifiStatus enableRequestInternal(uint16_t cmd_id,
-                                     const V1_0::NanEnableRequest& msg);
-    WifiStatus configRequestInternal(uint16_t cmd_id,
-                                     const V1_0::NanConfigRequest& msg);
-    WifiStatus disableRequestInternal(uint16_t cmd_id);
-    WifiStatus startPublishRequestInternal(uint16_t cmd_id,
-                                           const NanPublishRequest& msg);
-    WifiStatus stopPublishRequestInternal(uint16_t cmd_id, uint8_t sessionId);
-    WifiStatus startSubscribeRequestInternal(uint16_t cmd_id,
-                                             const NanSubscribeRequest& msg);
-    WifiStatus stopSubscribeRequestInternal(uint16_t cmd_id, uint8_t sessionId);
-    WifiStatus transmitFollowupRequestInternal(
-        uint16_t cmd_id, const NanTransmitFollowupRequest& msg);
-    WifiStatus createDataInterfaceRequestInternal(
-        uint16_t cmd_id, const std::string& iface_name);
-    WifiStatus deleteDataInterfaceRequestInternal(
-        uint16_t cmd_id, const std::string& iface_name);
-    WifiStatus initiateDataPathRequestInternal(
-        uint16_t cmd_id, const NanInitiateDataPathRequest& msg);
-    WifiStatus respondToDataPathIndicationRequestInternal(
-        uint16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg);
-    WifiStatus terminateDataPathRequestInternal(uint16_t cmd_id,
-                                                uint32_t ndpInstanceId);
-
-    WifiStatus registerEventCallback_1_2Internal(
-        const sp<V1_2::IWifiNanIfaceEventCallback>& callback);
-    WifiStatus enableRequest_1_2Internal(
-        uint16_t cmd_id, const V1_0::NanEnableRequest& msg1,
-        const V1_2::NanConfigRequestSupplemental& msg2);
-    WifiStatus configRequest_1_2Internal(
-        uint16_t cmd_id, const V1_0::NanConfigRequest& msg,
-        const V1_2::NanConfigRequestSupplemental& msg2);
-    WifiStatus enableRequest_1_4Internal(
-        uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
-        const V1_2::NanConfigRequestSupplemental& msg2);
-    WifiStatus configRequest_1_4Internal(
-        uint16_t cmd_id, const V1_4::NanConfigRequest& msg,
-        const V1_2::NanConfigRequestSupplemental& msg2);
-    WifiStatus registerEventCallback_1_5Internal(
-        const sp<IWifiNanIfaceEventCallback>& callback);
-    WifiStatus enableRequest_1_5Internal(
-        uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
-        const NanConfigRequestSupplemental& msg2);
-    WifiStatus configRequest_1_5Internal(
-        uint16_t cmd_id, const V1_4::NanConfigRequest& msg,
-        const NanConfigRequestSupplemental& msg2);
-    WifiStatus getCapabilitiesRequest_1_5Internal(uint16_t cmd_id);
-
-    // all 1_0 and descendant callbacks
-    std::set<sp<V1_0::IWifiNanIfaceEventCallback>> getEventCallbacks();
-    // all 1_2 and descendant callbacks
-    std::set<sp<V1_2::IWifiNanIfaceEventCallback>> getEventCallbacks_1_2();
-    // all 1_5 and descendant callbacks
-    std::set<sp<IWifiNanIfaceEventCallback>> getEventCallbacks_1_5();
-
-    std::string ifname_;
-    bool is_dedicated_iface_;
-    std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
-    std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
-    bool is_valid_;
-    hidl_callback_util::HidlCallbackHandler<V1_0::IWifiNanIfaceEventCallback>
-        event_cb_handler_;
-    hidl_callback_util::HidlCallbackHandler<V1_2::IWifiNanIfaceEventCallback>
-        event_cb_handler_1_2_;
-    hidl_callback_util::HidlCallbackHandler<IWifiNanIfaceEventCallback>
-        event_cb_handler_1_5_;
-
-    DISALLOW_COPY_AND_ASSIGN(WifiNanIface);
-};
-
-}  // namespace implementation
-}  // namespace V1_5
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WIFI_NAN_IFACE_H_
diff --git a/wifi/1.5/default/wifi_rtt_controller.cpp b/wifi/1.5/default/wifi_rtt_controller.cpp
deleted file mode 100644
index a0f9969..0000000
--- a/wifi/1.5/default/wifi_rtt_controller.cpp
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 "hidl_return_util.h"
-#include "hidl_struct_util.h"
-#include "wifi_rtt_controller.h"
-#include "wifi_status_util.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_5 {
-namespace implementation {
-using hidl_return_util::validateAndCall;
-
-WifiRttController::WifiRttController(
-    const std::string& iface_name, const sp<IWifiIface>& bound_iface,
-    const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
-    : ifname_(iface_name),
-      bound_iface_(bound_iface),
-      legacy_hal_(legacy_hal),
-      is_valid_(true) {}
-
-void WifiRttController::invalidate() {
-    legacy_hal_.reset();
-    event_callbacks_.clear();
-    is_valid_ = false;
-}
-
-bool WifiRttController::isValid() { return is_valid_; }
-
-std::vector<sp<V1_4::IWifiRttControllerEventCallback>>
-WifiRttController::getEventCallbacks() {
-    return event_callbacks_;
-}
-
-std::string WifiRttController::getIfaceName() { return ifname_; }
-
-Return<void> WifiRttController::getBoundIface(getBoundIface_cb hidl_status_cb) {
-    return validateAndCall(
-        this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-        &WifiRttController::getBoundIfaceInternal, hidl_status_cb);
-}
-
-Return<void> WifiRttController::registerEventCallback(
-    const sp<V1_0::IWifiRttControllerEventCallback>& callback,
-    registerEventCallback_cb hidl_status_cb) {
-    return validateAndCall(this,
-                           WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-                           &WifiRttController::registerEventCallbackInternal,
-                           hidl_status_cb, callback);
-}
-
-Return<void> WifiRttController::rangeRequest(
-    uint32_t cmd_id, const hidl_vec<V1_0::RttConfig>& rtt_configs,
-    rangeRequest_cb hidl_status_cb) {
-    return validateAndCall(this,
-                           WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-                           &WifiRttController::rangeRequestInternal,
-                           hidl_status_cb, cmd_id, rtt_configs);
-}
-
-Return<void> WifiRttController::rangeCancel(
-    uint32_t cmd_id, const hidl_vec<hidl_array<uint8_t, 6>>& addrs,
-    rangeCancel_cb hidl_status_cb) {
-    return validateAndCall(
-        this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-        &WifiRttController::rangeCancelInternal, hidl_status_cb, cmd_id, addrs);
-}
-
-Return<void> WifiRttController::getCapabilities(
-    getCapabilities_cb hidl_status_cb) {
-    return validateAndCall(
-        this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-        &WifiRttController::getCapabilitiesInternal, hidl_status_cb);
-}
-
-Return<void> WifiRttController::setLci(uint32_t cmd_id,
-                                       const RttLciInformation& lci,
-                                       setLci_cb hidl_status_cb) {
-    return validateAndCall(
-        this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-        &WifiRttController::setLciInternal, hidl_status_cb, cmd_id, lci);
-}
-
-Return<void> WifiRttController::setLcr(uint32_t cmd_id,
-                                       const RttLcrInformation& lcr,
-                                       setLcr_cb hidl_status_cb) {
-    return validateAndCall(
-        this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-        &WifiRttController::setLcrInternal, hidl_status_cb, cmd_id, lcr);
-}
-
-Return<void> WifiRttController::getResponderInfo(
-    getResponderInfo_cb hidl_status_cb) {
-    return validateAndCall(
-        this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-        &WifiRttController::getResponderInfoInternal, hidl_status_cb);
-}
-
-Return<void> WifiRttController::enableResponder(
-    uint32_t cmd_id, const WifiChannelInfo& channel_hint,
-    uint32_t max_duration_seconds, const V1_0::RttResponder& info,
-    enableResponder_cb hidl_status_cb) {
-    return validateAndCall(
-        this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-        &WifiRttController::enableResponderInternal, hidl_status_cb, cmd_id,
-        channel_hint, max_duration_seconds, info);
-}
-
-Return<void> WifiRttController::disableResponder(
-    uint32_t cmd_id, disableResponder_cb hidl_status_cb) {
-    return validateAndCall(
-        this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-        &WifiRttController::disableResponderInternal, hidl_status_cb, cmd_id);
-}
-
-Return<void> WifiRttController::registerEventCallback_1_4(
-    const sp<V1_4::IWifiRttControllerEventCallback>& callback,
-    registerEventCallback_1_4_cb hidl_status_cb) {
-    return validateAndCall(
-        this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-        &WifiRttController::registerEventCallbackInternal_1_4, hidl_status_cb,
-        callback);
-}
-
-Return<void> WifiRttController::rangeRequest_1_4(
-    uint32_t cmd_id, const hidl_vec<V1_4::RttConfig>& rtt_configs,
-    rangeRequest_1_4_cb hidl_status_cb) {
-    return validateAndCall(this,
-                           WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-                           &WifiRttController::rangeRequestInternal_1_4,
-                           hidl_status_cb, cmd_id, rtt_configs);
-}
-
-Return<void> WifiRttController::getCapabilities_1_4(
-    getCapabilities_1_4_cb hidl_status_cb) {
-    return validateAndCall(
-        this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-        &WifiRttController::getCapabilitiesInternal_1_4, hidl_status_cb);
-}
-
-Return<void> WifiRttController::getResponderInfo_1_4(
-    getResponderInfo_1_4_cb hidl_status_cb) {
-    return validateAndCall(
-        this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-        &WifiRttController::getResponderInfoInternal_1_4, hidl_status_cb);
-}
-
-Return<void> WifiRttController::enableResponder_1_4(
-    uint32_t cmd_id, const WifiChannelInfo& channel_hint,
-    uint32_t max_duration_seconds, const V1_4::RttResponder& info,
-    enableResponder_1_4_cb hidl_status_cb) {
-    return validateAndCall(
-        this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-        &WifiRttController::enableResponderInternal_1_4, hidl_status_cb, cmd_id,
-        channel_hint, max_duration_seconds, info);
-}
-
-std::pair<WifiStatus, sp<IWifiIface>>
-WifiRttController::getBoundIfaceInternal() {
-    return {createWifiStatus(WifiStatusCode::SUCCESS), bound_iface_};
-}
-
-WifiStatus WifiRttController::registerEventCallbackInternal(
-    const sp<V1_0::IWifiRttControllerEventCallback>& /* callback */) {
-    // Deprecated support for this api
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus WifiRttController::rangeRequestInternal(
-    uint32_t /* cmd_id */,
-    const std::vector<V1_0::RttConfig>& /* rtt_configs */) {
-    // Deprecated support for this api
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus WifiRttController::rangeCancelInternal(
-    uint32_t cmd_id, const std::vector<hidl_array<uint8_t, 6>>& addrs) {
-    std::vector<std::array<uint8_t, 6>> legacy_addrs;
-    for (const auto& addr : addrs) {
-        legacy_addrs.push_back(addr);
-    }
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->cancelRttRangeRequest(ifname_, cmd_id,
-                                                  legacy_addrs);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-std::pair<WifiStatus, V1_0::RttCapabilities>
-WifiRttController::getCapabilitiesInternal() {
-    // Deprecated support for this api
-    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
-}
-
-WifiStatus WifiRttController::setLciInternal(uint32_t cmd_id,
-                                             const RttLciInformation& lci) {
-    legacy_hal::wifi_lci_information legacy_lci;
-    if (!hidl_struct_util::convertHidlRttLciInformationToLegacy(lci,
-                                                                &legacy_lci)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->setRttLci(ifname_, cmd_id, legacy_lci);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiRttController::setLcrInternal(uint32_t cmd_id,
-                                             const RttLcrInformation& lcr) {
-    legacy_hal::wifi_lcr_information legacy_lcr;
-    if (!hidl_struct_util::convertHidlRttLcrInformationToLegacy(lcr,
-                                                                &legacy_lcr)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->setRttLcr(ifname_, cmd_id, legacy_lcr);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-std::pair<WifiStatus, V1_0::RttResponder>
-WifiRttController::getResponderInfoInternal() {
-    // Deprecated support for this api
-    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
-}
-
-WifiStatus WifiRttController::enableResponderInternal(
-    uint32_t /* cmd_id */, const WifiChannelInfo& /* channel_hint */,
-    uint32_t /* max_duration_seconds */, const V1_0::RttResponder& /* info */) {
-    // Deprecated support for this api
-    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED)};
-}
-
-WifiStatus WifiRttController::disableResponderInternal(uint32_t cmd_id) {
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->disableRttResponder(ifname_, cmd_id);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiRttController::registerEventCallbackInternal_1_4(
-    const sp<V1_4::IWifiRttControllerEventCallback>& callback) {
-    // TODO(b/31632518): remove the callback when the client is destroyed
-    event_callbacks_.emplace_back(callback);
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-WifiStatus WifiRttController::rangeRequestInternal_1_4(
-    uint32_t cmd_id, const std::vector<V1_4::RttConfig>& rtt_configs) {
-    std::vector<legacy_hal::wifi_rtt_config> legacy_configs;
-    if (!hidl_struct_util::convertHidlVectorOfRttConfigToLegacy(
-            rtt_configs, &legacy_configs)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    android::wp<WifiRttController> weak_ptr_this(this);
-    const auto& on_results_callback =
-        [weak_ptr_this](
-            legacy_hal::wifi_request_id id,
-            const std::vector<const legacy_hal::wifi_rtt_result*>& results) {
-            const auto shared_ptr_this = weak_ptr_this.promote();
-            if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                LOG(ERROR) << "Callback invoked on an invalid object";
-                return;
-            }
-            std::vector<V1_4::RttResult> hidl_results;
-            if (!hidl_struct_util::convertLegacyVectorOfRttResultToHidl(
-                    results, &hidl_results)) {
-                LOG(ERROR) << "Failed to convert rtt results to HIDL structs";
-                return;
-            }
-            for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                callback->onResults_1_4(id, hidl_results);
-            }
-        };
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->startRttRangeRequest(
-            ifname_, cmd_id, legacy_configs, on_results_callback);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-std::pair<WifiStatus, V1_4::RttCapabilities>
-WifiRttController::getCapabilitiesInternal_1_4() {
-    legacy_hal::wifi_error legacy_status;
-    legacy_hal::wifi_rtt_capabilities legacy_caps;
-    std::tie(legacy_status, legacy_caps) =
-        legacy_hal_.lock()->getRttCapabilities(ifname_);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        return {createWifiStatusFromLegacyError(legacy_status), {}};
-    }
-    V1_4::RttCapabilities hidl_caps;
-    if (!hidl_struct_util::convertLegacyRttCapabilitiesToHidl(legacy_caps,
-                                                              &hidl_caps)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
-}
-
-std::pair<WifiStatus, V1_4::RttResponder>
-WifiRttController::getResponderInfoInternal_1_4() {
-    legacy_hal::wifi_error legacy_status;
-    legacy_hal::wifi_rtt_responder legacy_responder;
-    std::tie(legacy_status, legacy_responder) =
-        legacy_hal_.lock()->getRttResponderInfo(ifname_);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        return {createWifiStatusFromLegacyError(legacy_status), {}};
-    }
-    V1_4::RttResponder hidl_responder;
-    if (!hidl_struct_util::convertLegacyRttResponderToHidl(legacy_responder,
-                                                           &hidl_responder)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_responder};
-}
-
-WifiStatus WifiRttController::enableResponderInternal_1_4(
-    uint32_t cmd_id, const WifiChannelInfo& channel_hint,
-    uint32_t max_duration_seconds, const V1_4::RttResponder& info) {
-    legacy_hal::wifi_channel_info legacy_channel_info;
-    if (!hidl_struct_util::convertHidlWifiChannelInfoToLegacy(
-            channel_hint, &legacy_channel_info)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_rtt_responder legacy_responder;
-    if (!hidl_struct_util::convertHidlRttResponderToLegacy(info,
-                                                           &legacy_responder)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->enableRttResponder(
-            ifname_, cmd_id, legacy_channel_info, max_duration_seconds,
-            legacy_responder);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-}  // namespace implementation
-}  // namespace V1_5
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.5/default/wifi_rtt_controller.h b/wifi/1.5/default/wifi_rtt_controller.h
deleted file mode 100644
index 9ac3e06..0000000
--- a/wifi/1.5/default/wifi_rtt_controller.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 WIFI_RTT_CONTROLLER_H_
-#define WIFI_RTT_CONTROLLER_H_
-
-#include <android-base/macros.h>
-#include <android/hardware/wifi/1.0/IWifiIface.h>
-#include <android/hardware/wifi/1.4/IWifiRttController.h>
-#include <android/hardware/wifi/1.4/IWifiRttControllerEventCallback.h>
-
-#include "wifi_legacy_hal.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_5 {
-namespace implementation {
-
-/**
- * HIDL interface object used to control all RTT operations.
- */
-class WifiRttController : public V1_4::IWifiRttController {
-   public:
-    WifiRttController(
-        const std::string& iface_name, const sp<IWifiIface>& bound_iface,
-        const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
-    // Refer to |WifiChip::invalidate()|.
-    void invalidate();
-    bool isValid();
-    std::vector<sp<V1_4::IWifiRttControllerEventCallback>> getEventCallbacks();
-    std::string getIfaceName();
-
-    // HIDL methods exposed.
-    Return<void> getBoundIface(getBoundIface_cb hidl_status_cb) override;
-    Return<void> registerEventCallback(
-        const sp<V1_0::IWifiRttControllerEventCallback>& callback,
-        registerEventCallback_cb hidl_status_cb) override;
-    Return<void> rangeRequest(uint32_t cmd_id,
-                              const hidl_vec<V1_0::RttConfig>& rtt_configs,
-                              rangeRequest_cb hidl_status_cb) override;
-    Return<void> rangeCancel(uint32_t cmd_id,
-                             const hidl_vec<hidl_array<uint8_t, 6>>& addrs,
-                             rangeCancel_cb hidl_status_cb) override;
-    Return<void> getCapabilities(getCapabilities_cb hidl_status_cb) override;
-    Return<void> setLci(uint32_t cmd_id, const RttLciInformation& lci,
-                        setLci_cb hidl_status_cb) override;
-    Return<void> setLcr(uint32_t cmd_id, const RttLcrInformation& lcr,
-                        setLcr_cb hidl_status_cb) override;
-    Return<void> getResponderInfo(getResponderInfo_cb hidl_status_cb) override;
-    Return<void> enableResponder(uint32_t cmd_id,
-                                 const WifiChannelInfo& channel_hint,
-                                 uint32_t max_duration_seconds,
-                                 const V1_0::RttResponder& info,
-                                 enableResponder_cb hidl_status_cb) override;
-    Return<void> disableResponder(uint32_t cmd_id,
-                                  disableResponder_cb hidl_status_cb) override;
-    Return<void> registerEventCallback_1_4(
-        const sp<V1_4::IWifiRttControllerEventCallback>& callback,
-        registerEventCallback_1_4_cb hidl_status_cb) override;
-    Return<void> rangeRequest_1_4(uint32_t cmd_id,
-                                  const hidl_vec<V1_4::RttConfig>& rtt_configs,
-                                  rangeRequest_1_4_cb hidl_status_cb) override;
-    Return<void> getCapabilities_1_4(
-        getCapabilities_1_4_cb hidl_status_cb) override;
-    Return<void> getResponderInfo_1_4(
-        getResponderInfo_1_4_cb hidl_status_cb) override;
-    Return<void> enableResponder_1_4(
-        uint32_t cmd_id, const WifiChannelInfo& channel_hint,
-        uint32_t max_duration_seconds, const V1_4::RttResponder& info,
-        enableResponder_1_4_cb hidl_status_cb) override;
-
-   private:
-    // Corresponding worker functions for the HIDL methods.
-    std::pair<WifiStatus, sp<IWifiIface>> getBoundIfaceInternal();
-    WifiStatus registerEventCallbackInternal(
-        const sp<V1_0::IWifiRttControllerEventCallback>& callback);
-    WifiStatus rangeRequestInternal(
-        uint32_t cmd_id, const std::vector<V1_0::RttConfig>& rtt_configs);
-    WifiStatus rangeCancelInternal(
-        uint32_t cmd_id, const std::vector<hidl_array<uint8_t, 6>>& addrs);
-    std::pair<WifiStatus, V1_0::RttCapabilities> getCapabilitiesInternal();
-    WifiStatus setLciInternal(uint32_t cmd_id, const RttLciInformation& lci);
-    WifiStatus setLcrInternal(uint32_t cmd_id, const RttLcrInformation& lcr);
-    std::pair<WifiStatus, V1_0::RttResponder> getResponderInfoInternal();
-    WifiStatus enableResponderInternal(uint32_t cmd_id,
-                                       const WifiChannelInfo& channel_hint,
-                                       uint32_t max_duration_seconds,
-                                       const V1_0::RttResponder& info);
-    WifiStatus disableResponderInternal(uint32_t cmd_id);
-    WifiStatus registerEventCallbackInternal_1_4(
-        const sp<V1_4::IWifiRttControllerEventCallback>& callback);
-    WifiStatus rangeRequestInternal_1_4(
-        uint32_t cmd_id, const std::vector<V1_4::RttConfig>& rtt_configs);
-    std::pair<WifiStatus, V1_4::RttCapabilities> getCapabilitiesInternal_1_4();
-    std::pair<WifiStatus, V1_4::RttResponder> getResponderInfoInternal_1_4();
-    WifiStatus enableResponderInternal_1_4(uint32_t cmd_id,
-                                           const WifiChannelInfo& channel_hint,
-                                           uint32_t max_duration_seconds,
-                                           const V1_4::RttResponder& info);
-
-    std::string ifname_;
-    sp<IWifiIface> bound_iface_;
-    std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
-    std::vector<sp<V1_4::IWifiRttControllerEventCallback>> event_callbacks_;
-    bool is_valid_;
-
-    DISALLOW_COPY_AND_ASSIGN(WifiRttController);
-};
-
-}  // namespace implementation
-}  // namespace V1_5
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WIFI_RTT_CONTROLLER_H_
diff --git a/wifi/1.5/default/wifi_sta_iface.cpp b/wifi/1.5/default/wifi_sta_iface.cpp
deleted file mode 100644
index 92c9fe4..0000000
--- a/wifi/1.5/default/wifi_sta_iface.cpp
+++ /dev/null
@@ -1,675 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 "hidl_return_util.h"
-#include "hidl_struct_util.h"
-#include "wifi_sta_iface.h"
-#include "wifi_status_util.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_5 {
-namespace implementation {
-using hidl_return_util::validateAndCall;
-
-WifiStaIface::WifiStaIface(
-    const std::string& ifname,
-    const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
-    const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
-    : ifname_(ifname),
-      legacy_hal_(legacy_hal),
-      iface_util_(iface_util),
-      is_valid_(true) {
-    // Turn on DFS channel usage for STA iface.
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->setDfsFlag(ifname_, true);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        LOG(ERROR)
-            << "Failed to set DFS flag; DFS channels may be unavailable.";
-    }
-}
-
-void WifiStaIface::invalidate() {
-    legacy_hal_.reset();
-    event_cb_handler_.invalidate();
-    is_valid_ = false;
-}
-
-bool WifiStaIface::isValid() { return is_valid_; }
-
-std::string WifiStaIface::getName() { return ifname_; }
-
-std::set<sp<IWifiStaIfaceEventCallback>> WifiStaIface::getEventCallbacks() {
-    return event_cb_handler_.getCallbacks();
-}
-
-Return<void> WifiStaIface::getName(getName_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getNameInternal, hidl_status_cb);
-}
-
-Return<void> WifiStaIface::getType(getType_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getTypeInternal, hidl_status_cb);
-}
-
-Return<void> WifiStaIface::registerEventCallback(
-    const sp<IWifiStaIfaceEventCallback>& callback,
-    registerEventCallback_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::registerEventCallbackInternal,
-                           hidl_status_cb, callback);
-}
-
-Return<void> WifiStaIface::getCapabilities(getCapabilities_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getCapabilitiesInternal,
-                           hidl_status_cb);
-}
-
-Return<void> WifiStaIface::getApfPacketFilterCapabilities(
-    getApfPacketFilterCapabilities_cb hidl_status_cb) {
-    return validateAndCall(
-        this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-        &WifiStaIface::getApfPacketFilterCapabilitiesInternal, hidl_status_cb);
-}
-
-Return<void> WifiStaIface::installApfPacketFilter(
-    uint32_t cmd_id, const hidl_vec<uint8_t>& program,
-    installApfPacketFilter_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::installApfPacketFilterInternal,
-                           hidl_status_cb, cmd_id, program);
-}
-
-Return<void> WifiStaIface::readApfPacketFilterData(
-    readApfPacketFilterData_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::readApfPacketFilterDataInternal,
-                           hidl_status_cb);
-}
-
-Return<void> WifiStaIface::getBackgroundScanCapabilities(
-    getBackgroundScanCapabilities_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getBackgroundScanCapabilitiesInternal,
-                           hidl_status_cb);
-}
-
-Return<void> WifiStaIface::getValidFrequenciesForBand(
-    V1_0::WifiBand band, getValidFrequenciesForBand_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getValidFrequenciesForBandInternal,
-                           hidl_status_cb, band);
-}
-
-Return<void> WifiStaIface::startBackgroundScan(
-    uint32_t cmd_id, const StaBackgroundScanParameters& params,
-    startBackgroundScan_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::startBackgroundScanInternal,
-                           hidl_status_cb, cmd_id, params);
-}
-
-Return<void> WifiStaIface::stopBackgroundScan(
-    uint32_t cmd_id, stopBackgroundScan_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::stopBackgroundScanInternal,
-                           hidl_status_cb, cmd_id);
-}
-
-Return<void> WifiStaIface::enableLinkLayerStatsCollection(
-    bool debug, enableLinkLayerStatsCollection_cb hidl_status_cb) {
-    return validateAndCall(
-        this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-        &WifiStaIface::enableLinkLayerStatsCollectionInternal, hidl_status_cb,
-        debug);
-}
-
-Return<void> WifiStaIface::disableLinkLayerStatsCollection(
-    disableLinkLayerStatsCollection_cb hidl_status_cb) {
-    return validateAndCall(
-        this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-        &WifiStaIface::disableLinkLayerStatsCollectionInternal, hidl_status_cb);
-}
-
-Return<void> WifiStaIface::getLinkLayerStats(
-    getLinkLayerStats_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getLinkLayerStatsInternal,
-                           hidl_status_cb);
-}
-
-Return<void> WifiStaIface::getLinkLayerStats_1_3(
-    getLinkLayerStats_1_3_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getLinkLayerStatsInternal_1_3,
-                           hidl_status_cb);
-}
-
-Return<void> WifiStaIface::getLinkLayerStats_1_5(
-    getLinkLayerStats_1_5_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getLinkLayerStatsInternal_1_5,
-                           hidl_status_cb);
-}
-
-Return<void> WifiStaIface::startRssiMonitoring(
-    uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi,
-    startRssiMonitoring_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::startRssiMonitoringInternal,
-                           hidl_status_cb, cmd_id, max_rssi, min_rssi);
-}
-
-Return<void> WifiStaIface::stopRssiMonitoring(
-    uint32_t cmd_id, stopRssiMonitoring_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::stopRssiMonitoringInternal,
-                           hidl_status_cb, cmd_id);
-}
-
-Return<void> WifiStaIface::getRoamingCapabilities(
-    getRoamingCapabilities_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getRoamingCapabilitiesInternal,
-                           hidl_status_cb);
-}
-
-Return<void> WifiStaIface::configureRoaming(
-    const StaRoamingConfig& config, configureRoaming_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::configureRoamingInternal,
-                           hidl_status_cb, config);
-}
-
-Return<void> WifiStaIface::setRoamingState(StaRoamingState state,
-                                           setRoamingState_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::setRoamingStateInternal,
-                           hidl_status_cb, state);
-}
-
-Return<void> WifiStaIface::enableNdOffload(bool enable,
-                                           enableNdOffload_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::enableNdOffloadInternal,
-                           hidl_status_cb, enable);
-}
-
-Return<void> WifiStaIface::startSendingKeepAlivePackets(
-    uint32_t cmd_id, const hidl_vec<uint8_t>& ip_packet_data,
-    uint16_t ether_type, const hidl_array<uint8_t, 6>& src_address,
-    const hidl_array<uint8_t, 6>& dst_address, uint32_t period_in_ms,
-    startSendingKeepAlivePackets_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::startSendingKeepAlivePacketsInternal,
-                           hidl_status_cb, cmd_id, ip_packet_data, ether_type,
-                           src_address, dst_address, period_in_ms);
-}
-
-Return<void> WifiStaIface::stopSendingKeepAlivePackets(
-    uint32_t cmd_id, stopSendingKeepAlivePackets_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::stopSendingKeepAlivePacketsInternal,
-                           hidl_status_cb, cmd_id);
-}
-
-Return<void> WifiStaIface::setScanningMacOui(
-    const hidl_array<uint8_t, 3>& oui, setScanningMacOui_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::setScanningMacOuiInternal,
-                           hidl_status_cb, oui);
-}
-
-Return<void> WifiStaIface::startDebugPacketFateMonitoring(
-    startDebugPacketFateMonitoring_cb hidl_status_cb) {
-    return validateAndCall(
-        this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-        &WifiStaIface::startDebugPacketFateMonitoringInternal, hidl_status_cb);
-}
-
-Return<void> WifiStaIface::getDebugTxPacketFates(
-    getDebugTxPacketFates_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getDebugTxPacketFatesInternal,
-                           hidl_status_cb);
-}
-
-Return<void> WifiStaIface::getDebugRxPacketFates(
-    getDebugRxPacketFates_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getDebugRxPacketFatesInternal,
-                           hidl_status_cb);
-}
-
-Return<void> WifiStaIface::setMacAddress(const hidl_array<uint8_t, 6>& mac,
-                                         setMacAddress_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::setMacAddressInternal, hidl_status_cb,
-                           mac);
-}
-
-Return<void> WifiStaIface::getFactoryMacAddress(
-    getFactoryMacAddress_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::getFactoryMacAddressInternal,
-                           hidl_status_cb);
-}
-
-Return<void> WifiStaIface::setScanMode(bool enable,
-                                       setScanMode_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiStaIface::setScanModeInternal, hidl_status_cb,
-                           enable);
-}
-
-std::pair<WifiStatus, std::string> WifiStaIface::getNameInternal() {
-    return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_};
-}
-
-std::pair<WifiStatus, IfaceType> WifiStaIface::getTypeInternal() {
-    return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::STA};
-}
-
-WifiStatus WifiStaIface::registerEventCallbackInternal(
-    const sp<IWifiStaIfaceEventCallback>& callback) {
-    if (!event_cb_handler_.addCallback(callback)) {
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-std::pair<WifiStatus, uint32_t> WifiStaIface::getCapabilitiesInternal() {
-    legacy_hal::wifi_error legacy_status;
-    uint64_t legacy_feature_set;
-    std::tie(legacy_status, legacy_feature_set) =
-        legacy_hal_.lock()->getSupportedFeatureSet(ifname_);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        return {createWifiStatusFromLegacyError(legacy_status), 0};
-    }
-    uint32_t legacy_logger_feature_set;
-    std::tie(legacy_status, legacy_logger_feature_set) =
-        legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname_);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        // some devices don't support querying logger feature set
-        legacy_logger_feature_set = 0;
-    }
-    uint32_t hidl_caps;
-    if (!hidl_struct_util::convertLegacyFeaturesToHidlStaCapabilities(
-            legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
-}
-
-std::pair<WifiStatus, StaApfPacketFilterCapabilities>
-WifiStaIface::getApfPacketFilterCapabilitiesInternal() {
-    legacy_hal::wifi_error legacy_status;
-    legacy_hal::PacketFilterCapabilities legacy_caps;
-    std::tie(legacy_status, legacy_caps) =
-        legacy_hal_.lock()->getPacketFilterCapabilities(ifname_);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        return {createWifiStatusFromLegacyError(legacy_status), {}};
-    }
-    StaApfPacketFilterCapabilities hidl_caps;
-    if (!hidl_struct_util::convertLegacyApfCapabilitiesToHidl(legacy_caps,
-                                                              &hidl_caps)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
-}
-
-WifiStatus WifiStaIface::installApfPacketFilterInternal(
-    uint32_t /* cmd_id */, const std::vector<uint8_t>& program) {
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->setPacketFilter(ifname_, program);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-std::pair<WifiStatus, std::vector<uint8_t>>
-WifiStaIface::readApfPacketFilterDataInternal() {
-    const std::pair<legacy_hal::wifi_error, std::vector<uint8_t>>
-        legacy_status_and_data =
-            legacy_hal_.lock()->readApfPacketFilterData(ifname_);
-    return {createWifiStatusFromLegacyError(legacy_status_and_data.first),
-            std::move(legacy_status_and_data.second)};
-}
-
-std::pair<WifiStatus, StaBackgroundScanCapabilities>
-WifiStaIface::getBackgroundScanCapabilitiesInternal() {
-    legacy_hal::wifi_error legacy_status;
-    legacy_hal::wifi_gscan_capabilities legacy_caps;
-    std::tie(legacy_status, legacy_caps) =
-        legacy_hal_.lock()->getGscanCapabilities(ifname_);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        return {createWifiStatusFromLegacyError(legacy_status), {}};
-    }
-    StaBackgroundScanCapabilities hidl_caps;
-    if (!hidl_struct_util::convertLegacyGscanCapabilitiesToHidl(legacy_caps,
-                                                                &hidl_caps)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
-}
-
-std::pair<WifiStatus, std::vector<WifiChannelInMhz>>
-WifiStaIface::getValidFrequenciesForBandInternal(V1_0::WifiBand band) {
-    static_assert(sizeof(WifiChannelInMhz) == sizeof(uint32_t),
-                  "Size mismatch");
-    legacy_hal::wifi_error legacy_status;
-    std::vector<uint32_t> valid_frequencies;
-    std::tie(legacy_status, valid_frequencies) =
-        legacy_hal_.lock()->getValidFrequenciesForBand(
-            ifname_, hidl_struct_util::convertHidlWifiBandToLegacy(band));
-    return {createWifiStatusFromLegacyError(legacy_status), valid_frequencies};
-}
-
-WifiStatus WifiStaIface::startBackgroundScanInternal(
-    uint32_t cmd_id, const StaBackgroundScanParameters& params) {
-    legacy_hal::wifi_scan_cmd_params legacy_params;
-    if (!hidl_struct_util::convertHidlGscanParamsToLegacy(params,
-                                                          &legacy_params)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    android::wp<WifiStaIface> weak_ptr_this(this);
-    const auto& on_failure_callback =
-        [weak_ptr_this](legacy_hal::wifi_request_id id) {
-            const auto shared_ptr_this = weak_ptr_this.promote();
-            if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                LOG(ERROR) << "Callback invoked on an invalid object";
-                return;
-            }
-            for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                if (!callback->onBackgroundScanFailure(id).isOk()) {
-                    LOG(ERROR)
-                        << "Failed to invoke onBackgroundScanFailure callback";
-                }
-            }
-        };
-    const auto& on_results_callback =
-        [weak_ptr_this](
-            legacy_hal::wifi_request_id id,
-            const std::vector<legacy_hal::wifi_cached_scan_results>& results) {
-            const auto shared_ptr_this = weak_ptr_this.promote();
-            if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                LOG(ERROR) << "Callback invoked on an invalid object";
-                return;
-            }
-            std::vector<StaScanData> hidl_scan_datas;
-            if (!hidl_struct_util::
-                    convertLegacyVectorOfCachedGscanResultsToHidl(
-                        results, &hidl_scan_datas)) {
-                LOG(ERROR) << "Failed to convert scan results to HIDL structs";
-                return;
-            }
-            for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                if (!callback->onBackgroundScanResults(id, hidl_scan_datas)
-                         .isOk()) {
-                    LOG(ERROR)
-                        << "Failed to invoke onBackgroundScanResults callback";
-                }
-            }
-        };
-    const auto& on_full_result_callback = [weak_ptr_this](
-                                              legacy_hal::wifi_request_id id,
-                                              const legacy_hal::
-                                                  wifi_scan_result* result,
-                                              uint32_t buckets_scanned) {
-        const auto shared_ptr_this = weak_ptr_this.promote();
-        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-            LOG(ERROR) << "Callback invoked on an invalid object";
-            return;
-        }
-        StaScanResult hidl_scan_result;
-        if (!hidl_struct_util::convertLegacyGscanResultToHidl(
-                *result, true, &hidl_scan_result)) {
-            LOG(ERROR) << "Failed to convert full scan results to HIDL structs";
-            return;
-        }
-        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-            if (!callback
-                     ->onBackgroundFullScanResult(id, buckets_scanned,
-                                                  hidl_scan_result)
-                     .isOk()) {
-                LOG(ERROR)
-                    << "Failed to invoke onBackgroundFullScanResult callback";
-            }
-        }
-    };
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startGscan(
-        ifname_, cmd_id, legacy_params, on_failure_callback,
-        on_results_callback, on_full_result_callback);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiStaIface::stopBackgroundScanInternal(uint32_t cmd_id) {
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->stopGscan(ifname_, cmd_id);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiStaIface::enableLinkLayerStatsCollectionInternal(bool debug) {
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->enableLinkLayerStats(ifname_, debug);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiStaIface::disableLinkLayerStatsCollectionInternal() {
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->disableLinkLayerStats(ifname_);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-std::pair<WifiStatus, V1_0::StaLinkLayerStats>
-WifiStaIface::getLinkLayerStatsInternal() {
-    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
-}
-
-std::pair<WifiStatus, V1_3::StaLinkLayerStats>
-WifiStaIface::getLinkLayerStatsInternal_1_3() {
-    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
-}
-
-std::pair<WifiStatus, V1_5::StaLinkLayerStats>
-WifiStaIface::getLinkLayerStatsInternal_1_5() {
-    legacy_hal::wifi_error legacy_status;
-    legacy_hal::LinkLayerStats legacy_stats;
-    std::tie(legacy_status, legacy_stats) =
-        legacy_hal_.lock()->getLinkLayerStats(ifname_);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        return {createWifiStatusFromLegacyError(legacy_status), {}};
-    }
-    V1_5::StaLinkLayerStats hidl_stats;
-    if (!hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats,
-                                                             &hidl_stats)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats};
-}
-
-WifiStatus WifiStaIface::startRssiMonitoringInternal(uint32_t cmd_id,
-                                                     int32_t max_rssi,
-                                                     int32_t min_rssi) {
-    android::wp<WifiStaIface> weak_ptr_this(this);
-    const auto& on_threshold_breached_callback =
-        [weak_ptr_this](legacy_hal::wifi_request_id id,
-                        std::array<uint8_t, 6> bssid, int8_t rssi) {
-            const auto shared_ptr_this = weak_ptr_this.promote();
-            if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                LOG(ERROR) << "Callback invoked on an invalid object";
-                return;
-            }
-            for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                if (!callback->onRssiThresholdBreached(id, bssid, rssi)
-                         .isOk()) {
-                    LOG(ERROR)
-                        << "Failed to invoke onRssiThresholdBreached callback";
-                }
-            }
-        };
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->startRssiMonitoring(ifname_, cmd_id, max_rssi,
-                                                min_rssi,
-                                                on_threshold_breached_callback);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiStaIface::stopRssiMonitoringInternal(uint32_t cmd_id) {
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->stopRssiMonitoring(ifname_, cmd_id);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-std::pair<WifiStatus, StaRoamingCapabilities>
-WifiStaIface::getRoamingCapabilitiesInternal() {
-    legacy_hal::wifi_error legacy_status;
-    legacy_hal::wifi_roaming_capabilities legacy_caps;
-    std::tie(legacy_status, legacy_caps) =
-        legacy_hal_.lock()->getRoamingCapabilities(ifname_);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        return {createWifiStatusFromLegacyError(legacy_status), {}};
-    }
-    StaRoamingCapabilities hidl_caps;
-    if (!hidl_struct_util::convertLegacyRoamingCapabilitiesToHidl(legacy_caps,
-                                                                  &hidl_caps)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
-}
-
-WifiStatus WifiStaIface::configureRoamingInternal(
-    const StaRoamingConfig& config) {
-    legacy_hal::wifi_roaming_config legacy_config;
-    if (!hidl_struct_util::convertHidlRoamingConfigToLegacy(config,
-                                                            &legacy_config)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->configureRoaming(ifname_, legacy_config);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiStaIface::setRoamingStateInternal(StaRoamingState state) {
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->enableFirmwareRoaming(
-            ifname_, hidl_struct_util::convertHidlRoamingStateToLegacy(state));
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiStaIface::enableNdOffloadInternal(bool enable) {
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->configureNdOffload(ifname_, enable);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiStaIface::startSendingKeepAlivePacketsInternal(
-    uint32_t cmd_id, const std::vector<uint8_t>& ip_packet_data,
-    uint16_t ether_type, const std::array<uint8_t, 6>& src_address,
-    const std::array<uint8_t, 6>& dst_address, uint32_t period_in_ms) {
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->startSendingOffloadedPacket(
-            ifname_, cmd_id, ether_type, ip_packet_data, src_address,
-            dst_address, period_in_ms);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiStaIface::stopSendingKeepAlivePacketsInternal(uint32_t cmd_id) {
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->stopSendingOffloadedPacket(ifname_, cmd_id);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-WifiStatus WifiStaIface::setScanningMacOuiInternal(
-    const std::array<uint8_t, 3>& /* oui */) {
-    // deprecated.
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-WifiStatus WifiStaIface::startDebugPacketFateMonitoringInternal() {
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->startPktFateMonitoring(ifname_);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
-
-std::pair<WifiStatus, std::vector<WifiDebugTxPacketFateReport>>
-WifiStaIface::getDebugTxPacketFatesInternal() {
-    legacy_hal::wifi_error legacy_status;
-    std::vector<legacy_hal::wifi_tx_report> legacy_fates;
-    std::tie(legacy_status, legacy_fates) =
-        legacy_hal_.lock()->getTxPktFates(ifname_);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        return {createWifiStatusFromLegacyError(legacy_status), {}};
-    }
-    std::vector<WifiDebugTxPacketFateReport> hidl_fates;
-    if (!hidl_struct_util::convertLegacyVectorOfDebugTxPacketFateToHidl(
-            legacy_fates, &hidl_fates)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_fates};
-}
-
-std::pair<WifiStatus, std::vector<WifiDebugRxPacketFateReport>>
-WifiStaIface::getDebugRxPacketFatesInternal() {
-    legacy_hal::wifi_error legacy_status;
-    std::vector<legacy_hal::wifi_rx_report> legacy_fates;
-    std::tie(legacy_status, legacy_fates) =
-        legacy_hal_.lock()->getRxPktFates(ifname_);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        return {createWifiStatusFromLegacyError(legacy_status), {}};
-    }
-    std::vector<WifiDebugRxPacketFateReport> hidl_fates;
-    if (!hidl_struct_util::convertLegacyVectorOfDebugRxPacketFateToHidl(
-            legacy_fates, &hidl_fates)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_fates};
-}
-
-WifiStatus WifiStaIface::setMacAddressInternal(
-    const std::array<uint8_t, 6>& mac) {
-    bool status = iface_util_.lock()->setMacAddress(ifname_, mac);
-    if (!status) {
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    return createWifiStatus(WifiStatusCode::SUCCESS);
-}
-
-std::pair<WifiStatus, std::array<uint8_t, 6>>
-WifiStaIface::getFactoryMacAddressInternal() {
-    std::array<uint8_t, 6> mac =
-        iface_util_.lock()->getFactoryMacAddress(ifname_);
-    if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 &&
-        mac[4] == 0 && mac[5] == 0) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), mac};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), mac};
-}
-
-WifiStatus WifiStaIface::setScanModeInternal(bool enable) {
-    // OEM's need to implement this on their devices if needed.
-    LOG(WARNING) << "setScanModeInternal(" << enable << ") not supported";
-    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
-}
-
-}  // namespace implementation
-}  // namespace V1_5
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wifi/1.5/default/wifi_sta_iface.h b/wifi/1.5/default/wifi_sta_iface.h
deleted file mode 100644
index f9058b8..0000000
--- a/wifi/1.5/default/wifi_sta_iface.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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 WIFI_STA_IFACE_H_
-#define WIFI_STA_IFACE_H_
-
-#include <android-base/macros.h>
-#include <android/hardware/wifi/1.0/IWifiStaIfaceEventCallback.h>
-#include <android/hardware/wifi/1.5/IWifiStaIface.h>
-
-#include "hidl_callback_util.h"
-#include "wifi_iface_util.h"
-#include "wifi_legacy_hal.h"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace V1_5 {
-namespace implementation {
-using namespace android::hardware::wifi::V1_0;
-
-/**
- * HIDL interface object used to control a STA Iface instance.
- */
-class WifiStaIface : public V1_5::IWifiStaIface {
-   public:
-    WifiStaIface(const std::string& ifname,
-                 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
-                 const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
-    // Refer to |WifiChip::invalidate()|.
-    void invalidate();
-    bool isValid();
-    std::set<sp<IWifiStaIfaceEventCallback>> getEventCallbacks();
-    std::string getName();
-
-    // HIDL methods exposed.
-    Return<void> getName(getName_cb hidl_status_cb) override;
-    Return<void> getType(getType_cb hidl_status_cb) override;
-    Return<void> registerEventCallback(
-        const sp<IWifiStaIfaceEventCallback>& callback,
-        registerEventCallback_cb hidl_status_cb) override;
-    Return<void> getCapabilities(getCapabilities_cb hidl_status_cb) override;
-    Return<void> getApfPacketFilterCapabilities(
-        getApfPacketFilterCapabilities_cb hidl_status_cb) override;
-    Return<void> installApfPacketFilter(
-        uint32_t cmd_id, const hidl_vec<uint8_t>& program,
-        installApfPacketFilter_cb hidl_status_cb) override;
-    Return<void> readApfPacketFilterData(
-        readApfPacketFilterData_cb hidl_status_cb) override;
-    Return<void> getBackgroundScanCapabilities(
-        getBackgroundScanCapabilities_cb hidl_status_cb) override;
-    Return<void> getValidFrequenciesForBand(
-        V1_0::WifiBand band,
-        getValidFrequenciesForBand_cb hidl_status_cb) override;
-    Return<void> startBackgroundScan(
-        uint32_t cmd_id, const StaBackgroundScanParameters& params,
-        startBackgroundScan_cb hidl_status_cb) override;
-    Return<void> stopBackgroundScan(
-        uint32_t cmd_id, stopBackgroundScan_cb hidl_status_cb) override;
-    Return<void> enableLinkLayerStatsCollection(
-        bool debug, enableLinkLayerStatsCollection_cb hidl_status_cb) override;
-    Return<void> disableLinkLayerStatsCollection(
-        disableLinkLayerStatsCollection_cb hidl_status_cb) override;
-    Return<void> getLinkLayerStats(
-        getLinkLayerStats_cb hidl_status_cb) override;
-    Return<void> getLinkLayerStats_1_3(
-        getLinkLayerStats_1_3_cb hidl_status_cb) override;
-    Return<void> getLinkLayerStats_1_5(
-        getLinkLayerStats_1_5_cb hidl_status_cb) override;
-    Return<void> startRssiMonitoring(
-        uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi,
-        startRssiMonitoring_cb hidl_status_cb) override;
-    Return<void> stopRssiMonitoring(
-        uint32_t cmd_id, stopRssiMonitoring_cb hidl_status_cb) override;
-    Return<void> getRoamingCapabilities(
-        getRoamingCapabilities_cb hidl_status_cb) override;
-    Return<void> configureRoaming(const StaRoamingConfig& config,
-                                  configureRoaming_cb hidl_status_cb) override;
-    Return<void> setRoamingState(StaRoamingState state,
-                                 setRoamingState_cb hidl_status_cb) override;
-    Return<void> enableNdOffload(bool enable,
-                                 enableNdOffload_cb hidl_status_cb) override;
-    Return<void> startSendingKeepAlivePackets(
-        uint32_t cmd_id, const hidl_vec<uint8_t>& ip_packet_data,
-        uint16_t ether_type, const hidl_array<uint8_t, 6>& src_address,
-        const hidl_array<uint8_t, 6>& dst_address, uint32_t period_in_ms,
-        startSendingKeepAlivePackets_cb hidl_status_cb) override;
-    Return<void> stopSendingKeepAlivePackets(
-        uint32_t cmd_id,
-        stopSendingKeepAlivePackets_cb hidl_status_cb) override;
-    Return<void> setScanningMacOui(
-        const hidl_array<uint8_t, 3>& oui,
-        setScanningMacOui_cb hidl_status_cb) override;
-    Return<void> startDebugPacketFateMonitoring(
-        startDebugPacketFateMonitoring_cb hidl_status_cb) override;
-    Return<void> getDebugTxPacketFates(
-        getDebugTxPacketFates_cb hidl_status_cb) override;
-    Return<void> getDebugRxPacketFates(
-        getDebugRxPacketFates_cb hidl_status_cb) override;
-    Return<void> setMacAddress(const hidl_array<uint8_t, 6>& mac,
-                               setMacAddress_cb hidl_status_cb) override;
-    Return<void> getFactoryMacAddress(
-        getFactoryMacAddress_cb hidl_status_cb) override;
-    Return<void> setScanMode(bool enable,
-                             setScanMode_cb hidl_status_cb) override;
-
-   private:
-    // Corresponding worker functions for the HIDL methods.
-    std::pair<WifiStatus, std::string> getNameInternal();
-    std::pair<WifiStatus, IfaceType> getTypeInternal();
-    WifiStatus registerEventCallbackInternal(
-        const sp<IWifiStaIfaceEventCallback>& callback);
-    std::pair<WifiStatus, uint32_t> getCapabilitiesInternal();
-    std::pair<WifiStatus, StaApfPacketFilterCapabilities>
-    getApfPacketFilterCapabilitiesInternal();
-    WifiStatus installApfPacketFilterInternal(
-        uint32_t cmd_id, const std::vector<uint8_t>& program);
-    std::pair<WifiStatus, std::vector<uint8_t>>
-    readApfPacketFilterDataInternal();
-    std::pair<WifiStatus, StaBackgroundScanCapabilities>
-    getBackgroundScanCapabilitiesInternal();
-    std::pair<WifiStatus, std::vector<WifiChannelInMhz>>
-    getValidFrequenciesForBandInternal(V1_0::WifiBand band);
-    WifiStatus startBackgroundScanInternal(
-        uint32_t cmd_id, const StaBackgroundScanParameters& params);
-    WifiStatus stopBackgroundScanInternal(uint32_t cmd_id);
-    WifiStatus enableLinkLayerStatsCollectionInternal(bool debug);
-    WifiStatus disableLinkLayerStatsCollectionInternal();
-    std::pair<WifiStatus, V1_0::StaLinkLayerStats> getLinkLayerStatsInternal();
-    std::pair<WifiStatus, V1_3::StaLinkLayerStats>
-    getLinkLayerStatsInternal_1_3();
-    std::pair<WifiStatus, V1_5::StaLinkLayerStats>
-    getLinkLayerStatsInternal_1_5();
-    WifiStatus startRssiMonitoringInternal(uint32_t cmd_id, int32_t max_rssi,
-                                           int32_t min_rssi);
-    WifiStatus stopRssiMonitoringInternal(uint32_t cmd_id);
-    std::pair<WifiStatus, StaRoamingCapabilities>
-    getRoamingCapabilitiesInternal();
-    WifiStatus configureRoamingInternal(const StaRoamingConfig& config);
-    WifiStatus setRoamingStateInternal(StaRoamingState state);
-    WifiStatus enableNdOffloadInternal(bool enable);
-    WifiStatus startSendingKeepAlivePacketsInternal(
-        uint32_t cmd_id, const std::vector<uint8_t>& ip_packet_data,
-        uint16_t ether_type, const std::array<uint8_t, 6>& src_address,
-        const std::array<uint8_t, 6>& dst_address, uint32_t period_in_ms);
-    WifiStatus stopSendingKeepAlivePacketsInternal(uint32_t cmd_id);
-    WifiStatus setScanningMacOuiInternal(const std::array<uint8_t, 3>& oui);
-    WifiStatus startDebugPacketFateMonitoringInternal();
-    std::pair<WifiStatus, std::vector<WifiDebugTxPacketFateReport>>
-    getDebugTxPacketFatesInternal();
-    std::pair<WifiStatus, std::vector<WifiDebugRxPacketFateReport>>
-    getDebugRxPacketFatesInternal();
-    WifiStatus setMacAddressInternal(const std::array<uint8_t, 6>& mac);
-    std::pair<WifiStatus, std::array<uint8_t, 6>>
-    getFactoryMacAddressInternal();
-    WifiStatus setScanModeInternal(bool enable);
-
-    std::string ifname_;
-    std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
-    std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
-    bool is_valid_;
-    hidl_callback_util::HidlCallbackHandler<IWifiStaIfaceEventCallback>
-        event_cb_handler_;
-
-    DISALLOW_COPY_AND_ASSIGN(WifiStaIface);
-};
-
-}  // namespace implementation
-}  // namespace V1_5
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WIFI_STA_IFACE_H_
diff --git a/wifi/1.6/Android.bp b/wifi/1.6/Android.bp
new file mode 100644
index 0000000..d293c73
--- /dev/null
+++ b/wifi/1.6/Android.bp
@@ -0,0 +1,32 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+hidl_interface {
+    name: "android.hardware.wifi@1.6",
+    root: "android.hardware",
+    srcs: [
+        "IWifi.hal",
+    ],
+    interfaces: [
+        "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",
+        "android.hidl.base@1.0",
+    ],
+    gen_java: true,
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.wifi",
+    ],
+}
diff --git a/wifi/1.6/IWifi.hal b/wifi/1.6/IWifi.hal
new file mode 100644
index 0000000..0123e6c
--- /dev/null
+++ b/wifi/1.6/IWifi.hal
@@ -0,0 +1,27 @@
+/*
+ * 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.wifi@1.6;
+
+import @1.5::IWifi;
+
+/**
+ * This is the root of the HAL module and is the interface returned when
+ * loading an implementation of the Wi-Fi HAL. There must be at most one
+ * module loaded in the system.
+ * IWifi.getChip() must return @1.5::IWifiChip
+ */
+interface IWifi extends @1.5::IWifi {};
diff --git a/wifi/1.5/default/Android.bp b/wifi/1.6/default/Android.bp
similarity index 100%
rename from wifi/1.5/default/Android.bp
rename to wifi/1.6/default/Android.bp
diff --git a/wifi/1.5/default/Android.mk b/wifi/1.6/default/Android.mk
similarity index 96%
rename from wifi/1.5/default/Android.mk
rename to wifi/1.6/default/Android.mk
index 1997b22..ca1c022 100644
--- a/wifi/1.5/default/Android.mk
+++ b/wifi/1.6/default/Android.mk
@@ -77,7 +77,8 @@
     android.hardware.wifi@1.2 \
     android.hardware.wifi@1.3 \
     android.hardware.wifi@1.4 \
-    android.hardware.wifi@1.5
+    android.hardware.wifi@1.5 \
+    android.hardware.wifi@1.6
 LOCAL_C_INCLUDES += $(TOP)/external/libxml2/include
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
 include $(BUILD_STATIC_LIBRARY)
@@ -111,7 +112,8 @@
     android.hardware.wifi@1.2 \
     android.hardware.wifi@1.3 \
     android.hardware.wifi@1.4 \
-    android.hardware.wifi@1.5
+    android.hardware.wifi@1.5 \
+    android.hardware.wifi@1.6
 LOCAL_STATIC_LIBRARIES := \
     android.hardware.wifi@1.0-service-lib
 LOCAL_INIT_RC := android.hardware.wifi@1.0-service.rc
@@ -148,7 +150,8 @@
     android.hardware.wifi@1.2 \
     android.hardware.wifi@1.3 \
     android.hardware.wifi@1.4 \
-    android.hardware.wifi@1.5
+    android.hardware.wifi@1.5 \
+    android.hardware.wifi@1.6
 LOCAL_STATIC_LIBRARIES := \
     android.hardware.wifi@1.0-service-lib
 LOCAL_INIT_RC := android.hardware.wifi@1.0-service-lazy.rc
@@ -185,6 +188,7 @@
     android.hardware.wifi@1.3 \
     android.hardware.wifi@1.4 \
     android.hardware.wifi@1.5 \
+    android.hardware.wifi@1.6 \
     android.hardware.wifi@1.0-service-lib
 LOCAL_SHARED_LIBRARIES := \
     libbase \
diff --git a/wifi/1.5/default/OWNERS b/wifi/1.6/default/OWNERS
similarity index 100%
rename from wifi/1.5/default/OWNERS
rename to wifi/1.6/default/OWNERS
diff --git a/wifi/1.5/default/THREADING.README b/wifi/1.6/default/THREADING.README
similarity index 100%
rename from wifi/1.5/default/THREADING.README
rename to wifi/1.6/default/THREADING.README
diff --git a/wifi/1.5/default/android.hardware.wifi@1.0-service-lazy.rc b/wifi/1.6/default/android.hardware.wifi@1.0-service-lazy.rc
similarity index 100%
rename from wifi/1.5/default/android.hardware.wifi@1.0-service-lazy.rc
rename to wifi/1.6/default/android.hardware.wifi@1.0-service-lazy.rc
diff --git a/wifi/1.5/default/android.hardware.wifi@1.0-service.rc b/wifi/1.6/default/android.hardware.wifi@1.0-service.rc
similarity index 89%
rename from wifi/1.5/default/android.hardware.wifi@1.0-service.rc
rename to wifi/1.6/default/android.hardware.wifi@1.0-service.rc
index 05706ef..18f40d0 100644
--- a/wifi/1.5/default/android.hardware.wifi@1.0-service.rc
+++ b/wifi/1.6/default/android.hardware.wifi@1.0-service.rc
@@ -5,6 +5,7 @@
     interface android.hardware.wifi@1.3::IWifi default
     interface android.hardware.wifi@1.4::IWifi default
     interface android.hardware.wifi@1.5::IWifi default
+    interface android.hardware.wifi@1.6::IWifi default
     class hal
     capabilities NET_ADMIN NET_RAW SYS_MODULE
     user wifi
diff --git a/wifi/1.5/default/android.hardware.wifi@1.0-service.xml b/wifi/1.6/default/android.hardware.wifi@1.0-service.xml
similarity index 89%
rename from wifi/1.5/default/android.hardware.wifi@1.0-service.xml
rename to wifi/1.6/default/android.hardware.wifi@1.0-service.xml
index 88dd1e3..771fbaa 100644
--- a/wifi/1.5/default/android.hardware.wifi@1.0-service.xml
+++ b/wifi/1.6/default/android.hardware.wifi@1.0-service.xml
@@ -2,7 +2,7 @@
     <hal format="hidl">
         <name>android.hardware.wifi</name>
         <transport>hwbinder</transport>
-        <version>1.5</version>
+        <version>1.6</version>
         <interface>
             <name>IWifi</name>
             <instance>default</instance>
diff --git a/wifi/1.5/default/hidl_callback_util.h b/wifi/1.6/default/hidl_callback_util.h
similarity index 88%
rename from wifi/1.5/default/hidl_callback_util.h
rename to wifi/1.6/default/hidl_callback_util.h
index d144658..3ac54c1 100644
--- a/wifi/1.5/default/hidl_callback_util.h
+++ b/wifi/1.6/default/hidl_callback_util.h
@@ -29,20 +29,18 @@
 // callbacks stored in HidlCallbackHandler.
 template <typename CallbackType>
 class HidlDeathHandler : public android::hardware::hidl_death_recipient {
-   public:
+  public:
     HidlDeathHandler(const on_death_cb_function& user_cb_function)
         : cb_function_(user_cb_function) {}
     ~HidlDeathHandler() = default;
 
     // Death notification for callbacks.
-    void serviceDied(
-        uint64_t cookie,
-        const android::wp<android::hidl::base::V1_0::IBase>& /* who */)
-        override {
+    void serviceDied(uint64_t cookie,
+                     const android::wp<android::hidl::base::V1_0::IBase>& /* who */) override {
         cb_function_(cookie);
     }
 
-   private:
+  private:
     on_death_cb_function cb_function_;
 
     DISALLOW_COPY_AND_ASSIGN(HidlDeathHandler);
@@ -52,18 +50,17 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 namespace hidl_callback_util {
 template <typename CallbackType>
 // Provides a class to manage callbacks for the various HIDL interfaces and
 // handle the death of the process hosting each callback.
 class HidlCallbackHandler {
-   public:
+  public:
     HidlCallbackHandler()
         : death_handler_(new HidlDeathHandler<CallbackType>(
-              std::bind(&HidlCallbackHandler::onObjectDeath, this,
-                        std::placeholders::_1))) {}
+                  std::bind(&HidlCallbackHandler::onObjectDeath, this, std::placeholders::_1))) {}
     ~HidlCallbackHandler() = default;
 
     bool addCallback(const sp<CallbackType>& cb) {
@@ -83,9 +80,7 @@
         return true;
     }
 
-    const std::set<android::sp<CallbackType>>& getCallbacks() {
-        return cb_set_;
-    }
+    const std::set<android::sp<CallbackType>>& getCallbacks() { return cb_set_; }
 
     // Death notification for callbacks.
     void onObjectDeath(uint64_t cookie) {
@@ -108,7 +103,7 @@
         cb_set_.clear();
     }
 
-   private:
+  private:
     std::set<sp<CallbackType>> cb_set_;
     sp<HidlDeathHandler<CallbackType>> death_handler_;
 
@@ -117,7 +112,7 @@
 
 }  // namespace hidl_callback_util
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/hidl_return_util.h b/wifi/1.6/default/hidl_return_util.h
similarity index 77%
rename from wifi/1.5/default/hidl_return_util.h
rename to wifi/1.6/default/hidl_return_util.h
index 4455185..a0efac2 100644
--- a/wifi/1.5/default/hidl_return_util.h
+++ b/wifi/1.6/default/hidl_return_util.h
@@ -23,7 +23,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 namespace hidl_return_util {
 using namespace android::hardware::wifi::V1_0;
@@ -40,9 +40,9 @@
  */
 // Use for HIDL methods which return only an instance of WifiStatus.
 template <typename ObjT, typename WorkFuncT, typename... Args>
-Return<void> validateAndCall(
-    ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work,
-    const std::function<void(const WifiStatus&)>& hidl_cb, Args&&... args) {
+Return<void> validateAndCall(ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work,
+                             const std::function<void(const WifiStatus&)>& hidl_cb,
+                             Args&&... args) {
     const auto lock = hidl_sync_util::acquireGlobalLock();
     if (obj->isValid()) {
         hidl_cb((obj->*work)(std::forward<Args>(args)...));
@@ -56,9 +56,10 @@
 // This version passes the global lock acquired to the body of the method.
 // Note: Only used by IWifi::stop() currently.
 template <typename ObjT, typename WorkFuncT, typename... Args>
-Return<void> validateAndCallWithLock(
-    ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work,
-    const std::function<void(const WifiStatus&)>& hidl_cb, Args&&... args) {
+Return<void> validateAndCallWithLock(ObjT* obj, WifiStatusCode status_code_if_invalid,
+                                     WorkFuncT&& work,
+                                     const std::function<void(const WifiStatus&)>& hidl_cb,
+                                     Args&&... args) {
     auto lock = hidl_sync_util::acquireGlobalLock();
     if (obj->isValid()) {
         hidl_cb((obj->*work)(&lock, std::forward<Args>(args)...));
@@ -71,10 +72,9 @@
 // Use for HIDL methods which return instance of WifiStatus and a single return
 // value.
 template <typename ObjT, typename WorkFuncT, typename ReturnT, typename... Args>
-Return<void> validateAndCall(
-    ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work,
-    const std::function<void(const WifiStatus&, ReturnT)>& hidl_cb,
-    Args&&... args) {
+Return<void> validateAndCall(ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work,
+                             const std::function<void(const WifiStatus&, ReturnT)>& hidl_cb,
+                             Args&&... args) {
     const auto lock = hidl_sync_util::acquireGlobalLock();
     if (obj->isValid()) {
         const auto& ret_pair = (obj->*work)(std::forward<Args>(args)...);
@@ -90,12 +90,10 @@
 
 // Use for HIDL methods which return instance of WifiStatus and 2 return
 // values.
-template <typename ObjT, typename WorkFuncT, typename ReturnT1,
-          typename ReturnT2, typename... Args>
+template <typename ObjT, typename WorkFuncT, typename ReturnT1, typename ReturnT2, typename... Args>
 Return<void> validateAndCall(
-    ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work,
-    const std::function<void(const WifiStatus&, ReturnT1, ReturnT2)>& hidl_cb,
-    Args&&... args) {
+        ObjT* obj, WifiStatusCode status_code_if_invalid, WorkFuncT&& work,
+        const std::function<void(const WifiStatus&, ReturnT1, ReturnT2)>& hidl_cb, Args&&... args) {
     const auto lock = hidl_sync_util::acquireGlobalLock();
     if (obj->isValid()) {
         const auto& ret_tuple = (obj->*work)(std::forward<Args>(args)...);
@@ -113,7 +111,7 @@
 
 }  // namespace hidl_return_util
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/hidl_struct_util.cpp b/wifi/1.6/default/hidl_struct_util.cpp
similarity index 63%
rename from wifi/1.5/default/hidl_struct_util.cpp
rename to wifi/1.6/default/hidl_struct_util.cpp
index 338a8f1..3489c9e 100644
--- a/wifi/1.5/default/hidl_struct_util.cpp
+++ b/wifi/1.6/default/hidl_struct_util.cpp
@@ -22,12 +22,13 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 namespace hidl_struct_util {
 
-WifiChannelWidthInMhz convertLegacyWifiChannelWidthToHidl(
-    legacy_hal::wifi_channel_width type);
+using V1_5::NanConfigRequestSupplemental;
+
+WifiChannelWidthInMhz convertLegacyWifiChannelWidthToHidl(legacy_hal::wifi_channel_width type);
 
 hidl_string safeConvertChar(const char* str, size_t max_len) {
     const char* c = str;
@@ -39,8 +40,7 @@
     return hidl_string(str, size);
 }
 
-IWifiChip::ChipCapabilityMask convertLegacyLoggerFeatureToHidlChipCapability(
-    uint32_t feature) {
+IWifiChip::ChipCapabilityMask convertLegacyLoggerFeatureToHidlChipCapability(uint32_t feature) {
     using HidlChipCaps = IWifiChip::ChipCapabilityMask;
     switch (feature) {
         case legacy_hal::WIFI_LOGGER_MEMORY_DUMP_SUPPORTED:
@@ -58,8 +58,8 @@
     return {};
 }
 
-IWifiStaIface::StaIfaceCapabilityMask
-convertLegacyLoggerFeatureToHidlStaIfaceCapability(uint32_t feature) {
+IWifiStaIface::StaIfaceCapabilityMask convertLegacyLoggerFeatureToHidlStaIfaceCapability(
+        uint32_t feature) {
     using HidlStaIfaceCaps = IWifiStaIface::StaIfaceCapabilityMask;
     switch (feature) {
         case legacy_hal::WIFI_LOGGER_PACKET_FATE_SUPPORTED:
@@ -69,8 +69,7 @@
     return {};
 }
 
-V1_5::IWifiChip::ChipCapabilityMask convertLegacyFeatureToHidlChipCapability(
-    uint64_t feature) {
+V1_5::IWifiChip::ChipCapabilityMask convertLegacyFeatureToHidlChipCapability(uint64_t feature) {
     using HidlChipCaps = V1_5::IWifiChip::ChipCapabilityMask;
     switch (feature) {
         case WIFI_FEATURE_SET_TX_POWER_LIMIT:
@@ -92,8 +91,8 @@
     return {};
 }
 
-IWifiStaIface::StaIfaceCapabilityMask
-convertLegacyFeatureToHidlStaIfaceCapability(uint64_t feature) {
+IWifiStaIface::StaIfaceCapabilityMask convertLegacyFeatureToHidlStaIfaceCapability(
+        uint64_t feature) {
     using HidlStaIfaceCaps = IWifiStaIface::StaIfaceCapabilityMask;
     switch (feature) {
         case WIFI_FEATURE_GSCAN:
@@ -127,9 +126,9 @@
     return {};
 }
 
-bool convertLegacyFeaturesToHidlChipCapabilities(
-    uint64_t legacy_feature_set, uint32_t legacy_logger_feature_set,
-    uint32_t* hidl_caps) {
+bool convertLegacyFeaturesToHidlChipCapabilities(uint64_t legacy_feature_set,
+                                                 uint32_t legacy_logger_feature_set,
+                                                 uint32_t* hidl_caps) {
     if (!hidl_caps) {
         return false;
     }
@@ -141,8 +140,7 @@
                                legacy_hal::WIFI_LOGGER_POWER_EVENT_SUPPORTED,
                                legacy_hal::WIFI_LOGGER_WAKE_LOCK_SUPPORTED}) {
         if (feature & legacy_logger_feature_set) {
-            *hidl_caps |=
-                convertLegacyLoggerFeatureToHidlChipCapability(feature);
+            *hidl_caps |= convertLegacyLoggerFeatureToHidlChipCapability(feature);
         }
     }
     std::vector<uint64_t> features = {WIFI_FEATURE_SET_TX_POWER_LIMIT,
@@ -166,8 +164,7 @@
     return true;
 }
 
-WifiDebugRingBufferFlags convertLegacyDebugRingBufferFlagsToHidl(
-    uint32_t flag) {
+WifiDebugRingBufferFlags convertLegacyDebugRingBufferFlagsToHidl(uint32_t flag) {
     switch (flag) {
         case WIFI_RING_BUFFER_FLAG_HAS_BINARY_ENTRIES:
             return WifiDebugRingBufferFlags::HAS_BINARY_ENTRIES;
@@ -179,22 +176,20 @@
 }
 
 bool convertLegacyDebugRingBufferStatusToHidl(
-    const legacy_hal::wifi_ring_buffer_status& legacy_status,
-    WifiDebugRingBufferStatus* hidl_status) {
+        const legacy_hal::wifi_ring_buffer_status& legacy_status,
+        WifiDebugRingBufferStatus* hidl_status) {
     if (!hidl_status) {
         return false;
     }
     *hidl_status = {};
-    hidl_status->ringName =
-        safeConvertChar(reinterpret_cast<const char*>(legacy_status.name),
-                        sizeof(legacy_status.name));
+    hidl_status->ringName = safeConvertChar(reinterpret_cast<const char*>(legacy_status.name),
+                                            sizeof(legacy_status.name));
     hidl_status->flags = 0;
-    for (const auto flag : {WIFI_RING_BUFFER_FLAG_HAS_BINARY_ENTRIES,
-                            WIFI_RING_BUFFER_FLAG_HAS_ASCII_ENTRIES}) {
+    for (const auto flag :
+         {WIFI_RING_BUFFER_FLAG_HAS_BINARY_ENTRIES, WIFI_RING_BUFFER_FLAG_HAS_ASCII_ENTRIES}) {
         if (flag & legacy_status.flags) {
-            hidl_status->flags |= static_cast<
-                std::underlying_type<WifiDebugRingBufferFlags>::type>(
-                convertLegacyDebugRingBufferFlagsToHidl(flag));
+            hidl_status->flags |= static_cast<std::underlying_type<WifiDebugRingBufferFlags>::type>(
+                    convertLegacyDebugRingBufferFlagsToHidl(flag));
         }
     }
     hidl_status->ringId = legacy_status.ring_id;
@@ -202,28 +197,25 @@
     // Calculate free size of the ring the buffer. We don't need to send the
     // exact read/write pointers that were there in the legacy HAL interface.
     if (legacy_status.written_bytes >= legacy_status.read_bytes) {
-        hidl_status->freeSizeInBytes =
-            legacy_status.ring_buffer_byte_size -
-            (legacy_status.written_bytes - legacy_status.read_bytes);
+        hidl_status->freeSizeInBytes = legacy_status.ring_buffer_byte_size -
+                                       (legacy_status.written_bytes - legacy_status.read_bytes);
     } else {
-        hidl_status->freeSizeInBytes =
-            legacy_status.read_bytes - legacy_status.written_bytes;
+        hidl_status->freeSizeInBytes = legacy_status.read_bytes - legacy_status.written_bytes;
     }
     hidl_status->verboseLevel = legacy_status.verbose_level;
     return true;
 }
 
 bool convertLegacyVectorOfDebugRingBufferStatusToHidl(
-    const std::vector<legacy_hal::wifi_ring_buffer_status>& legacy_status_vec,
-    std::vector<WifiDebugRingBufferStatus>* hidl_status_vec) {
+        const std::vector<legacy_hal::wifi_ring_buffer_status>& legacy_status_vec,
+        std::vector<WifiDebugRingBufferStatus>* hidl_status_vec) {
     if (!hidl_status_vec) {
         return false;
     }
     *hidl_status_vec = {};
     for (const auto& legacy_status : legacy_status_vec) {
         WifiDebugRingBufferStatus hidl_status;
-        if (!convertLegacyDebugRingBufferStatusToHidl(legacy_status,
-                                                      &hidl_status)) {
+        if (!convertLegacyDebugRingBufferStatusToHidl(legacy_status, &hidl_status)) {
             return false;
         }
         hidl_status_vec->push_back(hidl_status);
@@ -231,52 +223,44 @@
     return true;
 }
 
-bool convertLegacyWakeReasonStatsToHidl(
-    const legacy_hal::WakeReasonStats& legacy_stats,
-    WifiDebugHostWakeReasonStats* hidl_stats) {
+bool convertLegacyWakeReasonStatsToHidl(const legacy_hal::WakeReasonStats& legacy_stats,
+                                        WifiDebugHostWakeReasonStats* hidl_stats) {
     if (!hidl_stats) {
         return false;
     }
     *hidl_stats = {};
-    hidl_stats->totalCmdEventWakeCnt =
-        legacy_stats.wake_reason_cnt.total_cmd_event_wake;
+    hidl_stats->totalCmdEventWakeCnt = legacy_stats.wake_reason_cnt.total_cmd_event_wake;
     hidl_stats->cmdEventWakeCntPerType = legacy_stats.cmd_event_wake_cnt;
-    hidl_stats->totalDriverFwLocalWakeCnt =
-        legacy_stats.wake_reason_cnt.total_driver_fw_local_wake;
-    hidl_stats->driverFwLocalWakeCntPerType =
-        legacy_stats.driver_fw_local_wake_cnt;
-    hidl_stats->totalRxPacketWakeCnt =
-        legacy_stats.wake_reason_cnt.total_rx_data_wake;
+    hidl_stats->totalDriverFwLocalWakeCnt = legacy_stats.wake_reason_cnt.total_driver_fw_local_wake;
+    hidl_stats->driverFwLocalWakeCntPerType = legacy_stats.driver_fw_local_wake_cnt;
+    hidl_stats->totalRxPacketWakeCnt = legacy_stats.wake_reason_cnt.total_rx_data_wake;
     hidl_stats->rxPktWakeDetails.rxUnicastCnt =
-        legacy_stats.wake_reason_cnt.rx_wake_details.rx_unicast_cnt;
+            legacy_stats.wake_reason_cnt.rx_wake_details.rx_unicast_cnt;
     hidl_stats->rxPktWakeDetails.rxMulticastCnt =
-        legacy_stats.wake_reason_cnt.rx_wake_details.rx_multicast_cnt;
+            legacy_stats.wake_reason_cnt.rx_wake_details.rx_multicast_cnt;
     hidl_stats->rxPktWakeDetails.rxBroadcastCnt =
-        legacy_stats.wake_reason_cnt.rx_wake_details.rx_broadcast_cnt;
+            legacy_stats.wake_reason_cnt.rx_wake_details.rx_broadcast_cnt;
     hidl_stats->rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt =
-        legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info
-            .ipv4_rx_multicast_addr_cnt;
+            legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info.ipv4_rx_multicast_addr_cnt;
     hidl_stats->rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt =
-        legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info
-            .ipv6_rx_multicast_addr_cnt;
+            legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info.ipv6_rx_multicast_addr_cnt;
     hidl_stats->rxMulticastPkWakeDetails.otherRxMulticastAddrCnt =
-        legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info
-            .other_rx_multicast_addr_cnt;
+            legacy_stats.wake_reason_cnt.rx_multicast_wake_pkt_info.other_rx_multicast_addr_cnt;
     hidl_stats->rxIcmpPkWakeDetails.icmpPkt =
-        legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp_pkt;
+            legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp_pkt;
     hidl_stats->rxIcmpPkWakeDetails.icmp6Pkt =
-        legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_pkt;
+            legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_pkt;
     hidl_stats->rxIcmpPkWakeDetails.icmp6Ra =
-        legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_ra;
+            legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_ra;
     hidl_stats->rxIcmpPkWakeDetails.icmp6Na =
-        legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_na;
+            legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_na;
     hidl_stats->rxIcmpPkWakeDetails.icmp6Ns =
-        legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_ns;
+            legacy_stats.wake_reason_cnt.rx_wake_pkt_classification_info.icmp6_ns;
     return true;
 }
 
 legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy(
-    V1_1::IWifiChip::TxPowerScenario hidl_scenario) {
+        V1_1::IWifiChip::TxPowerScenario hidl_scenario) {
     switch (hidl_scenario) {
         // This is the only supported scenario for V1_1
         case V1_1::IWifiChip::TxPowerScenario::VOICE_CALL:
@@ -286,7 +270,7 @@
 }
 
 legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy_1_2(
-    V1_2::IWifiChip::TxPowerScenario hidl_scenario) {
+        V1_2::IWifiChip::TxPowerScenario hidl_scenario) {
     switch (hidl_scenario) {
         // This is the only supported scenario for V1_1
         case V1_2::IWifiChip::TxPowerScenario::VOICE_CALL:
@@ -305,7 +289,7 @@
 }
 
 legacy_hal::wifi_latency_mode convertHidlLatencyModeToLegacy(
-    V1_3::IWifiChip::LatencyMode hidl_latency_mode) {
+        V1_3::IWifiChip::LatencyMode hidl_latency_mode) {
     switch (hidl_latency_mode) {
         case V1_3::IWifiChip::LatencyMode::NORMAL:
             return legacy_hal::WIFI_LATENCY_MODE_NORMAL;
@@ -316,8 +300,8 @@
 }
 
 bool convertLegacyWifiMacInfoToHidl(
-    const legacy_hal::WifiMacInfo& legacy_mac_info,
-    V1_4::IWifiChipEventCallback::RadioModeInfo* hidl_radio_mode_info) {
+        const legacy_hal::WifiMacInfo& legacy_mac_info,
+        V1_4::IWifiChipEventCallback::RadioModeInfo* hidl_radio_mode_info) {
     if (!hidl_radio_mode_info) {
         return false;
     }
@@ -366,24 +350,20 @@
             return legacy_hal::WLAN_MAC_5_0_BAND;
         case V1_5::WifiBand::BAND_24GHZ_5GHZ:
         case V1_5::WifiBand::BAND_24GHZ_5GHZ_WITH_DFS:
-            return (legacy_hal::WLAN_MAC_2_4_BAND |
-                    legacy_hal::WLAN_MAC_5_0_BAND);
+            return (legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND);
         case V1_5::WifiBand::BAND_6GHZ:
             return legacy_hal::WLAN_MAC_6_0_BAND;
         case V1_5::WifiBand::BAND_5GHZ_6GHZ:
-            return (legacy_hal::WLAN_MAC_5_0_BAND |
-                    legacy_hal::WLAN_MAC_6_0_BAND);
+            return (legacy_hal::WLAN_MAC_5_0_BAND | legacy_hal::WLAN_MAC_6_0_BAND);
         case V1_5::WifiBand::BAND_24GHZ_5GHZ_6GHZ:
         case V1_5::WifiBand::BAND_24GHZ_5GHZ_WITH_DFS_6GHZ:
-            return (legacy_hal::WLAN_MAC_2_4_BAND |
-                    legacy_hal::WLAN_MAC_5_0_BAND |
+            return (legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND |
                     legacy_hal::WLAN_MAC_6_0_BAND);
         case V1_5::WifiBand::BAND_60GHZ:
             return legacy_hal::WLAN_MAC_60_0_BAND;
         default:
-            return (
-                legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND |
-                legacy_hal::WLAN_MAC_6_0_BAND | legacy_hal::WLAN_MAC_60_0_BAND);
+            return (legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND |
+                    legacy_hal::WLAN_MAC_6_0_BAND | legacy_hal::WLAN_MAC_60_0_BAND);
     }
 }
 
@@ -447,45 +427,41 @@
 
 uint32_t convertHidlUsableChannelFilterToLegacy(uint32_t hidl_filter_mask) {
     uint32_t legacy_filter_mask = 0;
-    if (hidl_filter_mask &
-        IWifiChip::UsableChannelFilter::CELLULAR_COEXISTENCE) {
-        legacy_filter_mask |=
-            legacy_hal::WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE;
+    if (hidl_filter_mask & V1_5::IWifiChip::UsableChannelFilter::CELLULAR_COEXISTENCE) {
+        legacy_filter_mask |= legacy_hal::WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE;
     }
-    if (hidl_filter_mask & IWifiChip::UsableChannelFilter::CONCURRENCY) {
-        legacy_filter_mask |=
-            legacy_hal::WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY;
+    if (hidl_filter_mask & V1_5::IWifiChip::UsableChannelFilter::CONCURRENCY) {
+        legacy_filter_mask |= legacy_hal::WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY;
     }
     return legacy_filter_mask;
 }
 
 bool convertLegacyWifiUsableChannelToHidl(
-    const legacy_hal::wifi_usable_channel& legacy_usable_channel,
-    V1_5::WifiUsableChannel* hidl_usable_channel) {
+        const legacy_hal::wifi_usable_channel& legacy_usable_channel,
+        V1_5::WifiUsableChannel* hidl_usable_channel) {
     if (!hidl_usable_channel) {
         return false;
     }
     *hidl_usable_channel = {};
     hidl_usable_channel->channel = legacy_usable_channel.freq;
     hidl_usable_channel->channelBandwidth =
-        convertLegacyWifiChannelWidthToHidl(legacy_usable_channel.width);
-    hidl_usable_channel->ifaceModeMask = convertLegacyWifiInterfaceModeToHidl(
-        legacy_usable_channel.iface_mode_mask);
+            convertLegacyWifiChannelWidthToHidl(legacy_usable_channel.width);
+    hidl_usable_channel->ifaceModeMask =
+            convertLegacyWifiInterfaceModeToHidl(legacy_usable_channel.iface_mode_mask);
 
     return true;
 }
 
 bool convertLegacyWifiUsableChannelsToHidl(
-    const std::vector<legacy_hal::wifi_usable_channel>& legacy_usable_channels,
-    std::vector<V1_5::WifiUsableChannel>* hidl_usable_channels) {
+        const std::vector<legacy_hal::wifi_usable_channel>& legacy_usable_channels,
+        std::vector<V1_5::WifiUsableChannel>* hidl_usable_channels) {
     if (!hidl_usable_channels) {
         return false;
     }
     *hidl_usable_channels = {};
     for (const auto& legacy_usable_channel : legacy_usable_channels) {
         V1_5::WifiUsableChannel hidl_usable_channel;
-        if (!convertLegacyWifiUsableChannelToHidl(legacy_usable_channel,
-                                                  &hidl_usable_channel)) {
+        if (!convertLegacyWifiUsableChannelToHidl(legacy_usable_channel, &hidl_usable_channel)) {
             return false;
         }
         hidl_usable_channels->push_back(hidl_usable_channel);
@@ -494,9 +470,8 @@
 }
 
 bool convertLegacyWifiMacInfosToHidl(
-    const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos,
-    std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo>*
-        hidl_radio_mode_infos) {
+        const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos,
+        std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo>* hidl_radio_mode_infos) {
     if (!hidl_radio_mode_infos) {
         return false;
     }
@@ -504,8 +479,7 @@
 
     for (const auto& legacy_mac_info : legacy_mac_infos) {
         V1_4::IWifiChipEventCallback::RadioModeInfo hidl_radio_mode_info;
-        if (!convertLegacyWifiMacInfoToHidl(legacy_mac_info,
-                                            &hidl_radio_mode_info)) {
+        if (!convertLegacyWifiMacInfoToHidl(legacy_mac_info, &hidl_radio_mode_info)) {
             return false;
         }
         hidl_radio_mode_infos->push_back(hidl_radio_mode_info);
@@ -513,9 +487,9 @@
     return true;
 }
 
-bool convertLegacyFeaturesToHidlStaCapabilities(
-    uint64_t legacy_feature_set, uint32_t legacy_logger_feature_set,
-    uint32_t* hidl_caps) {
+bool convertLegacyFeaturesToHidlStaCapabilities(uint64_t legacy_feature_set,
+                                                uint32_t legacy_logger_feature_set,
+                                                uint32_t* hidl_caps) {
     if (!hidl_caps) {
         return false;
     }
@@ -523,17 +497,14 @@
     using HidlStaIfaceCaps = IWifiStaIface::StaIfaceCapabilityMask;
     for (const auto feature : {legacy_hal::WIFI_LOGGER_PACKET_FATE_SUPPORTED}) {
         if (feature & legacy_logger_feature_set) {
-            *hidl_caps |=
-                convertLegacyLoggerFeatureToHidlStaIfaceCapability(feature);
+            *hidl_caps |= convertLegacyLoggerFeatureToHidlStaIfaceCapability(feature);
         }
     }
     for (const auto feature :
-         {WIFI_FEATURE_GSCAN, WIFI_FEATURE_LINK_LAYER_STATS,
-          WIFI_FEATURE_RSSI_MONITOR, WIFI_FEATURE_CONTROL_ROAMING,
-          WIFI_FEATURE_IE_WHITELIST, WIFI_FEATURE_SCAN_RAND,
-          WIFI_FEATURE_INFRA_5G, WIFI_FEATURE_HOTSPOT, WIFI_FEATURE_PNO,
-          WIFI_FEATURE_TDLS, WIFI_FEATURE_TDLS_OFFCHANNEL,
-          WIFI_FEATURE_CONFIG_NDO, WIFI_FEATURE_MKEEP_ALIVE}) {
+         {WIFI_FEATURE_GSCAN, WIFI_FEATURE_LINK_LAYER_STATS, WIFI_FEATURE_RSSI_MONITOR,
+          WIFI_FEATURE_CONTROL_ROAMING, WIFI_FEATURE_IE_WHITELIST, WIFI_FEATURE_SCAN_RAND,
+          WIFI_FEATURE_INFRA_5G, WIFI_FEATURE_HOTSPOT, WIFI_FEATURE_PNO, WIFI_FEATURE_TDLS,
+          WIFI_FEATURE_TDLS_OFFCHANNEL, WIFI_FEATURE_CONFIG_NDO, WIFI_FEATURE_MKEEP_ALIVE}) {
         if (feature & legacy_feature_set) {
             *hidl_caps |= convertLegacyFeatureToHidlStaIfaceCapability(feature);
         }
@@ -544,9 +515,8 @@
     return true;
 }
 
-bool convertLegacyApfCapabilitiesToHidl(
-    const legacy_hal::PacketFilterCapabilities& legacy_caps,
-    StaApfPacketFilterCapabilities* hidl_caps) {
+bool convertLegacyApfCapabilitiesToHidl(const legacy_hal::PacketFilterCapabilities& legacy_caps,
+                                        StaApfPacketFilterCapabilities* hidl_caps) {
     if (!hidl_caps) {
         return false;
     }
@@ -557,7 +527,7 @@
 }
 
 uint8_t convertHidlGscanReportEventFlagToLegacy(
-    StaBackgroundScanBucketEventReportSchemeMask hidl_flag) {
+        StaBackgroundScanBucketEventReportSchemeMask hidl_flag) {
     using HidlFlag = StaBackgroundScanBucketEventReportSchemeMask;
     switch (hidl_flag) {
         case HidlFlag::EACH_SCAN:
@@ -581,9 +551,8 @@
     return {};
 }
 
-bool convertLegacyGscanCapabilitiesToHidl(
-    const legacy_hal::wifi_gscan_capabilities& legacy_caps,
-    StaBackgroundScanCapabilities* hidl_caps) {
+bool convertLegacyGscanCapabilitiesToHidl(const legacy_hal::wifi_gscan_capabilities& legacy_caps,
+                                          StaBackgroundScanCapabilities* hidl_caps) {
     if (!hidl_caps) {
         return false;
     }
@@ -615,73 +584,61 @@
     CHECK(false);
 }
 
-bool convertHidlGscanParamsToLegacy(
-    const StaBackgroundScanParameters& hidl_scan_params,
-    legacy_hal::wifi_scan_cmd_params* legacy_scan_params) {
+bool convertHidlGscanParamsToLegacy(const StaBackgroundScanParameters& hidl_scan_params,
+                                    legacy_hal::wifi_scan_cmd_params* legacy_scan_params) {
     if (!legacy_scan_params) {
         return false;
     }
     *legacy_scan_params = {};
     legacy_scan_params->base_period = hidl_scan_params.basePeriodInMs;
     legacy_scan_params->max_ap_per_scan = hidl_scan_params.maxApPerScan;
-    legacy_scan_params->report_threshold_percent =
-        hidl_scan_params.reportThresholdPercent;
-    legacy_scan_params->report_threshold_num_scans =
-        hidl_scan_params.reportThresholdNumScans;
+    legacy_scan_params->report_threshold_percent = hidl_scan_params.reportThresholdPercent;
+    legacy_scan_params->report_threshold_num_scans = hidl_scan_params.reportThresholdNumScans;
     if (hidl_scan_params.buckets.size() > MAX_BUCKETS) {
         return false;
     }
     legacy_scan_params->num_buckets = hidl_scan_params.buckets.size();
-    for (uint32_t bucket_idx = 0; bucket_idx < hidl_scan_params.buckets.size();
-         bucket_idx++) {
+    for (uint32_t bucket_idx = 0; bucket_idx < hidl_scan_params.buckets.size(); bucket_idx++) {
         const StaBackgroundScanBucketParameters& hidl_bucket_spec =
-            hidl_scan_params.buckets[bucket_idx];
+                hidl_scan_params.buckets[bucket_idx];
         legacy_hal::wifi_scan_bucket_spec& legacy_bucket_spec =
-            legacy_scan_params->buckets[bucket_idx];
+                legacy_scan_params->buckets[bucket_idx];
         if (hidl_bucket_spec.bucketIdx >= MAX_BUCKETS) {
             return false;
         }
         legacy_bucket_spec.bucket = hidl_bucket_spec.bucketIdx;
-        legacy_bucket_spec.band =
-            convertHidlWifiBandToLegacy(hidl_bucket_spec.band);
+        legacy_bucket_spec.band = convertHidlWifiBandToLegacy(hidl_bucket_spec.band);
         legacy_bucket_spec.period = hidl_bucket_spec.periodInMs;
-        legacy_bucket_spec.max_period =
-            hidl_bucket_spec.exponentialMaxPeriodInMs;
+        legacy_bucket_spec.max_period = hidl_bucket_spec.exponentialMaxPeriodInMs;
         legacy_bucket_spec.base = hidl_bucket_spec.exponentialBase;
         legacy_bucket_spec.step_count = hidl_bucket_spec.exponentialStepCount;
         legacy_bucket_spec.report_events = 0;
         using HidlFlag = StaBackgroundScanBucketEventReportSchemeMask;
-        for (const auto flag : {HidlFlag::EACH_SCAN, HidlFlag::FULL_RESULTS,
-                                HidlFlag::NO_BATCH}) {
+        for (const auto flag : {HidlFlag::EACH_SCAN, HidlFlag::FULL_RESULTS, HidlFlag::NO_BATCH}) {
             if (hidl_bucket_spec.eventReportScheme &
                 static_cast<std::underlying_type<HidlFlag>::type>(flag)) {
-                legacy_bucket_spec.report_events |=
-                    convertHidlGscanReportEventFlagToLegacy(flag);
+                legacy_bucket_spec.report_events |= convertHidlGscanReportEventFlagToLegacy(flag);
             }
         }
         if (hidl_bucket_spec.frequencies.size() > MAX_CHANNELS) {
             return false;
         }
         legacy_bucket_spec.num_channels = hidl_bucket_spec.frequencies.size();
-        for (uint32_t freq_idx = 0;
-             freq_idx < hidl_bucket_spec.frequencies.size(); freq_idx++) {
-            legacy_bucket_spec.channels[freq_idx].channel =
-                hidl_bucket_spec.frequencies[freq_idx];
+        for (uint32_t freq_idx = 0; freq_idx < hidl_bucket_spec.frequencies.size(); freq_idx++) {
+            legacy_bucket_spec.channels[freq_idx].channel = hidl_bucket_spec.frequencies[freq_idx];
         }
     }
     return true;
 }
 
-bool convertLegacyIeToHidl(
-    const legacy_hal::wifi_information_element& legacy_ie,
-    WifiInformationElement* hidl_ie) {
+bool convertLegacyIeToHidl(const legacy_hal::wifi_information_element& legacy_ie,
+                           WifiInformationElement* hidl_ie) {
     if (!hidl_ie) {
         return false;
     }
     *hidl_ie = {};
     hidl_ie->id = legacy_ie.id;
-    hidl_ie->data =
-        std::vector<uint8_t>(legacy_ie.data, legacy_ie.data + legacy_ie.len);
+    hidl_ie->data = std::vector<uint8_t>(legacy_ie.data, legacy_ie.data + legacy_ie.len);
     return true;
 }
 
@@ -702,14 +659,12 @@
         uint32_t curr_ie_len = kIeHeaderLen + legacy_ie.len;
         if (next_ie + curr_ie_len > ies_end) {
             LOG(ERROR) << "Error parsing IE blob. Next IE: " << (void*)next_ie
-                       << ", Curr IE len: " << curr_ie_len
-                       << ", IEs End: " << (void*)ies_end;
+                       << ", Curr IE len: " << curr_ie_len << ", IEs End: " << (void*)ies_end;
             break;
         }
         WifiInformationElement hidl_ie;
         if (!convertLegacyIeToHidl(legacy_ie, &hidl_ie)) {
-            LOG(ERROR) << "Error converting IE. Id: " << legacy_ie.id
-                       << ", len: " << legacy_ie.len;
+            LOG(ERROR) << "Error converting IE. Id: " << legacy_ie.id << ", len: " << legacy_ie.len;
             break;
         }
         hidl_ies->push_back(std::move(hidl_ie));
@@ -717,24 +672,23 @@
     }
     // Check if the blob has been fully consumed.
     if (next_ie != ies_end) {
-        LOG(ERROR) << "Failed to fully parse IE blob. Next IE: "
-                   << (void*)next_ie << ", IEs End: " << (void*)ies_end;
+        LOG(ERROR) << "Failed to fully parse IE blob. Next IE: " << (void*)next_ie
+                   << ", IEs End: " << (void*)ies_end;
     }
     return true;
 }
 
-bool convertLegacyGscanResultToHidl(
-    const legacy_hal::wifi_scan_result& legacy_scan_result, bool has_ie_data,
-    StaScanResult* hidl_scan_result) {
+bool convertLegacyGscanResultToHidl(const legacy_hal::wifi_scan_result& legacy_scan_result,
+                                    bool has_ie_data, StaScanResult* hidl_scan_result) {
     if (!hidl_scan_result) {
         return false;
     }
     *hidl_scan_result = {};
     hidl_scan_result->timeStampInUs = legacy_scan_result.ts;
     hidl_scan_result->ssid = std::vector<uint8_t>(
-        legacy_scan_result.ssid,
-        legacy_scan_result.ssid + strnlen(legacy_scan_result.ssid,
-                                          sizeof(legacy_scan_result.ssid) - 1));
+            legacy_scan_result.ssid,
+            legacy_scan_result.ssid +
+                    strnlen(legacy_scan_result.ssid, sizeof(legacy_scan_result.ssid) - 1));
     memcpy(hidl_scan_result->bssid.data(), legacy_scan_result.bssid,
            hidl_scan_result->bssid.size());
     hidl_scan_result->frequency = legacy_scan_result.channel;
@@ -743,9 +697,8 @@
     hidl_scan_result->capability = legacy_scan_result.capability;
     if (has_ie_data) {
         std::vector<WifiInformationElement> ies;
-        if (!convertLegacyIeBlobToHidl(
-                reinterpret_cast<const uint8_t*>(legacy_scan_result.ie_data),
-                legacy_scan_result.ie_length, &ies)) {
+        if (!convertLegacyIeBlobToHidl(reinterpret_cast<const uint8_t*>(legacy_scan_result.ie_data),
+                                       legacy_scan_result.ie_length, &ies)) {
             return false;
         }
         hidl_scan_result->informationElements = std::move(ies);
@@ -754,8 +707,8 @@
 }
 
 bool convertLegacyCachedGscanResultsToHidl(
-    const legacy_hal::wifi_cached_scan_results& legacy_cached_scan_result,
-    StaScanData* hidl_scan_data) {
+        const legacy_hal::wifi_cached_scan_results& legacy_cached_scan_result,
+        StaScanData* hidl_scan_data) {
     if (!hidl_scan_data) {
         return false;
     }
@@ -763,8 +716,7 @@
     hidl_scan_data->flags = 0;
     for (const auto flag : {legacy_hal::WIFI_SCAN_FLAG_INTERRUPTED}) {
         if (legacy_cached_scan_result.flags & flag) {
-            hidl_scan_data->flags |=
-                static_cast<std::underlying_type<StaScanDataFlagMask>::type>(
+            hidl_scan_data->flags |= static_cast<std::underlying_type<StaScanDataFlagMask>::type>(
                     convertLegacyGscanDataFlagToHidl(flag));
         }
     }
@@ -773,12 +725,10 @@
     CHECK(legacy_cached_scan_result.num_results >= 0 &&
           legacy_cached_scan_result.num_results <= MAX_AP_CACHE_PER_SCAN);
     std::vector<StaScanResult> hidl_scan_results;
-    for (int32_t result_idx = 0;
-         result_idx < legacy_cached_scan_result.num_results; result_idx++) {
+    for (int32_t result_idx = 0; result_idx < legacy_cached_scan_result.num_results; result_idx++) {
         StaScanResult hidl_scan_result;
-        if (!convertLegacyGscanResultToHidl(
-                legacy_cached_scan_result.results[result_idx], false,
-                &hidl_scan_result)) {
+        if (!convertLegacyGscanResultToHidl(legacy_cached_scan_result.results[result_idx], false,
+                                            &hidl_scan_result)) {
             return false;
         }
         hidl_scan_results.push_back(hidl_scan_result);
@@ -788,17 +738,15 @@
 }
 
 bool convertLegacyVectorOfCachedGscanResultsToHidl(
-    const std::vector<legacy_hal::wifi_cached_scan_results>&
-        legacy_cached_scan_results,
-    std::vector<StaScanData>* hidl_scan_datas) {
+        const std::vector<legacy_hal::wifi_cached_scan_results>& legacy_cached_scan_results,
+        std::vector<StaScanData>* hidl_scan_datas) {
     if (!hidl_scan_datas) {
         return false;
     }
     *hidl_scan_datas = {};
     for (const auto& legacy_cached_scan_result : legacy_cached_scan_results) {
         StaScanData hidl_scan_data;
-        if (!convertLegacyCachedGscanResultsToHidl(legacy_cached_scan_result,
-                                                   &hidl_scan_data)) {
+        if (!convertLegacyCachedGscanResultsToHidl(legacy_cached_scan_result, &hidl_scan_data)) {
             return false;
         }
         hidl_scan_datas->push_back(hidl_scan_data);
@@ -806,8 +754,7 @@
     return true;
 }
 
-WifiDebugTxPacketFate convertLegacyDebugTxPacketFateToHidl(
-    legacy_hal::wifi_tx_packet_fate fate) {
+WifiDebugTxPacketFate convertLegacyDebugTxPacketFateToHidl(legacy_hal::wifi_tx_packet_fate fate) {
     switch (fate) {
         case legacy_hal::TX_PKT_FATE_ACKED:
             return WifiDebugTxPacketFate::ACKED;
@@ -833,8 +780,7 @@
     CHECK(false) << "Unknown legacy fate type: " << fate;
 }
 
-WifiDebugRxPacketFate convertLegacyDebugRxPacketFateToHidl(
-    legacy_hal::wifi_rx_packet_fate fate) {
+WifiDebugRxPacketFate convertLegacyDebugRxPacketFateToHidl(legacy_hal::wifi_rx_packet_fate fate) {
     switch (fate) {
         case legacy_hal::RX_PKT_FATE_SUCCESS:
             return WifiDebugRxPacketFate::SUCCESS;
@@ -863,7 +809,7 @@
 }
 
 WifiDebugPacketFateFrameType convertLegacyDebugPacketFateFrameTypeToHidl(
-    legacy_hal::frame_type type) {
+        legacy_hal::frame_type type) {
     switch (type) {
         case legacy_hal::FRAME_TYPE_UNKNOWN:
             return WifiDebugPacketFateFrameType::UNKNOWN;
@@ -875,40 +821,36 @@
     CHECK(false) << "Unknown legacy frame type: " << type;
 }
 
-bool convertLegacyDebugPacketFateFrameToHidl(
-    const legacy_hal::frame_info& legacy_frame,
-    WifiDebugPacketFateFrameInfo* hidl_frame) {
+bool convertLegacyDebugPacketFateFrameToHidl(const legacy_hal::frame_info& legacy_frame,
+                                             WifiDebugPacketFateFrameInfo* hidl_frame) {
     if (!hidl_frame) {
         return false;
     }
     *hidl_frame = {};
-    hidl_frame->frameType =
-        convertLegacyDebugPacketFateFrameTypeToHidl(legacy_frame.payload_type);
+    hidl_frame->frameType = convertLegacyDebugPacketFateFrameTypeToHidl(legacy_frame.payload_type);
     hidl_frame->frameLen = legacy_frame.frame_len;
     hidl_frame->driverTimestampUsec = legacy_frame.driver_timestamp_usec;
     hidl_frame->firmwareTimestampUsec = legacy_frame.firmware_timestamp_usec;
-    const uint8_t* frame_begin = reinterpret_cast<const uint8_t*>(
-        legacy_frame.frame_content.ethernet_ii_bytes);
+    const uint8_t* frame_begin =
+            reinterpret_cast<const uint8_t*>(legacy_frame.frame_content.ethernet_ii_bytes);
     hidl_frame->frameContent =
-        std::vector<uint8_t>(frame_begin, frame_begin + legacy_frame.frame_len);
+            std::vector<uint8_t>(frame_begin, frame_begin + legacy_frame.frame_len);
     return true;
 }
 
-bool convertLegacyDebugTxPacketFateToHidl(
-    const legacy_hal::wifi_tx_report& legacy_fate,
-    WifiDebugTxPacketFateReport* hidl_fate) {
+bool convertLegacyDebugTxPacketFateToHidl(const legacy_hal::wifi_tx_report& legacy_fate,
+                                          WifiDebugTxPacketFateReport* hidl_fate) {
     if (!hidl_fate) {
         return false;
     }
     *hidl_fate = {};
     hidl_fate->fate = convertLegacyDebugTxPacketFateToHidl(legacy_fate.fate);
-    return convertLegacyDebugPacketFateFrameToHidl(legacy_fate.frame_inf,
-                                                   &hidl_fate->frameInfo);
+    return convertLegacyDebugPacketFateFrameToHidl(legacy_fate.frame_inf, &hidl_fate->frameInfo);
 }
 
 bool convertLegacyVectorOfDebugTxPacketFateToHidl(
-    const std::vector<legacy_hal::wifi_tx_report>& legacy_fates,
-    std::vector<WifiDebugTxPacketFateReport>* hidl_fates) {
+        const std::vector<legacy_hal::wifi_tx_report>& legacy_fates,
+        std::vector<WifiDebugTxPacketFateReport>* hidl_fates) {
     if (!hidl_fates) {
         return false;
     }
@@ -923,21 +865,19 @@
     return true;
 }
 
-bool convertLegacyDebugRxPacketFateToHidl(
-    const legacy_hal::wifi_rx_report& legacy_fate,
-    WifiDebugRxPacketFateReport* hidl_fate) {
+bool convertLegacyDebugRxPacketFateToHidl(const legacy_hal::wifi_rx_report& legacy_fate,
+                                          WifiDebugRxPacketFateReport* hidl_fate) {
     if (!hidl_fate) {
         return false;
     }
     *hidl_fate = {};
     hidl_fate->fate = convertLegacyDebugRxPacketFateToHidl(legacy_fate.fate);
-    return convertLegacyDebugPacketFateFrameToHidl(legacy_fate.frame_inf,
-                                                   &hidl_fate->frameInfo);
+    return convertLegacyDebugPacketFateFrameToHidl(legacy_fate.frame_inf, &hidl_fate->frameInfo);
 }
 
 bool convertLegacyVectorOfDebugRxPacketFateToHidl(
-    const std::vector<legacy_hal::wifi_rx_report>& legacy_fates,
-    std::vector<WifiDebugRxPacketFateReport>* hidl_fates) {
+        const std::vector<legacy_hal::wifi_rx_report>& legacy_fates,
+        std::vector<WifiDebugRxPacketFateReport>* hidl_fates) {
     if (!hidl_fates) {
         return false;
     }
@@ -953,8 +893,8 @@
 }
 
 bool convertLegacyLinkLayerRadioStatsToHidl(
-    const legacy_hal::LinkLayerRadioStats& legacy_radio_stat,
-    V1_5::StaLinkLayerRadioStats* hidl_radio_stat) {
+        const legacy_hal::LinkLayerRadioStats& legacy_radio_stat,
+        V1_5::StaLinkLayerRadioStats* hidl_radio_stat) {
     if (!hidl_radio_stat) {
         return false;
     }
@@ -964,20 +904,13 @@
     hidl_radio_stat->V1_3.V1_0.onTimeInMs = legacy_radio_stat.stats.on_time;
     hidl_radio_stat->V1_3.V1_0.txTimeInMs = legacy_radio_stat.stats.tx_time;
     hidl_radio_stat->V1_3.V1_0.rxTimeInMs = legacy_radio_stat.stats.rx_time;
-    hidl_radio_stat->V1_3.V1_0.onTimeInMsForScan =
-        legacy_radio_stat.stats.on_time_scan;
-    hidl_radio_stat->V1_3.V1_0.txTimeInMsPerLevel =
-        legacy_radio_stat.tx_time_per_levels;
-    hidl_radio_stat->V1_3.onTimeInMsForNanScan =
-        legacy_radio_stat.stats.on_time_nbd;
-    hidl_radio_stat->V1_3.onTimeInMsForBgScan =
-        legacy_radio_stat.stats.on_time_gscan;
-    hidl_radio_stat->V1_3.onTimeInMsForRoamScan =
-        legacy_radio_stat.stats.on_time_roam_scan;
-    hidl_radio_stat->V1_3.onTimeInMsForPnoScan =
-        legacy_radio_stat.stats.on_time_pno_scan;
-    hidl_radio_stat->V1_3.onTimeInMsForHs20Scan =
-        legacy_radio_stat.stats.on_time_hs20;
+    hidl_radio_stat->V1_3.V1_0.onTimeInMsForScan = legacy_radio_stat.stats.on_time_scan;
+    hidl_radio_stat->V1_3.V1_0.txTimeInMsPerLevel = legacy_radio_stat.tx_time_per_levels;
+    hidl_radio_stat->V1_3.onTimeInMsForNanScan = legacy_radio_stat.stats.on_time_nbd;
+    hidl_radio_stat->V1_3.onTimeInMsForBgScan = legacy_radio_stat.stats.on_time_gscan;
+    hidl_radio_stat->V1_3.onTimeInMsForRoamScan = legacy_radio_stat.stats.on_time_roam_scan;
+    hidl_radio_stat->V1_3.onTimeInMsForPnoScan = legacy_radio_stat.stats.on_time_pno_scan;
+    hidl_radio_stat->V1_3.onTimeInMsForHs20Scan = legacy_radio_stat.stats.on_time_hs20;
 
     std::vector<V1_3::WifiChannelStats> hidl_channel_stats;
 
@@ -991,10 +924,8 @@
          */
         hidl_channel_stat.channel.width = WifiChannelWidthInMhz::WIDTH_20;
         hidl_channel_stat.channel.centerFreq = channel_stat.channel.center_freq;
-        hidl_channel_stat.channel.centerFreq0 =
-            channel_stat.channel.center_freq0;
-        hidl_channel_stat.channel.centerFreq1 =
-            channel_stat.channel.center_freq1;
+        hidl_channel_stat.channel.centerFreq0 = channel_stat.channel.center_freq0;
+        hidl_channel_stat.channel.centerFreq1 = channel_stat.channel.center_freq1;
         hidl_channel_stats.push_back(hidl_channel_stat);
     }
 
@@ -1003,9 +934,8 @@
     return true;
 }
 
-bool convertLegacyLinkLayerStatsToHidl(
-    const legacy_hal::LinkLayerStats& legacy_stats,
-    StaLinkLayerStats* hidl_stats) {
+bool convertLegacyLinkLayerStatsToHidl(const legacy_hal::LinkLayerStats& legacy_stats,
+                                       V1_5::StaLinkLayerStats* hidl_stats) {
     if (!hidl_stats) {
         return false;
     }
@@ -1014,77 +944,76 @@
     hidl_stats->iface.V1_0.beaconRx = legacy_stats.iface.beacon_rx;
     hidl_stats->iface.V1_0.avgRssiMgmt = legacy_stats.iface.rssi_mgmt;
     hidl_stats->iface.V1_0.wmeBePktStats.rxMpdu =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu;
     hidl_stats->iface.V1_0.wmeBePktStats.txMpdu =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu;
     hidl_stats->iface.V1_0.wmeBePktStats.lostMpdu =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost;
     hidl_stats->iface.V1_0.wmeBePktStats.retries =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries;
     hidl_stats->iface.wmeBeContentionTimeStats.contentionTimeMinInUsec =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min;
     hidl_stats->iface.wmeBeContentionTimeStats.contentionTimeMaxInUsec =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max;
     hidl_stats->iface.wmeBeContentionTimeStats.contentionTimeAvgInUsec =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg;
     hidl_stats->iface.wmeBeContentionTimeStats.contentionNumSamples =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples;
     hidl_stats->iface.V1_0.wmeBkPktStats.rxMpdu =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu;
     hidl_stats->iface.V1_0.wmeBkPktStats.txMpdu =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu;
     hidl_stats->iface.V1_0.wmeBkPktStats.lostMpdu =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost;
     hidl_stats->iface.V1_0.wmeBkPktStats.retries =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries;
     hidl_stats->iface.wmeBkContentionTimeStats.contentionTimeMinInUsec =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min;
     hidl_stats->iface.wmeBkContentionTimeStats.contentionTimeMaxInUsec =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max;
     hidl_stats->iface.wmeBkContentionTimeStats.contentionTimeAvgInUsec =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg;
     hidl_stats->iface.wmeBkContentionTimeStats.contentionNumSamples =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples;
     hidl_stats->iface.V1_0.wmeViPktStats.rxMpdu =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu;
     hidl_stats->iface.V1_0.wmeViPktStats.txMpdu =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu;
     hidl_stats->iface.V1_0.wmeViPktStats.lostMpdu =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost;
     hidl_stats->iface.V1_0.wmeViPktStats.retries =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries;
     hidl_stats->iface.wmeViContentionTimeStats.contentionTimeMinInUsec =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min;
     hidl_stats->iface.wmeViContentionTimeStats.contentionTimeMaxInUsec =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max;
     hidl_stats->iface.wmeViContentionTimeStats.contentionTimeAvgInUsec =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg;
     hidl_stats->iface.wmeViContentionTimeStats.contentionNumSamples =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples;
     hidl_stats->iface.V1_0.wmeVoPktStats.rxMpdu =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu;
     hidl_stats->iface.V1_0.wmeVoPktStats.txMpdu =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu;
     hidl_stats->iface.V1_0.wmeVoPktStats.lostMpdu =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost;
     hidl_stats->iface.V1_0.wmeVoPktStats.retries =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries;
     hidl_stats->iface.wmeVoContentionTimeStats.contentionTimeMinInUsec =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min;
     hidl_stats->iface.wmeVoContentionTimeStats.contentionTimeMaxInUsec =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max;
     hidl_stats->iface.wmeVoContentionTimeStats.contentionTimeAvgInUsec =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg;
     hidl_stats->iface.wmeVoContentionTimeStats.contentionNumSamples =
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples;
+            legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples;
     hidl_stats->iface.timeSliceDutyCycleInPercent =
-        legacy_stats.iface.info.time_slicing_duty_cycle_percent;
+            legacy_stats.iface.info.time_slicing_duty_cycle_percent;
     // peer info legacy_stats conversion.
-    std::vector<StaPeerInfo> hidl_peers_info_stats;
+    std::vector<V1_5::StaPeerInfo> hidl_peers_info_stats;
     for (const auto& legacy_peer_info_stats : legacy_stats.peers) {
-        StaPeerInfo hidl_peer_info_stats;
-        if (!convertLegacyPeerInfoStatsToHidl(legacy_peer_info_stats,
-                                              &hidl_peer_info_stats)) {
+        V1_5::StaPeerInfo hidl_peer_info_stats;
+        if (!convertLegacyPeerInfoStatsToHidl(legacy_peer_info_stats, &hidl_peer_info_stats)) {
             return false;
         }
         hidl_peers_info_stats.push_back(hidl_peer_info_stats);
@@ -1094,8 +1023,7 @@
     std::vector<V1_5::StaLinkLayerRadioStats> hidl_radios_stats;
     for (const auto& legacy_radio_stats : legacy_stats.radios) {
         V1_5::StaLinkLayerRadioStats hidl_radio_stats;
-        if (!convertLegacyLinkLayerRadioStatsToHidl(legacy_radio_stats,
-                                                    &hidl_radio_stats)) {
+        if (!convertLegacyLinkLayerRadioStatsToHidl(legacy_radio_stats, &hidl_radio_stats)) {
             return false;
         }
         hidl_radios_stats.push_back(hidl_radio_stats);
@@ -1107,23 +1035,19 @@
     return true;
 }
 
-bool convertLegacyPeerInfoStatsToHidl(
-    const legacy_hal::WifiPeerInfo& legacy_peer_info_stats,
-    StaPeerInfo* hidl_peer_info_stats) {
+bool convertLegacyPeerInfoStatsToHidl(const legacy_hal::WifiPeerInfo& legacy_peer_info_stats,
+                                      V1_5::StaPeerInfo* hidl_peer_info_stats) {
     if (!hidl_peer_info_stats) {
         return false;
     }
     *hidl_peer_info_stats = {};
-    hidl_peer_info_stats->staCount =
-        legacy_peer_info_stats.peer_info.bssload.sta_count;
-    hidl_peer_info_stats->chanUtil =
-        legacy_peer_info_stats.peer_info.bssload.chan_util;
+    hidl_peer_info_stats->staCount = legacy_peer_info_stats.peer_info.bssload.sta_count;
+    hidl_peer_info_stats->chanUtil = legacy_peer_info_stats.peer_info.bssload.chan_util;
 
-    std::vector<StaRateStat> hidlRateStats;
+    std::vector<V1_5::StaRateStat> hidlRateStats;
     for (const auto& legacy_rate_stats : legacy_peer_info_stats.rate_stats) {
-        StaRateStat rateStat;
-        if (!convertLegacyWifiRateInfoToHidl(legacy_rate_stats.rate,
-                                             &rateStat.rateInfo)) {
+        V1_5::StaRateStat rateStat;
+        if (!convertLegacyWifiRateInfoToHidl(legacy_rate_stats.rate, &rateStat.rateInfo)) {
             return false;
         }
         rateStat.txMpdu = legacy_rate_stats.tx_mpdu;
@@ -1137,8 +1061,8 @@
 }
 
 bool convertLegacyRoamingCapabilitiesToHidl(
-    const legacy_hal::wifi_roaming_capabilities& legacy_caps,
-    StaRoamingCapabilities* hidl_caps) {
+        const legacy_hal::wifi_roaming_capabilities& legacy_caps,
+        StaRoamingCapabilities* hidl_caps) {
     if (!hidl_caps) {
         return false;
     }
@@ -1148,9 +1072,8 @@
     return true;
 }
 
-bool convertHidlRoamingConfigToLegacy(
-    const StaRoamingConfig& hidl_config,
-    legacy_hal::wifi_roaming_config* legacy_config) {
+bool convertHidlRoamingConfigToLegacy(const StaRoamingConfig& hidl_config,
+                                      legacy_hal::wifi_roaming_config* legacy_config) {
     if (!legacy_config) {
         return false;
     }
@@ -1170,15 +1093,13 @@
     for (const auto& ssid : hidl_config.ssidWhitelist) {
         CHECK(ssid.size() <= sizeof(legacy_hal::ssid_t::ssid_str));
         legacy_config->whitelist_ssid[i].length = ssid.size();
-        memcpy(legacy_config->whitelist_ssid[i].ssid_str, ssid.data(),
-               ssid.size());
+        memcpy(legacy_config->whitelist_ssid[i].ssid_str, ssid.data(), ssid.size());
         i++;
     }
     return true;
 }
 
-legacy_hal::fw_roaming_state_t convertHidlRoamingStateToLegacy(
-    StaRoamingState state) {
+legacy_hal::fw_roaming_state_t convertHidlRoamingStateToLegacy(StaRoamingState state) {
     switch (state) {
         case StaRoamingState::ENABLED:
             return legacy_hal::ROAMING_ENABLE;
@@ -1200,8 +1121,7 @@
     CHECK(false);
 }
 
-legacy_hal::NanPublishType convertHidlNanPublishTypeToLegacy(
-    NanPublishType type) {
+legacy_hal::NanPublishType convertHidlNanPublishTypeToLegacy(NanPublishType type) {
     switch (type) {
         case NanPublishType::UNSOLICITED:
             return legacy_hal::NAN_PUBLISH_TYPE_UNSOLICITED;
@@ -1223,8 +1143,7 @@
     CHECK(false);
 }
 
-legacy_hal::NanSubscribeType convertHidlNanSubscribeTypeToLegacy(
-    NanSubscribeType type) {
+legacy_hal::NanSubscribeType convertHidlNanSubscribeTypeToLegacy(NanSubscribeType type) {
     switch (type) {
         case NanSubscribeType::PASSIVE:
             return legacy_hal::NAN_SUBSCRIBE_TYPE_PASSIVE;
@@ -1245,7 +1164,7 @@
 }
 
 legacy_hal::NanDataPathChannelCfg convertHidlNanDataPathChannelCfgToLegacy(
-    NanDataPathChannelCfg type) {
+        NanDataPathChannelCfg type) {
     switch (type) {
         case NanDataPathChannelCfg::CHANNEL_NOT_REQUESTED:
             return legacy_hal::NAN_DP_CHANNEL_NOT_REQUESTED;
@@ -1289,39 +1208,36 @@
     CHECK(false);
 }
 
-void convertToWifiNanStatus(legacy_hal::NanStatusType type, const char* str,
-                            size_t max_len, WifiNanStatus* wifiNanStatus) {
+void convertToWifiNanStatus(legacy_hal::NanStatusType type, const char* str, size_t max_len,
+                            WifiNanStatus* wifiNanStatus) {
     wifiNanStatus->status = convertLegacyNanStatusTypeToHidl(type);
     wifiNanStatus->description = safeConvertChar(str, max_len);
 }
 
-bool convertHidlNanEnableRequestToLegacy(
-    const V1_4::NanEnableRequest& hidl_request,
-    legacy_hal::NanEnableRequest* legacy_request) {
+bool convertHidlNanEnableRequestToLegacy(const V1_4::NanEnableRequest& hidl_request,
+                                         legacy_hal::NanEnableRequest* legacy_request) {
     if (!legacy_request) {
-        LOG(ERROR)
-            << "convertHidlNanEnableRequestToLegacy: null legacy_request";
+        LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: null legacy_request";
         return false;
     }
     *legacy_request = {};
 
     legacy_request->config_2dot4g_support = 1;
     legacy_request->support_2dot4g_val =
-        hidl_request.operateInBand[(size_t)NanBandIndex::NAN_BAND_24GHZ];
+            hidl_request.operateInBand[(size_t)NanBandIndex::NAN_BAND_24GHZ];
     legacy_request->config_support_5g = 1;
     legacy_request->support_5g_val =
-        hidl_request.operateInBand[(size_t)NanBandIndex::NAN_BAND_5GHZ];
+            hidl_request.operateInBand[(size_t)NanBandIndex::NAN_BAND_5GHZ];
     legacy_request->config_hop_count_limit = 1;
     legacy_request->hop_count_limit_val = hidl_request.hopCountMax;
     legacy_request->master_pref = hidl_request.configParams.masterPref;
     legacy_request->discovery_indication_cfg = 0;
     legacy_request->discovery_indication_cfg |=
-        hidl_request.configParams.disableDiscoveryAddressChangeIndication ? 0x1
-                                                                          : 0x0;
+            hidl_request.configParams.disableDiscoveryAddressChangeIndication ? 0x1 : 0x0;
     legacy_request->discovery_indication_cfg |=
-        hidl_request.configParams.disableStartedClusterIndication ? 0x2 : 0x0;
+            hidl_request.configParams.disableStartedClusterIndication ? 0x2 : 0x0;
     legacy_request->discovery_indication_cfg |=
-        hidl_request.configParams.disableJoinedClusterIndication ? 0x4 : 0x0;
+            hidl_request.configParams.disableJoinedClusterIndication ? 0x4 : 0x0;
     legacy_request->config_sid_beacon = 1;
     if (hidl_request.configParams.numberOfPublishServiceIdsInBeacon > 127) {
         LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: "
@@ -1329,9 +1245,8 @@
         return false;
     }
     legacy_request->sid_beacon_val =
-        (hidl_request.configParams.includePublishServiceIdsInBeacon ? 0x1
-                                                                    : 0x0) |
-        (hidl_request.configParams.numberOfPublishServiceIdsInBeacon << 1);
+            (hidl_request.configParams.includePublishServiceIdsInBeacon ? 0x1 : 0x0) |
+            (hidl_request.configParams.numberOfPublishServiceIdsInBeacon << 1);
     legacy_request->config_subscribe_sid_beacon = 1;
     if (hidl_request.configParams.numberOfSubscribeServiceIdsInBeacon > 127) {
         LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: "
@@ -1339,15 +1254,13 @@
         return false;
     }
     legacy_request->subscribe_sid_beacon_val =
-        (hidl_request.configParams.includeSubscribeServiceIdsInBeacon ? 0x1
-                                                                      : 0x0) |
-        (hidl_request.configParams.numberOfSubscribeServiceIdsInBeacon << 1);
+            (hidl_request.configParams.includeSubscribeServiceIdsInBeacon ? 0x1 : 0x0) |
+            (hidl_request.configParams.numberOfSubscribeServiceIdsInBeacon << 1);
     legacy_request->config_rssi_window_size = 1;
-    legacy_request->rssi_window_size_val =
-        hidl_request.configParams.rssiWindowSize;
+    legacy_request->rssi_window_size_val = hidl_request.configParams.rssiWindowSize;
     legacy_request->config_disc_mac_addr_randomization = 1;
     legacy_request->disc_mac_addr_rand_interval_sec =
-        hidl_request.configParams.macAddressRandomizationIntervalSec;
+            hidl_request.configParams.macAddressRandomizationIntervalSec;
     legacy_request->config_2dot4g_rssi_close = 1;
     if (hidl_request.configParams.bandSpecificConfig.size() != 3) {
         LOG(ERROR) << "convertHidlNanEnableRequestToLegacy: "
@@ -1355,134 +1268,93 @@
         return false;
     }
     legacy_request->rssi_close_2dot4g_val =
-        hidl_request.configParams
-            .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
-            .rssiClose;
+            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+                    .rssiClose;
     legacy_request->config_2dot4g_rssi_middle = 1;
     legacy_request->rssi_middle_2dot4g_val =
-        hidl_request.configParams
-            .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
-            .rssiMiddle;
+            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+                    .rssiMiddle;
     legacy_request->config_2dot4g_rssi_proximity = 1;
     legacy_request->rssi_proximity_2dot4g_val =
-        hidl_request.configParams
-            .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
-            .rssiCloseProximity;
+            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+                    .rssiCloseProximity;
     legacy_request->config_scan_params = 1;
-    legacy_request->scan_params_val
-        .dwell_time[legacy_hal::NAN_CHANNEL_24G_BAND] =
-        hidl_request.configParams
-            .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
-            .dwellTimeMs;
-    legacy_request->scan_params_val
-        .scan_period[legacy_hal::NAN_CHANNEL_24G_BAND] =
-        hidl_request.configParams
-            .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
-            .scanPeriodSec;
+    legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_24G_BAND] =
+            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+                    .dwellTimeMs;
+    legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_24G_BAND] =
+            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+                    .scanPeriodSec;
     legacy_request->config_dw.config_2dot4g_dw_band =
-        hidl_request.configParams
-            .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
-            .validDiscoveryWindowIntervalVal;
+            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+                    .validDiscoveryWindowIntervalVal;
     legacy_request->config_dw.dw_2dot4g_interval_val =
-        hidl_request.configParams
-            .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
-            .discoveryWindowIntervalVal;
+            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+                    .discoveryWindowIntervalVal;
     legacy_request->config_5g_rssi_close = 1;
     legacy_request->rssi_close_5g_val =
-        hidl_request.configParams
-            .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-            .rssiClose;
+            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+                    .rssiClose;
     legacy_request->config_5g_rssi_middle = 1;
     legacy_request->rssi_middle_5g_val =
-        hidl_request.configParams
-            .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-            .rssiMiddle;
+            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+                    .rssiMiddle;
     legacy_request->config_5g_rssi_close_proximity = 1;
     legacy_request->rssi_close_proximity_5g_val =
-        hidl_request.configParams
-            .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-            .rssiCloseProximity;
-    legacy_request->scan_params_val
-        .dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] =
-        hidl_request.configParams
-            .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-            .dwellTimeMs;
-    legacy_request->scan_params_val
-        .scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] =
-        hidl_request.configParams
-            .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-            .scanPeriodSec;
-    legacy_request->scan_params_val
-        .dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] =
-        hidl_request.configParams
-            .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-            .dwellTimeMs;
-    legacy_request->scan_params_val
-        .scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] =
-        hidl_request.configParams
-            .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-            .scanPeriodSec;
+            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+                    .rssiCloseProximity;
+    legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] =
+            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+                    .dwellTimeMs;
+    legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] =
+            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+                    .scanPeriodSec;
+    legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] =
+            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+                    .dwellTimeMs;
+    legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] =
+            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+                    .scanPeriodSec;
     legacy_request->config_dw.config_5g_dw_band =
-        hidl_request.configParams
-            .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-            .validDiscoveryWindowIntervalVal;
+            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+                    .validDiscoveryWindowIntervalVal;
     legacy_request->config_dw.dw_5g_interval_val =
-        hidl_request.configParams
-            .bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-            .discoveryWindowIntervalVal;
+            hidl_request.configParams.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+                    .discoveryWindowIntervalVal;
     if (hidl_request.debugConfigs.validClusterIdVals) {
-        legacy_request->cluster_low =
-            hidl_request.debugConfigs.clusterIdBottomRangeVal;
-        legacy_request->cluster_high =
-            hidl_request.debugConfigs.clusterIdTopRangeVal;
+        legacy_request->cluster_low = hidl_request.debugConfigs.clusterIdBottomRangeVal;
+        legacy_request->cluster_high = hidl_request.debugConfigs.clusterIdTopRangeVal;
     } else {  // need 'else' since not configurable in legacy HAL
         legacy_request->cluster_low = 0x0000;
         legacy_request->cluster_high = 0xFFFF;
     }
-    legacy_request->config_intf_addr =
-        hidl_request.debugConfigs.validIntfAddrVal;
-    memcpy(legacy_request->intf_addr_val,
-           hidl_request.debugConfigs.intfAddrVal.data(), 6);
+    legacy_request->config_intf_addr = hidl_request.debugConfigs.validIntfAddrVal;
+    memcpy(legacy_request->intf_addr_val, hidl_request.debugConfigs.intfAddrVal.data(), 6);
     legacy_request->config_oui = hidl_request.debugConfigs.validOuiVal;
     legacy_request->oui_val = hidl_request.debugConfigs.ouiVal;
     legacy_request->config_random_factor_force =
-        hidl_request.debugConfigs.validRandomFactorForceVal;
-    legacy_request->random_factor_force_val =
-        hidl_request.debugConfigs.randomFactorForceVal;
-    legacy_request->config_hop_count_force =
-        hidl_request.debugConfigs.validHopCountForceVal;
-    legacy_request->hop_count_force_val =
-        hidl_request.debugConfigs.hopCountForceVal;
-    legacy_request->config_24g_channel =
-        hidl_request.debugConfigs.validDiscoveryChannelVal;
+            hidl_request.debugConfigs.validRandomFactorForceVal;
+    legacy_request->random_factor_force_val = hidl_request.debugConfigs.randomFactorForceVal;
+    legacy_request->config_hop_count_force = hidl_request.debugConfigs.validHopCountForceVal;
+    legacy_request->hop_count_force_val = hidl_request.debugConfigs.hopCountForceVal;
+    legacy_request->config_24g_channel = hidl_request.debugConfigs.validDiscoveryChannelVal;
     legacy_request->channel_24g_val =
-        hidl_request.debugConfigs
-            .discoveryChannelMhzVal[(size_t)NanBandIndex::NAN_BAND_24GHZ];
-    legacy_request->config_5g_channel =
-        hidl_request.debugConfigs.validDiscoveryChannelVal;
+            hidl_request.debugConfigs.discoveryChannelMhzVal[(size_t)NanBandIndex::NAN_BAND_24GHZ];
+    legacy_request->config_5g_channel = hidl_request.debugConfigs.validDiscoveryChannelVal;
     legacy_request->channel_5g_val =
-        hidl_request.debugConfigs
-            .discoveryChannelMhzVal[(size_t)NanBandIndex::NAN_BAND_5GHZ];
-    legacy_request->config_2dot4g_beacons =
-        hidl_request.debugConfigs.validUseBeaconsInBandVal;
+            hidl_request.debugConfigs.discoveryChannelMhzVal[(size_t)NanBandIndex::NAN_BAND_5GHZ];
+    legacy_request->config_2dot4g_beacons = hidl_request.debugConfigs.validUseBeaconsInBandVal;
     legacy_request->beacon_2dot4g_val =
-        hidl_request.debugConfigs
-            .useBeaconsInBandVal[(size_t)NanBandIndex::NAN_BAND_24GHZ];
-    legacy_request->config_5g_beacons =
-        hidl_request.debugConfigs.validUseBeaconsInBandVal;
+            hidl_request.debugConfigs.useBeaconsInBandVal[(size_t)NanBandIndex::NAN_BAND_24GHZ];
+    legacy_request->config_5g_beacons = hidl_request.debugConfigs.validUseBeaconsInBandVal;
     legacy_request->beacon_5g_val =
-        hidl_request.debugConfigs
-            .useBeaconsInBandVal[(size_t)NanBandIndex::NAN_BAND_5GHZ];
-    legacy_request->config_2dot4g_sdf =
-        hidl_request.debugConfigs.validUseSdfInBandVal;
+            hidl_request.debugConfigs.useBeaconsInBandVal[(size_t)NanBandIndex::NAN_BAND_5GHZ];
+    legacy_request->config_2dot4g_sdf = hidl_request.debugConfigs.validUseSdfInBandVal;
     legacy_request->sdf_2dot4g_val =
-        hidl_request.debugConfigs
-            .useSdfInBandVal[(size_t)NanBandIndex::NAN_BAND_24GHZ];
-    legacy_request->config_5g_sdf =
-        hidl_request.debugConfigs.validUseSdfInBandVal;
+            hidl_request.debugConfigs.useSdfInBandVal[(size_t)NanBandIndex::NAN_BAND_24GHZ];
+    legacy_request->config_5g_sdf = hidl_request.debugConfigs.validUseSdfInBandVal;
     legacy_request->sdf_5g_val =
-        hidl_request.debugConfigs
-            .useSdfInBandVal[(size_t)NanBandIndex::NAN_BAND_5GHZ];
+            hidl_request.debugConfigs.useSdfInBandVal[(size_t)NanBandIndex::NAN_BAND_5GHZ];
 
     /* TODO: b/145609058
      * Missing updates needed to legacy_hal::NanEnableRequest and conversion to
@@ -1491,13 +1363,11 @@
     return true;
 }
 
-bool convertHidlNanEnableRequest_1_4ToLegacy(
-    const V1_4::NanEnableRequest& hidl_request1,
-    const NanConfigRequestSupplemental& hidl_request2,
-    legacy_hal::NanEnableRequest* legacy_request) {
+bool convertHidlNanEnableRequest_1_4ToLegacy(const V1_4::NanEnableRequest& hidl_request1,
+                                             const NanConfigRequestSupplemental& hidl_request2,
+                                             legacy_hal::NanEnableRequest* legacy_request) {
     if (!legacy_request) {
-        LOG(ERROR)
-            << "convertHidlNanEnableRequest_1_4ToLegacy: null legacy_request";
+        LOG(ERROR) << "convertHidlNanEnableRequest_1_4ToLegacy: null legacy_request";
         return false;
     }
 
@@ -1507,71 +1377,60 @@
     }
 
     legacy_request->config_discovery_beacon_int = 1;
-    legacy_request->discovery_beacon_interval =
-        hidl_request2.V1_2.discoveryBeaconIntervalMs;
+    legacy_request->discovery_beacon_interval = hidl_request2.V1_2.discoveryBeaconIntervalMs;
     legacy_request->config_nss = 1;
     legacy_request->nss = hidl_request2.V1_2.numberOfSpatialStreamsInDiscovery;
     legacy_request->config_dw_early_termination = 1;
     legacy_request->enable_dw_termination =
-        hidl_request2.V1_2.enableDiscoveryWindowEarlyTermination;
+            hidl_request2.V1_2.enableDiscoveryWindowEarlyTermination;
     legacy_request->config_enable_ranging = 1;
     legacy_request->enable_ranging = hidl_request2.V1_2.enableRanging;
 
     return true;
 }
 
-bool convertHidlNanEnableRequest_1_5ToLegacy(
-    const V1_4::NanEnableRequest& hidl_request1,
-    const NanConfigRequestSupplemental& hidl_request2,
-    legacy_hal::NanEnableRequest* legacy_request) {
+bool convertHidlNanEnableRequest_1_5ToLegacy(const V1_4::NanEnableRequest& hidl_request1,
+                                             const NanConfigRequestSupplemental& hidl_request2,
+                                             legacy_hal::NanEnableRequest* legacy_request) {
     if (!legacy_request) {
-        LOG(ERROR)
-            << "convertHidlNanEnableRequest_1_5ToLegacy: null legacy_request";
+        LOG(ERROR) << "convertHidlNanEnableRequest_1_5ToLegacy: null legacy_request";
         return false;
     }
 
     *legacy_request = {};
-    if (!convertHidlNanEnableRequest_1_4ToLegacy(hidl_request1, hidl_request2,
-                                                 legacy_request)) {
+    if (!convertHidlNanEnableRequest_1_4ToLegacy(hidl_request1, hidl_request2, legacy_request)) {
         return false;
     }
 
     legacy_request->config_enable_instant_mode = 1;
-    legacy_request->enable_instant_mode =
-        hidl_request2.enableInstantCommunicationMode;
+    legacy_request->enable_instant_mode = hidl_request2.enableInstantCommunicationMode;
 
     return true;
 }
 
-bool convertHidlNanConfigRequest_1_5ToLegacy(
-    const V1_4::NanConfigRequest& hidl_request1,
-    const NanConfigRequestSupplemental& hidl_request2,
-    legacy_hal::NanConfigRequest* legacy_request) {
+bool convertHidlNanConfigRequest_1_5ToLegacy(const V1_4::NanConfigRequest& hidl_request1,
+                                             const NanConfigRequestSupplemental& hidl_request2,
+                                             legacy_hal::NanConfigRequest* legacy_request) {
     if (!legacy_request) {
-        LOG(ERROR)
-            << "convertHidlNanConfigRequest_1_5ToLegacy: null legacy_request";
+        LOG(ERROR) << "convertHidlNanConfigRequest_1_5ToLegacy: null legacy_request";
         return false;
     }
 
     *legacy_request = {};
-    if (!convertHidlNanConfigRequest_1_4ToLegacy(hidl_request1, hidl_request2,
-                                                 legacy_request)) {
+    if (!convertHidlNanConfigRequest_1_4ToLegacy(hidl_request1, hidl_request2, legacy_request)) {
         return false;
     }
 
     legacy_request->config_enable_instant_mode = 1;
-    legacy_request->enable_instant_mode =
-        hidl_request2.enableInstantCommunicationMode;
+    legacy_request->enable_instant_mode = hidl_request2.enableInstantCommunicationMode;
 
     return true;
 }
 
-bool convertHidlNanPublishRequestToLegacy(
-    const NanPublishRequest& hidl_request,
-    legacy_hal::NanPublishRequest* legacy_request) {
+bool convertHidlNanPublishRequestToLegacy(const NanPublishRequest& hidl_request,
+                                          legacy_hal::NanPublishRequest* legacy_request) {
     if (!legacy_request) {
-        LOG(ERROR)
-            << "convertHidlNanPublishRequestToLegacy: null legacy_request";
+        LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: null legacy_request";
         return false;
     }
     *legacy_request = {};
@@ -1580,22 +1439,18 @@
     legacy_request->ttl = hidl_request.baseConfigs.ttlSec;
     legacy_request->period = hidl_request.baseConfigs.discoveryWindowPeriod;
     legacy_request->publish_count = hidl_request.baseConfigs.discoveryCount;
-    legacy_request->service_name_len =
-        hidl_request.baseConfigs.serviceName.size();
+    legacy_request->service_name_len = hidl_request.baseConfigs.serviceName.size();
     if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
         LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: service_name_len "
                       "too large";
         return false;
     }
-    memcpy(legacy_request->service_name,
-           hidl_request.baseConfigs.serviceName.data(),
+    memcpy(legacy_request->service_name, hidl_request.baseConfigs.serviceName.data(),
            legacy_request->service_name_len);
-    legacy_request->publish_match_indicator = convertHidlNanMatchAlgToLegacy(
-        hidl_request.baseConfigs.discoveryMatchIndicator);
-    legacy_request->service_specific_info_len =
-        hidl_request.baseConfigs.serviceSpecificInfo.size();
-    if (legacy_request->service_specific_info_len >
-        NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
+    legacy_request->publish_match_indicator =
+            convertHidlNanMatchAlgToLegacy(hidl_request.baseConfigs.discoveryMatchIndicator);
+    legacy_request->service_specific_info_len = hidl_request.baseConfigs.serviceSpecificInfo.size();
+    if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
         LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: "
                       "service_specific_info_len too large";
         return false;
@@ -1604,9 +1459,8 @@
            hidl_request.baseConfigs.serviceSpecificInfo.data(),
            legacy_request->service_specific_info_len);
     legacy_request->sdea_service_specific_info_len =
-        hidl_request.baseConfigs.extendedServiceSpecificInfo.size();
-    if (legacy_request->sdea_service_specific_info_len >
-        NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
+            hidl_request.baseConfigs.extendedServiceSpecificInfo.size();
+    if (legacy_request->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
         LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: "
                       "sdea_service_specific_info_len too large";
         return false;
@@ -1614,49 +1468,38 @@
     memcpy(legacy_request->sdea_service_specific_info,
            hidl_request.baseConfigs.extendedServiceSpecificInfo.data(),
            legacy_request->sdea_service_specific_info_len);
-    legacy_request->rx_match_filter_len =
-        hidl_request.baseConfigs.rxMatchFilter.size();
+    legacy_request->rx_match_filter_len = hidl_request.baseConfigs.rxMatchFilter.size();
     if (legacy_request->rx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
         LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: "
                       "rx_match_filter_len too large";
         return false;
     }
-    memcpy(legacy_request->rx_match_filter,
-           hidl_request.baseConfigs.rxMatchFilter.data(),
+    memcpy(legacy_request->rx_match_filter, hidl_request.baseConfigs.rxMatchFilter.data(),
            legacy_request->rx_match_filter_len);
-    legacy_request->tx_match_filter_len =
-        hidl_request.baseConfigs.txMatchFilter.size();
+    legacy_request->tx_match_filter_len = hidl_request.baseConfigs.txMatchFilter.size();
     if (legacy_request->tx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
         LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: "
                       "tx_match_filter_len too large";
         return false;
     }
-    memcpy(legacy_request->tx_match_filter,
-           hidl_request.baseConfigs.txMatchFilter.data(),
+    memcpy(legacy_request->tx_match_filter, hidl_request.baseConfigs.txMatchFilter.data(),
            legacy_request->tx_match_filter_len);
-    legacy_request->rssi_threshold_flag =
-        hidl_request.baseConfigs.useRssiThreshold;
+    legacy_request->rssi_threshold_flag = hidl_request.baseConfigs.useRssiThreshold;
     legacy_request->recv_indication_cfg = 0;
     legacy_request->recv_indication_cfg |=
-        hidl_request.baseConfigs.disableDiscoveryTerminationIndication ? 0x1
-                                                                       : 0x0;
+            hidl_request.baseConfigs.disableDiscoveryTerminationIndication ? 0x1 : 0x0;
     legacy_request->recv_indication_cfg |=
-        hidl_request.baseConfigs.disableMatchExpirationIndication ? 0x2 : 0x0;
+            hidl_request.baseConfigs.disableMatchExpirationIndication ? 0x2 : 0x0;
     legacy_request->recv_indication_cfg |=
-        hidl_request.baseConfigs.disableFollowupReceivedIndication ? 0x4 : 0x0;
+            hidl_request.baseConfigs.disableFollowupReceivedIndication ? 0x4 : 0x0;
     legacy_request->recv_indication_cfg |= 0x8;
-    legacy_request->cipher_type =
-        (unsigned int)hidl_request.baseConfigs.securityConfig.cipherType;
-    if (hidl_request.baseConfigs.securityConfig.securityType ==
-        NanDataPathSecurityType::PMK) {
-        legacy_request->key_info.key_type =
-            legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
+    legacy_request->cipher_type = (unsigned int)hidl_request.baseConfigs.securityConfig.cipherType;
+    if (hidl_request.baseConfigs.securityConfig.securityType == NanDataPathSecurityType::PMK) {
+        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
         legacy_request->key_info.body.pmk_info.pmk_len =
-            hidl_request.baseConfigs.securityConfig.pmk.size();
-        if (legacy_request->key_info.body.pmk_info.pmk_len !=
-            NAN_PMK_INFO_LEN) {
-            LOG(ERROR)
-                << "convertHidlNanPublishRequestToLegacy: invalid pmk_len";
+                hidl_request.baseConfigs.securityConfig.pmk.size();
+        if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
+            LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: invalid pmk_len";
             return false;
         }
         memcpy(legacy_request->key_info.body.pmk_info.pmk,
@@ -1665,10 +1508,9 @@
     }
     if (hidl_request.baseConfigs.securityConfig.securityType ==
         NanDataPathSecurityType::PASSPHRASE) {
-        legacy_request->key_info.key_type =
-            legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
         legacy_request->key_info.body.passphrase_info.passphrase_len =
-            hidl_request.baseConfigs.securityConfig.passphrase.size();
+                hidl_request.baseConfigs.securityConfig.passphrase.size();
         if (legacy_request->key_info.body.passphrase_info.passphrase_len <
             NAN_SECURITY_MIN_PASSPHRASE_LEN) {
             LOG(ERROR) << "convertHidlNanPublishRequestToLegacy: "
@@ -1686,45 +1528,36 @@
                legacy_request->key_info.body.passphrase_info.passphrase_len);
     }
     legacy_request->sdea_params.security_cfg =
-        (hidl_request.baseConfigs.securityConfig.securityType !=
-         NanDataPathSecurityType::OPEN)
-            ? legacy_hal::NAN_DP_CONFIG_SECURITY
-            : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
-    legacy_request->sdea_params.ranging_state =
-        hidl_request.baseConfigs.rangingRequired
-            ? legacy_hal::NAN_RANGING_ENABLE
-            : legacy_hal::NAN_RANGING_DISABLE;
+            (hidl_request.baseConfigs.securityConfig.securityType != NanDataPathSecurityType::OPEN)
+                    ? legacy_hal::NAN_DP_CONFIG_SECURITY
+                    : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
+    legacy_request->sdea_params.ranging_state = hidl_request.baseConfigs.rangingRequired
+                                                        ? legacy_hal::NAN_RANGING_ENABLE
+                                                        : legacy_hal::NAN_RANGING_DISABLE;
     legacy_request->ranging_cfg.ranging_interval_msec =
-        hidl_request.baseConfigs.rangingIntervalMsec;
+            hidl_request.baseConfigs.rangingIntervalMsec;
     legacy_request->ranging_cfg.config_ranging_indications =
-        hidl_request.baseConfigs.configRangingIndications;
+            hidl_request.baseConfigs.configRangingIndications;
     legacy_request->ranging_cfg.distance_ingress_mm =
-        hidl_request.baseConfigs.distanceIngressCm * 10;
-    legacy_request->ranging_cfg.distance_egress_mm =
-        hidl_request.baseConfigs.distanceEgressCm * 10;
-    legacy_request->ranging_auto_response =
-        hidl_request.baseConfigs.rangingRequired
-            ? legacy_hal::NAN_RANGING_AUTO_RESPONSE_ENABLE
-            : legacy_hal::NAN_RANGING_AUTO_RESPONSE_DISABLE;
-    legacy_request->sdea_params.range_report =
-        legacy_hal::NAN_DISABLE_RANGE_REPORT;
-    legacy_request->publish_type =
-        convertHidlNanPublishTypeToLegacy(hidl_request.publishType);
+            hidl_request.baseConfigs.distanceIngressCm * 10;
+    legacy_request->ranging_cfg.distance_egress_mm = hidl_request.baseConfigs.distanceEgressCm * 10;
+    legacy_request->ranging_auto_response = hidl_request.baseConfigs.rangingRequired
+                                                    ? legacy_hal::NAN_RANGING_AUTO_RESPONSE_ENABLE
+                                                    : legacy_hal::NAN_RANGING_AUTO_RESPONSE_DISABLE;
+    legacy_request->sdea_params.range_report = legacy_hal::NAN_DISABLE_RANGE_REPORT;
+    legacy_request->publish_type = convertHidlNanPublishTypeToLegacy(hidl_request.publishType);
     legacy_request->tx_type = convertHidlNanTxTypeToLegacy(hidl_request.txType);
-    legacy_request->service_responder_policy =
-        hidl_request.autoAcceptDataPathRequests
-            ? legacy_hal::NAN_SERVICE_ACCEPT_POLICY_ALL
-            : legacy_hal::NAN_SERVICE_ACCEPT_POLICY_NONE;
+    legacy_request->service_responder_policy = hidl_request.autoAcceptDataPathRequests
+                                                       ? legacy_hal::NAN_SERVICE_ACCEPT_POLICY_ALL
+                                                       : legacy_hal::NAN_SERVICE_ACCEPT_POLICY_NONE;
 
     return true;
 }
 
-bool convertHidlNanSubscribeRequestToLegacy(
-    const NanSubscribeRequest& hidl_request,
-    legacy_hal::NanSubscribeRequest* legacy_request) {
+bool convertHidlNanSubscribeRequestToLegacy(const NanSubscribeRequest& hidl_request,
+                                            legacy_hal::NanSubscribeRequest* legacy_request) {
     if (!legacy_request) {
-        LOG(ERROR)
-            << "convertHidlNanSubscribeRequestToLegacy: legacy_request is null";
+        LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: legacy_request is null";
         return false;
     }
     *legacy_request = {};
@@ -1733,22 +1566,18 @@
     legacy_request->ttl = hidl_request.baseConfigs.ttlSec;
     legacy_request->period = hidl_request.baseConfigs.discoveryWindowPeriod;
     legacy_request->subscribe_count = hidl_request.baseConfigs.discoveryCount;
-    legacy_request->service_name_len =
-        hidl_request.baseConfigs.serviceName.size();
+    legacy_request->service_name_len = hidl_request.baseConfigs.serviceName.size();
     if (legacy_request->service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
         LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: "
                       "service_name_len too large";
         return false;
     }
-    memcpy(legacy_request->service_name,
-           hidl_request.baseConfigs.serviceName.data(),
+    memcpy(legacy_request->service_name, hidl_request.baseConfigs.serviceName.data(),
            legacy_request->service_name_len);
-    legacy_request->subscribe_match_indicator = convertHidlNanMatchAlgToLegacy(
-        hidl_request.baseConfigs.discoveryMatchIndicator);
-    legacy_request->service_specific_info_len =
-        hidl_request.baseConfigs.serviceSpecificInfo.size();
-    if (legacy_request->service_specific_info_len >
-        NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
+    legacy_request->subscribe_match_indicator =
+            convertHidlNanMatchAlgToLegacy(hidl_request.baseConfigs.discoveryMatchIndicator);
+    legacy_request->service_specific_info_len = hidl_request.baseConfigs.serviceSpecificInfo.size();
+    if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
         LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: "
                       "service_specific_info_len too large";
         return false;
@@ -1757,9 +1586,8 @@
            hidl_request.baseConfigs.serviceSpecificInfo.data(),
            legacy_request->service_specific_info_len);
     legacy_request->sdea_service_specific_info_len =
-        hidl_request.baseConfigs.extendedServiceSpecificInfo.size();
-    if (legacy_request->sdea_service_specific_info_len >
-        NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
+            hidl_request.baseConfigs.extendedServiceSpecificInfo.size();
+    if (legacy_request->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
         LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: "
                       "sdea_service_specific_info_len too large";
         return false;
@@ -1767,48 +1595,37 @@
     memcpy(legacy_request->sdea_service_specific_info,
            hidl_request.baseConfigs.extendedServiceSpecificInfo.data(),
            legacy_request->sdea_service_specific_info_len);
-    legacy_request->rx_match_filter_len =
-        hidl_request.baseConfigs.rxMatchFilter.size();
+    legacy_request->rx_match_filter_len = hidl_request.baseConfigs.rxMatchFilter.size();
     if (legacy_request->rx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
         LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: "
                       "rx_match_filter_len too large";
         return false;
     }
-    memcpy(legacy_request->rx_match_filter,
-           hidl_request.baseConfigs.rxMatchFilter.data(),
+    memcpy(legacy_request->rx_match_filter, hidl_request.baseConfigs.rxMatchFilter.data(),
            legacy_request->rx_match_filter_len);
-    legacy_request->tx_match_filter_len =
-        hidl_request.baseConfigs.txMatchFilter.size();
+    legacy_request->tx_match_filter_len = hidl_request.baseConfigs.txMatchFilter.size();
     if (legacy_request->tx_match_filter_len > NAN_MAX_MATCH_FILTER_LEN) {
         LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: "
                       "tx_match_filter_len too large";
         return false;
     }
-    memcpy(legacy_request->tx_match_filter,
-           hidl_request.baseConfigs.txMatchFilter.data(),
+    memcpy(legacy_request->tx_match_filter, hidl_request.baseConfigs.txMatchFilter.data(),
            legacy_request->tx_match_filter_len);
-    legacy_request->rssi_threshold_flag =
-        hidl_request.baseConfigs.useRssiThreshold;
+    legacy_request->rssi_threshold_flag = hidl_request.baseConfigs.useRssiThreshold;
     legacy_request->recv_indication_cfg = 0;
     legacy_request->recv_indication_cfg |=
-        hidl_request.baseConfigs.disableDiscoveryTerminationIndication ? 0x1
-                                                                       : 0x0;
+            hidl_request.baseConfigs.disableDiscoveryTerminationIndication ? 0x1 : 0x0;
     legacy_request->recv_indication_cfg |=
-        hidl_request.baseConfigs.disableMatchExpirationIndication ? 0x2 : 0x0;
+            hidl_request.baseConfigs.disableMatchExpirationIndication ? 0x2 : 0x0;
     legacy_request->recv_indication_cfg |=
-        hidl_request.baseConfigs.disableFollowupReceivedIndication ? 0x4 : 0x0;
-    legacy_request->cipher_type =
-        (unsigned int)hidl_request.baseConfigs.securityConfig.cipherType;
-    if (hidl_request.baseConfigs.securityConfig.securityType ==
-        NanDataPathSecurityType::PMK) {
-        legacy_request->key_info.key_type =
-            legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
+            hidl_request.baseConfigs.disableFollowupReceivedIndication ? 0x4 : 0x0;
+    legacy_request->cipher_type = (unsigned int)hidl_request.baseConfigs.securityConfig.cipherType;
+    if (hidl_request.baseConfigs.securityConfig.securityType == NanDataPathSecurityType::PMK) {
+        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
         legacy_request->key_info.body.pmk_info.pmk_len =
-            hidl_request.baseConfigs.securityConfig.pmk.size();
-        if (legacy_request->key_info.body.pmk_info.pmk_len !=
-            NAN_PMK_INFO_LEN) {
-            LOG(ERROR)
-                << "convertHidlNanSubscribeRequestToLegacy: invalid pmk_len";
+                hidl_request.baseConfigs.securityConfig.pmk.size();
+        if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
+            LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: invalid pmk_len";
             return false;
         }
         memcpy(legacy_request->key_info.body.pmk_info.pmk,
@@ -1817,10 +1634,9 @@
     }
     if (hidl_request.baseConfigs.securityConfig.securityType ==
         NanDataPathSecurityType::PASSPHRASE) {
-        legacy_request->key_info.key_type =
-            legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
         legacy_request->key_info.body.passphrase_info.passphrase_len =
-            hidl_request.baseConfigs.securityConfig.passphrase.size();
+                hidl_request.baseConfigs.securityConfig.passphrase.size();
         if (legacy_request->key_info.body.passphrase_info.passphrase_len <
             NAN_SECURITY_MIN_PASSPHRASE_LEN) {
             LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: "
@@ -1838,43 +1654,34 @@
                legacy_request->key_info.body.passphrase_info.passphrase_len);
     }
     legacy_request->sdea_params.security_cfg =
-        (hidl_request.baseConfigs.securityConfig.securityType !=
-         NanDataPathSecurityType::OPEN)
-            ? legacy_hal::NAN_DP_CONFIG_SECURITY
-            : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
-    legacy_request->sdea_params.ranging_state =
-        hidl_request.baseConfigs.rangingRequired
-            ? legacy_hal::NAN_RANGING_ENABLE
-            : legacy_hal::NAN_RANGING_DISABLE;
+            (hidl_request.baseConfigs.securityConfig.securityType != NanDataPathSecurityType::OPEN)
+                    ? legacy_hal::NAN_DP_CONFIG_SECURITY
+                    : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
+    legacy_request->sdea_params.ranging_state = hidl_request.baseConfigs.rangingRequired
+                                                        ? legacy_hal::NAN_RANGING_ENABLE
+                                                        : legacy_hal::NAN_RANGING_DISABLE;
     legacy_request->ranging_cfg.ranging_interval_msec =
-        hidl_request.baseConfigs.rangingIntervalMsec;
+            hidl_request.baseConfigs.rangingIntervalMsec;
     legacy_request->ranging_cfg.config_ranging_indications =
-        hidl_request.baseConfigs.configRangingIndications;
+            hidl_request.baseConfigs.configRangingIndications;
     legacy_request->ranging_cfg.distance_ingress_mm =
-        hidl_request.baseConfigs.distanceIngressCm * 10;
-    legacy_request->ranging_cfg.distance_egress_mm =
-        hidl_request.baseConfigs.distanceEgressCm * 10;
-    legacy_request->ranging_auto_response =
-        hidl_request.baseConfigs.rangingRequired
-            ? legacy_hal::NAN_RANGING_AUTO_RESPONSE_ENABLE
-            : legacy_hal::NAN_RANGING_AUTO_RESPONSE_DISABLE;
-    legacy_request->sdea_params.range_report =
-        legacy_hal::NAN_DISABLE_RANGE_REPORT;
+            hidl_request.baseConfigs.distanceIngressCm * 10;
+    legacy_request->ranging_cfg.distance_egress_mm = hidl_request.baseConfigs.distanceEgressCm * 10;
+    legacy_request->ranging_auto_response = hidl_request.baseConfigs.rangingRequired
+                                                    ? legacy_hal::NAN_RANGING_AUTO_RESPONSE_ENABLE
+                                                    : legacy_hal::NAN_RANGING_AUTO_RESPONSE_DISABLE;
+    legacy_request->sdea_params.range_report = legacy_hal::NAN_DISABLE_RANGE_REPORT;
     legacy_request->subscribe_type =
-        convertHidlNanSubscribeTypeToLegacy(hidl_request.subscribeType);
-    legacy_request->serviceResponseFilter =
-        convertHidlNanSrfTypeToLegacy(hidl_request.srfType);
-    legacy_request->serviceResponseInclude =
-        hidl_request.srfRespondIfInAddressSet
-            ? legacy_hal::NAN_SRF_INCLUDE_RESPOND
-            : legacy_hal::NAN_SRF_INCLUDE_DO_NOT_RESPOND;
+            convertHidlNanSubscribeTypeToLegacy(hidl_request.subscribeType);
+    legacy_request->serviceResponseFilter = convertHidlNanSrfTypeToLegacy(hidl_request.srfType);
+    legacy_request->serviceResponseInclude = hidl_request.srfRespondIfInAddressSet
+                                                     ? legacy_hal::NAN_SRF_INCLUDE_RESPOND
+                                                     : legacy_hal::NAN_SRF_INCLUDE_DO_NOT_RESPOND;
     legacy_request->useServiceResponseFilter =
-        hidl_request.shouldUseSrf ? legacy_hal::NAN_USE_SRF
-                                  : legacy_hal::NAN_DO_NOT_USE_SRF;
+            hidl_request.shouldUseSrf ? legacy_hal::NAN_USE_SRF : legacy_hal::NAN_DO_NOT_USE_SRF;
     legacy_request->ssiRequiredForMatchIndication =
-        hidl_request.isSsiRequiredForMatch
-            ? legacy_hal::NAN_SSI_REQUIRED_IN_MATCH_IND
-            : legacy_hal::NAN_SSI_NOT_REQUIRED_IN_MATCH_IND;
+            hidl_request.isSsiRequiredForMatch ? legacy_hal::NAN_SSI_REQUIRED_IN_MATCH_IND
+                                               : legacy_hal::NAN_SSI_NOT_REQUIRED_IN_MATCH_IND;
     legacy_request->num_intf_addr_present = hidl_request.intfAddr.size();
     if (legacy_request->num_intf_addr_present > NAN_MAX_SUBSCRIBE_MAX_ADDRESS) {
         LOG(ERROR) << "convertHidlNanSubscribeRequestToLegacy: "
@@ -1882,16 +1689,15 @@
         return false;
     }
     for (int i = 0; i < legacy_request->num_intf_addr_present; i++) {
-        memcpy(legacy_request->intf_addr[i], hidl_request.intfAddr[i].data(),
-               6);
+        memcpy(legacy_request->intf_addr[i], hidl_request.intfAddr[i].data(), 6);
     }
 
     return true;
 }
 
 bool convertHidlNanTransmitFollowupRequestToLegacy(
-    const NanTransmitFollowupRequest& hidl_request,
-    legacy_hal::NanTransmitFollowupRequest* legacy_request) {
+        const NanTransmitFollowupRequest& hidl_request,
+        legacy_hal::NanTransmitFollowupRequest* legacy_request) {
     if (!legacy_request) {
         LOG(ERROR) << "convertHidlNanTransmitFollowupRequestToLegacy: "
                       "legacy_request is null";
@@ -1902,27 +1708,22 @@
     legacy_request->publish_subscribe_id = hidl_request.discoverySessionId;
     legacy_request->requestor_instance_id = hidl_request.peerId;
     memcpy(legacy_request->addr, hidl_request.addr.data(), 6);
-    legacy_request->priority = hidl_request.isHighPriority
-                                   ? legacy_hal::NAN_TX_PRIORITY_HIGH
-                                   : legacy_hal::NAN_TX_PRIORITY_NORMAL;
+    legacy_request->priority = hidl_request.isHighPriority ? legacy_hal::NAN_TX_PRIORITY_HIGH
+                                                           : legacy_hal::NAN_TX_PRIORITY_NORMAL;
     legacy_request->dw_or_faw = hidl_request.shouldUseDiscoveryWindow
-                                    ? legacy_hal::NAN_TRANSMIT_IN_DW
-                                    : legacy_hal::NAN_TRANSMIT_IN_FAW;
-    legacy_request->service_specific_info_len =
-        hidl_request.serviceSpecificInfo.size();
-    if (legacy_request->service_specific_info_len >
-        NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
+                                        ? legacy_hal::NAN_TRANSMIT_IN_DW
+                                        : legacy_hal::NAN_TRANSMIT_IN_FAW;
+    legacy_request->service_specific_info_len = hidl_request.serviceSpecificInfo.size();
+    if (legacy_request->service_specific_info_len > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) {
         LOG(ERROR) << "convertHidlNanTransmitFollowupRequestToLegacy: "
                       "service_specific_info_len too large";
         return false;
     }
-    memcpy(legacy_request->service_specific_info,
-           hidl_request.serviceSpecificInfo.data(),
+    memcpy(legacy_request->service_specific_info, hidl_request.serviceSpecificInfo.data(),
            legacy_request->service_specific_info_len);
     legacy_request->sdea_service_specific_info_len =
-        hidl_request.extendedServiceSpecificInfo.size();
-    if (legacy_request->sdea_service_specific_info_len >
-        NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
+            hidl_request.extendedServiceSpecificInfo.size();
+    if (legacy_request->sdea_service_specific_info_len > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) {
         LOG(ERROR) << "convertHidlNanTransmitFollowupRequestToLegacy: "
                       "sdea_service_specific_info_len too large";
         return false;
@@ -1930,18 +1731,15 @@
     memcpy(legacy_request->sdea_service_specific_info,
            hidl_request.extendedServiceSpecificInfo.data(),
            legacy_request->sdea_service_specific_info_len);
-    legacy_request->recv_indication_cfg =
-        hidl_request.disableFollowupResultIndication ? 0x1 : 0x0;
+    legacy_request->recv_indication_cfg = hidl_request.disableFollowupResultIndication ? 0x1 : 0x0;
 
     return true;
 }
 
-bool convertHidlNanConfigRequestToLegacy(
-    const V1_4::NanConfigRequest& hidl_request,
-    legacy_hal::NanConfigRequest* legacy_request) {
+bool convertHidlNanConfigRequestToLegacy(const V1_4::NanConfigRequest& hidl_request,
+                                         legacy_hal::NanConfigRequest* legacy_request) {
     if (!legacy_request) {
-        LOG(ERROR)
-            << "convertHidlNanConfigRequestToLegacy: legacy_request is null";
+        LOG(ERROR) << "convertHidlNanConfigRequestToLegacy: legacy_request is null";
         return false;
     }
     *legacy_request = {};
@@ -1951,20 +1749,19 @@
     legacy_request->master_pref = hidl_request.masterPref;
     legacy_request->discovery_indication_cfg = 0;
     legacy_request->discovery_indication_cfg |=
-        hidl_request.disableDiscoveryAddressChangeIndication ? 0x1 : 0x0;
+            hidl_request.disableDiscoveryAddressChangeIndication ? 0x1 : 0x0;
     legacy_request->discovery_indication_cfg |=
-        hidl_request.disableStartedClusterIndication ? 0x2 : 0x0;
+            hidl_request.disableStartedClusterIndication ? 0x2 : 0x0;
     legacy_request->discovery_indication_cfg |=
-        hidl_request.disableJoinedClusterIndication ? 0x4 : 0x0;
+            hidl_request.disableJoinedClusterIndication ? 0x4 : 0x0;
     legacy_request->config_sid_beacon = 1;
     if (hidl_request.numberOfPublishServiceIdsInBeacon > 127) {
         LOG(ERROR) << "convertHidlNanConfigRequestToLegacy: "
                       "numberOfPublishServiceIdsInBeacon > 127";
         return false;
     }
-    legacy_request->sid_beacon =
-        (hidl_request.includePublishServiceIdsInBeacon ? 0x1 : 0x0) |
-        (hidl_request.numberOfPublishServiceIdsInBeacon << 1);
+    legacy_request->sid_beacon = (hidl_request.includePublishServiceIdsInBeacon ? 0x1 : 0x0) |
+                                 (hidl_request.numberOfPublishServiceIdsInBeacon << 1);
     legacy_request->config_subscribe_sid_beacon = 1;
     if (hidl_request.numberOfSubscribeServiceIdsInBeacon > 127) {
         LOG(ERROR) << "convertHidlNanConfigRequestToLegacy: "
@@ -1972,13 +1769,13 @@
         return false;
     }
     legacy_request->subscribe_sid_beacon_val =
-        (hidl_request.includeSubscribeServiceIdsInBeacon ? 0x1 : 0x0) |
-        (hidl_request.numberOfSubscribeServiceIdsInBeacon << 1);
+            (hidl_request.includeSubscribeServiceIdsInBeacon ? 0x1 : 0x0) |
+            (hidl_request.numberOfSubscribeServiceIdsInBeacon << 1);
     legacy_request->config_rssi_window_size = 1;
     legacy_request->rssi_window_size_val = hidl_request.rssiWindowSize;
     legacy_request->config_disc_mac_addr_randomization = 1;
     legacy_request->disc_mac_addr_rand_interval_sec =
-        hidl_request.macAddressRandomizationIntervalSec;
+            hidl_request.macAddressRandomizationIntervalSec;
     /* TODO : missing
     legacy_request->config_2dot4g_rssi_close = 1;
     legacy_request->rssi_close_2dot4g_val =
@@ -1994,20 +1791,16 @@
               (size_t) NanBandIndex::NAN_BAND_24GHZ].rssiCloseProximity;
     */
     legacy_request->config_scan_params = 1;
-    legacy_request->scan_params_val
-        .dwell_time[legacy_hal::NAN_CHANNEL_24G_BAND] =
-        hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
-            .dwellTimeMs;
-    legacy_request->scan_params_val
-        .scan_period[legacy_hal::NAN_CHANNEL_24G_BAND] =
-        hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
-            .scanPeriodSec;
+    legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_24G_BAND] =
+            hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ].dwellTimeMs;
+    legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_24G_BAND] =
+            hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ].scanPeriodSec;
     legacy_request->config_dw.config_2dot4g_dw_band =
-        hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
-            .validDiscoveryWindowIntervalVal;
+            hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+                    .validDiscoveryWindowIntervalVal;
     legacy_request->config_dw.dw_2dot4g_interval_val =
-        hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
-            .discoveryWindowIntervalVal;
+            hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_24GHZ]
+                    .discoveryWindowIntervalVal;
     /* TODO: missing
     legacy_request->config_5g_rssi_close = 1;
     legacy_request->rssi_close_5g_val =
@@ -2020,30 +1813,21 @@
     */
     legacy_request->config_5g_rssi_close_proximity = 1;
     legacy_request->rssi_close_proximity_5g_val =
-        hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-            .rssiCloseProximity;
-    legacy_request->scan_params_val
-        .dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] =
-        hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-            .dwellTimeMs;
-    legacy_request->scan_params_val
-        .scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] =
-        hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-            .scanPeriodSec;
-    legacy_request->scan_params_val
-        .dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] =
-        hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-            .dwellTimeMs;
-    legacy_request->scan_params_val
-        .scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] =
-        hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-            .scanPeriodSec;
+            hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].rssiCloseProximity;
+    legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] =
+            hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].dwellTimeMs;
+    legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_LOW] =
+            hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].scanPeriodSec;
+    legacy_request->scan_params_val.dwell_time[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] =
+            hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].dwellTimeMs;
+    legacy_request->scan_params_val.scan_period[legacy_hal::NAN_CHANNEL_5G_BAND_HIGH] =
+            hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ].scanPeriodSec;
     legacy_request->config_dw.config_5g_dw_band =
-        hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-            .validDiscoveryWindowIntervalVal;
+            hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+                    .validDiscoveryWindowIntervalVal;
     legacy_request->config_dw.dw_5g_interval_val =
-        hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
-            .discoveryWindowIntervalVal;
+            hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
+                    .discoveryWindowIntervalVal;
     /* TODO: b/145609058
      * Missing updates needed to legacy_hal::NanConfigRequest and conversion to
      * it for 6GHz band */
@@ -2051,10 +1835,9 @@
     return true;
 }
 
-bool convertHidlNanConfigRequest_1_4ToLegacy(
-    const V1_4::NanConfigRequest& hidl_request1,
-    const NanConfigRequestSupplemental& hidl_request2,
-    legacy_hal::NanConfigRequest* legacy_request) {
+bool convertHidlNanConfigRequest_1_4ToLegacy(const V1_4::NanConfigRequest& hidl_request1,
+                                             const NanConfigRequestSupplemental& hidl_request2,
+                                             legacy_hal::NanConfigRequest* legacy_request) {
     if (!legacy_request) {
         LOG(ERROR) << "convertHidlNanConfigRequest_1_4ToLegacy: legacy_request "
                       "is null";
@@ -2067,13 +1850,12 @@
     }
 
     legacy_request->config_discovery_beacon_int = 1;
-    legacy_request->discovery_beacon_interval =
-        hidl_request2.V1_2.discoveryBeaconIntervalMs;
+    legacy_request->discovery_beacon_interval = hidl_request2.V1_2.discoveryBeaconIntervalMs;
     legacy_request->config_nss = 1;
     legacy_request->nss = hidl_request2.V1_2.numberOfSpatialStreamsInDiscovery;
     legacy_request->config_dw_early_termination = 1;
     legacy_request->enable_dw_termination =
-        hidl_request2.V1_2.enableDiscoveryWindowEarlyTermination;
+            hidl_request2.V1_2.enableDiscoveryWindowEarlyTermination;
     legacy_request->config_enable_ranging = 1;
     legacy_request->enable_ranging = hidl_request2.V1_2.enableRanging;
 
@@ -2081,8 +1863,8 @@
 }
 
 bool convertHidlNanDataPathInitiatorRequestToLegacy(
-    const NanInitiateDataPathRequest& hidl_request,
-    legacy_hal::NanDataPathInitiatorRequest* legacy_request) {
+        const NanInitiateDataPathRequest& hidl_request,
+        legacy_hal::NanDataPathInitiatorRequest* legacy_request) {
     if (!legacy_request) {
         LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: "
                       "legacy_request is null";
@@ -2091,24 +1873,20 @@
     *legacy_request = {};
 
     legacy_request->requestor_instance_id = hidl_request.peerId;
-    memcpy(legacy_request->peer_disc_mac_addr,
-           hidl_request.peerDiscMacAddr.data(), 6);
+    memcpy(legacy_request->peer_disc_mac_addr, hidl_request.peerDiscMacAddr.data(), 6);
     legacy_request->channel_request_type =
-        convertHidlNanDataPathChannelCfgToLegacy(
-            hidl_request.channelRequestType);
+            convertHidlNanDataPathChannelCfgToLegacy(hidl_request.channelRequestType);
     legacy_request->channel = hidl_request.channel;
     if (strnlen(hidl_request.ifaceName.c_str(), IFNAMSIZ + 1) == IFNAMSIZ + 1) {
         LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: "
                       "ifaceName too long";
         return false;
     }
-    strncpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str(),
-            IFNAMSIZ + 1);
+    strncpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str(), IFNAMSIZ + 1);
     legacy_request->ndp_cfg.security_cfg =
-        (hidl_request.securityConfig.securityType !=
-         NanDataPathSecurityType::OPEN)
-            ? legacy_hal::NAN_DP_CONFIG_SECURITY
-            : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
+            (hidl_request.securityConfig.securityType != NanDataPathSecurityType::OPEN)
+                    ? legacy_hal::NAN_DP_CONFIG_SECURITY
+                    : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
     legacy_request->app_info.ndp_app_info_len = hidl_request.appInfo.size();
     if (legacy_request->app_info.ndp_app_info_len > NAN_DP_MAX_APP_INFO_LEN) {
         LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: "
@@ -2117,30 +1895,22 @@
     }
     memcpy(legacy_request->app_info.ndp_app_info, hidl_request.appInfo.data(),
            legacy_request->app_info.ndp_app_info_len);
-    legacy_request->cipher_type =
-        (unsigned int)hidl_request.securityConfig.cipherType;
-    if (hidl_request.securityConfig.securityType ==
-        NanDataPathSecurityType::PMK) {
-        legacy_request->key_info.key_type =
-            legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
-        legacy_request->key_info.body.pmk_info.pmk_len =
-            hidl_request.securityConfig.pmk.size();
-        if (legacy_request->key_info.body.pmk_info.pmk_len !=
-            NAN_PMK_INFO_LEN) {
+    legacy_request->cipher_type = (unsigned int)hidl_request.securityConfig.cipherType;
+    if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PMK) {
+        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
+        legacy_request->key_info.body.pmk_info.pmk_len = hidl_request.securityConfig.pmk.size();
+        if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
             LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: "
                           "invalid pmk_len";
             return false;
         }
-        memcpy(legacy_request->key_info.body.pmk_info.pmk,
-               hidl_request.securityConfig.pmk.data(),
+        memcpy(legacy_request->key_info.body.pmk_info.pmk, hidl_request.securityConfig.pmk.data(),
                legacy_request->key_info.body.pmk_info.pmk_len);
     }
-    if (hidl_request.securityConfig.securityType ==
-        NanDataPathSecurityType::PASSPHRASE) {
-        legacy_request->key_info.key_type =
-            legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+    if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PASSPHRASE) {
+        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
         legacy_request->key_info.body.passphrase_info.passphrase_len =
-            hidl_request.securityConfig.passphrase.size();
+                hidl_request.securityConfig.passphrase.size();
         if (legacy_request->key_info.body.passphrase_info.passphrase_len <
             NAN_SECURITY_MIN_PASSPHRASE_LEN) {
             LOG(ERROR) << "convertHidlNanDataPathInitiatorRequestToLegacy: "
@@ -2163,16 +1933,15 @@
                       "service_name_len too large";
         return false;
     }
-    memcpy(legacy_request->service_name,
-           hidl_request.serviceNameOutOfBand.data(),
+    memcpy(legacy_request->service_name, hidl_request.serviceNameOutOfBand.data(),
            legacy_request->service_name_len);
 
     return true;
 }
 
 bool convertHidlNanDataPathIndicationResponseToLegacy(
-    const NanRespondToDataPathIndicationRequest& hidl_request,
-    legacy_hal::NanDataPathIndicationResponse* legacy_request) {
+        const NanRespondToDataPathIndicationRequest& hidl_request,
+        legacy_hal::NanDataPathIndicationResponse* legacy_request) {
     if (!legacy_request) {
         LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: "
                       "legacy_request is null";
@@ -2180,22 +1949,19 @@
     }
     *legacy_request = {};
 
-    legacy_request->rsp_code = hidl_request.acceptRequest
-                                   ? legacy_hal::NAN_DP_REQUEST_ACCEPT
-                                   : legacy_hal::NAN_DP_REQUEST_REJECT;
+    legacy_request->rsp_code = hidl_request.acceptRequest ? legacy_hal::NAN_DP_REQUEST_ACCEPT
+                                                          : legacy_hal::NAN_DP_REQUEST_REJECT;
     legacy_request->ndp_instance_id = hidl_request.ndpInstanceId;
     if (strnlen(hidl_request.ifaceName.c_str(), IFNAMSIZ + 1) == IFNAMSIZ + 1) {
         LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: "
                       "ifaceName too long";
         return false;
     }
-    strncpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str(),
-            IFNAMSIZ + 1);
+    strncpy(legacy_request->ndp_iface, hidl_request.ifaceName.c_str(), IFNAMSIZ + 1);
     legacy_request->ndp_cfg.security_cfg =
-        (hidl_request.securityConfig.securityType !=
-         NanDataPathSecurityType::OPEN)
-            ? legacy_hal::NAN_DP_CONFIG_SECURITY
-            : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
+            (hidl_request.securityConfig.securityType != NanDataPathSecurityType::OPEN)
+                    ? legacy_hal::NAN_DP_CONFIG_SECURITY
+                    : legacy_hal::NAN_DP_CONFIG_NO_SECURITY;
     legacy_request->app_info.ndp_app_info_len = hidl_request.appInfo.size();
     if (legacy_request->app_info.ndp_app_info_len > NAN_DP_MAX_APP_INFO_LEN) {
         LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: "
@@ -2204,30 +1970,22 @@
     }
     memcpy(legacy_request->app_info.ndp_app_info, hidl_request.appInfo.data(),
            legacy_request->app_info.ndp_app_info_len);
-    legacy_request->cipher_type =
-        (unsigned int)hidl_request.securityConfig.cipherType;
-    if (hidl_request.securityConfig.securityType ==
-        NanDataPathSecurityType::PMK) {
-        legacy_request->key_info.key_type =
-            legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
-        legacy_request->key_info.body.pmk_info.pmk_len =
-            hidl_request.securityConfig.pmk.size();
-        if (legacy_request->key_info.body.pmk_info.pmk_len !=
-            NAN_PMK_INFO_LEN) {
+    legacy_request->cipher_type = (unsigned int)hidl_request.securityConfig.cipherType;
+    if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PMK) {
+        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PMK;
+        legacy_request->key_info.body.pmk_info.pmk_len = hidl_request.securityConfig.pmk.size();
+        if (legacy_request->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) {
             LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: "
                           "invalid pmk_len";
             return false;
         }
-        memcpy(legacy_request->key_info.body.pmk_info.pmk,
-               hidl_request.securityConfig.pmk.data(),
+        memcpy(legacy_request->key_info.body.pmk_info.pmk, hidl_request.securityConfig.pmk.data(),
                legacy_request->key_info.body.pmk_info.pmk_len);
     }
-    if (hidl_request.securityConfig.securityType ==
-        NanDataPathSecurityType::PASSPHRASE) {
-        legacy_request->key_info.key_type =
-            legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
+    if (hidl_request.securityConfig.securityType == NanDataPathSecurityType::PASSPHRASE) {
+        legacy_request->key_info.key_type = legacy_hal::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
         legacy_request->key_info.body.passphrase_info.passphrase_len =
-            hidl_request.securityConfig.passphrase.size();
+                hidl_request.securityConfig.passphrase.size();
         if (legacy_request->key_info.body.passphrase_info.passphrase_len <
             NAN_SECURITY_MIN_PASSPHRASE_LEN) {
             LOG(ERROR) << "convertHidlNanDataPathIndicationResponseToLegacy: "
@@ -2250,19 +2008,16 @@
                       "service_name_len too large";
         return false;
     }
-    memcpy(legacy_request->service_name,
-           hidl_request.serviceNameOutOfBand.data(),
+    memcpy(legacy_request->service_name, hidl_request.serviceNameOutOfBand.data(),
            legacy_request->service_name_len);
 
     return true;
 }
 
-bool convertLegacyNanResponseHeaderToHidl(
-    const legacy_hal::NanResponseMsg& legacy_response,
-    WifiNanStatus* wifiNanStatus) {
+bool convertLegacyNanResponseHeaderToHidl(const legacy_hal::NanResponseMsg& legacy_response,
+                                          WifiNanStatus* wifiNanStatus) {
     if (!wifiNanStatus) {
-        LOG(ERROR)
-            << "convertLegacyNanResponseHeaderToHidl: wifiNanStatus is null";
+        LOG(ERROR) << "convertLegacyNanResponseHeaderToHidl: wifiNanStatus is null";
         return false;
     }
     *wifiNanStatus = {};
@@ -2272,9 +2027,8 @@
     return true;
 }
 
-bool convertLegacyNanCapabilitiesResponseToHidl(
-    const legacy_hal::NanCapabilities& legacy_response,
-    NanCapabilities* hidl_response) {
+bool convertLegacyNanCapabilitiesResponseToHidl(const legacy_hal::NanCapabilities& legacy_response,
+                                                V1_5::NanCapabilities* hidl_response) {
     if (!hidl_response) {
         LOG(ERROR) << "convertLegacyNanCapabilitiesResponseToHidl: "
                       "hidl_response is null";
@@ -2282,31 +2036,23 @@
     }
     *hidl_response = {};
 
-    hidl_response->V1_0.maxConcurrentClusters =
-        legacy_response.max_concurrent_nan_clusters;
+    hidl_response->V1_0.maxConcurrentClusters = legacy_response.max_concurrent_nan_clusters;
     hidl_response->V1_0.maxPublishes = legacy_response.max_publishes;
     hidl_response->V1_0.maxSubscribes = legacy_response.max_subscribes;
-    hidl_response->V1_0.maxServiceNameLen =
-        legacy_response.max_service_name_len;
-    hidl_response->V1_0.maxMatchFilterLen =
-        legacy_response.max_match_filter_len;
-    hidl_response->V1_0.maxTotalMatchFilterLen =
-        legacy_response.max_total_match_filter_len;
-    hidl_response->V1_0.maxServiceSpecificInfoLen =
-        legacy_response.max_service_specific_info_len;
+    hidl_response->V1_0.maxServiceNameLen = legacy_response.max_service_name_len;
+    hidl_response->V1_0.maxMatchFilterLen = legacy_response.max_match_filter_len;
+    hidl_response->V1_0.maxTotalMatchFilterLen = legacy_response.max_total_match_filter_len;
+    hidl_response->V1_0.maxServiceSpecificInfoLen = legacy_response.max_service_specific_info_len;
     hidl_response->V1_0.maxExtendedServiceSpecificInfoLen =
-        legacy_response.max_sdea_service_specific_info_len;
+            legacy_response.max_sdea_service_specific_info_len;
     hidl_response->V1_0.maxNdiInterfaces = legacy_response.max_ndi_interfaces;
     hidl_response->V1_0.maxNdpSessions = legacy_response.max_ndp_sessions;
     hidl_response->V1_0.maxAppInfoLen = legacy_response.max_app_info_len;
     hidl_response->V1_0.maxQueuedTransmitFollowupMsgs =
-        legacy_response.max_queued_transmit_followup_msgs;
-    hidl_response->V1_0.maxSubscribeInterfaceAddresses =
-        legacy_response.max_subscribe_address;
-    hidl_response->V1_0.supportedCipherSuites =
-        legacy_response.cipher_suites_supported;
-    hidl_response->instantCommunicationModeSupportFlag =
-        legacy_response.is_instant_mode_supported;
+            legacy_response.max_queued_transmit_followup_msgs;
+    hidl_response->V1_0.maxSubscribeInterfaceAddresses = legacy_response.max_subscribe_address;
+    hidl_response->V1_0.supportedCipherSuites = legacy_response.cipher_suites_supported;
+    hidl_response->instantCommunicationModeSupportFlag = legacy_response.is_instant_mode_supported;
 
     return true;
 }
@@ -2322,36 +2068,31 @@
     hidl_ind->discoverySessionId = legacy_ind.publish_subscribe_id;
     hidl_ind->peerId = legacy_ind.requestor_instance_id;
     hidl_ind->addr = hidl_array<uint8_t, 6>(legacy_ind.addr);
-    hidl_ind->serviceSpecificInfo =
-        std::vector<uint8_t>(legacy_ind.service_specific_info,
-                             legacy_ind.service_specific_info +
-                                 legacy_ind.service_specific_info_len);
-    hidl_ind->extendedServiceSpecificInfo =
-        std::vector<uint8_t>(legacy_ind.sdea_service_specific_info,
-                             legacy_ind.sdea_service_specific_info +
-                                 legacy_ind.sdea_service_specific_info_len);
-    hidl_ind->matchFilter = std::vector<uint8_t>(
-        legacy_ind.sdf_match_filter,
-        legacy_ind.sdf_match_filter + legacy_ind.sdf_match_filter_len);
+    hidl_ind->serviceSpecificInfo = std::vector<uint8_t>(
+            legacy_ind.service_specific_info,
+            legacy_ind.service_specific_info + legacy_ind.service_specific_info_len);
+    hidl_ind->extendedServiceSpecificInfo = std::vector<uint8_t>(
+            legacy_ind.sdea_service_specific_info,
+            legacy_ind.sdea_service_specific_info + legacy_ind.sdea_service_specific_info_len);
+    hidl_ind->matchFilter =
+            std::vector<uint8_t>(legacy_ind.sdf_match_filter,
+                                 legacy_ind.sdf_match_filter + legacy_ind.sdf_match_filter_len);
     hidl_ind->matchOccuredInBeaconFlag = legacy_ind.match_occured_flag == 1;
     hidl_ind->outOfResourceFlag = legacy_ind.out_of_resource_flag == 1;
     hidl_ind->rssiValue = legacy_ind.rssi_value;
     hidl_ind->peerCipherType = (NanCipherSuiteType)legacy_ind.peer_cipher_type;
     hidl_ind->peerRequiresSecurityEnabledInNdp =
-        legacy_ind.peer_sdea_params.security_cfg ==
-        legacy_hal::NAN_DP_CONFIG_SECURITY;
-    hidl_ind->peerRequiresRanging = legacy_ind.peer_sdea_params.ranging_state ==
-                                    legacy_hal::NAN_RANGING_ENABLE;
-    hidl_ind->rangingMeasurementInCm =
-        legacy_ind.range_info.range_measurement_mm / 10;
+            legacy_ind.peer_sdea_params.security_cfg == legacy_hal::NAN_DP_CONFIG_SECURITY;
+    hidl_ind->peerRequiresRanging =
+            legacy_ind.peer_sdea_params.ranging_state == legacy_hal::NAN_RANGING_ENABLE;
+    hidl_ind->rangingMeasurementInCm = legacy_ind.range_info.range_measurement_mm / 10;
     hidl_ind->rangingIndicationType = legacy_ind.range_info.ranging_event_type;
 
     return true;
 }
 
-bool convertLegacyNanFollowupIndToHidl(
-    const legacy_hal::NanFollowupInd& legacy_ind,
-    NanFollowupReceivedInd* hidl_ind) {
+bool convertLegacyNanFollowupIndToHidl(const legacy_hal::NanFollowupInd& legacy_ind,
+                                       NanFollowupReceivedInd* hidl_ind) {
     if (!hidl_ind) {
         LOG(ERROR) << "convertLegacyNanFollowupIndToHidl: hidl_ind is null";
         return false;
@@ -2362,45 +2103,38 @@
     hidl_ind->peerId = legacy_ind.requestor_instance_id;
     hidl_ind->addr = hidl_array<uint8_t, 6>(legacy_ind.addr);
     hidl_ind->receivedInFaw = legacy_ind.dw_or_faw == 1;
-    hidl_ind->serviceSpecificInfo =
-        std::vector<uint8_t>(legacy_ind.service_specific_info,
-                             legacy_ind.service_specific_info +
-                                 legacy_ind.service_specific_info_len);
-    hidl_ind->extendedServiceSpecificInfo =
-        std::vector<uint8_t>(legacy_ind.sdea_service_specific_info,
-                             legacy_ind.sdea_service_specific_info +
-                                 legacy_ind.sdea_service_specific_info_len);
+    hidl_ind->serviceSpecificInfo = std::vector<uint8_t>(
+            legacy_ind.service_specific_info,
+            legacy_ind.service_specific_info + legacy_ind.service_specific_info_len);
+    hidl_ind->extendedServiceSpecificInfo = std::vector<uint8_t>(
+            legacy_ind.sdea_service_specific_info,
+            legacy_ind.sdea_service_specific_info + legacy_ind.sdea_service_specific_info_len);
 
     return true;
 }
 
-bool convertLegacyNanDataPathRequestIndToHidl(
-    const legacy_hal::NanDataPathRequestInd& legacy_ind,
-    NanDataPathRequestInd* hidl_ind) {
+bool convertLegacyNanDataPathRequestIndToHidl(const legacy_hal::NanDataPathRequestInd& legacy_ind,
+                                              NanDataPathRequestInd* hidl_ind) {
     if (!hidl_ind) {
-        LOG(ERROR)
-            << "convertLegacyNanDataPathRequestIndToHidl: hidl_ind is null";
+        LOG(ERROR) << "convertLegacyNanDataPathRequestIndToHidl: hidl_ind is null";
         return false;
     }
     *hidl_ind = {};
 
     hidl_ind->discoverySessionId = legacy_ind.service_instance_id;
-    hidl_ind->peerDiscMacAddr =
-        hidl_array<uint8_t, 6>(legacy_ind.peer_disc_mac_addr);
+    hidl_ind->peerDiscMacAddr = hidl_array<uint8_t, 6>(legacy_ind.peer_disc_mac_addr);
     hidl_ind->ndpInstanceId = legacy_ind.ndp_instance_id;
     hidl_ind->securityRequired =
-        legacy_ind.ndp_cfg.security_cfg == legacy_hal::NAN_DP_CONFIG_SECURITY;
-    hidl_ind->appInfo =
-        std::vector<uint8_t>(legacy_ind.app_info.ndp_app_info,
-                             legacy_ind.app_info.ndp_app_info +
-                                 legacy_ind.app_info.ndp_app_info_len);
+            legacy_ind.ndp_cfg.security_cfg == legacy_hal::NAN_DP_CONFIG_SECURITY;
+    hidl_ind->appInfo = std::vector<uint8_t>(
+            legacy_ind.app_info.ndp_app_info,
+            legacy_ind.app_info.ndp_app_info + legacy_ind.app_info.ndp_app_info_len);
 
     return true;
 }
 
-bool convertLegacyNdpChannelInfoToHidl(
-    const legacy_hal::NanChannelInfo& legacy_struct,
-    V1_2::NanDataPathChannelInfo* hidl_struct) {
+bool convertLegacyNdpChannelInfoToHidl(const legacy_hal::NanChannelInfo& legacy_struct,
+                                       V1_2::NanDataPathChannelInfo* hidl_struct) {
     if (!hidl_struct) {
         LOG(ERROR) << "convertLegacyNdpChannelInfoToHidl: hidl_struct is null";
         return false;
@@ -2409,40 +2143,33 @@
 
     hidl_struct->channelFreq = legacy_struct.channel;
     hidl_struct->channelBandwidth = convertLegacyWifiChannelWidthToHidl(
-        (legacy_hal::wifi_channel_width)legacy_struct.bandwidth);
+            (legacy_hal::wifi_channel_width)legacy_struct.bandwidth);
     hidl_struct->numSpatialStreams = legacy_struct.nss;
 
     return true;
 }
 
-bool convertLegacyNanDataPathConfirmIndToHidl(
-    const legacy_hal::NanDataPathConfirmInd& legacy_ind,
-    V1_2::NanDataPathConfirmInd* hidl_ind) {
+bool convertLegacyNanDataPathConfirmIndToHidl(const legacy_hal::NanDataPathConfirmInd& legacy_ind,
+                                              V1_2::NanDataPathConfirmInd* hidl_ind) {
     if (!hidl_ind) {
-        LOG(ERROR)
-            << "convertLegacyNanDataPathConfirmIndToHidl: hidl_ind is null";
+        LOG(ERROR) << "convertLegacyNanDataPathConfirmIndToHidl: hidl_ind is null";
         return false;
     }
     *hidl_ind = {};
 
     hidl_ind->V1_0.ndpInstanceId = legacy_ind.ndp_instance_id;
-    hidl_ind->V1_0.dataPathSetupSuccess =
-        legacy_ind.rsp_code == legacy_hal::NAN_DP_REQUEST_ACCEPT;
-    hidl_ind->V1_0.peerNdiMacAddr =
-        hidl_array<uint8_t, 6>(legacy_ind.peer_ndi_mac_addr);
-    hidl_ind->V1_0.appInfo =
-        std::vector<uint8_t>(legacy_ind.app_info.ndp_app_info,
-                             legacy_ind.app_info.ndp_app_info +
-                                 legacy_ind.app_info.ndp_app_info_len);
-    hidl_ind->V1_0.status.status =
-        convertLegacyNanStatusTypeToHidl(legacy_ind.reason_code);
+    hidl_ind->V1_0.dataPathSetupSuccess = legacy_ind.rsp_code == legacy_hal::NAN_DP_REQUEST_ACCEPT;
+    hidl_ind->V1_0.peerNdiMacAddr = hidl_array<uint8_t, 6>(legacy_ind.peer_ndi_mac_addr);
+    hidl_ind->V1_0.appInfo = std::vector<uint8_t>(
+            legacy_ind.app_info.ndp_app_info,
+            legacy_ind.app_info.ndp_app_info + legacy_ind.app_info.ndp_app_info_len);
+    hidl_ind->V1_0.status.status = convertLegacyNanStatusTypeToHidl(legacy_ind.reason_code);
     hidl_ind->V1_0.status.description = "";  // TODO: b/34059183
 
     std::vector<V1_2::NanDataPathChannelInfo> channelInfo;
     for (unsigned int i = 0; i < legacy_ind.num_channels; ++i) {
         V1_2::NanDataPathChannelInfo hidl_struct;
-        if (!convertLegacyNdpChannelInfoToHidl(legacy_ind.channel_info[i],
-                                               &hidl_struct)) {
+        if (!convertLegacyNdpChannelInfoToHidl(legacy_ind.channel_info[i], &hidl_struct)) {
             return false;
         }
         channelInfo.push_back(hidl_struct);
@@ -2453,8 +2180,8 @@
 }
 
 bool convertLegacyNanDataPathScheduleUpdateIndToHidl(
-    const legacy_hal::NanDataPathScheduleUpdateInd& legacy_ind,
-    V1_2::NanDataPathScheduleUpdateInd* hidl_ind) {
+        const legacy_hal::NanDataPathScheduleUpdateInd& legacy_ind,
+        V1_2::NanDataPathScheduleUpdateInd* hidl_ind) {
     if (!hidl_ind) {
         LOG(ERROR) << "convertLegacyNanDataPathScheduleUpdateIndToHidl: "
                       "hidl_ind is null";
@@ -2462,13 +2189,11 @@
     }
     *hidl_ind = {};
 
-    hidl_ind->peerDiscoveryAddress =
-        hidl_array<uint8_t, 6>(legacy_ind.peer_mac_addr);
+    hidl_ind->peerDiscoveryAddress = hidl_array<uint8_t, 6>(legacy_ind.peer_mac_addr);
     std::vector<V1_2::NanDataPathChannelInfo> channelInfo;
     for (unsigned int i = 0; i < legacy_ind.num_channels; ++i) {
         V1_2::NanDataPathChannelInfo hidl_struct;
-        if (!convertLegacyNdpChannelInfoToHidl(legacy_ind.channel_info[i],
-                                               &hidl_struct)) {
+        if (!convertLegacyNdpChannelInfoToHidl(legacy_ind.channel_info[i], &hidl_struct)) {
             return false;
         }
         channelInfo.push_back(hidl_struct);
@@ -2519,8 +2244,7 @@
     CHECK(false);
 }
 
-legacy_hal::wifi_channel_width convertHidlWifiChannelWidthToLegacy(
-    WifiChannelWidthInMhz type) {
+legacy_hal::wifi_channel_width convertHidlWifiChannelWidthToLegacy(WifiChannelWidthInMhz type) {
     switch (type) {
         case WifiChannelWidthInMhz::WIDTH_20:
             return legacy_hal::WIFI_CHAN_WIDTH_20;
@@ -2542,8 +2266,7 @@
     CHECK(false);
 }
 
-WifiChannelWidthInMhz convertLegacyWifiChannelWidthToHidl(
-    legacy_hal::wifi_channel_width type) {
+WifiChannelWidthInMhz convertLegacyWifiChannelWidthToHidl(legacy_hal::wifi_channel_width type) {
     switch (type) {
         case legacy_hal::WIFI_CHAN_WIDTH_20:
             return WifiChannelWidthInMhz::WIDTH_20;
@@ -2564,8 +2287,7 @@
     };
 }
 
-legacy_hal::wifi_rtt_preamble convertHidlRttPreambleToLegacy(
-    V1_4::RttPreamble type) {
+legacy_hal::wifi_rtt_preamble convertHidlRttPreambleToLegacy(V1_4::RttPreamble type) {
     switch (type) {
         case V1_4::RttPreamble::LEGACY:
             return legacy_hal::WIFI_RTT_PREAMBLE_LEGACY;
@@ -2579,8 +2301,7 @@
     CHECK(false);
 }
 
-V1_4::RttPreamble convertLegacyRttPreambleToHidl(
-    legacy_hal::wifi_rtt_preamble type) {
+V1_4::RttPreamble convertLegacyRttPreambleToHidl(legacy_hal::wifi_rtt_preamble type) {
     switch (type) {
         case legacy_hal::WIFI_RTT_PREAMBLE_LEGACY:
             return V1_4::RttPreamble::LEGACY;
@@ -2630,8 +2351,7 @@
     CHECK(false) << "Unknown legacy type: " << type;
 }
 
-legacy_hal::wifi_motion_pattern convertHidlRttMotionPatternToLegacy(
-    RttMotionPattern type) {
+legacy_hal::wifi_motion_pattern convertHidlRttMotionPatternToLegacy(RttMotionPattern type) {
     switch (type) {
         case RttMotionPattern::NOT_EXPECTED:
             return legacy_hal::WIFI_MOTION_NOT_EXPECTED;
@@ -2718,9 +2438,8 @@
     CHECK(false) << "Unknown legacy status: " << status;
 }
 
-bool convertHidlWifiChannelInfoToLegacy(
-    const WifiChannelInfo& hidl_info,
-    legacy_hal::wifi_channel_info* legacy_info) {
+bool convertHidlWifiChannelInfoToLegacy(const WifiChannelInfo& hidl_info,
+                                        legacy_hal::wifi_channel_info* legacy_info) {
     if (!legacy_info) {
         return false;
     }
@@ -2732,9 +2451,8 @@
     return true;
 }
 
-bool convertLegacyWifiChannelInfoToHidl(
-    const legacy_hal::wifi_channel_info& legacy_info,
-    WifiChannelInfo* hidl_info) {
+bool convertLegacyWifiChannelInfoToHidl(const legacy_hal::wifi_channel_info& legacy_info,
+                                        WifiChannelInfo* hidl_info) {
     if (!hidl_info) {
         return false;
     }
@@ -2753,32 +2471,28 @@
     }
     *legacy_config = {};
     CHECK(hidl_config.addr.size() == sizeof(legacy_config->addr));
-    memcpy(legacy_config->addr, hidl_config.addr.data(),
-           hidl_config.addr.size());
+    memcpy(legacy_config->addr, hidl_config.addr.data(), hidl_config.addr.size());
     legacy_config->type = convertHidlRttTypeToLegacy(hidl_config.type);
     legacy_config->peer = convertHidlRttPeerTypeToLegacy(hidl_config.peer);
-    if (!convertHidlWifiChannelInfoToLegacy(hidl_config.channel,
-                                            &legacy_config->channel)) {
+    if (!convertHidlWifiChannelInfoToLegacy(hidl_config.channel, &legacy_config->channel)) {
         return false;
     }
     legacy_config->burst_period = hidl_config.burstPeriod;
     legacy_config->num_burst = hidl_config.numBurst;
     legacy_config->num_frames_per_burst = hidl_config.numFramesPerBurst;
-    legacy_config->num_retries_per_rtt_frame =
-        hidl_config.numRetriesPerRttFrame;
+    legacy_config->num_retries_per_rtt_frame = hidl_config.numRetriesPerRttFrame;
     legacy_config->num_retries_per_ftmr = hidl_config.numRetriesPerFtmr;
     legacy_config->LCI_request = hidl_config.mustRequestLci;
     legacy_config->LCR_request = hidl_config.mustRequestLcr;
     legacy_config->burst_duration = hidl_config.burstDuration;
-    legacy_config->preamble =
-        convertHidlRttPreambleToLegacy(hidl_config.preamble);
+    legacy_config->preamble = convertHidlRttPreambleToLegacy(hidl_config.preamble);
     legacy_config->bw = convertHidlRttBwToLegacy(hidl_config.bw);
     return true;
 }
 
 bool convertHidlVectorOfRttConfigToLegacy(
-    const std::vector<V1_4::RttConfig>& hidl_configs,
-    std::vector<legacy_hal::wifi_rtt_config>* legacy_configs) {
+        const std::vector<V1_4::RttConfig>& hidl_configs,
+        std::vector<legacy_hal::wifi_rtt_config>* legacy_configs) {
     if (!legacy_configs) {
         return false;
     }
@@ -2793,9 +2507,8 @@
     return true;
 }
 
-bool convertHidlRttLciInformationToLegacy(
-    const RttLciInformation& hidl_info,
-    legacy_hal::wifi_lci_information* legacy_info) {
+bool convertHidlRttLciInformationToLegacy(const RttLciInformation& hidl_info,
+                                          legacy_hal::wifi_lci_information* legacy_info) {
     if (!legacy_info) {
         return false;
     }
@@ -2806,99 +2519,83 @@
     legacy_info->latitude_unc = hidl_info.latitudeUnc;
     legacy_info->longitude_unc = hidl_info.longitudeUnc;
     legacy_info->altitude_unc = hidl_info.altitudeUnc;
-    legacy_info->motion_pattern =
-        convertHidlRttMotionPatternToLegacy(hidl_info.motionPattern);
+    legacy_info->motion_pattern = convertHidlRttMotionPatternToLegacy(hidl_info.motionPattern);
     legacy_info->floor = hidl_info.floor;
     legacy_info->height_above_floor = hidl_info.heightAboveFloor;
     legacy_info->height_unc = hidl_info.heightUnc;
     return true;
 }
 
-bool convertHidlRttLcrInformationToLegacy(
-    const RttLcrInformation& hidl_info,
-    legacy_hal::wifi_lcr_information* legacy_info) {
+bool convertHidlRttLcrInformationToLegacy(const RttLcrInformation& hidl_info,
+                                          legacy_hal::wifi_lcr_information* legacy_info) {
     if (!legacy_info) {
         return false;
     }
     *legacy_info = {};
     CHECK(hidl_info.countryCode.size() == sizeof(legacy_info->country_code));
-    memcpy(legacy_info->country_code, hidl_info.countryCode.data(),
-           hidl_info.countryCode.size());
+    memcpy(legacy_info->country_code, hidl_info.countryCode.data(), hidl_info.countryCode.size());
     if (hidl_info.civicInfo.size() > sizeof(legacy_info->civic_info)) {
         return false;
     }
     legacy_info->length = hidl_info.civicInfo.size();
-    memcpy(legacy_info->civic_info, hidl_info.civicInfo.c_str(),
-           hidl_info.civicInfo.size());
+    memcpy(legacy_info->civic_info, hidl_info.civicInfo.c_str(), hidl_info.civicInfo.size());
     return true;
 }
 
-bool convertHidlRttResponderToLegacy(
-    const V1_4::RttResponder& hidl_responder,
-    legacy_hal::wifi_rtt_responder* legacy_responder) {
+bool convertHidlRttResponderToLegacy(const V1_4::RttResponder& hidl_responder,
+                                     legacy_hal::wifi_rtt_responder* legacy_responder) {
     if (!legacy_responder) {
         return false;
     }
     *legacy_responder = {};
-    if (!convertHidlWifiChannelInfoToLegacy(hidl_responder.channel,
-                                            &legacy_responder->channel)) {
+    if (!convertHidlWifiChannelInfoToLegacy(hidl_responder.channel, &legacy_responder->channel)) {
         return false;
     }
-    legacy_responder->preamble =
-        convertHidlRttPreambleToLegacy(hidl_responder.preamble);
+    legacy_responder->preamble = convertHidlRttPreambleToLegacy(hidl_responder.preamble);
     return true;
 }
 
-bool convertLegacyRttResponderToHidl(
-    const legacy_hal::wifi_rtt_responder& legacy_responder,
-    V1_4::RttResponder* hidl_responder) {
+bool convertLegacyRttResponderToHidl(const legacy_hal::wifi_rtt_responder& legacy_responder,
+                                     V1_4::RttResponder* hidl_responder) {
     if (!hidl_responder) {
         return false;
     }
     *hidl_responder = {};
-    if (!convertLegacyWifiChannelInfoToHidl(legacy_responder.channel,
-                                            &hidl_responder->channel)) {
+    if (!convertLegacyWifiChannelInfoToHidl(legacy_responder.channel, &hidl_responder->channel)) {
         return false;
     }
-    hidl_responder->preamble =
-        convertLegacyRttPreambleToHidl(legacy_responder.preamble);
+    hidl_responder->preamble = convertLegacyRttPreambleToHidl(legacy_responder.preamble);
     return true;
 }
 
 bool convertLegacyRttCapabilitiesToHidl(
-    const legacy_hal::wifi_rtt_capabilities& legacy_capabilities,
-    V1_4::RttCapabilities* hidl_capabilities) {
+        const legacy_hal::wifi_rtt_capabilities& legacy_capabilities,
+        V1_4::RttCapabilities* hidl_capabilities) {
     if (!hidl_capabilities) {
         return false;
     }
     *hidl_capabilities = {};
-    hidl_capabilities->rttOneSidedSupported =
-        legacy_capabilities.rtt_one_sided_supported;
+    hidl_capabilities->rttOneSidedSupported = legacy_capabilities.rtt_one_sided_supported;
     hidl_capabilities->rttFtmSupported = legacy_capabilities.rtt_ftm_supported;
     hidl_capabilities->lciSupported = legacy_capabilities.lci_support;
     hidl_capabilities->lcrSupported = legacy_capabilities.lcr_support;
-    hidl_capabilities->responderSupported =
-        legacy_capabilities.responder_supported;
+    hidl_capabilities->responderSupported = legacy_capabilities.responder_supported;
     hidl_capabilities->preambleSupport = 0;
-    for (const auto flag :
-         {legacy_hal::WIFI_RTT_PREAMBLE_LEGACY,
-          legacy_hal::WIFI_RTT_PREAMBLE_HT, legacy_hal::WIFI_RTT_PREAMBLE_VHT,
-          legacy_hal::WIFI_RTT_PREAMBLE_HE}) {
+    for (const auto flag : {legacy_hal::WIFI_RTT_PREAMBLE_LEGACY, legacy_hal::WIFI_RTT_PREAMBLE_HT,
+                            legacy_hal::WIFI_RTT_PREAMBLE_VHT, legacy_hal::WIFI_RTT_PREAMBLE_HE}) {
         if (legacy_capabilities.preamble_support & flag) {
             hidl_capabilities->preambleSupport |=
-                static_cast<std::underlying_type<V1_4::RttPreamble>::type>(
-                    convertLegacyRttPreambleToHidl(flag));
+                    static_cast<std::underlying_type<V1_4::RttPreamble>::type>(
+                            convertLegacyRttPreambleToHidl(flag));
         }
     }
     hidl_capabilities->bwSupport = 0;
     for (const auto flag :
-         {legacy_hal::WIFI_RTT_BW_5, legacy_hal::WIFI_RTT_BW_10,
-          legacy_hal::WIFI_RTT_BW_20, legacy_hal::WIFI_RTT_BW_40,
-          legacy_hal::WIFI_RTT_BW_80, legacy_hal::WIFI_RTT_BW_160}) {
+         {legacy_hal::WIFI_RTT_BW_5, legacy_hal::WIFI_RTT_BW_10, legacy_hal::WIFI_RTT_BW_20,
+          legacy_hal::WIFI_RTT_BW_40, legacy_hal::WIFI_RTT_BW_80, legacy_hal::WIFI_RTT_BW_160}) {
         if (legacy_capabilities.bw_support & flag) {
             hidl_capabilities->bwSupport |=
-                static_cast<std::underlying_type<RttBw>::type>(
-                    convertLegacyRttBwToHidl(flag));
+                    static_cast<std::underlying_type<RttBw>::type>(convertLegacyRttBwToHidl(flag));
         }
     }
     hidl_capabilities->mcVersion = legacy_capabilities.mc_version;
@@ -2911,26 +2608,23 @@
         return false;
     }
     *hidl_rate = {};
-    hidl_rate->preamble =
-        convertLegacyWifiRatePreambleToHidl(legacy_rate.preamble);
+    hidl_rate->preamble = convertLegacyWifiRatePreambleToHidl(legacy_rate.preamble);
     hidl_rate->nss = convertLegacyWifiRateNssToHidl(legacy_rate.nss);
     hidl_rate->bw = convertLegacyWifiChannelWidthToHidl(
-        static_cast<legacy_hal::wifi_channel_width>(legacy_rate.bw));
+            static_cast<legacy_hal::wifi_channel_width>(legacy_rate.bw));
     hidl_rate->rateMcsIdx = legacy_rate.rateMcsIdx;
     hidl_rate->bitRateInKbps = legacy_rate.bitrate;
     return true;
 }
 
-bool convertLegacyRttResultToHidl(
-    const legacy_hal::wifi_rtt_result& legacy_result,
-    V1_4::RttResult* hidl_result) {
+bool convertLegacyRttResultToHidl(const legacy_hal::wifi_rtt_result& legacy_result,
+                                  V1_4::RttResult* hidl_result) {
     if (!hidl_result) {
         return false;
     }
     *hidl_result = {};
     CHECK(sizeof(legacy_result.addr) == hidl_result->addr.size());
-    memcpy(hidl_result->addr.data(), legacy_result.addr,
-           sizeof(legacy_result.addr));
+    memcpy(hidl_result->addr.data(), legacy_result.addr, sizeof(legacy_result.addr));
     hidl_result->burstNum = legacy_result.burst_num;
     hidl_result->measurementNumber = legacy_result.measurement_number;
     hidl_result->successNumber = legacy_result.success_number;
@@ -2940,12 +2634,10 @@
     hidl_result->type = convertLegacyRttTypeToHidl(legacy_result.type);
     hidl_result->rssi = legacy_result.rssi;
     hidl_result->rssiSpread = legacy_result.rssi_spread;
-    if (!convertLegacyWifiRateInfoToHidl(legacy_result.tx_rate,
-                                         &hidl_result->txRate)) {
+    if (!convertLegacyWifiRateInfoToHidl(legacy_result.tx_rate, &hidl_result->txRate)) {
         return false;
     }
-    if (!convertLegacyWifiRateInfoToHidl(legacy_result.rx_rate,
-                                         &hidl_result->rxRate)) {
+    if (!convertLegacyWifiRateInfoToHidl(legacy_result.rx_rate, &hidl_result->rxRate)) {
         return false;
     }
     hidl_result->rtt = legacy_result.rtt;
@@ -2957,20 +2649,18 @@
     hidl_result->timeStampInUs = legacy_result.ts;
     hidl_result->burstDurationInMs = legacy_result.burst_duration;
     hidl_result->negotiatedBurstNum = legacy_result.negotiated_burst_num;
-    if (legacy_result.LCI &&
-        !convertLegacyIeToHidl(*legacy_result.LCI, &hidl_result->lci)) {
+    if (legacy_result.LCI && !convertLegacyIeToHidl(*legacy_result.LCI, &hidl_result->lci)) {
         return false;
     }
-    if (legacy_result.LCR &&
-        !convertLegacyIeToHidl(*legacy_result.LCR, &hidl_result->lcr)) {
+    if (legacy_result.LCR && !convertLegacyIeToHidl(*legacy_result.LCR, &hidl_result->lcr)) {
         return false;
     }
     return true;
 }
 
 bool convertLegacyVectorOfRttResultToHidl(
-    const std::vector<const legacy_hal::wifi_rtt_result*>& legacy_results,
-    std::vector<V1_4::RttResult>* hidl_results) {
+        const std::vector<const legacy_hal::wifi_rtt_result*>& legacy_results,
+        std::vector<V1_4::RttResult>* hidl_results) {
     if (!hidl_results) {
         return false;
     }
@@ -2985,8 +2675,7 @@
     return true;
 }
 
-legacy_hal::wifi_interface_type convertHidlIfaceTypeToLegacy(
-    IfaceType hidl_interface_type) {
+legacy_hal::wifi_interface_type convertHidlIfaceTypeToLegacy(IfaceType hidl_interface_type) {
     switch (hidl_interface_type) {
         case IfaceType::STA:
             return legacy_hal::WIFI_INTERFACE_TYPE_STA;
@@ -3001,28 +2690,28 @@
 }
 
 legacy_hal::wifi_multi_sta_use_case convertHidlMultiStaUseCaseToLegacy(
-    IWifiChip::MultiStaUseCase use_case) {
+        V1_5::IWifiChip::MultiStaUseCase use_case) {
     switch (use_case) {
-        case IWifiChip::MultiStaUseCase::DUAL_STA_TRANSIENT_PREFER_PRIMARY:
+        case V1_5::IWifiChip::MultiStaUseCase::DUAL_STA_TRANSIENT_PREFER_PRIMARY:
             return legacy_hal::WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY;
-        case IWifiChip::MultiStaUseCase::DUAL_STA_NON_TRANSIENT_UNBIASED:
+        case V1_5::IWifiChip::MultiStaUseCase::DUAL_STA_NON_TRANSIENT_UNBIASED:
             return legacy_hal::WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED;
     }
     CHECK(false);
 }
 
 bool convertHidlCoexUnsafeChannelToLegacy(
-    const IWifiChip::CoexUnsafeChannel& hidl_unsafe_channel,
-    legacy_hal::wifi_coex_unsafe_channel* legacy_unsafe_channel) {
+        const V1_5::IWifiChip::CoexUnsafeChannel& hidl_unsafe_channel,
+        legacy_hal::wifi_coex_unsafe_channel* legacy_unsafe_channel) {
     if (!legacy_unsafe_channel) {
         return false;
     }
     *legacy_unsafe_channel = {};
     switch (hidl_unsafe_channel.band) {
-        case WifiBand::BAND_24GHZ:
+        case V1_5::WifiBand::BAND_24GHZ:
             legacy_unsafe_channel->band = legacy_hal::WLAN_MAC_2_4_BAND;
             break;
-        case WifiBand::BAND_5GHZ:
+        case V1_5::WifiBand::BAND_5GHZ:
             legacy_unsafe_channel->band = legacy_hal::WLAN_MAC_5_0_BAND;
             break;
         default:
@@ -3034,16 +2723,16 @@
 }
 
 bool convertHidlVectorOfCoexUnsafeChannelToLegacy(
-    const std::vector<IWifiChip::CoexUnsafeChannel>& hidl_unsafe_channels,
-    std::vector<legacy_hal::wifi_coex_unsafe_channel>* legacy_unsafe_channels) {
+        const std::vector<V1_5::IWifiChip::CoexUnsafeChannel>& hidl_unsafe_channels,
+        std::vector<legacy_hal::wifi_coex_unsafe_channel>* legacy_unsafe_channels) {
     if (!legacy_unsafe_channels) {
         return false;
     }
     *legacy_unsafe_channels = {};
     for (const auto& hidl_unsafe_channel : hidl_unsafe_channels) {
         legacy_hal::wifi_coex_unsafe_channel legacy_unsafe_channel;
-        if (!hidl_struct_util::convertHidlCoexUnsafeChannelToLegacy(
-                hidl_unsafe_channel, &legacy_unsafe_channel)) {
+        if (!hidl_struct_util::convertHidlCoexUnsafeChannelToLegacy(hidl_unsafe_channel,
+                                                                    &legacy_unsafe_channel)) {
             return false;
         }
         legacy_unsafe_channels->push_back(legacy_unsafe_channel);
@@ -3053,7 +2742,7 @@
 
 }  // namespace hidl_struct_util
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.6/default/hidl_struct_util.h b/wifi/1.6/default/hidl_struct_util.h
new file mode 100644
index 0000000..15a3205
--- /dev/null
+++ b/wifi/1.6/default/hidl_struct_util.h
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 HIDL_STRUCT_UTIL_H_
+#define HIDL_STRUCT_UTIL_H_
+
+#include <vector>
+
+#include <android/hardware/wifi/1.0/IWifiChip.h>
+#include <android/hardware/wifi/1.0/types.h>
+#include <android/hardware/wifi/1.2/types.h>
+#include <android/hardware/wifi/1.3/types.h>
+#include <android/hardware/wifi/1.4/IWifiChipEventCallback.h>
+#include <android/hardware/wifi/1.4/types.h>
+#include <android/hardware/wifi/1.5/IWifiChip.h>
+#include <android/hardware/wifi/1.5/types.h>
+
+#include "wifi_legacy_hal.h"
+
+/**
+ * This file contains a bunch of functions to convert structs from the legacy
+ * HAL to HIDL and vice versa.
+ * TODO(b/32093047): Add unit tests for these conversion methods in the VTS test
+ * suite.
+ */
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+namespace hidl_struct_util {
+using namespace android::hardware::wifi::V1_0;
+
+// Chip conversion methods.
+bool convertLegacyFeaturesToHidlChipCapabilities(uint64_t legacy_feature_set,
+                                                 uint32_t legacy_logger_feature_set,
+                                                 uint32_t* hidl_caps);
+bool convertLegacyDebugRingBufferStatusToHidl(
+        const legacy_hal::wifi_ring_buffer_status& legacy_status,
+        WifiDebugRingBufferStatus* hidl_status);
+bool convertLegacyVectorOfDebugRingBufferStatusToHidl(
+        const std::vector<legacy_hal::wifi_ring_buffer_status>& legacy_status_vec,
+        std::vector<WifiDebugRingBufferStatus>* hidl_status_vec);
+bool convertLegacyWakeReasonStatsToHidl(const legacy_hal::WakeReasonStats& legacy_stats,
+                                        WifiDebugHostWakeReasonStats* hidl_stats);
+legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy(
+        V1_1::IWifiChip::TxPowerScenario hidl_scenario);
+legacy_hal::wifi_latency_mode convertHidlLatencyModeToLegacy(
+        V1_3::IWifiChip::LatencyMode hidl_latency_mode);
+legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy_1_2(
+        V1_2::IWifiChip::TxPowerScenario hidl_scenario);
+bool convertLegacyWifiMacInfosToHidl(
+        const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos,
+        std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo>* hidl_radio_mode_infos);
+legacy_hal::wifi_interface_type convertHidlIfaceTypeToLegacy(IfaceType hidl_interface_type);
+legacy_hal::wifi_multi_sta_use_case convertHidlMultiStaUseCaseToLegacy(
+        V1_5::IWifiChip::MultiStaUseCase use_case);
+bool convertHidlCoexUnsafeChannelToLegacy(
+        const V1_5::IWifiChip::CoexUnsafeChannel& hidl_unsafe_channel,
+        legacy_hal::wifi_coex_unsafe_channel* legacy_unsafe_channel);
+bool convertHidlVectorOfCoexUnsafeChannelToLegacy(
+        const std::vector<V1_5::IWifiChip::CoexUnsafeChannel>& hidl_unsafe_channels,
+        std::vector<legacy_hal::wifi_coex_unsafe_channel>* legacy_unsafe_channels);
+
+// STA iface conversion methods.
+bool convertLegacyFeaturesToHidlStaCapabilities(uint64_t legacy_feature_set,
+                                                uint32_t legacy_logger_feature_set,
+                                                uint32_t* hidl_caps);
+bool convertLegacyApfCapabilitiesToHidl(const legacy_hal::PacketFilterCapabilities& legacy_caps,
+                                        StaApfPacketFilterCapabilities* hidl_caps);
+bool convertLegacyGscanCapabilitiesToHidl(const legacy_hal::wifi_gscan_capabilities& legacy_caps,
+                                          StaBackgroundScanCapabilities* hidl_caps);
+legacy_hal::wifi_band convertHidlWifiBandToLegacy(V1_0::WifiBand band);
+bool convertHidlGscanParamsToLegacy(const StaBackgroundScanParameters& hidl_scan_params,
+                                    legacy_hal::wifi_scan_cmd_params* legacy_scan_params);
+// |has_ie_data| indicates whether or not the wifi_scan_result includes 802.11
+// Information Elements (IEs)
+bool convertLegacyGscanResultToHidl(const legacy_hal::wifi_scan_result& legacy_scan_result,
+                                    bool has_ie_data, StaScanResult* hidl_scan_result);
+// |cached_results| is assumed to not include IEs.
+bool convertLegacyVectorOfCachedGscanResultsToHidl(
+        const std::vector<legacy_hal::wifi_cached_scan_results>& legacy_cached_scan_results,
+        std::vector<StaScanData>* hidl_scan_datas);
+bool convertLegacyLinkLayerStatsToHidl(const legacy_hal::LinkLayerStats& legacy_stats,
+                                       V1_5::StaLinkLayerStats* hidl_stats);
+bool convertLegacyRoamingCapabilitiesToHidl(
+        const legacy_hal::wifi_roaming_capabilities& legacy_caps,
+        StaRoamingCapabilities* hidl_caps);
+bool convertHidlRoamingConfigToLegacy(const StaRoamingConfig& hidl_config,
+                                      legacy_hal::wifi_roaming_config* legacy_config);
+legacy_hal::fw_roaming_state_t convertHidlRoamingStateToLegacy(StaRoamingState state);
+bool convertLegacyVectorOfDebugTxPacketFateToHidl(
+        const std::vector<legacy_hal::wifi_tx_report>& legacy_fates,
+        std::vector<WifiDebugTxPacketFateReport>* hidl_fates);
+bool convertLegacyVectorOfDebugRxPacketFateToHidl(
+        const std::vector<legacy_hal::wifi_rx_report>& legacy_fates,
+        std::vector<WifiDebugRxPacketFateReport>* hidl_fates);
+
+// NAN iface conversion methods.
+void convertToWifiNanStatus(legacy_hal::NanStatusType type, const char* str, size_t max_len,
+                            WifiNanStatus* wifiNanStatus);
+bool convertHidlNanEnableRequestToLegacy(const V1_4::NanEnableRequest& hidl_request,
+                                         legacy_hal::NanEnableRequest* legacy_request);
+bool convertHidlNanConfigRequestToLegacy(const V1_4::NanConfigRequest& hidl_request,
+                                         legacy_hal::NanConfigRequest* legacy_request);
+bool convertHidlNanEnableRequest_1_4ToLegacy(
+        const V1_4::NanEnableRequest& hidl_request1,
+        const V1_5::NanConfigRequestSupplemental& hidl_request2,
+        legacy_hal::NanEnableRequest* legacy_request);
+bool convertHidlNanConfigRequest_1_4ToLegacy(
+        const V1_4::NanConfigRequest& hidl_request1,
+        const V1_5::NanConfigRequestSupplemental& hidl_request2,
+        legacy_hal::NanConfigRequest* legacy_request);
+bool convertHidlNanEnableRequest_1_5ToLegacy(
+        const V1_4::NanEnableRequest& hidl_request1,
+        const V1_5::NanConfigRequestSupplemental& hidl_request2,
+        legacy_hal::NanEnableRequest* legacy_request);
+bool convertHidlNanConfigRequest_1_5ToLegacy(
+        const V1_4::NanConfigRequest& hidl_request1,
+        const V1_5::NanConfigRequestSupplemental& hidl_request2,
+        legacy_hal::NanConfigRequest* legacy_request);
+bool convertHidlNanPublishRequestToLegacy(const NanPublishRequest& hidl_request,
+                                          legacy_hal::NanPublishRequest* legacy_request);
+bool convertHidlNanSubscribeRequestToLegacy(const NanSubscribeRequest& hidl_request,
+                                            legacy_hal::NanSubscribeRequest* legacy_request);
+bool convertHidlNanTransmitFollowupRequestToLegacy(
+        const NanTransmitFollowupRequest& hidl_request,
+        legacy_hal::NanTransmitFollowupRequest* legacy_request);
+bool convertHidlNanDataPathInitiatorRequestToLegacy(
+        const NanInitiateDataPathRequest& hidl_request,
+        legacy_hal::NanDataPathInitiatorRequest* legacy_request);
+bool convertHidlNanDataPathIndicationResponseToLegacy(
+        const NanRespondToDataPathIndicationRequest& hidl_response,
+        legacy_hal::NanDataPathIndicationResponse* legacy_response);
+bool convertLegacyNanResponseHeaderToHidl(const legacy_hal::NanResponseMsg& legacy_response,
+                                          WifiNanStatus* wifiNanStatus);
+bool convertLegacyNanCapabilitiesResponseToHidl(const legacy_hal::NanCapabilities& legacy_response,
+                                                V1_5::NanCapabilities* hidl_response);
+bool convertLegacyNanMatchIndToHidl(const legacy_hal::NanMatchInd& legacy_ind,
+                                    NanMatchInd* hidl_ind);
+bool convertLegacyNanFollowupIndToHidl(const legacy_hal::NanFollowupInd& legacy_ind,
+                                       NanFollowupReceivedInd* hidl_ind);
+bool convertLegacyNanDataPathRequestIndToHidl(const legacy_hal::NanDataPathRequestInd& legacy_ind,
+                                              NanDataPathRequestInd* hidl_ind);
+bool convertLegacyNanDataPathConfirmIndToHidl(const legacy_hal::NanDataPathConfirmInd& legacy_ind,
+                                              V1_2::NanDataPathConfirmInd* hidl_ind);
+bool convertLegacyNanDataPathScheduleUpdateIndToHidl(
+        const legacy_hal::NanDataPathScheduleUpdateInd& legacy_ind,
+        V1_2::NanDataPathScheduleUpdateInd* hidl_ind);
+
+// RTT controller conversion methods.
+bool convertHidlVectorOfRttConfigToLegacy(const std::vector<V1_4::RttConfig>& hidl_configs,
+                                          std::vector<legacy_hal::wifi_rtt_config>* legacy_configs);
+bool convertHidlRttLciInformationToLegacy(const RttLciInformation& hidl_info,
+                                          legacy_hal::wifi_lci_information* legacy_info);
+bool convertHidlRttLcrInformationToLegacy(const RttLcrInformation& hidl_info,
+                                          legacy_hal::wifi_lcr_information* legacy_info);
+bool convertHidlRttResponderToLegacy(const V1_4::RttResponder& hidl_responder,
+                                     legacy_hal::wifi_rtt_responder* legacy_responder);
+bool convertHidlWifiChannelInfoToLegacy(const WifiChannelInfo& hidl_info,
+                                        legacy_hal::wifi_channel_info* legacy_info);
+bool convertLegacyRttResponderToHidl(const legacy_hal::wifi_rtt_responder& legacy_responder,
+                                     V1_4::RttResponder* hidl_responder);
+bool convertLegacyRttCapabilitiesToHidl(
+        const legacy_hal::wifi_rtt_capabilities& legacy_capabilities,
+        V1_4::RttCapabilities* hidl_capabilities);
+bool convertLegacyVectorOfRttResultToHidl(
+        const std::vector<const legacy_hal::wifi_rtt_result*>& legacy_results,
+        std::vector<V1_4::RttResult>* hidl_results);
+uint32_t convertHidlWifiBandToLegacyMacBand(V1_5::WifiBand band);
+uint32_t convertHidlWifiIfaceModeToLegacy(uint32_t hidl_iface_mask);
+uint32_t convertHidlUsableChannelFilterToLegacy(uint32_t hidl_filter_mask);
+bool convertLegacyWifiUsableChannelsToHidl(
+        const std::vector<legacy_hal::wifi_usable_channel>& legacy_usable_channels,
+        std::vector<V1_5::WifiUsableChannel>* hidl_usable_channels);
+bool convertLegacyPeerInfoStatsToHidl(const legacy_hal::WifiPeerInfo& legacy_peer_info_stats,
+                                      V1_5::StaPeerInfo* hidl_peer_info_stats);
+bool convertLegacyWifiRateInfoToHidl(const legacy_hal::wifi_rate& legacy_rate,
+                                     V1_4::WifiRateInfo* hidl_rate);
+}  // namespace hidl_struct_util
+}  // namespace implementation
+}  // namespace V1_6
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+
+#endif  // HIDL_STRUCT_UTIL_H_
diff --git a/wifi/1.5/default/hidl_sync_util.cpp b/wifi/1.6/default/hidl_sync_util.cpp
similarity index 96%
rename from wifi/1.5/default/hidl_sync_util.cpp
rename to wifi/1.6/default/hidl_sync_util.cpp
index 93eefe9..358d95e 100644
--- a/wifi/1.5/default/hidl_sync_util.cpp
+++ b/wifi/1.6/default/hidl_sync_util.cpp
@@ -23,7 +23,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 namespace hidl_sync_util {
 
@@ -33,7 +33,7 @@
 
 }  // namespace hidl_sync_util
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/hidl_sync_util.h b/wifi/1.6/default/hidl_sync_util.h
similarity index 96%
rename from wifi/1.5/default/hidl_sync_util.h
rename to wifi/1.6/default/hidl_sync_util.h
index e706f4c..2c1c37b 100644
--- a/wifi/1.5/default/hidl_sync_util.h
+++ b/wifi/1.6/default/hidl_sync_util.h
@@ -24,13 +24,13 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 namespace hidl_sync_util {
 std::unique_lock<std::recursive_mutex> acquireGlobalLock();
 }  // namespace hidl_sync_util
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/ringbuffer.cpp b/wifi/1.6/default/ringbuffer.cpp
similarity index 91%
rename from wifi/1.5/default/ringbuffer.cpp
rename to wifi/1.6/default/ringbuffer.cpp
index f554111..6d4ed84 100644
--- a/wifi/1.5/default/ringbuffer.cpp
+++ b/wifi/1.6/default/ringbuffer.cpp
@@ -21,7 +21,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 
 Ringbuffer::Ringbuffer(size_t maxSize) : size_(0), maxSize_(maxSize) {}
@@ -31,8 +31,7 @@
         return;
     }
     if (input.size() > maxSize_) {
-        LOG(INFO) << "Oversized message of " << input.size()
-                  << " bytes is dropped";
+        LOG(INFO) << "Oversized message of " << input.size() << " bytes is dropped";
         return;
     }
     data_.push_back(input);
@@ -53,7 +52,7 @@
 }
 
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/ringbuffer.h b/wifi/1.6/default/ringbuffer.h
similarity index 95%
rename from wifi/1.5/default/ringbuffer.h
rename to wifi/1.6/default/ringbuffer.h
index 03fb37a..8571a9f 100644
--- a/wifi/1.5/default/ringbuffer.h
+++ b/wifi/1.6/default/ringbuffer.h
@@ -23,14 +23,14 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 
 /**
  * Ringbuffer object used to store debug data.
  */
 class Ringbuffer {
-   public:
+  public:
     explicit Ringbuffer(size_t maxSize);
 
     // Appends the data buffer and deletes from the front until buffer is
@@ -39,14 +39,14 @@
     const std::list<std::vector<uint8_t>>& getData() const;
     void clear();
 
-   private:
+  private:
     std::list<std::vector<uint8_t>> data_;
     size_t size_;
     size_t maxSize_;
 };
 
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/service.cpp b/wifi/1.6/default/service.cpp
similarity index 63%
rename from wifi/1.5/default/service.cpp
rename to wifi/1.6/default/service.cpp
index 3de49b2..c874d8b 100644
--- a/wifi/1.5/default/service.cpp
+++ b/wifi/1.6/default/service.cpp
@@ -30,13 +30,10 @@
 using android::hardware::configureRpcThreadpool;
 using android::hardware::joinRpcThreadpool;
 using android::hardware::LazyServiceRegistrar;
-using android::hardware::wifi::V1_5::implementation::feature_flags::
-    WifiFeatureFlags;
-using android::hardware::wifi::V1_5::implementation::legacy_hal::WifiLegacyHal;
-using android::hardware::wifi::V1_5::implementation::legacy_hal::
-    WifiLegacyHalFactory;
-using android::hardware::wifi::V1_5::implementation::mode_controller::
-    WifiModeController;
+using android::hardware::wifi::V1_6::implementation::feature_flags::WifiFeatureFlags;
+using android::hardware::wifi::V1_6::implementation::legacy_hal::WifiLegacyHal;
+using android::hardware::wifi::V1_6::implementation::legacy_hal::WifiLegacyHalFactory;
+using android::hardware::wifi::V1_6::implementation::mode_controller::WifiModeController;
 
 #ifdef LAZY_SERVICE
 const bool kLazyService = true;
@@ -46,30 +43,25 @@
 
 int main(int /*argc*/, char** argv) {
     signal(SIGPIPE, SIG_IGN);
-    android::base::InitLogging(
-        argv, android::base::LogdLogger(android::base::SYSTEM));
+    android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM));
     LOG(INFO) << "Wifi Hal is booting up...";
 
     configureRpcThreadpool(1, true /* callerWillJoin */);
 
-    const auto iface_tool =
-        std::make_shared<android::wifi_system::InterfaceTool>();
-    const auto legacy_hal_factory =
-        std::make_shared<WifiLegacyHalFactory>(iface_tool);
+    const auto iface_tool = std::make_shared<android::wifi_system::InterfaceTool>();
+    const auto legacy_hal_factory = std::make_shared<WifiLegacyHalFactory>(iface_tool);
 
     // Setup hwbinder service
-    android::sp<android::hardware::wifi::V1_5::IWifi> service =
-        new android::hardware::wifi::V1_5::implementation::Wifi(
-            iface_tool, legacy_hal_factory,
-            std::make_shared<WifiModeController>(),
-            std::make_shared<WifiFeatureFlags>());
+    android::sp<android::hardware::wifi::V1_6::IWifi> service =
+            new android::hardware::wifi::V1_6::implementation::Wifi(
+                    iface_tool, legacy_hal_factory, std::make_shared<WifiModeController>(),
+                    std::make_shared<WifiFeatureFlags>());
     if (kLazyService) {
         auto registrar = LazyServiceRegistrar::getInstance();
         CHECK_EQ(registrar.registerService(service), android::NO_ERROR)
-            << "Failed to register wifi HAL";
+                << "Failed to register wifi HAL";
     } else {
-        CHECK_EQ(service->registerAsService(), android::NO_ERROR)
-            << "Failed to register wifi HAL";
+        CHECK_EQ(service->registerAsService(), android::NO_ERROR) << "Failed to register wifi HAL";
     }
 
     joinRpcThreadpool();
diff --git a/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp b/wifi/1.6/default/tests/hidl_struct_util_unit_tests.cpp
similarity index 74%
rename from wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp
rename to wifi/1.6/default/tests/hidl_struct_util_unit_tests.cpp
index 4b4ebd6..1182a58 100644
--- a/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp
+++ b/wifi/1.6/default/tests/hidl_struct_util_unit_tests.cpp
@@ -34,7 +34,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 using namespace android::hardware::wifi::V1_0;
 using ::android::hardware::wifi::V1_0::WifiChannelWidthInMhz;
@@ -44,21 +44,17 @@
 TEST_F(HidlStructUtilTest, CanConvertLegacyWifiMacInfosToHidlWithOneMac) {
     std::vector<legacy_hal::WifiMacInfo> legacy_mac_infos;
     legacy_hal::WifiMacInfo legacy_mac_info1 = {
-        .wlan_mac_id = kMacId1,
-        .mac_band =
-            legacy_hal::WLAN_MAC_5_0_BAND | legacy_hal::WLAN_MAC_2_4_BAND};
-    legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1,
-                                                    .channel = kIfaceChannel1};
-    legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2,
-                                                    .channel = kIfaceChannel2};
+            .wlan_mac_id = kMacId1,
+            .mac_band = legacy_hal::WLAN_MAC_5_0_BAND | legacy_hal::WLAN_MAC_2_4_BAND};
+    legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1, .channel = kIfaceChannel1};
+    legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2, .channel = kIfaceChannel2};
     legacy_mac_info1.iface_infos.push_back(legacy_iface_info1);
     legacy_mac_info1.iface_infos.push_back(legacy_iface_info2);
     legacy_mac_infos.push_back(legacy_mac_info1);
 
-    std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo>
-        hidl_radio_mode_infos;
-    ASSERT_TRUE(hidl_struct_util::convertLegacyWifiMacInfosToHidl(
-        legacy_mac_infos, &hidl_radio_mode_infos));
+    std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo> hidl_radio_mode_infos;
+    ASSERT_TRUE(hidl_struct_util::convertLegacyWifiMacInfosToHidl(legacy_mac_infos,
+                                                                  &hidl_radio_mode_infos));
 
     ASSERT_EQ(1u, hidl_radio_mode_infos.size());
     auto hidl_radio_mode_info1 = hidl_radio_mode_infos[0];
@@ -67,65 +63,56 @@
     ASSERT_EQ(2u, hidl_radio_mode_info1.ifaceInfos.size());
     auto hidl_iface_info1 = hidl_radio_mode_info1.ifaceInfos[0];
     EXPECT_EQ(legacy_iface_info1.name, hidl_iface_info1.name);
-    EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info1.channel),
-              hidl_iface_info1.channel);
+    EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info1.channel), hidl_iface_info1.channel);
     auto hidl_iface_info2 = hidl_radio_mode_info1.ifaceInfos[1];
     EXPECT_EQ(legacy_iface_info2.name, hidl_iface_info2.name);
-    EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info2.channel),
-              hidl_iface_info2.channel);
+    EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info2.channel), hidl_iface_info2.channel);
 }
 
 TEST_F(HidlStructUtilTest, CanConvertLegacyWifiMacInfosToHidlWithTwoMac) {
     std::vector<legacy_hal::WifiMacInfo> legacy_mac_infos;
-    legacy_hal::WifiMacInfo legacy_mac_info1 = {
-        .wlan_mac_id = kMacId1, .mac_band = legacy_hal::WLAN_MAC_5_0_BAND};
-    legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1,
-                                                    .channel = kIfaceChannel1};
-    legacy_hal::WifiMacInfo legacy_mac_info2 = {
-        .wlan_mac_id = kMacId2, .mac_band = legacy_hal::WLAN_MAC_2_4_BAND};
-    legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2,
-                                                    .channel = kIfaceChannel2};
+    legacy_hal::WifiMacInfo legacy_mac_info1 = {.wlan_mac_id = kMacId1,
+                                                .mac_band = legacy_hal::WLAN_MAC_5_0_BAND};
+    legacy_hal::WifiIfaceInfo legacy_iface_info1 = {.name = kIfaceName1, .channel = kIfaceChannel1};
+    legacy_hal::WifiMacInfo legacy_mac_info2 = {.wlan_mac_id = kMacId2,
+                                                .mac_band = legacy_hal::WLAN_MAC_2_4_BAND};
+    legacy_hal::WifiIfaceInfo legacy_iface_info2 = {.name = kIfaceName2, .channel = kIfaceChannel2};
     legacy_mac_info1.iface_infos.push_back(legacy_iface_info1);
     legacy_mac_infos.push_back(legacy_mac_info1);
     legacy_mac_info2.iface_infos.push_back(legacy_iface_info2);
     legacy_mac_infos.push_back(legacy_mac_info2);
 
-    std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo>
-        hidl_radio_mode_infos;
-    ASSERT_TRUE(hidl_struct_util::convertLegacyWifiMacInfosToHidl(
-        legacy_mac_infos, &hidl_radio_mode_infos));
+    std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo> hidl_radio_mode_infos;
+    ASSERT_TRUE(hidl_struct_util::convertLegacyWifiMacInfosToHidl(legacy_mac_infos,
+                                                                  &hidl_radio_mode_infos));
 
     ASSERT_EQ(2u, hidl_radio_mode_infos.size());
 
     // Find mac info 1.
     const auto hidl_radio_mode_info1 =
-        std::find_if(hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(),
-                     [&legacy_mac_info1](
-                         const V1_4::IWifiChipEventCallback::RadioModeInfo& x) {
-                         return x.radioId == legacy_mac_info1.wlan_mac_id;
-                     });
+            std::find_if(hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(),
+                         [&legacy_mac_info1](const V1_4::IWifiChipEventCallback::RadioModeInfo& x) {
+                             return x.radioId == legacy_mac_info1.wlan_mac_id;
+                         });
     ASSERT_NE(hidl_radio_mode_infos.end(), hidl_radio_mode_info1);
     EXPECT_EQ(V1_4::WifiBand::BAND_5GHZ, hidl_radio_mode_info1->bandInfo);
     ASSERT_EQ(1u, hidl_radio_mode_info1->ifaceInfos.size());
     auto hidl_iface_info1 = hidl_radio_mode_info1->ifaceInfos[0];
     EXPECT_EQ(legacy_iface_info1.name, hidl_iface_info1.name);
-    EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info1.channel),
-              hidl_iface_info1.channel);
+    EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info1.channel), hidl_iface_info1.channel);
 
     // Find mac info 2.
     const auto hidl_radio_mode_info2 =
-        std::find_if(hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(),
-                     [&legacy_mac_info2](
-                         const V1_4::IWifiChipEventCallback::RadioModeInfo& x) {
-                         return x.radioId == legacy_mac_info2.wlan_mac_id;
-                     });
+            std::find_if(hidl_radio_mode_infos.begin(), hidl_radio_mode_infos.end(),
+                         [&legacy_mac_info2](const V1_4::IWifiChipEventCallback::RadioModeInfo& x) {
+                             return x.radioId == legacy_mac_info2.wlan_mac_id;
+                         });
     ASSERT_NE(hidl_radio_mode_infos.end(), hidl_radio_mode_info2);
     EXPECT_EQ(V1_4::WifiBand::BAND_24GHZ, hidl_radio_mode_info2->bandInfo);
     ASSERT_EQ(1u, hidl_radio_mode_info2->ifaceInfos.size());
     auto hidl_iface_info2 = hidl_radio_mode_info2->ifaceInfos[0];
     EXPECT_EQ(legacy_iface_info2.name, hidl_iface_info2.name);
-    EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info2.channel),
-              hidl_iface_info2.channel);
+    EXPECT_EQ(static_cast<uint32_t>(legacy_iface_info2.channel), hidl_iface_info2.channel);
 }
 
 TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) {
@@ -143,8 +130,7 @@
     legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min = rand();
     legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max = rand();
     legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples =
-        rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples = rand();
 
     legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu = rand();
     legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu = rand();
@@ -153,8 +139,7 @@
     legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min = rand();
     legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max = rand();
     legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples =
-        rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples = rand();
 
     legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu = rand();
     legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu = rand();
@@ -163,8 +148,7 @@
     legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min = rand();
     legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max = rand();
     legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples =
-        rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples = rand();
 
     legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu = rand();
     legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu = rand();
@@ -173,8 +157,7 @@
     legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min = rand();
     legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max = rand();
     legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg = rand();
-    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples =
-        rand();
+    legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples = rand();
 
     legacy_stats.iface.info.time_slicing_duty_cycle_percent = rand();
     legacy_stats.iface.num_peers = 1;
@@ -195,14 +178,14 @@
         }
 
         legacy_hal::wifi_channel_stat channel_stat1 = {
-            .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 2437, 2437, 0},
-            .on_time = 0x1111,
-            .cca_busy_time = 0x55,
+                .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 2437, 2437, 0},
+                .on_time = 0x1111,
+                .cca_busy_time = 0x55,
         };
         legacy_hal::wifi_channel_stat channel_stat2 = {
-            .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 5180, 5180, 0},
-            .on_time = 0x2222,
-            .cca_busy_time = 0x66,
+                .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 5180, 5180, 0},
+                .on_time = 0x2222,
+                .cca_busy_time = 0x66,
         };
         radio.channel_stats.push_back(channel_stat1);
         radio.channel_stats.push_back(channel_stat2);
@@ -212,30 +195,29 @@
         peer.peer_info.bssload.sta_count = rand();
         peer.peer_info.bssload.chan_util = rand();
         wifi_rate_stat rate_stat1 = {
-            .rate = {3, 1, 2, 5, 0, 0},
-            .tx_mpdu = 0,
-            .rx_mpdu = 1,
-            .mpdu_lost = 2,
-            .retries = 3,
-            .retries_short = 4,
-            .retries_long = 5,
+                .rate = {3, 1, 2, 5, 0, 0},
+                .tx_mpdu = 0,
+                .rx_mpdu = 1,
+                .mpdu_lost = 2,
+                .retries = 3,
+                .retries_short = 4,
+                .retries_long = 5,
         };
         wifi_rate_stat rate_stat2 = {
-            .rate = {2, 2, 1, 6, 0, 1},
-            .tx_mpdu = 6,
-            .rx_mpdu = 7,
-            .mpdu_lost = 8,
-            .retries = 9,
-            .retries_short = 10,
-            .retries_long = 11,
+                .rate = {2, 2, 1, 6, 0, 1},
+                .tx_mpdu = 6,
+                .rx_mpdu = 7,
+                .mpdu_lost = 8,
+                .retries = 9,
+                .retries_short = 10,
+                .retries_long = 11,
         };
         peer.rate_stats.push_back(rate_stat1);
         peer.rate_stats.push_back(rate_stat2);
     }
 
     V1_5::StaLinkLayerStats converted{};
-    hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats,
-                                                        &converted);
+    hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats, &converted);
     EXPECT_EQ(legacy_stats.iface.beacon_rx, converted.iface.V1_0.beaconRx);
     EXPECT_EQ(legacy_stats.iface.rssi_mgmt, converted.iface.V1_0.avgRssiMgmt);
     EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu,
@@ -252,9 +234,8 @@
               converted.iface.wmeBeContentionTimeStats.contentionTimeMaxInUsec);
     EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg,
               converted.iface.wmeBeContentionTimeStats.contentionTimeAvgInUsec);
-    EXPECT_EQ(
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples,
-        converted.iface.wmeBeContentionTimeStats.contentionNumSamples);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples,
+              converted.iface.wmeBeContentionTimeStats.contentionNumSamples);
 
     EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu,
               converted.iface.V1_0.wmeBkPktStats.rxMpdu);
@@ -270,9 +251,8 @@
               converted.iface.wmeBkContentionTimeStats.contentionTimeMaxInUsec);
     EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg,
               converted.iface.wmeBkContentionTimeStats.contentionTimeAvgInUsec);
-    EXPECT_EQ(
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples,
-        converted.iface.wmeBkContentionTimeStats.contentionNumSamples);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples,
+              converted.iface.wmeBkContentionTimeStats.contentionNumSamples);
 
     EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu,
               converted.iface.V1_0.wmeViPktStats.rxMpdu);
@@ -288,9 +268,8 @@
               converted.iface.wmeViContentionTimeStats.contentionTimeMaxInUsec);
     EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg,
               converted.iface.wmeViContentionTimeStats.contentionTimeAvgInUsec);
-    EXPECT_EQ(
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples,
-        converted.iface.wmeViContentionTimeStats.contentionNumSamples);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples,
+              converted.iface.wmeViContentionTimeStats.contentionNumSamples);
 
     EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu,
               converted.iface.V1_0.wmeVoPktStats.rxMpdu);
@@ -306,29 +285,23 @@
               converted.iface.wmeVoContentionTimeStats.contentionTimeMaxInUsec);
     EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg,
               converted.iface.wmeVoContentionTimeStats.contentionTimeAvgInUsec);
-    EXPECT_EQ(
-        legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples,
-        converted.iface.wmeVoContentionTimeStats.contentionNumSamples);
+    EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples,
+              converted.iface.wmeVoContentionTimeStats.contentionNumSamples);
 
     EXPECT_EQ(legacy_stats.iface.info.time_slicing_duty_cycle_percent,
               converted.iface.timeSliceDutyCycleInPercent);
 
     EXPECT_EQ(legacy_stats.radios.size(), converted.radios.size());
     for (size_t i = 0; i < legacy_stats.radios.size(); i++) {
-        EXPECT_EQ(legacy_stats.radios[i].stats.radio,
-                  converted.radios[i].radioId);
-        EXPECT_EQ(legacy_stats.radios[i].stats.on_time,
-                  converted.radios[i].V1_3.V1_0.onTimeInMs);
-        EXPECT_EQ(legacy_stats.radios[i].stats.tx_time,
-                  converted.radios[i].V1_3.V1_0.txTimeInMs);
-        EXPECT_EQ(legacy_stats.radios[i].stats.rx_time,
-                  converted.radios[i].V1_3.V1_0.rxTimeInMs);
+        EXPECT_EQ(legacy_stats.radios[i].stats.radio, converted.radios[i].radioId);
+        EXPECT_EQ(legacy_stats.radios[i].stats.on_time, converted.radios[i].V1_3.V1_0.onTimeInMs);
+        EXPECT_EQ(legacy_stats.radios[i].stats.tx_time, converted.radios[i].V1_3.V1_0.txTimeInMs);
+        EXPECT_EQ(legacy_stats.radios[i].stats.rx_time, converted.radios[i].V1_3.V1_0.rxTimeInMs);
         EXPECT_EQ(legacy_stats.radios[i].stats.on_time_scan,
                   converted.radios[i].V1_3.V1_0.onTimeInMsForScan);
         EXPECT_EQ(legacy_stats.radios[i].tx_time_per_levels.size(),
                   converted.radios[i].V1_3.V1_0.txTimeInMsPerLevel.size());
-        for (size_t j = 0; j < legacy_stats.radios[i].tx_time_per_levels.size();
-             j++) {
+        for (size_t j = 0; j < legacy_stats.radios[i].tx_time_per_levels.size(); j++) {
             EXPECT_EQ(legacy_stats.radios[i].tx_time_per_levels[j],
                       converted.radios[i].V1_3.V1_0.txTimeInMsPerLevel[j]);
         }
@@ -344,20 +317,16 @@
                   converted.radios[i].V1_3.onTimeInMsForHs20Scan);
         EXPECT_EQ(legacy_stats.radios[i].channel_stats.size(),
                   converted.radios[i].V1_3.channelStats.size());
-        for (size_t k = 0; k < legacy_stats.radios[i].channel_stats.size();
-             k++) {
+        for (size_t k = 0; k < legacy_stats.radios[i].channel_stats.size(); k++) {
             auto& legacy_channel_st = legacy_stats.radios[i].channel_stats[k];
             EXPECT_EQ(WifiChannelWidthInMhz::WIDTH_20,
                       converted.radios[i].V1_3.channelStats[k].channel.width);
-            EXPECT_EQ(
-                WifiChannelInMhz(legacy_channel_st.channel.center_freq),
-                converted.radios[i].V1_3.channelStats[k].channel.centerFreq);
-            EXPECT_EQ(
-                WifiChannelInMhz(legacy_channel_st.channel.center_freq0),
-                converted.radios[i].V1_3.channelStats[k].channel.centerFreq0);
-            EXPECT_EQ(
-                WifiChannelInMhz(legacy_channel_st.channel.center_freq1),
-                converted.radios[i].V1_3.channelStats[k].channel.centerFreq1);
+            EXPECT_EQ(WifiChannelInMhz(legacy_channel_st.channel.center_freq),
+                      converted.radios[i].V1_3.channelStats[k].channel.centerFreq);
+            EXPECT_EQ(WifiChannelInMhz(legacy_channel_st.channel.center_freq0),
+                      converted.radios[i].V1_3.channelStats[k].channel.centerFreq0);
+            EXPECT_EQ(WifiChannelInMhz(legacy_channel_st.channel.center_freq1),
+                      converted.radios[i].V1_3.channelStats[k].channel.centerFreq1);
             EXPECT_EQ(legacy_channel_st.cca_busy_time,
                       converted.radios[i].V1_3.channelStats[k].ccaBusyTimeInMs);
             EXPECT_EQ(legacy_channel_st.on_time,
@@ -373,18 +342,13 @@
                   converted.iface.peers[i].chanUtil);
         for (size_t j = 0; j < legacy_stats.peers[i].rate_stats.size(); j++) {
             EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.preamble,
-                      (uint32_t)converted.iface.peers[i]
-                          .rateStats[j]
-                          .rateInfo.preamble);
-            EXPECT_EQ(
-                legacy_stats.peers[i].rate_stats[j].rate.nss,
-                (uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.nss);
-            EXPECT_EQ(
-                legacy_stats.peers[i].rate_stats[j].rate.bw,
-                (uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.bw);
-            EXPECT_EQ(
-                legacy_stats.peers[i].rate_stats[j].rate.rateMcsIdx,
-                converted.iface.peers[i].rateStats[j].rateInfo.rateMcsIdx);
+                      (uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.preamble);
+            EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.nss,
+                      (uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.nss);
+            EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.bw,
+                      (uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.bw);
+            EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.rateMcsIdx,
+                      converted.iface.peers[i].rateStats[j].rateInfo.rateMcsIdx);
             EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].tx_mpdu,
                       converted.iface.peers[i].rateStats[j].txMpdu);
             EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rx_mpdu,
@@ -402,23 +366,20 @@
 
     uint32_t hidle_caps;
 
-    uint32_t legacy_feature_set =
-        WIFI_FEATURE_D2D_RTT | WIFI_FEATURE_SET_LATENCY_MODE;
-    uint32_t legacy_logger_feature_set =
-        legacy_hal::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED;
+    uint32_t legacy_feature_set = WIFI_FEATURE_D2D_RTT | WIFI_FEATURE_SET_LATENCY_MODE;
+    uint32_t legacy_logger_feature_set = legacy_hal::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED;
 
     ASSERT_TRUE(hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities(
-        legacy_feature_set, legacy_logger_feature_set, &hidle_caps));
+            legacy_feature_set, legacy_logger_feature_set, &hidle_caps));
 
     EXPECT_EQ(HidlChipCaps::DEBUG_RING_BUFFER_VENDOR_DATA |
-                  HidlChipCaps::DEBUG_HOST_WAKE_REASON_STATS |
-                  HidlChipCaps::DEBUG_ERROR_ALERTS | HidlChipCaps::D2D_RTT |
-                  HidlChipCaps::SET_LATENCY_MODE |
-                  HidlChipCaps::DEBUG_MEMORY_DRIVER_DUMP,
+                      HidlChipCaps::DEBUG_HOST_WAKE_REASON_STATS |
+                      HidlChipCaps::DEBUG_ERROR_ALERTS | HidlChipCaps::D2D_RTT |
+                      HidlChipCaps::SET_LATENCY_MODE | HidlChipCaps::DEBUG_MEMORY_DRIVER_DUMP,
               hidle_caps);
 }
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/tests/main.cpp b/wifi/1.6/default/tests/main.cpp
similarity index 100%
rename from wifi/1.5/default/tests/main.cpp
rename to wifi/1.6/default/tests/main.cpp
diff --git a/wifi/1.5/default/tests/mock_interface_tool.cpp b/wifi/1.6/default/tests/mock_interface_tool.cpp
similarity index 100%
rename from wifi/1.5/default/tests/mock_interface_tool.cpp
rename to wifi/1.6/default/tests/mock_interface_tool.cpp
diff --git a/wifi/1.5/default/tests/mock_interface_tool.h b/wifi/1.6/default/tests/mock_interface_tool.h
similarity index 83%
rename from wifi/1.5/default/tests/mock_interface_tool.h
rename to wifi/1.6/default/tests/mock_interface_tool.h
index 0f17551..7ce3992 100644
--- a/wifi/1.5/default/tests/mock_interface_tool.h
+++ b/wifi/1.6/default/tests/mock_interface_tool.h
@@ -24,17 +24,15 @@
 namespace wifi_system {
 
 class MockInterfaceTool : public InterfaceTool {
-   public:
+  public:
     MockInterfaceTool();
 
     MOCK_METHOD1(GetUpState, bool(const char* if_name));
     MOCK_METHOD2(SetUpState, bool(const char* if_name, bool request_up));
     MOCK_METHOD1(SetWifiUpState, bool(bool request_up));
     MOCK_METHOD2(SetMacAddress,
-                 bool(const char* if_name,
-                      const std::array<uint8_t, ETH_ALEN>& address));
-    MOCK_METHOD1(GetFactoryMacAddress,
-                 std::array<uint8_t, ETH_ALEN>(const char* if_name));
+                 bool(const char* if_name, const std::array<uint8_t, ETH_ALEN>& address));
+    MOCK_METHOD1(GetFactoryMacAddress, std::array<uint8_t, ETH_ALEN>(const char* if_name));
 
 };  // class MockInterfaceTool
 
diff --git a/wifi/1.5/default/tests/mock_wifi_feature_flags.cpp b/wifi/1.6/default/tests/mock_wifi_feature_flags.cpp
similarity index 96%
rename from wifi/1.5/default/tests/mock_wifi_feature_flags.cpp
rename to wifi/1.6/default/tests/mock_wifi_feature_flags.cpp
index 2f66ba1..d10b74c 100644
--- a/wifi/1.5/default/tests/mock_wifi_feature_flags.cpp
+++ b/wifi/1.6/default/tests/mock_wifi_feature_flags.cpp
@@ -21,7 +21,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 namespace feature_flags {
 
@@ -29,7 +29,7 @@
 
 }  // namespace feature_flags
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/tests/mock_wifi_feature_flags.h b/wifi/1.6/default/tests/mock_wifi_feature_flags.h
similarity index 88%
rename from wifi/1.5/default/tests/mock_wifi_feature_flags.h
rename to wifi/1.6/default/tests/mock_wifi_feature_flags.h
index c3877ed..fa3600a 100644
--- a/wifi/1.5/default/tests/mock_wifi_feature_flags.h
+++ b/wifi/1.6/default/tests/mock_wifi_feature_flags.h
@@ -25,22 +25,21 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 namespace feature_flags {
 
 class MockWifiFeatureFlags : public WifiFeatureFlags {
-   public:
+  public:
     MockWifiFeatureFlags();
 
-    MOCK_METHOD1(getChipModes,
-                 std::vector<V1_0::IWifiChip::ChipMode>(bool is_primary));
+    MOCK_METHOD1(getChipModes, std::vector<V1_0::IWifiChip::ChipMode>(bool is_primary));
     MOCK_METHOD0(isApMacRandomizationDisabled, bool());
 };
 
 }  // namespace feature_flags
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/tests/mock_wifi_iface_util.cpp b/wifi/1.6/default/tests/mock_wifi_iface_util.cpp
similarity index 82%
rename from wifi/1.5/default/tests/mock_wifi_iface_util.cpp
rename to wifi/1.6/default/tests/mock_wifi_iface_util.cpp
index b101c4a..24b16cb 100644
--- a/wifi/1.5/default/tests/mock_wifi_iface_util.cpp
+++ b/wifi/1.6/default/tests/mock_wifi_iface_util.cpp
@@ -24,17 +24,16 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 namespace iface_util {
 
-MockWifiIfaceUtil::MockWifiIfaceUtil(
-    const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
-    const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
+MockWifiIfaceUtil::MockWifiIfaceUtil(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
+                                     const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
     : WifiIfaceUtil(iface_tool, legacy_hal) {}
 }  // namespace iface_util
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/tests/mock_wifi_iface_util.h b/wifi/1.6/default/tests/mock_wifi_iface_util.h
similarity index 71%
rename from wifi/1.5/default/tests/mock_wifi_iface_util.h
rename to wifi/1.6/default/tests/mock_wifi_iface_util.h
index 6d5f59c..2701c36 100644
--- a/wifi/1.5/default/tests/mock_wifi_iface_util.h
+++ b/wifi/1.6/default/tests/mock_wifi_iface_util.h
@@ -24,29 +24,25 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 namespace iface_util {
 
 class MockWifiIfaceUtil : public WifiIfaceUtil {
-   public:
-    MockWifiIfaceUtil(
-        const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
-        const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
-    MOCK_METHOD1(getFactoryMacAddress,
-                 std::array<uint8_t, 6>(const std::string&));
-    MOCK_METHOD2(setMacAddress,
-                 bool(const std::string&, const std::array<uint8_t, 6>&));
+  public:
+    MockWifiIfaceUtil(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
+                      const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
+    MOCK_METHOD1(getFactoryMacAddress, std::array<uint8_t, 6>(const std::string&));
+    MOCK_METHOD2(setMacAddress, bool(const std::string&, const std::array<uint8_t, 6>&));
     MOCK_METHOD0(getOrCreateRandomMacAddress, std::array<uint8_t, 6>());
-    MOCK_METHOD2(registerIfaceEventHandlers,
-                 void(const std::string&, IfaceEventHandlers));
+    MOCK_METHOD2(registerIfaceEventHandlers, void(const std::string&, IfaceEventHandlers));
     MOCK_METHOD1(unregisterIfaceEventHandlers, void(const std::string&));
     MOCK_METHOD2(setUpState, bool(const std::string&, bool));
     MOCK_METHOD1(ifNameToIndex, unsigned(const std::string&));
 };
 }  // namespace iface_util
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/tests/mock_wifi_legacy_hal.cpp b/wifi/1.6/default/tests/mock_wifi_legacy_hal.cpp
similarity index 83%
rename from wifi/1.5/default/tests/mock_wifi_legacy_hal.cpp
rename to wifi/1.6/default/tests/mock_wifi_legacy_hal.cpp
index d13c556..2c55861 100644
--- a/wifi/1.5/default/tests/mock_wifi_legacy_hal.cpp
+++ b/wifi/1.6/default/tests/mock_wifi_legacy_hal.cpp
@@ -24,17 +24,16 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 namespace legacy_hal {
 
-MockWifiLegacyHal::MockWifiLegacyHal(
-    const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
-    const wifi_hal_fn& fn, bool is_primary)
+MockWifiLegacyHal::MockWifiLegacyHal(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
+                                     const wifi_hal_fn& fn, bool is_primary)
     : WifiLegacyHal(iface_tool, fn, is_primary) {}
 }  // namespace legacy_hal
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.6/default/tests/mock_wifi_legacy_hal.h b/wifi/1.6/default/tests/mock_wifi_legacy_hal.h
new file mode 100644
index 0000000..b1f5327
--- /dev/null
+++ b/wifi/1.6/default/tests/mock_wifi_legacy_hal.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 MOCK_WIFI_LEGACY_HAL_H_
+#define MOCK_WIFI_LEGACY_HAL_H_
+
+#include <gmock/gmock.h>
+
+#include "wifi_legacy_hal.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+namespace legacy_hal {
+
+class MockWifiLegacyHal : public WifiLegacyHal {
+  public:
+    MockWifiLegacyHal(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
+                      const wifi_hal_fn& fn, bool is_primary);
+    MOCK_METHOD0(initialize, wifi_error());
+    MOCK_METHOD0(start, wifi_error());
+    MOCK_METHOD2(stop,
+                 wifi_error(std::unique_lock<std::recursive_mutex>*, const std::function<void()>&));
+    MOCK_METHOD2(setDfsFlag, wifi_error(const std::string&, bool));
+    MOCK_METHOD2(registerRadioModeChangeCallbackHandler,
+                 wifi_error(const std::string&, const on_radio_mode_change_callback&));
+    MOCK_METHOD1(getFirmwareVersion,
+                 std::pair<wifi_error, std::string>(const std::string& iface_name));
+    MOCK_METHOD1(getDriverVersion,
+                 std::pair<wifi_error, std::string>(const std::string& iface_name));
+
+    MOCK_METHOD2(selectTxPowerScenario,
+                 wifi_error(const std::string& iface_name, wifi_power_scenario scenario));
+    MOCK_METHOD1(resetTxPowerScenario, wifi_error(const std::string& iface_name));
+    MOCK_METHOD2(nanRegisterCallbackHandlers,
+                 wifi_error(const std::string&, const NanCallbackHandlers&));
+    MOCK_METHOD2(nanDisableRequest, wifi_error(const std::string&, transaction_id));
+    MOCK_METHOD3(nanDataInterfaceDelete,
+                 wifi_error(const std::string&, transaction_id, const std::string&));
+    MOCK_METHOD2(createVirtualInterface,
+                 wifi_error(const std::string& ifname, wifi_interface_type iftype));
+    MOCK_METHOD1(deleteVirtualInterface, wifi_error(const std::string& ifname));
+    MOCK_METHOD0(waitForDriverReady, wifi_error());
+};
+}  // namespace legacy_hal
+}  // namespace implementation
+}  // namespace V1_6
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+
+#endif  // MOCK_WIFI_LEGACY_HAL_H_
diff --git a/wifi/1.5/default/tests/mock_wifi_mode_controller.cpp b/wifi/1.6/default/tests/mock_wifi_mode_controller.cpp
similarity index 96%
rename from wifi/1.5/default/tests/mock_wifi_mode_controller.cpp
rename to wifi/1.6/default/tests/mock_wifi_mode_controller.cpp
index e7ab22a..446f829 100644
--- a/wifi/1.5/default/tests/mock_wifi_mode_controller.cpp
+++ b/wifi/1.6/default/tests/mock_wifi_mode_controller.cpp
@@ -24,14 +24,14 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 namespace mode_controller {
 
 MockWifiModeController::MockWifiModeController() : WifiModeController() {}
 }  // namespace mode_controller
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/tests/mock_wifi_mode_controller.h b/wifi/1.6/default/tests/mock_wifi_mode_controller.h
similarity index 96%
rename from wifi/1.5/default/tests/mock_wifi_mode_controller.h
rename to wifi/1.6/default/tests/mock_wifi_mode_controller.h
index b9151f1..addcc81 100644
--- a/wifi/1.5/default/tests/mock_wifi_mode_controller.h
+++ b/wifi/1.6/default/tests/mock_wifi_mode_controller.h
@@ -24,12 +24,12 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 namespace mode_controller {
 
 class MockWifiModeController : public WifiModeController {
-   public:
+  public:
     MockWifiModeController();
     MOCK_METHOD0(initialize, bool());
     MOCK_METHOD1(changeFirmwareMode, bool(IfaceType));
@@ -38,7 +38,7 @@
 };
 }  // namespace mode_controller
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/tests/ringbuffer_unit_tests.cpp b/wifi/1.6/default/tests/ringbuffer_unit_tests.cpp
similarity index 98%
rename from wifi/1.5/default/tests/ringbuffer_unit_tests.cpp
rename to wifi/1.6/default/tests/ringbuffer_unit_tests.cpp
index 6fd34ee..eb86194 100644
--- a/wifi/1.5/default/tests/ringbuffer_unit_tests.cpp
+++ b/wifi/1.6/default/tests/ringbuffer_unit_tests.cpp
@@ -24,11 +24,11 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 
 class RingbufferTest : public Test {
-   public:
+  public:
     const uint32_t maxBufferSize_ = 10;
     Ringbuffer buffer_{maxBufferSize_};
 };
@@ -91,7 +91,7 @@
     EXPECT_EQ(input, buffer_.getData().front());
 }
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/tests/runtests.sh b/wifi/1.6/default/tests/runtests.sh
similarity index 100%
rename from wifi/1.5/default/tests/runtests.sh
rename to wifi/1.6/default/tests/runtests.sh
diff --git a/wifi/1.5/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.6/default/tests/wifi_chip_unit_tests.cpp
similarity index 74%
rename from wifi/1.5/default/tests/wifi_chip_unit_tests.cpp
rename to wifi/1.6/default/tests/wifi_chip_unit_tests.cpp
index 0ad6f3e..5390411 100644
--- a/wifi/1.5/default/tests/wifi_chip_unit_tests.cpp
+++ b/wifi/1.6/default/tests/wifi_chip_unit_tests.cpp
@@ -41,11 +41,11 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 
 class WifiChipTest : public Test {
-   protected:
+  protected:
     void setupV1IfaceCombination() {
         // clang-format off
         const hidl_vec<V1_0::IWifiChip::ChipIfaceCombination> combinationsSta = {
@@ -59,8 +59,7 @@
             {feature_flags::chip_mode_ids::kV1Ap, combinationsAp}
         };
         // clang-format on
-        EXPECT_CALL(*feature_flags_, getChipModes(true))
-            .WillRepeatedly(testing::Return(modes));
+        EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
     }
 
     void setupV1_AwareIfaceCombination() {
@@ -76,8 +75,7 @@
             {feature_flags::chip_mode_ids::kV1Ap, combinationsAp}
         };
         // clang-format on
-        EXPECT_CALL(*feature_flags_, getChipModes(true))
-            .WillRepeatedly(testing::Return(modes));
+        EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
     }
 
     void setupV1_AwareDisabledApIfaceCombination() {
@@ -89,8 +87,7 @@
             {feature_flags::chip_mode_ids::kV1Sta, combinationsSta}
         };
         // clang-format on
-        EXPECT_CALL(*feature_flags_, getChipModes(true))
-            .WillRepeatedly(testing::Return(modes));
+        EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
     }
 
     void setupV2_AwareIfaceCombination() {
@@ -103,8 +100,7 @@
             {feature_flags::chip_mode_ids::kV3, combinations}
         };
         // clang-format on
-        EXPECT_CALL(*feature_flags_, getChipModes(true))
-            .WillRepeatedly(testing::Return(modes));
+        EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
     }
 
     void setupV2_AwareDisabledApIfaceCombination() {
@@ -116,8 +112,7 @@
             {feature_flags::chip_mode_ids::kV3, combinations}
         };
         // clang-format on
-        EXPECT_CALL(*feature_flags_, getChipModes(true))
-            .WillRepeatedly(testing::Return(modes));
+        EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
     }
 
     void setup_MultiIfaceCombination() {
@@ -129,39 +124,35 @@
             {feature_flags::chip_mode_ids::kV3, combinations}
         };
         // clang-format on
-        EXPECT_CALL(*feature_flags_, getChipModes(true))
-            .WillRepeatedly(testing::Return(modes));
+        EXPECT_CALL(*feature_flags_, getChipModes(true)).WillRepeatedly(testing::Return(modes));
     }
 
     void assertNumberOfModes(uint32_t num_modes) {
-        chip_->getAvailableModes(
-            [num_modes](const WifiStatus& status,
-                        const std::vector<WifiChip::ChipMode>& modes) {
-                ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-                // V2_Aware has 1 mode of operation.
-                ASSERT_EQ(num_modes, modes.size());
-            });
+        chip_->getAvailableModes([num_modes](const WifiStatus& status,
+                                             const std::vector<WifiChip::ChipMode>& modes) {
+            ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
+            // V2_Aware has 1 mode of operation.
+            ASSERT_EQ(num_modes, modes.size());
+        });
     }
 
     void findModeAndConfigureForIfaceType(const IfaceType& type) {
         // This should be aligned with kInvalidModeId in wifi_chip.cpp.
         ChipModeId mode_id = UINT32_MAX;
-        chip_->getAvailableModes(
-            [&mode_id, &type](const WifiStatus& status,
-                              const std::vector<WifiChip::ChipMode>& modes) {
-                ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-                for (const auto& mode : modes) {
-                    for (const auto& combination : mode.availableCombinations) {
-                        for (const auto& limit : combination.limits) {
-                            if (limit.types.end() !=
-                                std::find(limit.types.begin(),
-                                          limit.types.end(), type)) {
-                                mode_id = mode.id;
-                            }
+        chip_->getAvailableModes([&mode_id, &type](const WifiStatus& status,
+                                                   const std::vector<WifiChip::ChipMode>& modes) {
+            ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
+            for (const auto& mode : modes) {
+                for (const auto& combination : mode.availableCombinations) {
+                    for (const auto& limit : combination.limits) {
+                        if (limit.types.end() !=
+                            std::find(limit.types.begin(), limit.types.end(), type)) {
+                            mode_id = mode.id;
                         }
                     }
                 }
-            });
+            }
+        });
         ASSERT_NE(UINT32_MAX, mode_id);
 
         chip_->configureChip(mode_id, [](const WifiStatus& status) {
@@ -174,58 +165,53 @@
         std::string iface_name;
         if (type == IfaceType::AP) {
             chip_->createApIface(
-                [&iface_name](const WifiStatus& status,
-                              const sp<V1_0::IWifiApIface>& iface) {
-                    if (WifiStatusCode::SUCCESS == status.code) {
-                        ASSERT_NE(iface.get(), nullptr);
-                        iface->getName([&iface_name](const WifiStatus& status,
-                                                     const hidl_string& name) {
-                            ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-                            iface_name = name.c_str();
-                        });
-                    }
-                });
+                    [&iface_name](const WifiStatus& status, const sp<V1_0::IWifiApIface>& iface) {
+                        if (WifiStatusCode::SUCCESS == status.code) {
+                            ASSERT_NE(iface.get(), nullptr);
+                            iface->getName([&iface_name](const WifiStatus& status,
+                                                         const hidl_string& name) {
+                                ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
+                                iface_name = name.c_str();
+                            });
+                        }
+                    });
         } else if (type == IfaceType::NAN) {
             chip_->createNanIface(
-                [&iface_name](
-                    const WifiStatus& status,
-                    const sp<android::hardware::wifi::V1_0::IWifiNanIface>&
-                        iface) {
-                    if (WifiStatusCode::SUCCESS == status.code) {
-                        ASSERT_NE(iface.get(), nullptr);
-                        iface->getName([&iface_name](const WifiStatus& status,
-                                                     const hidl_string& name) {
-                            ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-                            iface_name = name.c_str();
-                        });
-                    }
-                });
+                    [&iface_name](const WifiStatus& status,
+                                  const sp<android::hardware::wifi::V1_0::IWifiNanIface>& iface) {
+                        if (WifiStatusCode::SUCCESS == status.code) {
+                            ASSERT_NE(iface.get(), nullptr);
+                            iface->getName([&iface_name](const WifiStatus& status,
+                                                         const hidl_string& name) {
+                                ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
+                                iface_name = name.c_str();
+                            });
+                        }
+                    });
         } else if (type == IfaceType::P2P) {
             chip_->createP2pIface(
-                [&iface_name](const WifiStatus& status,
-                              const sp<IWifiP2pIface>& iface) {
-                    if (WifiStatusCode::SUCCESS == status.code) {
-                        ASSERT_NE(iface.get(), nullptr);
-                        iface->getName([&iface_name](const WifiStatus& status,
-                                                     const hidl_string& name) {
-                            ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-                            iface_name = name.c_str();
-                        });
-                    }
-                });
+                    [&iface_name](const WifiStatus& status, const sp<IWifiP2pIface>& iface) {
+                        if (WifiStatusCode::SUCCESS == status.code) {
+                            ASSERT_NE(iface.get(), nullptr);
+                            iface->getName([&iface_name](const WifiStatus& status,
+                                                         const hidl_string& name) {
+                                ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
+                                iface_name = name.c_str();
+                            });
+                        }
+                    });
         } else if (type == IfaceType::STA) {
             chip_->createStaIface(
-                [&iface_name](const WifiStatus& status,
-                              const sp<V1_0::IWifiStaIface>& iface) {
-                    if (WifiStatusCode::SUCCESS == status.code) {
-                        ASSERT_NE(iface.get(), nullptr);
-                        iface->getName([&iface_name](const WifiStatus& status,
-                                                     const hidl_string& name) {
-                            ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-                            iface_name = name.c_str();
-                        });
-                    }
-                });
+                    [&iface_name](const WifiStatus& status, const sp<V1_0::IWifiStaIface>& iface) {
+                        if (WifiStatusCode::SUCCESS == status.code) {
+                            ASSERT_NE(iface.get(), nullptr);
+                            iface->getName([&iface_name](const WifiStatus& status,
+                                                         const hidl_string& name) {
+                                ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
+                                iface_name = name.c_str();
+                            });
+                        }
+                    });
         }
         return iface_name;
     }
@@ -253,13 +239,12 @@
     bool createRttController() {
         bool success = false;
         chip_->createRttController_1_4(
-            NULL, [&success](const WifiStatus& status,
-                             const sp<IWifiRttController>& rtt) {
-                if (WifiStatusCode::SUCCESS == status.code) {
-                    ASSERT_NE(rtt.get(), nullptr);
-                    success = true;
-                }
-            });
+                NULL, [&success](const WifiStatus& status, const sp<IWifiRttController>& rtt) {
+                    if (WifiStatusCode::SUCCESS == status.code) {
+                        ASSERT_NE(rtt.get(), nullptr);
+                        success = true;
+                    }
+                });
         return success;
     }
 
@@ -269,27 +254,25 @@
     ChipId chip_id_ = kFakeChipId;
     legacy_hal::wifi_hal_fn fake_func_table_;
     std::shared_ptr<NiceMock<wifi_system::MockInterfaceTool>> iface_tool_{
-        new NiceMock<wifi_system::MockInterfaceTool>};
+            new NiceMock<wifi_system::MockInterfaceTool>};
     std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
-        new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_,
-                                                    fake_func_table_, true)};
-    std::shared_ptr<NiceMock<mode_controller::MockWifiModeController>>
-        mode_controller_{new NiceMock<mode_controller::MockWifiModeController>};
+            new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_, fake_func_table_, true)};
+    std::shared_ptr<NiceMock<mode_controller::MockWifiModeController>> mode_controller_{
+            new NiceMock<mode_controller::MockWifiModeController>};
     std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{
-        new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_, legacy_hal_)};
-    std::shared_ptr<NiceMock<feature_flags::MockWifiFeatureFlags>>
-        feature_flags_{new NiceMock<feature_flags::MockWifiFeatureFlags>};
+            new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_, legacy_hal_)};
+    std::shared_ptr<NiceMock<feature_flags::MockWifiFeatureFlags>> feature_flags_{
+            new NiceMock<feature_flags::MockWifiFeatureFlags>};
 
-   public:
+  public:
     void SetUp() override {
-        chip_ =
-            new WifiChip(chip_id_, true, legacy_hal_, mode_controller_,
-                         iface_util_, feature_flags_, subsystemRestartHandler);
+        chip_ = new WifiChip(chip_id_, true, legacy_hal_, mode_controller_, iface_util_,
+                             feature_flags_, subsystemRestartHandler);
 
         EXPECT_CALL(*mode_controller_, changeFirmwareMode(testing::_))
-            .WillRepeatedly(testing::Return(true));
+                .WillRepeatedly(testing::Return(true));
         EXPECT_CALL(*legacy_hal_, start())
-            .WillRepeatedly(testing::Return(legacy_hal::WIFI_SUCCESS));
+                .WillRepeatedly(testing::Return(legacy_hal::WIFI_SUCCESS));
     }
 
     void TearDown() override {
@@ -305,7 +288,7 @@
 // Mode 1 - STA + P2P
 // Mode 2 - AP
 class WifiChipV1IfaceCombinationTest : public WifiChipTest {
-   public:
+  public:
     void SetUp() override {
         setupV1IfaceCombination();
         WifiChipTest::SetUp();
@@ -364,7 +347,7 @@
 // Mode 1 - STA + P2P/NAN
 // Mode 2 - AP
 class WifiChipV1_AwareIfaceCombinationTest : public WifiChipTest {
-   public:
+  public:
     void SetUp() override {
         setupV1_AwareIfaceCombination();
         WifiChipTest::SetUp();
@@ -393,30 +376,26 @@
     ASSERT_TRUE(createIface(IfaceType::AP).empty());
 }
 
-TEST_F(WifiChipV1_AwareIfaceCombinationTest,
-       StaMode_CreateStaP2p_ShouldSucceed) {
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaP2p_ShouldSucceed) {
     findModeAndConfigureForIfaceType(IfaceType::STA);
     ASSERT_FALSE(createIface(IfaceType::STA).empty());
     ASSERT_FALSE(createIface(IfaceType::P2P).empty());
 }
 
-TEST_F(WifiChipV1_AwareIfaceCombinationTest,
-       StaMode_CreateStaNan_ShouldSucceed) {
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaNan_ShouldSucceed) {
     findModeAndConfigureForIfaceType(IfaceType::STA);
     ASSERT_FALSE(createIface(IfaceType::STA).empty());
     ASSERT_FALSE(createIface(IfaceType::NAN).empty());
 }
 
-TEST_F(WifiChipV1_AwareIfaceCombinationTest,
-       StaMode_CreateStaP2PNan_ShouldFail) {
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaP2PNan_ShouldFail) {
     findModeAndConfigureForIfaceType(IfaceType::STA);
     ASSERT_FALSE(createIface(IfaceType::STA).empty());
     ASSERT_FALSE(createIface(IfaceType::P2P).empty());
     ASSERT_TRUE(createIface(IfaceType::NAN).empty());
 }
 
-TEST_F(WifiChipV1_AwareIfaceCombinationTest,
-       StaMode_CreateStaNan_AfterP2pRemove_ShouldSucceed) {
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaNan_AfterP2pRemove_ShouldSucceed) {
     findModeAndConfigureForIfaceType(IfaceType::STA);
     ASSERT_FALSE(createIface(IfaceType::STA).empty());
     const auto p2p_iface_name = createIface(IfaceType::P2P);
@@ -428,8 +407,7 @@
     ASSERT_FALSE(createIface(IfaceType::NAN).empty());
 }
 
-TEST_F(WifiChipV1_AwareIfaceCombinationTest,
-       StaMode_CreateStaP2p_AfterNanRemove_ShouldSucceed) {
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateStaP2p_AfterNanRemove_ShouldSucceed) {
     findModeAndConfigureForIfaceType(IfaceType::STA);
     ASSERT_FALSE(createIface(IfaceType::STA).empty());
     const auto nan_iface_name = createIface(IfaceType::NAN);
@@ -488,31 +466,27 @@
     findModeAndConfigureForIfaceType(IfaceType::STA);
     ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
     EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_))
-        .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
+            .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
     chip_->selectTxPowerScenario_1_2(
-        V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF,
-        [](const WifiStatus& status) {
-            ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-        });
+            V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF,
+            [](const WifiStatus& status) { ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); });
 }
 
 TEST_F(WifiChipV1_AwareIfaceCombinationTest, SelectTxScenarioWithOnlyAp) {
     findModeAndConfigureForIfaceType(IfaceType::AP);
     ASSERT_EQ(createIface(IfaceType::AP), "wlan0");
     EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_))
-        .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
+            .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
     chip_->selectTxPowerScenario_1_2(
-        V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF,
-        [](const WifiStatus& status) {
-            ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-        });
+            V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF,
+            [](const WifiStatus& status) { ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); });
 }
 
 ////////// V2 + Aware Iface Combinations ////////////
 // Mode 1 - STA + STA/AP
 //        - STA + P2P/NAN
 class WifiChipV2_AwareIfaceCombinationTest : public WifiChipTest {
-   public:
+  public:
     void SetUp() override {
         setupV2_AwareIfaceCombination();
         WifiChipTest::SetUp();
@@ -559,8 +533,7 @@
     ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
 }
 
-TEST_F(WifiChipV2_AwareIfaceCombinationTest,
-       CreateSta_AfterStaApRemove_ShouldSucceed) {
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateSta_AfterStaApRemove_ShouldSucceed) {
     findModeAndConfigureForIfaceType(IfaceType::STA);
     const auto sta_iface_name = createIface(IfaceType::STA);
     ASSERT_FALSE(sta_iface_name.empty());
@@ -594,8 +567,7 @@
     ASSERT_TRUE(createIface(IfaceType::NAN).empty());
 }
 
-TEST_F(WifiChipV2_AwareIfaceCombinationTest,
-       CreateStaNan_AfterP2pRemove_ShouldSucceed) {
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaNan_AfterP2pRemove_ShouldSucceed) {
     findModeAndConfigureForIfaceType(IfaceType::STA);
     ASSERT_FALSE(createIface(IfaceType::STA).empty());
     const auto p2p_iface_name = createIface(IfaceType::P2P);
@@ -607,8 +579,7 @@
     ASSERT_FALSE(createIface(IfaceType::NAN).empty());
 }
 
-TEST_F(WifiChipV2_AwareIfaceCombinationTest,
-       CreateStaP2p_AfterNanRemove_ShouldSucceed) {
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaP2p_AfterNanRemove_ShouldSucceed) {
     findModeAndConfigureForIfaceType(IfaceType::STA);
     ASSERT_FALSE(createIface(IfaceType::STA).empty());
     const auto nan_iface_name = createIface(IfaceType::NAN);
@@ -632,8 +603,7 @@
     ASSERT_TRUE(createIface(IfaceType::P2P).empty());
 }
 
-TEST_F(WifiChipV2_AwareIfaceCombinationTest,
-       StaMode_CreateStaNan_AfterP2pRemove_ShouldSucceed) {
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, StaMode_CreateStaNan_AfterP2pRemove_ShouldSucceed) {
     findModeAndConfigureForIfaceType(IfaceType::STA);
     ASSERT_FALSE(createIface(IfaceType::STA).empty());
     const auto p2p_iface_name = createIface(IfaceType::P2P);
@@ -645,8 +615,7 @@
     ASSERT_FALSE(createIface(IfaceType::NAN).empty());
 }
 
-TEST_F(WifiChipV2_AwareIfaceCombinationTest,
-       StaMode_CreateStaP2p_AfterNanRemove_ShouldSucceed) {
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, StaMode_CreateStaP2p_AfterNanRemove_ShouldSucceed) {
     findModeAndConfigureForIfaceType(IfaceType::STA);
     ASSERT_FALSE(createIface(IfaceType::STA).empty());
     const auto nan_iface_name = createIface(IfaceType::NAN);
@@ -658,8 +627,7 @@
     ASSERT_FALSE(createIface(IfaceType::P2P).empty());
 }
 
-TEST_F(WifiChipV2_AwareIfaceCombinationTest,
-       CreateStaAp_EnsureDifferentIfaceNames) {
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaAp_EnsureDifferentIfaceNames) {
     findModeAndConfigureForIfaceType(IfaceType::AP);
     const auto sta_iface_name = createIface(IfaceType::STA);
     const auto ap_iface_name = createIface(IfaceType::AP);
@@ -690,28 +658,23 @@
     findModeAndConfigureForIfaceType(IfaceType::STA);
     ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
     EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_))
-        .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
+            .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
     chip_->selectTxPowerScenario_1_2(
-        V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF,
-        [](const WifiStatus& status) {
-            ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-        });
+            V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF,
+            [](const WifiStatus& status) { ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); });
 }
 
 TEST_F(WifiChipV2_AwareIfaceCombinationTest, SelectTxScenarioWithOnlyAp) {
     findModeAndConfigureForIfaceType(IfaceType::AP);
     ASSERT_EQ(createIface(IfaceType::AP), "wlan1");
     EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan1", testing::_))
-        .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
+            .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
     chip_->selectTxPowerScenario_1_2(
-        V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF,
-        [](const WifiStatus& status) {
-            ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-        });
+            V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF,
+            [](const WifiStatus& status) { ASSERT_EQ(WifiStatusCode::SUCCESS, status.code); });
 }
 
-TEST_F(WifiChipV2_AwareIfaceCombinationTest,
-       InvalidateAndRemoveNanOnStaRemove) {
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, InvalidateAndRemoveNanOnStaRemove) {
     findModeAndConfigureForIfaceType(IfaceType::STA);
     ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
 
@@ -719,64 +682,55 @@
     ASSERT_EQ(createIface(IfaceType::NAN), "wlan0");
 
     // We should have 1 nan iface.
-    chip_->getNanIfaceNames(
-        [](const WifiStatus& status, const hidl_vec<hidl_string>& iface_names) {
-            ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-            ASSERT_EQ(iface_names.size(), 1u);
-            ASSERT_EQ(iface_names[0], "wlan0");
-        });
+    chip_->getNanIfaceNames([](const WifiStatus& status, const hidl_vec<hidl_string>& iface_names) {
+        ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
+        ASSERT_EQ(iface_names.size(), 1u);
+        ASSERT_EQ(iface_names[0], "wlan0");
+    });
     // Retrieve the exact iface object.
     sp<android::hardware::wifi::V1_0::IWifiNanIface> nan_iface;
-    chip_->getNanIface(
-        "wlan0",
-        [&nan_iface](
-            const WifiStatus& status,
-            const sp<android::hardware::wifi::V1_0::IWifiNanIface>& iface) {
-            ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-            ASSERT_NE(iface.get(), nullptr);
-            nan_iface = iface;
-        });
+    chip_->getNanIface("wlan0",
+                       [&nan_iface](const WifiStatus& status,
+                                    const sp<android::hardware::wifi::V1_0::IWifiNanIface>& iface) {
+                           ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
+                           ASSERT_NE(iface.get(), nullptr);
+                           nan_iface = iface;
+                       });
 
     // Remove the STA iface.
     removeIface(IfaceType::STA, "wlan0");
     // We should have 0 nan iface now.
-    chip_->getNanIfaceNames(
-        [](const WifiStatus& status, const hidl_vec<hidl_string>& iface_names) {
-            ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
-            ASSERT_EQ(iface_names.size(), 0u);
-        });
+    chip_->getNanIfaceNames([](const WifiStatus& status, const hidl_vec<hidl_string>& iface_names) {
+        ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
+        ASSERT_EQ(iface_names.size(), 0u);
+    });
     // Any operation on the nan iface object should return error now.
-    nan_iface->getName(
-        [](const WifiStatus& status, const std::string& /* iface_name */) {
-            ASSERT_EQ(WifiStatusCode::ERROR_WIFI_IFACE_INVALID, status.code);
-        });
+    nan_iface->getName([](const WifiStatus& status, const std::string& /* iface_name */) {
+        ASSERT_EQ(WifiStatusCode::ERROR_WIFI_IFACE_INVALID, status.code);
+    });
 }
 
-TEST_F(WifiChipV2_AwareIfaceCombinationTest,
-       InvalidateAndRemoveRttControllerOnStaRemove) {
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, InvalidateAndRemoveRttControllerOnStaRemove) {
     findModeAndConfigureForIfaceType(IfaceType::STA);
     ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
 
     // Create RTT controller
     sp<IWifiRttController> rtt_controller;
     chip_->createRttController_1_4(
-        NULL, [&rtt_controller](const WifiStatus& status,
-                                const sp<IWifiRttController>& rtt) {
-            if (WifiStatusCode::SUCCESS == status.code) {
-                ASSERT_NE(rtt.get(), nullptr);
-                rtt_controller = rtt;
-            }
-        });
+            NULL, [&rtt_controller](const WifiStatus& status, const sp<IWifiRttController>& rtt) {
+                if (WifiStatusCode::SUCCESS == status.code) {
+                    ASSERT_NE(rtt.get(), nullptr);
+                    rtt_controller = rtt;
+                }
+            });
 
     // Remove the STA iface.
     removeIface(IfaceType::STA, "wlan0");
 
     // Any operation on the rtt controller object should return error now.
-    rtt_controller->getBoundIface(
-        [](const WifiStatus& status, const sp<IWifiIface>& /* iface */) {
-            ASSERT_EQ(WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
-                      status.code);
-        });
+    rtt_controller->getBoundIface([](const WifiStatus& status, const sp<IWifiIface>& /* iface */) {
+        ASSERT_EQ(WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, status.code);
+    });
 }
 
 TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNanWithSharedNanIface) {
@@ -792,28 +746,24 @@
     property_set("wifi.aware.interface", "aware0");
     findModeAndConfigureForIfaceType(IfaceType::STA);
     ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
-    EXPECT_CALL(*iface_util_, ifNameToIndex("aware0"))
-        .WillOnce(testing::Return(4));
-    EXPECT_CALL(*iface_util_, setUpState("aware0", true))
-        .WillOnce(testing::Return(true));
+    EXPECT_CALL(*iface_util_, ifNameToIndex("aware0")).WillOnce(testing::Return(4));
+    EXPECT_CALL(*iface_util_, setUpState("aware0", true)).WillOnce(testing::Return(true));
     ASSERT_EQ(createIface(IfaceType::NAN), "aware0");
 
-    EXPECT_CALL(*iface_util_, setUpState("aware0", false))
-        .WillOnce(testing::Return(true));
+    EXPECT_CALL(*iface_util_, setUpState("aware0", false)).WillOnce(testing::Return(true));
     removeIface(IfaceType::NAN, "aware0");
 }
 
 ////////// V1 Iface Combinations when AP creation is disabled //////////
 class WifiChipV1_AwareDisabledApIfaceCombinationTest : public WifiChipTest {
-   public:
+  public:
     void SetUp() override {
         setupV1_AwareDisabledApIfaceCombination();
         WifiChipTest::SetUp();
     }
 };
 
-TEST_F(WifiChipV1_AwareDisabledApIfaceCombinationTest,
-       StaMode_CreateSta_ShouldSucceed) {
+TEST_F(WifiChipV1_AwareDisabledApIfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) {
     findModeAndConfigureForIfaceType(IfaceType::STA);
     ASSERT_FALSE(createIface(IfaceType::STA).empty());
     ASSERT_TRUE(createIface(IfaceType::AP).empty());
@@ -821,15 +771,14 @@
 
 ////////// V2 Iface Combinations when AP creation is disabled //////////
 class WifiChipV2_AwareDisabledApIfaceCombinationTest : public WifiChipTest {
-   public:
+  public:
     void SetUp() override {
         setupV2_AwareDisabledApIfaceCombination();
         WifiChipTest::SetUp();
     }
 };
 
-TEST_F(WifiChipV2_AwareDisabledApIfaceCombinationTest,
-       CreateSta_ShouldSucceed) {
+TEST_F(WifiChipV2_AwareDisabledApIfaceCombinationTest, CreateSta_ShouldSucceed) {
     findModeAndConfigureForIfaceType(IfaceType::STA);
     ASSERT_FALSE(createIface(IfaceType::STA).empty());
     ASSERT_TRUE(createIface(IfaceType::AP).empty());
@@ -837,7 +786,7 @@
 
 ////////// Hypothetical Iface Combination with multiple ifaces //////////
 class WifiChip_MultiIfaceTest : public WifiChipTest {
-   public:
+  public:
     void SetUp() override {
         setup_MultiIfaceCombination();
         WifiChipTest::SetUp();
@@ -899,7 +848,7 @@
     ASSERT_EQ(createIface(IfaceType::STA), "wlan3");
 }
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/tests/wifi_iface_util_unit_tests.cpp b/wifi/1.6/default/tests/wifi_iface_util_unit_tests.cpp
similarity index 82%
rename from wifi/1.5/default/tests/wifi_iface_util_unit_tests.cpp
rename to wifi/1.6/default/tests/wifi_iface_util_unit_tests.cpp
index 8b67bb8..cc9a334 100644
--- a/wifi/1.5/default/tests/wifi_iface_util_unit_tests.cpp
+++ b/wifi/1.6/default/tests/wifi_iface_util_unit_tests.cpp
@@ -32,8 +32,7 @@
 constexpr uint8_t kMacAddress[] = {0x02, 0x12, 0x45, 0x56, 0xab, 0xcc};
 constexpr char kIfaceName[] = "test-wlan0";
 
-bool isValidUnicastLocallyAssignedMacAddress(
-    const std::array<uint8_t, 6>& mac_address) {
+bool isValidUnicastLocallyAssignedMacAddress(const std::array<uint8_t, 6>& mac_address) {
     uint8_t first_byte = mac_address[0];
     return (first_byte & 0x3) == kValidUnicastLocallyAssignedMacAddressMask;
 }
@@ -42,17 +41,16 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 namespace iface_util {
 class WifiIfaceUtilTest : public Test {
-   protected:
+  protected:
     std::shared_ptr<NiceMock<wifi_system::MockInterfaceTool>> iface_tool_{
-        new NiceMock<wifi_system::MockInterfaceTool>};
+            new NiceMock<wifi_system::MockInterfaceTool>};
     legacy_hal::wifi_hal_fn fake_func_table_;
     std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
-        new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_,
-                                                    fake_func_table_, true)};
+            new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_, fake_func_table_, true)};
     WifiIfaceUtil* iface_util_ = new WifiIfaceUtil(iface_tool_, legacy_hal_);
 };
 
@@ -67,20 +65,17 @@
 
 TEST_F(WifiIfaceUtilTest, IfaceEventHandlers_SetMacAddress) {
     std::array<uint8_t, 6> mac_address = {};
-    std::copy(std::begin(kMacAddress), std::end(kMacAddress),
-              std::begin(mac_address));
+    std::copy(std::begin(kMacAddress), std::end(kMacAddress), std::begin(mac_address));
     EXPECT_CALL(*iface_tool_, SetMacAddress(testing::_, testing::_))
-        .WillRepeatedly(testing::Return(true));
+            .WillRepeatedly(testing::Return(true));
     EXPECT_CALL(*iface_tool_, SetUpState(testing::_, testing::_))
-        .WillRepeatedly(testing::Return(true));
+            .WillRepeatedly(testing::Return(true));
 
     // Register for iface state toggle events.
     bool callback_invoked = false;
     iface_util::IfaceEventHandlers event_handlers = {};
     event_handlers.on_state_toggle_off_on =
-        [&callback_invoked](const std::string& /* iface_name */) {
-            callback_invoked = true;
-        };
+            [&callback_invoked](const std::string& /* iface_name */) { callback_invoked = true; };
     iface_util_->registerIfaceEventHandlers(kIfaceName, event_handlers);
     // Invoke setMacAddress and ensure that the cb is invoked.
     ASSERT_TRUE(iface_util_->setMacAddress(kIfaceName, mac_address));
@@ -95,7 +90,7 @@
 }
 }  // namespace iface_util
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.6/default/tests/wifi_nan_iface_unit_tests.cpp b/wifi/1.6/default/tests/wifi_nan_iface_unit_tests.cpp
new file mode 100644
index 0000000..c7c566b
--- /dev/null
+++ b/wifi/1.6/default/tests/wifi_nan_iface_unit_tests.cpp
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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-base/macros.h>
+#include <cutils/properties.h>
+#include <gmock/gmock.h>
+
+#undef NAN  // This is weird, NAN is defined in bionic/libc/include/math.h:38
+#include "wifi_nan_iface.h"
+
+#include "mock_interface_tool.h"
+#include "mock_wifi_feature_flags.h"
+#include "mock_wifi_iface_util.h"
+#include "mock_wifi_legacy_hal.h"
+
+using testing::NiceMock;
+using testing::Return;
+using testing::Test;
+
+namespace {
+constexpr char kIfaceName[] = "mockWlan0";
+}  // namespace
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+
+using android::hardware::wifi::V1_2::NanDataPathConfirmInd;
+
+bool CaptureIfaceEventHandlers(const std::string& /* iface_name*/,
+                               iface_util::IfaceEventHandlers in_iface_event_handlers,
+                               iface_util::IfaceEventHandlers* out_iface_event_handlers) {
+    *out_iface_event_handlers = in_iface_event_handlers;
+    return true;
+}
+
+class MockNanIfaceEventCallback : public V1_5::IWifiNanIfaceEventCallback {
+  public:
+    MockNanIfaceEventCallback() = default;
+
+    MOCK_METHOD3(notifyCapabilitiesResponse,
+                 Return<void>(uint16_t, const WifiNanStatus&,
+                              const android::hardware::wifi::V1_0::NanCapabilities&));
+    MOCK_METHOD2(notifyEnableResponse, Return<void>(uint16_t, const WifiNanStatus&));
+    MOCK_METHOD2(notifyConfigResponse, Return<void>(uint16_t, const WifiNanStatus&));
+    MOCK_METHOD2(notifyDisableResponse, Return<void>(uint16_t, const WifiNanStatus&));
+    MOCK_METHOD3(notifyStartPublishResponse, Return<void>(uint16_t, const WifiNanStatus&, uint8_t));
+    MOCK_METHOD2(notifyStopPublishResponse, Return<void>(uint16_t, const WifiNanStatus&));
+    MOCK_METHOD3(notifyStartSubscribeResponse,
+                 Return<void>(uint16_t, const WifiNanStatus&, uint8_t));
+    MOCK_METHOD2(notifyStopSubscribeResponse, Return<void>(uint16_t, const WifiNanStatus&));
+    MOCK_METHOD2(notifyTransmitFollowupResponse, Return<void>(uint16_t, const WifiNanStatus&));
+    MOCK_METHOD2(notifyCreateDataInterfaceResponse, Return<void>(uint16_t, const WifiNanStatus&));
+    MOCK_METHOD2(notifyDeleteDataInterfaceResponse, Return<void>(uint16_t, const WifiNanStatus&));
+    MOCK_METHOD3(notifyInitiateDataPathResponse,
+                 Return<void>(uint16_t, const WifiNanStatus&, uint32_t));
+    MOCK_METHOD2(notifyRespondToDataPathIndicationResponse,
+                 Return<void>(uint16_t, const WifiNanStatus&));
+    MOCK_METHOD2(notifyTerminateDataPathResponse, Return<void>(uint16_t, const WifiNanStatus&));
+    MOCK_METHOD1(eventClusterEvent, Return<void>(const NanClusterEventInd&));
+    MOCK_METHOD1(eventDisabled, Return<void>(const WifiNanStatus&));
+    MOCK_METHOD2(eventPublishTerminated, Return<void>(uint8_t, const WifiNanStatus&));
+    MOCK_METHOD2(eventSubscribeTerminated, Return<void>(uint8_t, const WifiNanStatus&));
+    MOCK_METHOD1(eventMatch, Return<void>(const NanMatchInd&));
+    MOCK_METHOD2(eventMatchExpired, Return<void>(uint8_t, uint32_t));
+    MOCK_METHOD1(eventFollowupReceived, Return<void>(const NanFollowupReceivedInd&));
+    MOCK_METHOD2(eventTransmitFollowup, Return<void>(uint16_t, const WifiNanStatus&));
+    MOCK_METHOD1(eventDataPathRequest, Return<void>(const NanDataPathRequestInd&));
+    MOCK_METHOD1(eventDataPathConfirm,
+                 Return<void>(const android::hardware::wifi::V1_0::NanDataPathConfirmInd&));
+    MOCK_METHOD1(eventDataPathTerminated, Return<void>(uint32_t));
+    MOCK_METHOD1(eventDataPathConfirm_1_2, Return<void>(const NanDataPathConfirmInd&));
+    MOCK_METHOD1(eventDataPathScheduleUpdate, Return<void>(const NanDataPathScheduleUpdateInd&));
+    MOCK_METHOD3(notifyCapabilitiesResponse_1_5,
+                 Return<void>(uint16_t, const WifiNanStatus&, const V1_5::NanCapabilities&));
+};
+
+class WifiNanIfaceTest : public Test {
+  protected:
+    legacy_hal::wifi_hal_fn fake_func_table_;
+    std::shared_ptr<NiceMock<wifi_system::MockInterfaceTool>> iface_tool_{
+            new NiceMock<wifi_system::MockInterfaceTool>};
+    std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
+            new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_, fake_func_table_, true)};
+    std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{
+            new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_, legacy_hal_)};
+};
+
+TEST_F(WifiNanIfaceTest, IfacEventHandlers_OnStateToggleOffOn) {
+    iface_util::IfaceEventHandlers captured_iface_event_handlers = {};
+    EXPECT_CALL(*legacy_hal_, nanRegisterCallbackHandlers(testing::_, testing::_))
+            .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
+    EXPECT_CALL(*iface_util_, registerIfaceEventHandlers(testing::_, testing::_))
+            .WillOnce(testing::Invoke(bind(CaptureIfaceEventHandlers, std::placeholders::_1,
+                                           std::placeholders::_2, &captured_iface_event_handlers)));
+    sp<WifiNanIface> nan_iface = new WifiNanIface(kIfaceName, false, legacy_hal_, iface_util_);
+
+    // Register a mock nan event callback.
+    sp<NiceMock<MockNanIfaceEventCallback>> mock_event_callback{
+            new NiceMock<MockNanIfaceEventCallback>};
+    nan_iface->registerEventCallback(mock_event_callback, [](const WifiStatus& status) {
+        ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
+    });
+    // Ensure that the eventDisabled() function in mock callback will be
+    // invoked.
+    WifiNanStatus expected_nan_status = {NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""};
+    EXPECT_CALL(*mock_event_callback, eventDisabled(expected_nan_status)).Times(1);
+
+    // Trigger the iface state toggle callback.
+    captured_iface_event_handlers.on_state_toggle_off_on(kIfaceName);
+}
+}  // namespace implementation
+}  // namespace V1_6
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
diff --git a/wifi/1.5/default/wifi.cpp b/wifi/1.6/default/wifi.cpp
similarity index 74%
rename from wifi/1.5/default/wifi.cpp
rename to wifi/1.6/default/wifi.cpp
index a85b242..c302ce2 100644
--- a/wifi/1.5/default/wifi.cpp
+++ b/wifi/1.6/default/wifi.cpp
@@ -28,16 +28,15 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 using hidl_return_util::validateAndCall;
 using hidl_return_util::validateAndCallWithLock;
 
-Wifi::Wifi(
-    const std::shared_ptr<wifi_system::InterfaceTool> iface_tool,
-    const std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory,
-    const std::shared_ptr<mode_controller::WifiModeController> mode_controller,
-    const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags)
+Wifi::Wifi(const std::shared_ptr<wifi_system::InterfaceTool> iface_tool,
+           const std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory,
+           const std::shared_ptr<mode_controller::WifiModeController> mode_controller,
+           const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags)
     : iface_tool_(iface_tool),
       legacy_hal_factory_(legacy_hal_factory),
       mode_controller_(mode_controller),
@@ -49,46 +48,44 @@
     return true;
 }
 
-Return<void> Wifi::registerEventCallback(
-    const sp<V1_0::IWifiEventCallback>& event_callback,
-    registerEventCallback_cb hidl_status_cb) {
+Return<void> Wifi::registerEventCallback(const sp<V1_0::IWifiEventCallback>& event_callback,
+                                         registerEventCallback_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN,
-                           &Wifi::registerEventCallbackInternal, hidl_status_cb,
+                           &Wifi::registerEventCallbackInternal, hidl_status_cb, event_callback);
+}
+
+Return<void> Wifi::registerEventCallback_1_5(const sp<V1_5::IWifiEventCallback>& event_callback,
+                                             registerEventCallback_1_5_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN,
+                           &Wifi::registerEventCallbackInternal_1_5, hidl_status_cb,
                            event_callback);
 }
 
-Return<void> Wifi::registerEventCallback_1_5(
-    const sp<V1_5::IWifiEventCallback>& event_callback,
-    registerEventCallback_1_5_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN,
-                           &Wifi::registerEventCallbackInternal_1_5,
-                           hidl_status_cb, event_callback);
+Return<bool> Wifi::isStarted() {
+    return run_state_ != RunState::STOPPED;
 }
 
-Return<bool> Wifi::isStarted() { return run_state_ != RunState::STOPPED; }
-
 Return<void> Wifi::start(start_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN,
-                           &Wifi::startInternal, hidl_status_cb);
+    return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::startInternal,
+                           hidl_status_cb);
 }
 
 Return<void> Wifi::stop(stop_cb hidl_status_cb) {
-    return validateAndCallWithLock(this, WifiStatusCode::ERROR_UNKNOWN,
-                                   &Wifi::stopInternal, hidl_status_cb);
+    return validateAndCallWithLock(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::stopInternal,
+                                   hidl_status_cb);
 }
 
 Return<void> Wifi::getChipIds(getChipIds_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN,
-                           &Wifi::getChipIdsInternal, hidl_status_cb);
+    return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::getChipIdsInternal,
+                           hidl_status_cb);
 }
 
 Return<void> Wifi::getChip(ChipId chip_id, getChip_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN,
-                           &Wifi::getChipInternal, hidl_status_cb, chip_id);
+    return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::getChipInternal,
+                           hidl_status_cb, chip_id);
 }
 
-Return<void> Wifi::debug(const hidl_handle& handle,
-                         const hidl_vec<hidl_string>&) {
+Return<void> Wifi::debug(const hidl_handle& handle, const hidl_vec<hidl_string>&) {
     LOG(INFO) << "-----------Debug is called----------------";
     if (chips_.size() == 0) {
         return Void();
@@ -103,13 +100,13 @@
 }
 
 WifiStatus Wifi::registerEventCallbackInternal(
-    const sp<V1_0::IWifiEventCallback>& event_callback __unused) {
+        const sp<V1_0::IWifiEventCallback>& event_callback __unused) {
     // Deprecated support for this callback.
     return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
 }
 
 WifiStatus Wifi::registerEventCallbackInternal_1_5(
-    const sp<V1_5::IWifiEventCallback>& event_callback) {
+        const sp<V1_5::IWifiEventCallback>& event_callback) {
     if (!event_cb_handler_.addCallback(event_callback)) {
         return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
     }
@@ -120,36 +117,32 @@
     if (run_state_ == RunState::STARTED) {
         return createWifiStatus(WifiStatusCode::SUCCESS);
     } else if (run_state_ == RunState::STOPPING) {
-        return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE,
-                                "HAL is stopping");
+        return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, "HAL is stopping");
     }
     WifiStatus wifi_status = initializeModeControllerAndLegacyHal();
     if (wifi_status.code == WifiStatusCode::SUCCESS) {
         // Register the callback for subsystem restart
-        const auto& on_subsystem_restart_callback =
-            [this](const std::string& error) {
-                WifiStatus wifi_status =
-                    createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, error);
-                for (const auto& callback : event_cb_handler_.getCallbacks()) {
-                    LOG(INFO) << "Attempting to invoke onSubsystemRestart "
+        const auto& on_subsystem_restart_callback = [this](const std::string& error) {
+            WifiStatus wifi_status = createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, error);
+            for (const auto& callback : event_cb_handler_.getCallbacks()) {
+                LOG(INFO) << "Attempting to invoke onSubsystemRestart "
+                             "callback";
+                if (!callback->onSubsystemRestart(wifi_status).isOk()) {
+                    LOG(ERROR) << "Failed to invoke onSubsystemRestart callback";
+                } else {
+                    LOG(INFO) << "Succeeded to invoke onSubsystemRestart "
                                  "callback";
-                    if (!callback->onSubsystemRestart(wifi_status).isOk()) {
-                        LOG(ERROR)
-                            << "Failed to invoke onSubsystemRestart callback";
-                    } else {
-                        LOG(INFO) << "Succeeded to invoke onSubsystemRestart "
-                                     "callback";
-                    }
                 }
-            };
+            }
+        };
 
         // Create the chip instance once the HAL is started.
         android::hardware::wifi::V1_0::ChipId chipId = kPrimaryChipId;
         for (auto& hal : legacy_hals_) {
-            chips_.push_back(new WifiChip(
-                chipId, chipId == kPrimaryChipId, hal, mode_controller_,
-                std::make_shared<iface_util::WifiIfaceUtil>(iface_tool_, hal),
-                feature_flags_, on_subsystem_restart_callback));
+            chips_.push_back(
+                    new WifiChip(chipId, chipId == kPrimaryChipId, hal, mode_controller_,
+                                 std::make_shared<iface_util::WifiIfaceUtil>(iface_tool_, hal),
+                                 feature_flags_, on_subsystem_restart_callback));
             chipId++;
         }
         run_state_ = RunState::STARTED;
@@ -173,12 +166,11 @@
 }
 
 WifiStatus Wifi::stopInternal(
-    /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock) {
+        /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock) {
     if (run_state_ == RunState::STOPPED) {
         return createWifiStatus(WifiStatusCode::SUCCESS);
     } else if (run_state_ == RunState::STOPPING) {
-        return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE,
-                                "HAL is stopping");
+        return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE, "HAL is stopping");
     }
     // Clear the chip object and its child objects since the HAL is now
     // stopped.
@@ -220,8 +212,7 @@
     return {createWifiStatus(WifiStatusCode::SUCCESS), std::move(chip_ids)};
 }
 
-std::pair<WifiStatus, sp<V1_4::IWifiChip>> Wifi::getChipInternal(
-    ChipId chip_id) {
+std::pair<WifiStatus, sp<V1_4::IWifiChip>> Wifi::getChipInternal(ChipId chip_id) {
     for (auto& chip : chips_) {
         ChipId cand_id = getChipIdFromWifiChip(chip);
         if ((cand_id != UINT32_MAX) && (cand_id == chip_id))
@@ -238,8 +229,7 @@
     }
 
     legacy_hals_ = legacy_hal_factory_->getHals();
-    if (legacy_hals_.empty())
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+    if (legacy_hals_.empty()) return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
     int index = 0;  // for failure log
     for (auto& hal : legacy_hals_) {
         legacy_hal::wifi_error legacy_status = hal->initialize();
@@ -258,7 +248,7 @@
 }
 
 WifiStatus Wifi::stopLegacyHalAndDeinitializeModeController(
-    /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock) {
+        /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock) {
     legacy_hal::wifi_error legacy_status = legacy_hal::WIFI_SUCCESS;
     int index = 0;
 
@@ -298,7 +288,7 @@
     return chip_id;
 }
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/wifi.h b/wifi/1.6/default/wifi.h
similarity index 79%
rename from wifi/1.5/default/wifi.h
rename to wifi/1.6/default/wifi.h
index c94ef3f..435358e 100644
--- a/wifi/1.5/default/wifi.h
+++ b/wifi/1.6/default/wifi.h
@@ -21,7 +21,7 @@
 // headers. This wifi HAL uses an enum called NAN, which does not compile when
 // the macro is defined. Undefine NAN to work around it.
 #undef NAN
-#include <android/hardware/wifi/1.5/IWifi.h>
+#include <android/hardware/wifi/1.6/IWifi.h>
 
 #include <android-base/macros.h>
 #include <utils/Looper.h>
@@ -37,46 +37,41 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 
 /**
  * Root HIDL interface object used to control the Wifi HAL.
  */
-class Wifi : public V1_5::IWifi {
-   public:
+class Wifi : public V1_6::IWifi {
+  public:
     Wifi(const std::shared_ptr<wifi_system::InterfaceTool> iface_tool,
-         const std::shared_ptr<legacy_hal::WifiLegacyHalFactory>
-             legacy_hal_factory,
-         const std::shared_ptr<mode_controller::WifiModeController>
-             mode_controller,
+         const std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory,
+         const std::shared_ptr<mode_controller::WifiModeController> mode_controller,
          const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags);
 
     bool isValid();
 
     // HIDL methods exposed.
-    Return<void> registerEventCallback(
-        const sp<V1_0::IWifiEventCallback>& event_callback,
-        registerEventCallback_cb hidl_status_cb) override;
-    Return<void> registerEventCallback_1_5(
-        const sp<V1_5::IWifiEventCallback>& event_callback,
-        registerEventCallback_1_5_cb hidl_status_cb) override;
+    Return<void> registerEventCallback(const sp<V1_0::IWifiEventCallback>& event_callback,
+                                       registerEventCallback_cb hidl_status_cb) override;
+    Return<void> registerEventCallback_1_5(const sp<V1_5::IWifiEventCallback>& event_callback,
+                                           registerEventCallback_1_5_cb hidl_status_cb) override;
     Return<bool> isStarted() override;
     Return<void> start(start_cb hidl_status_cb) override;
     Return<void> stop(stop_cb hidl_status_cb) override;
     Return<void> getChipIds(getChipIds_cb hidl_status_cb) override;
     Return<void> getChip(ChipId chip_id, getChip_cb hidl_status_cb) override;
-    Return<void> debug(const hidl_handle& handle,
-                       const hidl_vec<hidl_string>& options) override;
+    Return<void> debug(const hidl_handle& handle, const hidl_vec<hidl_string>& options) override;
 
-   private:
+  private:
     enum class RunState { STOPPED, STARTED, STOPPING };
 
     // Corresponding worker functions for the HIDL methods.
     WifiStatus registerEventCallbackInternal(
-        const sp<V1_0::IWifiEventCallback>& event_callback __unused);
+            const sp<V1_0::IWifiEventCallback>& event_callback __unused);
     WifiStatus registerEventCallbackInternal_1_5(
-        const sp<V1_5::IWifiEventCallback>& event_callback);
+            const sp<V1_5::IWifiEventCallback>& event_callback);
     WifiStatus startInternal();
     WifiStatus stopInternal(std::unique_lock<std::recursive_mutex>* lock);
     std::pair<WifiStatus, std::vector<ChipId>> getChipIdsInternal();
@@ -84,7 +79,7 @@
 
     WifiStatus initializeModeControllerAndLegacyHal();
     WifiStatus stopLegacyHalAndDeinitializeModeController(
-        std::unique_lock<std::recursive_mutex>* lock);
+            std::unique_lock<std::recursive_mutex>* lock);
     ChipId getChipIdFromWifiChip(sp<WifiChip>& chip);
 
     // Instance is created in this root level |IWifi| HIDL interface object
@@ -96,14 +91,13 @@
     std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags_;
     RunState run_state_;
     std::vector<sp<WifiChip>> chips_;
-    hidl_callback_util::HidlCallbackHandler<V1_5::IWifiEventCallback>
-        event_cb_handler_;
+    hidl_callback_util::HidlCallbackHandler<V1_5::IWifiEventCallback> event_cb_handler_;
 
     DISALLOW_COPY_AND_ASSIGN(Wifi);
 };
 
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/wifi_ap_iface.cpp b/wifi/1.6/default/wifi_ap_iface.cpp
similarity index 75%
rename from wifi/1.5/default/wifi_ap_iface.cpp
rename to wifi/1.6/default/wifi_ap_iface.cpp
index 1ae7905..b2957db 100644
--- a/wifi/1.5/default/wifi_ap_iface.cpp
+++ b/wifi/1.6/default/wifi_ap_iface.cpp
@@ -24,14 +24,13 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 using hidl_return_util::validateAndCall;
 
-WifiApIface::WifiApIface(
-    const std::string& ifname, const std::vector<std::string>& instances,
-    const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
-    const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
+WifiApIface::WifiApIface(const std::string& ifname, const std::vector<std::string>& instances,
+                         const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+                         const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
     : ifname_(ifname),
       instances_(instances),
       legacy_hal_(legacy_hal),
@@ -43,14 +42,16 @@
     is_valid_ = false;
 }
 
-bool WifiApIface::isValid() { return is_valid_; }
+bool WifiApIface::isValid() {
+    return is_valid_;
+}
 
-std::string WifiApIface::getName() { return ifname_; }
+std::string WifiApIface::getName() {
+    return ifname_;
+}
 
 void WifiApIface::removeInstance(std::string instance) {
-    instances_.erase(
-        std::remove(instances_.begin(), instances_.end(), instance),
-        instances_.end());
+    instances_.erase(std::remove(instances_.begin(), instances_.end(), instance), instances_.end());
 }
 
 Return<void> WifiApIface::getName(getName_cb hidl_status_cb) {
@@ -66,44 +67,35 @@
 Return<void> WifiApIface::setCountryCode(const hidl_array<int8_t, 2>& code,
                                          setCountryCode_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiApIface::setCountryCodeInternal, hidl_status_cb,
-                           code);
+                           &WifiApIface::setCountryCodeInternal, hidl_status_cb, code);
 }
 
-Return<void> WifiApIface::getValidFrequenciesForBand(
-    V1_0::WifiBand band, getValidFrequenciesForBand_cb hidl_status_cb) {
+Return<void> WifiApIface::getValidFrequenciesForBand(V1_0::WifiBand band,
+                                                     getValidFrequenciesForBand_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiApIface::getValidFrequenciesForBandInternal,
-                           hidl_status_cb, band);
+                           &WifiApIface::getValidFrequenciesForBandInternal, hidl_status_cb, band);
 }
 
 Return<void> WifiApIface::setMacAddress(const hidl_array<uint8_t, 6>& mac,
                                         setMacAddress_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiApIface::setMacAddressInternal, hidl_status_cb,
-                           mac);
+                           &WifiApIface::setMacAddressInternal, hidl_status_cb, mac);
 }
 
-Return<void> WifiApIface::getFactoryMacAddress(
-    getFactoryMacAddress_cb hidl_status_cb) {
+Return<void> WifiApIface::getFactoryMacAddress(getFactoryMacAddress_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiApIface::getFactoryMacAddressInternal,
-                           hidl_status_cb,
+                           &WifiApIface::getFactoryMacAddressInternal, hidl_status_cb,
                            instances_.size() > 0 ? instances_[0] : ifname_);
 }
 
-Return<void> WifiApIface::resetToFactoryMacAddress(
-    resetToFactoryMacAddress_cb hidl_status_cb) {
+Return<void> WifiApIface::resetToFactoryMacAddress(resetToFactoryMacAddress_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiApIface::resetToFactoryMacAddressInternal,
-                           hidl_status_cb);
+                           &WifiApIface::resetToFactoryMacAddressInternal, hidl_status_cb);
 }
 
-Return<void> WifiApIface::getBridgedInstances(
-    getBridgedInstances_cb hidl_status_cb) {
+Return<void> WifiApIface::getBridgedInstances(getBridgedInstances_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiApIface::getBridgedInstancesInternal,
-                           hidl_status_cb);
+                           &WifiApIface::getBridgedInstancesInternal, hidl_status_cb);
 }
 
 std::pair<WifiStatus, std::string> WifiApIface::getNameInternal() {
@@ -114,28 +106,24 @@
     return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::AP};
 }
 
-WifiStatus WifiApIface::setCountryCodeInternal(
-    const std::array<int8_t, 2>& code) {
+WifiStatus WifiApIface::setCountryCodeInternal(const std::array<int8_t, 2>& code) {
     legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setCountryCode(
-        instances_.size() > 0 ? instances_[0] : ifname_, code);
+            instances_.size() > 0 ? instances_[0] : ifname_, code);
     return createWifiStatusFromLegacyError(legacy_status);
 }
 
 std::pair<WifiStatus, std::vector<WifiChannelInMhz>>
 WifiApIface::getValidFrequenciesForBandInternal(V1_0::WifiBand band) {
-    static_assert(sizeof(WifiChannelInMhz) == sizeof(uint32_t),
-                  "Size mismatch");
+    static_assert(sizeof(WifiChannelInMhz) == sizeof(uint32_t), "Size mismatch");
     legacy_hal::wifi_error legacy_status;
     std::vector<uint32_t> valid_frequencies;
-    std::tie(legacy_status, valid_frequencies) =
-        legacy_hal_.lock()->getValidFrequenciesForBand(
+    std::tie(legacy_status, valid_frequencies) = legacy_hal_.lock()->getValidFrequenciesForBand(
             instances_.size() > 0 ? instances_[0] : ifname_,
             hidl_struct_util::convertHidlWifiBandToLegacy(band));
     return {createWifiStatusFromLegacyError(legacy_status), valid_frequencies};
 }
 
-WifiStatus WifiApIface::setMacAddressInternal(
-    const std::array<uint8_t, 6>& mac) {
+WifiStatus WifiApIface::setMacAddressInternal(const std::array<uint8_t, 6>& mac) {
     // Support random MAC up to 2 interfaces
     if (instances_.size() == 2) {
         int rbyte = 1;
@@ -160,12 +148,10 @@
     return createWifiStatus(WifiStatusCode::SUCCESS);
 }
 
-std::pair<WifiStatus, std::array<uint8_t, 6>>
-WifiApIface::getFactoryMacAddressInternal(const std::string& ifaceName) {
-    std::array<uint8_t, 6> mac =
-        iface_util_.lock()->getFactoryMacAddress(ifaceName);
-    if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 &&
-        mac[4] == 0 && mac[5] == 0) {
+std::pair<WifiStatus, std::array<uint8_t, 6>> WifiApIface::getFactoryMacAddressInternal(
+        const std::string& ifaceName) {
+    std::array<uint8_t, 6> mac = iface_util_.lock()->getFactoryMacAddress(ifaceName);
+    if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 && mac[4] == 0 && mac[5] == 0) {
         return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), mac};
     }
     return {createWifiStatus(WifiStatusCode::SUCCESS), mac};
@@ -188,10 +174,9 @@
         // bridged interface even if we got the request to reset the Factory
         // MAC. Since the bridged interface is an internal interface for the
         // operation of bpf and others networking operation.
-        if (!iface_util_.lock()->setMacAddress(
-                ifname_, iface_util_.lock()->createRandomMacAddress())) {
-            LOG(ERROR) << "Fail to config MAC for bridged interface "
-                       << ifname_;
+        if (!iface_util_.lock()->setMacAddress(ifname_,
+                                               iface_util_.lock()->createRandomMacAddress())) {
+            LOG(ERROR) << "Fail to config MAC for bridged interface " << ifname_;
             return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
         }
     } else {
@@ -205,8 +190,7 @@
     return createWifiStatus(WifiStatusCode::SUCCESS);
 }
 
-std::pair<WifiStatus, std::vector<hidl_string>>
-WifiApIface::getBridgedInstancesInternal() {
+std::pair<WifiStatus, std::vector<hidl_string>> WifiApIface::getBridgedInstancesInternal() {
     std::vector<hidl_string> instances;
     for (const auto& instance_name : instances_) {
         instances.push_back(instance_name);
@@ -214,7 +198,7 @@
     return {createWifiStatus(WifiStatusCode::SUCCESS), instances};
 }
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/wifi_ap_iface.h b/wifi/1.6/default/wifi_ap_iface.h
similarity index 75%
rename from wifi/1.5/default/wifi_ap_iface.h
rename to wifi/1.6/default/wifi_ap_iface.h
index 8f8387d..d1c0642 100644
--- a/wifi/1.5/default/wifi_ap_iface.h
+++ b/wifi/1.6/default/wifi_ap_iface.h
@@ -26,7 +26,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 using namespace android::hardware::wifi::V1_0;
 
@@ -34,9 +34,8 @@
  * HIDL interface object used to control a AP Iface instance.
  */
 class WifiApIface : public V1_5::IWifiApIface {
-   public:
-    WifiApIface(const std::string& ifname,
-                const std::vector<std::string>& instances,
+  public:
+    WifiApIface(const std::string& ifname, const std::vector<std::string>& instances,
                 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
                 const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
     // Refer to |WifiChip::invalidate()|.
@@ -50,32 +49,27 @@
     Return<void> getType(getType_cb hidl_status_cb) override;
     Return<void> setCountryCode(const hidl_array<int8_t, 2>& code,
                                 setCountryCode_cb hidl_status_cb) override;
-    Return<void> getValidFrequenciesForBand(
-        V1_0::WifiBand band,
-        getValidFrequenciesForBand_cb hidl_status_cb) override;
+    Return<void> getValidFrequenciesForBand(V1_0::WifiBand band,
+                                            getValidFrequenciesForBand_cb hidl_status_cb) override;
     Return<void> setMacAddress(const hidl_array<uint8_t, 6>& mac,
                                setMacAddress_cb hidl_status_cb) override;
-    Return<void> getFactoryMacAddress(
-        getFactoryMacAddress_cb hidl_status_cb) override;
-    Return<void> resetToFactoryMacAddress(
-        resetToFactoryMacAddress_cb hidl_status_cb) override;
+    Return<void> getFactoryMacAddress(getFactoryMacAddress_cb hidl_status_cb) override;
+    Return<void> resetToFactoryMacAddress(resetToFactoryMacAddress_cb hidl_status_cb) override;
 
-    Return<void> getBridgedInstances(
-        getBridgedInstances_cb hidl_status_cb) override;
+    Return<void> getBridgedInstances(getBridgedInstances_cb hidl_status_cb) override;
 
-   private:
+  private:
     // Corresponding worker functions for the HIDL methods.
     std::pair<WifiStatus, std::string> getNameInternal();
     std::pair<WifiStatus, IfaceType> getTypeInternal();
     WifiStatus setCountryCodeInternal(const std::array<int8_t, 2>& code);
-    std::pair<WifiStatus, std::vector<WifiChannelInMhz>>
-    getValidFrequenciesForBandInternal(V1_0::WifiBand band);
+    std::pair<WifiStatus, std::vector<WifiChannelInMhz>> getValidFrequenciesForBandInternal(
+            V1_0::WifiBand band);
     WifiStatus setMacAddressInternal(const std::array<uint8_t, 6>& mac);
     std::pair<WifiStatus, std::array<uint8_t, 6>> getFactoryMacAddressInternal(
-        const std::string& ifaceName);
+            const std::string& ifaceName);
     WifiStatus resetToFactoryMacAddressInternal();
-    std::pair<WifiStatus, std::vector<hidl_string>>
-    getBridgedInstancesInternal();
+    std::pair<WifiStatus, std::vector<hidl_string>> getBridgedInstancesInternal();
 
     std::string ifname_;
     std::vector<std::string> instances_;
@@ -87,7 +81,7 @@
 };
 
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.6/default/wifi_chip.cpp
similarity index 72%
rename from wifi/1.5/default/wifi_chip.cpp
rename to wifi/1.6/default/wifi_chip.cpp
index 6bdff42..c1ce766 100644
--- a/wifi/1.5/default/wifi_chip.cpp
+++ b/wifi/1.6/default/wifi_chip.cpp
@@ -52,8 +52,7 @@
 template <typename Iface>
 void invalidateAndClear(std::vector<sp<Iface>>& ifaces, sp<Iface> iface) {
     iface->invalidate();
-    ifaces.erase(std::remove(ifaces.begin(), ifaces.end(), iface),
-                 ifaces.end());
+    ifaces.erase(std::remove(ifaces.begin(), ifaces.end(), iface), ifaces.end());
 }
 
 template <typename Iface>
@@ -74,8 +73,7 @@
 }
 
 template <typename Iface>
-sp<Iface> findUsingName(std::vector<sp<Iface>>& ifaces,
-                        const std::string& name) {
+sp<Iface> findUsingName(std::vector<sp<Iface>>& ifaces, const std::string& name) {
     std::vector<hidl_string> names;
     for (const auto& iface : ifaces) {
         if (name == iface->getName()) {
@@ -93,8 +91,7 @@
 
     std::array<char, PROPERTY_VALUE_MAX> buffer;
     if (idx == 0 || idx == 1) {
-        const char* altPropName =
-            (idx == 0) ? "wifi.interface" : "wifi.concurrent.interface";
+        const char* altPropName = (idx == 0) ? "wifi.interface" : "wifi.concurrent.interface";
         auto res = property_get(altPropName, buffer.data(), nullptr);
         if (res > 0) return buffer.data();
     }
@@ -111,15 +108,13 @@
     std::vector<std::string> ifnames;
     std::array<char, PROPERTY_VALUE_MAX> buffer;
     buffer.fill(0);
-    if (property_get("ro.vendor.wifi.sap.interface", buffer.data(), nullptr) ==
-        0) {
+    if (property_get("ro.vendor.wifi.sap.interface", buffer.data(), nullptr) == 0) {
         return ifnames;
     }
     ifnames.push_back(buffer.data());
     if (is_bridged) {
         buffer.fill(0);
-        if (property_get("ro.vendor.wifi.sap.concurrent.iface", buffer.data(),
-                         nullptr) == 0) {
+        if (property_get("ro.vendor.wifi.sap.concurrent.iface", buffer.data(), nullptr) == 0) {
             return ifnames;
         }
         ifnames.push_back(buffer.data());
@@ -133,29 +128,25 @@
     std::string p2pDevIfName = "";
     std::array<char, PROPERTY_VALUE_MAX> buffer;
     property_get("wifi.direct.interface", buffer.data(), "p2p0");
-    if (strncmp(buffer.data(), P2P_MGMT_DEVICE_PREFIX,
-                strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
+    if (strncmp(buffer.data(), P2P_MGMT_DEVICE_PREFIX, strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
         /* Get the p2p parent interface name from p2p device interface name set
          * in property */
         strncpy(p2pParentIfname, buffer.data() + strlen(P2P_MGMT_DEVICE_PREFIX),
                 strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX));
-        if (property_get(kActiveWlanIfaceNameProperty, primaryIfaceName.data(),
-                         nullptr) == 0) {
+        if (property_get(kActiveWlanIfaceNameProperty, primaryIfaceName.data(), nullptr) == 0) {
             return buffer.data();
         }
         /* Check if the parent interface derived from p2p device interface name
          * is active */
         if (strncmp(p2pParentIfname, primaryIfaceName.data(),
-                    strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX)) !=
-            0) {
+                    strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX)) != 0) {
             /*
              * Update the predefined p2p device interface parent interface name
              * with current active wlan interface
              */
             p2pDevIfName += P2P_MGMT_DEVICE_PREFIX;
             p2pDevIfName += primaryIfaceName.data();
-            LOG(INFO) << "update the p2p device interface name to "
-                      << p2pDevIfName.c_str();
+            LOG(INFO) << "update the p2p device interface name to " << p2pDevIfName.c_str();
             return p2pDevIfName;
         }
     }
@@ -184,8 +175,7 @@
 bool removeOldFilesInternal() {
     time_t now = time(0);
     const time_t delete_files_before = now - kMaxRingBufferFileAgeSeconds;
-    std::unique_ptr<DIR, decltype(&closedir)> dir_dump(
-        opendir(kTombstoneFolderPath), closedir);
+    std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(kTombstoneFolderPath), closedir);
     if (!dir_dump) {
         PLOG(ERROR) << "Failed to open directory";
         return false;
@@ -206,15 +196,13 @@
             continue;
         }
         const time_t cur_file_time = cur_file_stat.st_mtime;
-        valid_files.push_back(
-            std::pair<const time_t, std::string>(cur_file_time, cur_file_path));
+        valid_files.push_back(std::pair<const time_t, std::string>(cur_file_time, cur_file_path));
     }
     valid_files.sort();  // sort the list of files by last modified time from
                          // small to big.
     uint32_t cur_file_count = valid_files.size();
     for (auto cur_file : valid_files) {
-        if (cur_file_count > kMaxRingBufferFileNum ||
-            cur_file.first < delete_files_before) {
+        if (cur_file_count > kMaxRingBufferFileNum || cur_file.first < delete_files_before) {
             if (unlink(cur_file.second.c_str()) != 0) {
                 PLOG(ERROR) << "Error deleting file";
                 success = false;
@@ -228,17 +216,14 @@
 }
 
 // Helper function for |cpioArchiveFilesInDir|
-bool cpioWriteHeader(int out_fd, struct stat& st, const char* file_name,
-                     size_t file_name_len) {
+bool cpioWriteHeader(int out_fd, struct stat& st, const char* file_name, size_t file_name_len) {
     std::array<char, 32 * 1024> read_buf;
     ssize_t llen =
-        sprintf(read_buf.data(),
-                "%s%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X",
-                kCpioMagic, static_cast<int>(st.st_ino), st.st_mode, st.st_uid,
-                st.st_gid, static_cast<int>(st.st_nlink),
-                static_cast<int>(st.st_mtime), static_cast<int>(st.st_size),
-                major(st.st_dev), minor(st.st_dev), major(st.st_rdev),
-                minor(st.st_rdev), static_cast<uint32_t>(file_name_len), 0);
+            sprintf(read_buf.data(), "%s%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X",
+                    kCpioMagic, static_cast<int>(st.st_ino), st.st_mode, st.st_uid, st.st_gid,
+                    static_cast<int>(st.st_nlink), static_cast<int>(st.st_mtime),
+                    static_cast<int>(st.st_size), major(st.st_dev), minor(st.st_dev),
+                    major(st.st_rdev), minor(st.st_rdev), static_cast<uint32_t>(file_name_len), 0);
     if (write(out_fd, read_buf.data(), llen) == -1) {
         PLOG(ERROR) << "Error writing cpio header to file " << file_name;
         return false;
@@ -300,9 +285,7 @@
     std::array<char, 4096> read_buf;
     read_buf.fill(0);
     if (write(out_fd, read_buf.data(),
-              sprintf(read_buf.data(), "070701%040X%056X%08XTRAILER!!!", 1,
-                      0x0b, 0) +
-                  4) == -1) {
+              sprintf(read_buf.data(), "070701%040X%056X%08XTRAILER!!!", 1, 0x0b, 0) + 4) == -1) {
         PLOG(ERROR) << "Error writing trailing bytes";
         return false;
     }
@@ -315,8 +298,7 @@
 size_t cpioArchiveFilesInDir(int out_fd, const char* input_dir) {
     struct dirent* dp;
     size_t n_error = 0;
-    std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(input_dir),
-                                                       closedir);
+    std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(input_dir), closedir);
     if (!dir_dump) {
         PLOG(ERROR) << "Failed to open directory";
         return ++n_error;
@@ -340,14 +322,12 @@
             continue;
         }
         std::string file_name_with_last_modified_time =
-            cur_file_name + "-" + std::to_string(st.st_mtime);
+                cur_file_name + "-" + std::to_string(st.st_mtime);
         // string.size() does not include the null terminator. The cpio FreeBSD
         // file header expects the null character to be included in the length.
-        const size_t file_name_len =
-            file_name_with_last_modified_time.size() + 1;
+        const size_t file_name_len = file_name_with_last_modified_time.size() + 1;
         unique_fd file_auto_closer(fd_read);
-        if (!cpioWriteHeader(out_fd, st,
-                             file_name_with_last_modified_time.c_str(),
+        if (!cpioWriteHeader(out_fd, st, file_name_with_last_modified_time.c_str(),
                              file_name_len)) {
             return ++n_error;
         }
@@ -375,18 +355,17 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 using hidl_return_util::validateAndCall;
 using hidl_return_util::validateAndCallWithLock;
 
-WifiChip::WifiChip(
-    ChipId chip_id, bool is_primary,
-    const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
-    const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
-    const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
-    const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
-    const std::function<void(const std::string&)>& handler)
+WifiChip::WifiChip(ChipId chip_id, bool is_primary,
+                   const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+                   const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
+                   const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
+                   const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
+                   const std::function<void(const std::string&)>& handler)
     : chip_id_(chip_id),
       legacy_hal_(legacy_hal),
       mode_controller_(mode_controller),
@@ -410,24 +389,25 @@
     is_valid_ = false;
 }
 
-bool WifiChip::isValid() { return is_valid_; }
+bool WifiChip::isValid() {
+    return is_valid_;
+}
 
 std::set<sp<V1_4::IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
     return event_cb_handler_.getCallbacks();
 }
 
 Return<void> WifiChip::getId(getId_cb hidl_status_cb) {
-    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getIdInternal, hidl_status_cb);
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::getIdInternal,
+                           hidl_status_cb);
 }
 
 // Deprecated support for this callback
-Return<void> WifiChip::registerEventCallback(
-    const sp<V1_0::IWifiChipEventCallback>& event_callback,
-    registerEventCallback_cb hidl_status_cb) {
+Return<void> WifiChip::registerEventCallback(const sp<V1_0::IWifiChipEventCallback>& event_callback,
+                                             registerEventCallback_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::registerEventCallbackInternal,
-                           hidl_status_cb, event_callback);
+                           &WifiChip::registerEventCallbackInternal, hidl_status_cb,
+                           event_callback);
 }
 
 Return<void> WifiChip::getCapabilities(getCapabilities_cb hidl_status_cb) {
@@ -437,15 +417,12 @@
 
 Return<void> WifiChip::getAvailableModes(getAvailableModes_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getAvailableModesInternal,
-                           hidl_status_cb);
+                           &WifiChip::getAvailableModesInternal, hidl_status_cb);
 }
 
-Return<void> WifiChip::configureChip(ChipModeId mode_id,
-                                     configureChip_cb hidl_status_cb) {
-    return validateAndCallWithLock(
-        this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-        &WifiChip::configureChipInternal, hidl_status_cb, mode_id);
+Return<void> WifiChip::configureChip(ChipModeId mode_id, configureChip_cb hidl_status_cb) {
+    return validateAndCallWithLock(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                                   &WifiChip::configureChipInternal, hidl_status_cb, mode_id);
 }
 
 Return<void> WifiChip::getMode(getMode_cb hidl_status_cb) {
@@ -453,25 +430,19 @@
                            &WifiChip::getModeInternal, hidl_status_cb);
 }
 
-Return<void> WifiChip::requestChipDebugInfo(
-    requestChipDebugInfo_cb hidl_status_cb) {
+Return<void> WifiChip::requestChipDebugInfo(requestChipDebugInfo_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::requestChipDebugInfoInternal,
-                           hidl_status_cb);
+                           &WifiChip::requestChipDebugInfoInternal, hidl_status_cb);
 }
 
-Return<void> WifiChip::requestDriverDebugDump(
-    requestDriverDebugDump_cb hidl_status_cb) {
+Return<void> WifiChip::requestDriverDebugDump(requestDriverDebugDump_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::requestDriverDebugDumpInternal,
-                           hidl_status_cb);
+                           &WifiChip::requestDriverDebugDumpInternal, hidl_status_cb);
 }
 
-Return<void> WifiChip::requestFirmwareDebugDump(
-    requestFirmwareDebugDump_cb hidl_status_cb) {
+Return<void> WifiChip::requestFirmwareDebugDump(requestFirmwareDebugDump_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::requestFirmwareDebugDumpInternal,
-                           hidl_status_cb);
+                           &WifiChip::requestFirmwareDebugDumpInternal, hidl_status_cb);
 }
 
 Return<void> WifiChip::createApIface(createApIface_cb hidl_status_cb) {
@@ -479,11 +450,9 @@
                            &WifiChip::createApIfaceInternal, hidl_status_cb);
 }
 
-Return<void> WifiChip::createBridgedApIface(
-    createBridgedApIface_cb hidl_status_cb) {
+Return<void> WifiChip::createBridgedApIface(createBridgedApIface_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::createBridgedApIfaceInternal,
-                           hidl_status_cb);
+                           &WifiChip::createBridgedApIfaceInternal, hidl_status_cb);
 }
 
 Return<void> WifiChip::getApIfaceNames(getApIfaceNames_cb hidl_status_cb) {
@@ -491,27 +460,22 @@
                            &WifiChip::getApIfaceNamesInternal, hidl_status_cb);
 }
 
-Return<void> WifiChip::getApIface(const hidl_string& ifname,
-                                  getApIface_cb hidl_status_cb) {
+Return<void> WifiChip::getApIface(const hidl_string& ifname, getApIface_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getApIfaceInternal, hidl_status_cb,
-                           ifname);
+                           &WifiChip::getApIfaceInternal, hidl_status_cb, ifname);
 }
 
-Return<void> WifiChip::removeApIface(const hidl_string& ifname,
-                                     removeApIface_cb hidl_status_cb) {
+Return<void> WifiChip::removeApIface(const hidl_string& ifname, removeApIface_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::removeApIfaceInternal, hidl_status_cb,
-                           ifname);
+                           &WifiChip::removeApIfaceInternal, hidl_status_cb, ifname);
 }
 
 Return<void> WifiChip::removeIfaceInstanceFromBridgedApIface(
-    const hidl_string& ifname, const hidl_string& ifInstanceName,
-    removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) {
-    return validateAndCall(
-        this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-        &WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal,
-        hidl_status_cb, ifname, ifInstanceName);
+        const hidl_string& ifname, const hidl_string& ifInstanceName,
+        removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal, hidl_status_cb,
+                           ifname, ifInstanceName);
 }
 
 Return<void> WifiChip::createNanIface(createNanIface_cb hidl_status_cb) {
@@ -524,18 +488,14 @@
                            &WifiChip::getNanIfaceNamesInternal, hidl_status_cb);
 }
 
-Return<void> WifiChip::getNanIface(const hidl_string& ifname,
-                                   getNanIface_cb hidl_status_cb) {
+Return<void> WifiChip::getNanIface(const hidl_string& ifname, getNanIface_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getNanIfaceInternal, hidl_status_cb,
-                           ifname);
+                           &WifiChip::getNanIfaceInternal, hidl_status_cb, ifname);
 }
 
-Return<void> WifiChip::removeNanIface(const hidl_string& ifname,
-                                      removeNanIface_cb hidl_status_cb) {
+Return<void> WifiChip::removeNanIface(const hidl_string& ifname, removeNanIface_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::removeNanIfaceInternal, hidl_status_cb,
-                           ifname);
+                           &WifiChip::removeNanIfaceInternal, hidl_status_cb, ifname);
 }
 
 Return<void> WifiChip::createP2pIface(createP2pIface_cb hidl_status_cb) {
@@ -548,18 +508,14 @@
                            &WifiChip::getP2pIfaceNamesInternal, hidl_status_cb);
 }
 
-Return<void> WifiChip::getP2pIface(const hidl_string& ifname,
-                                   getP2pIface_cb hidl_status_cb) {
+Return<void> WifiChip::getP2pIface(const hidl_string& ifname, getP2pIface_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getP2pIfaceInternal, hidl_status_cb,
-                           ifname);
+                           &WifiChip::getP2pIfaceInternal, hidl_status_cb, ifname);
 }
 
-Return<void> WifiChip::removeP2pIface(const hidl_string& ifname,
-                                      removeP2pIface_cb hidl_status_cb) {
+Return<void> WifiChip::removeP2pIface(const hidl_string& ifname, removeP2pIface_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::removeP2pIfaceInternal, hidl_status_cb,
-                           ifname);
+                           &WifiChip::removeP2pIfaceInternal, hidl_status_cb, ifname);
 }
 
 Return<void> WifiChip::createStaIface(createStaIface_cb hidl_status_cb) {
@@ -572,132 +528,106 @@
                            &WifiChip::getStaIfaceNamesInternal, hidl_status_cb);
 }
 
-Return<void> WifiChip::getStaIface(const hidl_string& ifname,
-                                   getStaIface_cb hidl_status_cb) {
+Return<void> WifiChip::getStaIface(const hidl_string& ifname, getStaIface_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getStaIfaceInternal, hidl_status_cb,
-                           ifname);
+                           &WifiChip::getStaIfaceInternal, hidl_status_cb, ifname);
 }
 
-Return<void> WifiChip::removeStaIface(const hidl_string& ifname,
-                                      removeStaIface_cb hidl_status_cb) {
+Return<void> WifiChip::removeStaIface(const hidl_string& ifname, removeStaIface_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::removeStaIfaceInternal, hidl_status_cb,
-                           ifname);
+                           &WifiChip::removeStaIfaceInternal, hidl_status_cb, ifname);
 }
 
-Return<void> WifiChip::createRttController(
-    const sp<IWifiIface>& bound_iface, createRttController_cb hidl_status_cb) {
+Return<void> WifiChip::createRttController(const sp<IWifiIface>& bound_iface,
+                                           createRttController_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::createRttControllerInternal,
-                           hidl_status_cb, bound_iface);
+                           &WifiChip::createRttControllerInternal, hidl_status_cb, bound_iface);
 }
 
-Return<void> WifiChip::getDebugRingBuffersStatus(
-    getDebugRingBuffersStatus_cb hidl_status_cb) {
+Return<void> WifiChip::getDebugRingBuffersStatus(getDebugRingBuffersStatus_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getDebugRingBuffersStatusInternal,
-                           hidl_status_cb);
+                           &WifiChip::getDebugRingBuffersStatusInternal, hidl_status_cb);
 }
 
 Return<void> WifiChip::startLoggingToDebugRingBuffer(
-    const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
-    uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes,
-    startLoggingToDebugRingBuffer_cb hidl_status_cb) {
+        const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
+        uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes,
+        startLoggingToDebugRingBuffer_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::startLoggingToDebugRingBufferInternal,
-                           hidl_status_cb, ring_name, verbose_level,
-                           max_interval_in_sec, min_data_size_in_bytes);
+                           &WifiChip::startLoggingToDebugRingBufferInternal, hidl_status_cb,
+                           ring_name, verbose_level, max_interval_in_sec, min_data_size_in_bytes);
 }
 
-Return<void> WifiChip::forceDumpToDebugRingBuffer(
-    const hidl_string& ring_name,
-    forceDumpToDebugRingBuffer_cb hidl_status_cb) {
+Return<void> WifiChip::forceDumpToDebugRingBuffer(const hidl_string& ring_name,
+                                                  forceDumpToDebugRingBuffer_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::forceDumpToDebugRingBufferInternal,
-                           hidl_status_cb, ring_name);
+                           &WifiChip::forceDumpToDebugRingBufferInternal, hidl_status_cb,
+                           ring_name);
 }
 
-Return<void> WifiChip::flushRingBufferToFile(
-    flushRingBufferToFile_cb hidl_status_cb) {
+Return<void> WifiChip::flushRingBufferToFile(flushRingBufferToFile_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::flushRingBufferToFileInternal,
-                           hidl_status_cb);
+                           &WifiChip::flushRingBufferToFileInternal, hidl_status_cb);
 }
 
 Return<void> WifiChip::stopLoggingToDebugRingBuffer(
-    stopLoggingToDebugRingBuffer_cb hidl_status_cb) {
+        stopLoggingToDebugRingBuffer_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::stopLoggingToDebugRingBufferInternal,
-                           hidl_status_cb);
+                           &WifiChip::stopLoggingToDebugRingBufferInternal, hidl_status_cb);
 }
 
-Return<void> WifiChip::getDebugHostWakeReasonStats(
-    getDebugHostWakeReasonStats_cb hidl_status_cb) {
+Return<void> WifiChip::getDebugHostWakeReasonStats(getDebugHostWakeReasonStats_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getDebugHostWakeReasonStatsInternal,
-                           hidl_status_cb);
+                           &WifiChip::getDebugHostWakeReasonStatsInternal, hidl_status_cb);
 }
 
-Return<void> WifiChip::enableDebugErrorAlerts(
-    bool enable, enableDebugErrorAlerts_cb hidl_status_cb) {
+Return<void> WifiChip::enableDebugErrorAlerts(bool enable,
+                                              enableDebugErrorAlerts_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::enableDebugErrorAlertsInternal,
-                           hidl_status_cb, enable);
+                           &WifiChip::enableDebugErrorAlertsInternal, hidl_status_cb, enable);
 }
 
-Return<void> WifiChip::selectTxPowerScenario(
-    V1_1::IWifiChip::TxPowerScenario scenario,
-    selectTxPowerScenario_cb hidl_status_cb) {
+Return<void> WifiChip::selectTxPowerScenario(V1_1::IWifiChip::TxPowerScenario scenario,
+                                             selectTxPowerScenario_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::selectTxPowerScenarioInternal,
-                           hidl_status_cb, scenario);
+                           &WifiChip::selectTxPowerScenarioInternal, hidl_status_cb, scenario);
 }
 
-Return<void> WifiChip::resetTxPowerScenario(
-    resetTxPowerScenario_cb hidl_status_cb) {
+Return<void> WifiChip::resetTxPowerScenario(resetTxPowerScenario_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::resetTxPowerScenarioInternal,
-                           hidl_status_cb);
+                           &WifiChip::resetTxPowerScenarioInternal, hidl_status_cb);
 }
 
-Return<void> WifiChip::setLatencyMode(LatencyMode mode,
-                                      setLatencyMode_cb hidl_status_cb) {
+Return<void> WifiChip::setLatencyMode(LatencyMode mode, setLatencyMode_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::setLatencyModeInternal, hidl_status_cb,
-                           mode);
+                           &WifiChip::setLatencyModeInternal, hidl_status_cb, mode);
 }
 
 Return<void> WifiChip::registerEventCallback_1_2(
-    const sp<V1_2::IWifiChipEventCallback>& event_callback,
-    registerEventCallback_cb hidl_status_cb) {
+        const sp<V1_2::IWifiChipEventCallback>& event_callback,
+        registerEventCallback_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::registerEventCallbackInternal_1_2,
-                           hidl_status_cb, event_callback);
+                           &WifiChip::registerEventCallbackInternal_1_2, hidl_status_cb,
+                           event_callback);
 }
 
-Return<void> WifiChip::selectTxPowerScenario_1_2(
-    TxPowerScenario scenario, selectTxPowerScenario_cb hidl_status_cb) {
+Return<void> WifiChip::selectTxPowerScenario_1_2(TxPowerScenario scenario,
+                                                 selectTxPowerScenario_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::selectTxPowerScenarioInternal_1_2,
-                           hidl_status_cb, scenario);
+                           &WifiChip::selectTxPowerScenarioInternal_1_2, hidl_status_cb, scenario);
 }
 
 Return<void> WifiChip::getCapabilities_1_3(getCapabilities_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getCapabilitiesInternal_1_3,
-                           hidl_status_cb);
+                           &WifiChip::getCapabilitiesInternal_1_3, hidl_status_cb);
 }
 
-Return<void> WifiChip::getCapabilities_1_5(
-    getCapabilities_1_5_cb hidl_status_cb) {
+Return<void> WifiChip::getCapabilities_1_5(getCapabilities_1_5_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getCapabilitiesInternal_1_5,
-                           hidl_status_cb);
+                           &WifiChip::getCapabilitiesInternal_1_5, hidl_status_cb);
 }
 
-Return<void> WifiChip::debug(const hidl_handle& handle,
-                             const hidl_vec<hidl_string>&) {
+Return<void> WifiChip::debug(const hidl_handle& handle, const hidl_vec<hidl_string>&) {
     if (handle != nullptr && handle->numFds >= 1) {
         {
             std::unique_lock<std::mutex> lk(lock_t);
@@ -723,66 +653,58 @@
     return Void();
 }
 
-Return<void> WifiChip::createRttController_1_4(
-    const sp<IWifiIface>& bound_iface,
-    createRttController_1_4_cb hidl_status_cb) {
+Return<void> WifiChip::createRttController_1_4(const sp<IWifiIface>& bound_iface,
+                                               createRttController_1_4_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::createRttControllerInternal_1_4,
-                           hidl_status_cb, bound_iface);
+                           &WifiChip::createRttControllerInternal_1_4, hidl_status_cb, bound_iface);
 }
 
 Return<void> WifiChip::registerEventCallback_1_4(
-    const sp<V1_4::IWifiChipEventCallback>& event_callback,
-    registerEventCallback_cb hidl_status_cb) {
+        const sp<V1_4::IWifiChipEventCallback>& event_callback,
+        registerEventCallback_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::registerEventCallbackInternal_1_4,
-                           hidl_status_cb, event_callback);
+                           &WifiChip::registerEventCallbackInternal_1_4, hidl_status_cb,
+                           event_callback);
 }
 
 Return<void> WifiChip::setMultiStaPrimaryConnection(
-    const hidl_string& ifname, setMultiStaPrimaryConnection_cb hidl_status_cb) {
+        const hidl_string& ifname, setMultiStaPrimaryConnection_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::setMultiStaPrimaryConnectionInternal,
-                           hidl_status_cb, ifname);
+                           &WifiChip::setMultiStaPrimaryConnectionInternal, hidl_status_cb, ifname);
 }
 
-Return<void> WifiChip::setMultiStaUseCase(
-    MultiStaUseCase use_case, setMultiStaUseCase_cb hidl_status_cb) {
+Return<void> WifiChip::setMultiStaUseCase(MultiStaUseCase use_case,
+                                          setMultiStaUseCase_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::setMultiStaUseCaseInternal,
-                           hidl_status_cb, use_case);
+                           &WifiChip::setMultiStaUseCaseInternal, hidl_status_cb, use_case);
 }
 
-Return<void> WifiChip::setCoexUnsafeChannels(
-    const hidl_vec<CoexUnsafeChannel>& unsafeChannels,
-    hidl_bitfield<CoexRestriction> restrictions,
-    setCoexUnsafeChannels_cb hidl_status_cb) {
+Return<void> WifiChip::setCoexUnsafeChannels(const hidl_vec<CoexUnsafeChannel>& unsafeChannels,
+                                             hidl_bitfield<CoexRestriction> restrictions,
+                                             setCoexUnsafeChannels_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::setCoexUnsafeChannelsInternal,
-                           hidl_status_cb, unsafeChannels, restrictions);
+                           &WifiChip::setCoexUnsafeChannelsInternal, hidl_status_cb, unsafeChannels,
+                           restrictions);
 }
 
 Return<void> WifiChip::setCountryCode(const hidl_array<int8_t, 2>& code,
                                       setCountryCode_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
-                           &WifiChip::setCountryCodeInternal, hidl_status_cb,
-                           code);
+                           &WifiChip::setCountryCodeInternal, hidl_status_cb, code);
 }
 
 Return<void> WifiChip::getUsableChannels(
-    WifiBand band, hidl_bitfield<WifiIfaceMode> ifaceModeMask,
-    hidl_bitfield<UsableChannelFilter> filterMask,
-    getUsableChannels_cb _hidl_cb) {
+        WifiBand band, hidl_bitfield<V1_5::WifiIfaceMode> ifaceModeMask,
+        hidl_bitfield<V1_5::IWifiChip::UsableChannelFilter> filterMask,
+        getUsableChannels_cb _hidl_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::getUsableChannelsInternal, _hidl_cb, band,
-                           ifaceModeMask, filterMask);
+                           &WifiChip::getUsableChannelsInternal, _hidl_cb, band, ifaceModeMask,
+                           filterMask);
 }
 
-Return<void> WifiChip::triggerSubsystemRestart(
-    triggerSubsystemRestart_cb hidl_status_cb) {
+Return<void> WifiChip::triggerSubsystemRestart(triggerSubsystemRestart_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::triggerSubsystemRestartInternal,
-                           hidl_status_cb);
+                           &WifiChip::triggerSubsystemRestartInternal, hidl_status_cb);
 }
 
 void WifiChip::invalidateAndRemoveAllIfaces() {
@@ -799,16 +721,13 @@
     rtt_controllers_.clear();
 }
 
-void WifiChip::invalidateAndRemoveDependencies(
-    const std::string& removed_iface_name) {
+void WifiChip::invalidateAndRemoveDependencies(const std::string& removed_iface_name) {
     for (auto it = nan_ifaces_.begin(); it != nan_ifaces_.end();) {
         auto nan_iface = *it;
         if (nan_iface->getName() == removed_iface_name) {
             nan_iface->invalidate();
             for (const auto& callback : event_cb_handler_.getCallbacks()) {
-                if (!callback
-                         ->onIfaceRemoved(IfaceType::NAN, removed_iface_name)
-                         .isOk()) {
+                if (!callback->onIfaceRemoved(IfaceType::NAN, removed_iface_name).isOk()) {
                     LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
                 }
             }
@@ -834,7 +753,7 @@
 }
 
 WifiStatus WifiChip::registerEventCallbackInternal(
-    const sp<V1_0::IWifiChipEventCallback>& /* event_callback */) {
+        const sp<V1_0::IWifiChipEventCallback>& /* event_callback */) {
     // Deprecated support for this callback.
     return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
 }
@@ -850,8 +769,7 @@
 }
 
 WifiStatus WifiChip::configureChipInternal(
-    /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
-    ChipModeId mode_id) {
+        /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id) {
     if (!isValidModeId(mode_id)) {
         return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
     }
@@ -863,8 +781,7 @@
     if (status.code != WifiStatusCode::SUCCESS) {
         for (const auto& callback : event_cb_handler_.getCallbacks()) {
             if (!callback->onChipReconfigureFailure(status).isOk()) {
-                LOG(ERROR)
-                    << "Failed to invoke onChipReconfigureFailure callback";
+                LOG(ERROR) << "Failed to invoke onChipReconfigureFailure callback";
             }
         }
         return status;
@@ -878,45 +795,38 @@
     LOG(INFO) << "Configured chip in mode " << mode_id;
     setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
 
-    legacy_hal_.lock()->registerSubsystemRestartCallbackHandler(
-        subsystemCallbackHandler_);
+    legacy_hal_.lock()->registerSubsystemRestartCallbackHandler(subsystemCallbackHandler_);
 
     return status;
 }
 
 std::pair<WifiStatus, uint32_t> WifiChip::getModeInternal() {
     if (!isValidModeId(current_mode_id_)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE),
-                current_mode_id_};
+        return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), current_mode_id_};
     }
     return {createWifiStatus(WifiStatusCode::SUCCESS), current_mode_id_};
 }
 
-std::pair<WifiStatus, V1_4::IWifiChip::ChipDebugInfo>
-WifiChip::requestChipDebugInfoInternal() {
+std::pair<WifiStatus, V1_4::IWifiChip::ChipDebugInfo> WifiChip::requestChipDebugInfoInternal() {
     V1_4::IWifiChip::ChipDebugInfo result;
     legacy_hal::wifi_error legacy_status;
     std::string driver_desc;
     const auto ifname = getFirstActiveWlanIfaceName();
-    std::tie(legacy_status, driver_desc) =
-        legacy_hal_.lock()->getDriverVersion(ifname);
+    std::tie(legacy_status, driver_desc) = legacy_hal_.lock()->getDriverVersion(ifname);
     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        LOG(ERROR) << "Failed to get driver version: "
-                   << legacyErrorToString(legacy_status);
-        WifiStatus status = createWifiStatusFromLegacyError(
-            legacy_status, "failed to get driver version");
+        LOG(ERROR) << "Failed to get driver version: " << legacyErrorToString(legacy_status);
+        WifiStatus status =
+                createWifiStatusFromLegacyError(legacy_status, "failed to get driver version");
         return {status, result};
     }
     result.driverDescription = driver_desc.c_str();
 
     std::string firmware_desc;
-    std::tie(legacy_status, firmware_desc) =
-        legacy_hal_.lock()->getFirmwareVersion(ifname);
+    std::tie(legacy_status, firmware_desc) = legacy_hal_.lock()->getFirmwareVersion(ifname);
     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        LOG(ERROR) << "Failed to get firmware version: "
-                   << legacyErrorToString(legacy_status);
-        WifiStatus status = createWifiStatusFromLegacyError(
-            legacy_status, "failed to get firmware version");
+        LOG(ERROR) << "Failed to get firmware version: " << legacyErrorToString(legacy_status);
+        WifiStatus status =
+                createWifiStatusFromLegacyError(legacy_status, "failed to get firmware version");
         return {status, result};
     }
     result.firmwareDescription = firmware_desc.c_str();
@@ -924,32 +834,25 @@
     return {createWifiStatus(WifiStatusCode::SUCCESS), result};
 }
 
-std::pair<WifiStatus, std::vector<uint8_t>>
-WifiChip::requestDriverDebugDumpInternal() {
+std::pair<WifiStatus, std::vector<uint8_t>> WifiChip::requestDriverDebugDumpInternal() {
     legacy_hal::wifi_error legacy_status;
     std::vector<uint8_t> driver_dump;
     std::tie(legacy_status, driver_dump) =
-        legacy_hal_.lock()->requestDriverMemoryDump(
-            getFirstActiveWlanIfaceName());
+            legacy_hal_.lock()->requestDriverMemoryDump(getFirstActiveWlanIfaceName());
     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        LOG(ERROR) << "Failed to get driver debug dump: "
-                   << legacyErrorToString(legacy_status);
-        return {createWifiStatusFromLegacyError(legacy_status),
-                std::vector<uint8_t>()};
+        LOG(ERROR) << "Failed to get driver debug dump: " << legacyErrorToString(legacy_status);
+        return {createWifiStatusFromLegacyError(legacy_status), std::vector<uint8_t>()};
     }
     return {createWifiStatus(WifiStatusCode::SUCCESS), driver_dump};
 }
 
-std::pair<WifiStatus, std::vector<uint8_t>>
-WifiChip::requestFirmwareDebugDumpInternal() {
+std::pair<WifiStatus, std::vector<uint8_t>> WifiChip::requestFirmwareDebugDumpInternal() {
     legacy_hal::wifi_error legacy_status;
     std::vector<uint8_t> firmware_dump;
     std::tie(legacy_status, firmware_dump) =
-        legacy_hal_.lock()->requestFirmwareMemoryDump(
-            getFirstActiveWlanIfaceName());
+            legacy_hal_.lock()->requestFirmwareMemoryDump(getFirstActiveWlanIfaceName());
     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        LOG(ERROR) << "Failed to get firmware debug dump: "
-                   << legacyErrorToString(legacy_status);
+        LOG(ERROR) << "Failed to get firmware debug dump: " << legacyErrorToString(legacy_status);
         return {createWifiStatusFromLegacyError(legacy_status), {}};
     }
     return {createWifiStatus(WifiStatusCode::SUCCESS), firmware_dump};
@@ -958,8 +861,7 @@
 WifiStatus WifiChip::createVirtualApInterface(const std::string& apVirtIf) {
     legacy_hal::wifi_error legacy_status;
     legacy_status = legacy_hal_.lock()->createVirtualInterface(
-        apVirtIf,
-        hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::AP));
+            apVirtIf, hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::AP));
     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
         LOG(ERROR) << "Failed to add interface: " << apVirtIf << " "
                    << legacyErrorToString(legacy_status);
@@ -975,8 +877,7 @@
             ap_instances = it.second;
         }
     }
-    sp<WifiApIface> iface =
-        new WifiApIface(ifname, ap_instances, legacy_hal_, iface_util_);
+    sp<WifiApIface> iface = new WifiApIface(ifname, ap_instances, legacy_hal_, iface_util_);
     ap_ifaces_.push_back(iface);
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
         if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) {
@@ -987,8 +888,7 @@
     return iface;
 }
 
-std::pair<WifiStatus, sp<V1_5::IWifiApIface>>
-WifiChip::createApIfaceInternal() {
+std::pair<WifiStatus, sp<V1_5::IWifiApIface>> WifiChip::createApIfaceInternal() {
     if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) {
         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
     }
@@ -1001,8 +901,7 @@
     return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
 }
 
-std::pair<WifiStatus, sp<V1_5::IWifiApIface>>
-WifiChip::createBridgedApIfaceInternal() {
+std::pair<WifiStatus, sp<V1_5::IWifiApIface>> WifiChip::createBridgedApIfaceInternal() {
     if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) {
         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
     }
@@ -1018,7 +917,7 @@
             if (i != 0) {  // The failure happened when creating second virtual
                            // iface.
                 legacy_hal_.lock()->deleteVirtualInterface(
-                    ap_instances.front());  // Remove the first virtual iface.
+                        ap_instances.front());  // Remove the first virtual iface.
             }
             return {status, {}};
         }
@@ -1032,8 +931,7 @@
     for (auto const& instance : ap_instances) {
         // Bind ap instance interface to AP bridge
         if (!iface_util_->addIfaceToBridge(br_ifname, instance)) {
-            LOG(ERROR) << "Failed add if to Bridge - if_name="
-                       << instance.c_str();
+            LOG(ERROR) << "Failed add if to Bridge - if_name=" << instance.c_str();
             invalidateAndClearBridgedAp(br_ifname);
             return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
         }
@@ -1042,8 +940,7 @@
     return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
 }
 
-std::pair<WifiStatus, std::vector<hidl_string>>
-WifiChip::getApIfaceNamesInternal() {
+std::pair<WifiStatus, std::vector<hidl_string>> WifiChip::getApIfaceNamesInternal() {
     if (ap_ifaces_.empty()) {
         return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
     }
@@ -1051,7 +948,7 @@
 }
 
 std::pair<WifiStatus, sp<V1_5::IWifiApIface>> WifiChip::getApIfaceInternal(
-    const std::string& ifname) {
+        const std::string& ifname) {
     const auto iface = findUsingName(ap_ifaces_, ifname);
     if (!iface.get()) {
         return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
@@ -1082,7 +979,7 @@
 }
 
 WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal(
-    const std::string& ifname, const std::string& ifInstanceName) {
+        const std::string& ifname, const std::string& ifInstanceName) {
     const auto iface = findUsingName(ap_ifaces_, ifname);
     if (!iface.get() || ifInstanceName.empty()) {
         return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
@@ -1094,23 +991,20 @@
             for (auto const& iface : ap_instances) {
                 if (iface == ifInstanceName) {
                     if (!iface_util_->removeIfaceFromBridge(it.first, iface)) {
-                        LOG(ERROR)
-                            << "Failed to remove interface: " << ifInstanceName
-                            << " from " << ifname;
-                        return createWifiStatus(
-                            WifiStatusCode::ERROR_NOT_AVAILABLE);
+                        LOG(ERROR) << "Failed to remove interface: " << ifInstanceName << " from "
+                                   << ifname;
+                        return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE);
                     }
                     legacy_hal::wifi_error legacy_status =
-                        legacy_hal_.lock()->deleteVirtualInterface(iface);
+                            legacy_hal_.lock()->deleteVirtualInterface(iface);
                     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-                        LOG(ERROR) << "Failed to del interface: " << iface
-                                   << " " << legacyErrorToString(legacy_status);
+                        LOG(ERROR) << "Failed to del interface: " << iface << " "
+                                   << legacyErrorToString(legacy_status);
                         return createWifiStatusFromLegacyError(legacy_status);
                     }
                     ap_instances.erase(
-                        std::remove(ap_instances.begin(), ap_instances.end(),
-                                    ifInstanceName),
-                        ap_instances.end());
+                            std::remove(ap_instances.begin(), ap_instances.end(), ifInstanceName),
+                            ap_instances.end());
                     br_ifaces_ap_instances_[ifname] = ap_instances;
                     break;
                 }
@@ -1124,8 +1018,7 @@
     return createWifiStatus(WifiStatusCode::SUCCESS);
 }
 
-std::pair<WifiStatus, sp<V1_4::IWifiNanIface>>
-WifiChip::createNanIfaceInternal() {
+std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> WifiChip::createNanIfaceInternal() {
     if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::NAN)) {
         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
     }
@@ -1137,8 +1030,7 @@
         ifname = getFirstActiveWlanIfaceName();
         is_dedicated_iface = false;
     }
-    sp<WifiNanIface> iface =
-        new WifiNanIface(ifname, is_dedicated_iface, legacy_hal_, iface_util_);
+    sp<WifiNanIface> iface = new WifiNanIface(ifname, is_dedicated_iface, legacy_hal_, iface_util_);
     nan_ifaces_.push_back(iface);
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
         if (!callback->onIfaceAdded(IfaceType::NAN, ifname).isOk()) {
@@ -1148,8 +1040,7 @@
     return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
 }
 
-std::pair<WifiStatus, std::vector<hidl_string>>
-WifiChip::getNanIfaceNamesInternal() {
+std::pair<WifiStatus, std::vector<hidl_string>> WifiChip::getNanIfaceNamesInternal() {
     if (nan_ifaces_.empty()) {
         return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
     }
@@ -1157,7 +1048,7 @@
 }
 
 std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> WifiChip::getNanIfaceInternal(
-    const std::string& ifname) {
+        const std::string& ifname) {
     const auto iface = findUsingName(nan_ifaces_, ifname);
     if (!iface.get()) {
         return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
@@ -1194,16 +1085,14 @@
     return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
 }
 
-std::pair<WifiStatus, std::vector<hidl_string>>
-WifiChip::getP2pIfaceNamesInternal() {
+std::pair<WifiStatus, std::vector<hidl_string>> WifiChip::getP2pIfaceNamesInternal() {
     if (p2p_ifaces_.empty()) {
         return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
     }
     return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(p2p_ifaces_)};
 }
 
-std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::getP2pIfaceInternal(
-    const std::string& ifname) {
+std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::getP2pIfaceInternal(const std::string& ifname) {
     const auto iface = findUsingName(p2p_ifaces_, ifname);
     if (!iface.get()) {
         return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
@@ -1225,16 +1114,13 @@
     return createWifiStatus(WifiStatusCode::SUCCESS);
 }
 
-std::pair<WifiStatus, sp<V1_5::IWifiStaIface>>
-WifiChip::createStaIfaceInternal() {
+std::pair<WifiStatus, sp<V1_5::IWifiStaIface>> WifiChip::createStaIfaceInternal() {
     if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::STA)) {
         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
     }
     std::string ifname = allocateStaIfaceName();
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->createVirtualInterface(
-            ifname,
-            hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::STA));
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->createVirtualInterface(
+            ifname, hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::STA));
     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
         LOG(ERROR) << "Failed to add interface: " << ifname << " "
                    << legacyErrorToString(legacy_status);
@@ -1251,8 +1137,7 @@
     return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
 }
 
-std::pair<WifiStatus, std::vector<hidl_string>>
-WifiChip::getStaIfaceNamesInternal() {
+std::pair<WifiStatus, std::vector<hidl_string>> WifiChip::getStaIfaceNamesInternal() {
     if (sta_ifaces_.empty()) {
         return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
     }
@@ -1260,7 +1145,7 @@
 }
 
 std::pair<WifiStatus, sp<V1_5::IWifiStaIface>> WifiChip::getStaIfaceInternal(
-    const std::string& ifname) {
+        const std::string& ifname) {
     const auto iface = findUsingName(sta_ifaces_, ifname);
     if (!iface.get()) {
         return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
@@ -1275,8 +1160,7 @@
     }
     // Invalidate & remove any dependent objects first.
     invalidateAndRemoveDependencies(ifname);
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->deleteVirtualInterface(ifname);
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->deleteVirtualInterface(ifname);
     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
         LOG(ERROR) << "Failed to remove interface: " << ifname << " "
                    << legacyErrorToString(legacy_status);
@@ -1291,8 +1175,8 @@
     return createWifiStatus(WifiStatusCode::SUCCESS);
 }
 
-std::pair<WifiStatus, sp<V1_0::IWifiRttController>>
-WifiChip::createRttControllerInternal(const sp<IWifiIface>& /*bound_iface*/) {
+std::pair<WifiStatus, sp<V1_0::IWifiRttController>> WifiChip::createRttControllerInternal(
+        const sp<IWifiIface>& /*bound_iface*/) {
     LOG(ERROR) << "createRttController is not supported on this HAL";
     return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
 }
@@ -1300,38 +1184,33 @@
 std::pair<WifiStatus, std::vector<WifiDebugRingBufferStatus>>
 WifiChip::getDebugRingBuffersStatusInternal() {
     legacy_hal::wifi_error legacy_status;
-    std::vector<legacy_hal::wifi_ring_buffer_status>
-        legacy_ring_buffer_status_vec;
+    std::vector<legacy_hal::wifi_ring_buffer_status> legacy_ring_buffer_status_vec;
     std::tie(legacy_status, legacy_ring_buffer_status_vec) =
-        legacy_hal_.lock()->getRingBuffersStatus(getFirstActiveWlanIfaceName());
+            legacy_hal_.lock()->getRingBuffersStatus(getFirstActiveWlanIfaceName());
     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
         return {createWifiStatusFromLegacyError(legacy_status), {}};
     }
     std::vector<WifiDebugRingBufferStatus> hidl_ring_buffer_status_vec;
     if (!hidl_struct_util::convertLegacyVectorOfDebugRingBufferStatusToHidl(
-            legacy_ring_buffer_status_vec, &hidl_ring_buffer_status_vec)) {
+                legacy_ring_buffer_status_vec, &hidl_ring_buffer_status_vec)) {
         return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
     }
-    return {createWifiStatus(WifiStatusCode::SUCCESS),
-            hidl_ring_buffer_status_vec};
+    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_ring_buffer_status_vec};
 }
 
 WifiStatus WifiChip::startLoggingToDebugRingBufferInternal(
-    const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
-    uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes) {
+        const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
+        uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes) {
     WifiStatus status = registerDebugRingBufferCallback();
     if (status.code != WifiStatusCode::SUCCESS) {
         return status;
     }
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->startRingBufferLogging(
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRingBufferLogging(
             getFirstActiveWlanIfaceName(), ring_name,
-            static_cast<
-                std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>(
-                verbose_level),
+            static_cast<std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>(verbose_level),
             max_interval_in_sec, min_data_size_in_bytes);
-    ringbuffer_map_.insert(std::pair<std::string, Ringbuffer>(
-        ring_name, Ringbuffer(kMaxBufferSizeBytes)));
+    ringbuffer_map_.insert(
+            std::pair<std::string, Ringbuffer>(ring_name, Ringbuffer(kMaxBufferSizeBytes)));
     // if verbose logging enabled, turn up HAL daemon logging as well.
     if (verbose_level < WifiDebugRingBufferVerboseLevel::VERBOSE) {
         android::base::SetMinimumLogSeverity(android::base::DEBUG);
@@ -1341,15 +1220,13 @@
     return createWifiStatusFromLegacyError(legacy_status);
 }
 
-WifiStatus WifiChip::forceDumpToDebugRingBufferInternal(
-    const hidl_string& ring_name) {
+WifiStatus WifiChip::forceDumpToDebugRingBufferInternal(const hidl_string& ring_name) {
     WifiStatus status = registerDebugRingBufferCallback();
     if (status.code != WifiStatusCode::SUCCESS) {
         return status;
     }
     legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->getRingBufferData(getFirstActiveWlanIfaceName(),
-                                              ring_name);
+            legacy_hal_.lock()->getRingBufferData(getFirstActiveWlanIfaceName(), ring_name);
 
     return createWifiStatusFromLegacyError(legacy_status);
 }
@@ -1364,8 +1241,7 @@
 
 WifiStatus WifiChip::stopLoggingToDebugRingBufferInternal() {
     legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->deregisterRingBufferCallbackHandler(
-            getFirstActiveWlanIfaceName());
+            legacy_hal_.lock()->deregisterRingBufferCallbackHandler(getFirstActiveWlanIfaceName());
     if (legacy_status == legacy_hal::WIFI_SUCCESS) {
         debug_ring_buffer_cb_registered_ = false;
     }
@@ -1377,13 +1253,12 @@
     legacy_hal::wifi_error legacy_status;
     legacy_hal::WakeReasonStats legacy_stats;
     std::tie(legacy_status, legacy_stats) =
-        legacy_hal_.lock()->getWakeReasonStats(getFirstActiveWlanIfaceName());
+            legacy_hal_.lock()->getWakeReasonStats(getFirstActiveWlanIfaceName());
     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
         return {createWifiStatusFromLegacyError(legacy_status), {}};
     }
     WifiDebugHostWakeReasonStats hidl_stats;
-    if (!hidl_struct_util::convertLegacyWakeReasonStatsToHidl(legacy_stats,
-                                                              &hidl_stats)) {
+    if (!hidl_struct_util::convertLegacyWakeReasonStatsToHidl(legacy_stats, &hidl_stats)) {
         return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
     }
     return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats};
@@ -1393,62 +1268,56 @@
     legacy_hal::wifi_error legacy_status;
     if (enable) {
         android::wp<WifiChip> weak_ptr_this(this);
-        const auto& on_alert_callback = [weak_ptr_this](
-                                            int32_t error_code,
-                                            std::vector<uint8_t> debug_data) {
+        const auto& on_alert_callback = [weak_ptr_this](int32_t error_code,
+                                                        std::vector<uint8_t> debug_data) {
             const auto shared_ptr_this = weak_ptr_this.promote();
             if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
                 LOG(ERROR) << "Callback invoked on an invalid object";
                 return;
             }
             for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                if (!callback->onDebugErrorAlert(error_code, debug_data)
-                         .isOk()) {
+                if (!callback->onDebugErrorAlert(error_code, debug_data).isOk()) {
                     LOG(ERROR) << "Failed to invoke onDebugErrorAlert callback";
                 }
             }
         };
         legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler(
-            getFirstActiveWlanIfaceName(), on_alert_callback);
+                getFirstActiveWlanIfaceName(), on_alert_callback);
     } else {
         legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler(
-            getFirstActiveWlanIfaceName());
+                getFirstActiveWlanIfaceName());
     }
     return createWifiStatusFromLegacyError(legacy_status);
 }
 
-WifiStatus WifiChip::selectTxPowerScenarioInternal(
-    V1_1::IWifiChip::TxPowerScenario scenario) {
+WifiStatus WifiChip::selectTxPowerScenarioInternal(V1_1::IWifiChip::TxPowerScenario scenario) {
     auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
-        getFirstActiveWlanIfaceName(),
-        hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario));
+            getFirstActiveWlanIfaceName(),
+            hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario));
     return createWifiStatusFromLegacyError(legacy_status);
 }
 
 WifiStatus WifiChip::resetTxPowerScenarioInternal() {
-    auto legacy_status =
-        legacy_hal_.lock()->resetTxPowerScenario(getFirstActiveWlanIfaceName());
+    auto legacy_status = legacy_hal_.lock()->resetTxPowerScenario(getFirstActiveWlanIfaceName());
     return createWifiStatusFromLegacyError(legacy_status);
 }
 
 WifiStatus WifiChip::setLatencyModeInternal(LatencyMode mode) {
     auto legacy_status = legacy_hal_.lock()->setLatencyMode(
-        getFirstActiveWlanIfaceName(),
-        hidl_struct_util::convertHidlLatencyModeToLegacy(mode));
+            getFirstActiveWlanIfaceName(), hidl_struct_util::convertHidlLatencyModeToLegacy(mode));
     return createWifiStatusFromLegacyError(legacy_status);
 }
 
 WifiStatus WifiChip::registerEventCallbackInternal_1_2(
-    const sp<V1_2::IWifiChipEventCallback>& /* event_callback */) {
+        const sp<V1_2::IWifiChipEventCallback>& /* event_callback */) {
     // Deprecated support for this callback.
     return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
 }
 
-WifiStatus WifiChip::selectTxPowerScenarioInternal_1_2(
-    TxPowerScenario scenario) {
+WifiStatus WifiChip::selectTxPowerScenarioInternal_1_2(TxPowerScenario scenario) {
     auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
-        getFirstActiveWlanIfaceName(),
-        hidl_struct_util::convertHidlTxPowerScenarioToLegacy_1_2(scenario));
+            getFirstActiveWlanIfaceName(),
+            hidl_struct_util::convertHidlTxPowerScenarioToLegacy_1_2(scenario));
     return createWifiStatusFromLegacyError(legacy_status);
 }
 
@@ -1463,65 +1332,61 @@
     uint32_t legacy_logger_feature_set;
     const auto ifname = getFirstActiveWlanIfaceName();
     std::tie(legacy_status, legacy_feature_set) =
-        legacy_hal_.lock()->getSupportedFeatureSet(ifname);
+            legacy_hal_.lock()->getSupportedFeatureSet(ifname);
     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
         return {createWifiStatusFromLegacyError(legacy_status), 0};
     }
     std::tie(legacy_status, legacy_logger_feature_set) =
-        legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname);
+            legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname);
     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
         // some devices don't support querying logger feature set
         legacy_logger_feature_set = 0;
     }
     uint32_t hidl_caps;
     if (!hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities(
-            legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
+                legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
         return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
     }
     return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
 }
 
-std::pair<WifiStatus, sp<V1_4::IWifiRttController>>
-WifiChip::createRttControllerInternal_1_4(const sp<IWifiIface>& bound_iface) {
-    if (sta_ifaces_.size() == 0 &&
-        !canCurrentModeSupportIfaceOfType(IfaceType::STA)) {
-        LOG(ERROR)
-            << "createRttControllerInternal_1_4: Chip cannot support STAs "
-               "(and RTT by extension)";
+std::pair<WifiStatus, sp<V1_4::IWifiRttController>> WifiChip::createRttControllerInternal_1_4(
+        const sp<IWifiIface>& bound_iface) {
+    if (sta_ifaces_.size() == 0 && !canCurrentModeSupportIfaceOfType(IfaceType::STA)) {
+        LOG(ERROR) << "createRttControllerInternal_1_4: Chip cannot support STAs "
+                      "(and RTT by extension)";
         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
     }
-    sp<WifiRttController> rtt = new WifiRttController(
-        getFirstActiveWlanIfaceName(), bound_iface, legacy_hal_);
+    sp<WifiRttController> rtt =
+            new WifiRttController(getFirstActiveWlanIfaceName(), bound_iface, legacy_hal_);
     rtt_controllers_.emplace_back(rtt);
     return {createWifiStatus(WifiStatusCode::SUCCESS), rtt};
 }
 
 WifiStatus WifiChip::registerEventCallbackInternal_1_4(
-    const sp<V1_4::IWifiChipEventCallback>& event_callback) {
+        const sp<V1_4::IWifiChipEventCallback>& event_callback) {
     if (!event_cb_handler_.addCallback(event_callback)) {
         return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
     }
     return createWifiStatus(WifiStatusCode::SUCCESS);
 }
 
-WifiStatus WifiChip::setMultiStaPrimaryConnectionInternal(
-    const std::string& ifname) {
-    auto legacy_status =
-        legacy_hal_.lock()->multiStaSetPrimaryConnection(ifname);
+WifiStatus WifiChip::setMultiStaPrimaryConnectionInternal(const std::string& ifname) {
+    auto legacy_status = legacy_hal_.lock()->multiStaSetPrimaryConnection(ifname);
     return createWifiStatusFromLegacyError(legacy_status);
 }
 
 WifiStatus WifiChip::setMultiStaUseCaseInternal(MultiStaUseCase use_case) {
     auto legacy_status = legacy_hal_.lock()->multiStaSetUseCase(
-        hidl_struct_util::convertHidlMultiStaUseCaseToLegacy(use_case));
+            hidl_struct_util::convertHidlMultiStaUseCaseToLegacy(use_case));
     return createWifiStatusFromLegacyError(legacy_status);
 }
 
-WifiStatus WifiChip::setCoexUnsafeChannelsInternal(
-    std::vector<CoexUnsafeChannel> unsafe_channels, uint32_t restrictions) {
+WifiStatus WifiChip::setCoexUnsafeChannelsInternal(std::vector<CoexUnsafeChannel> unsafe_channels,
+                                                   uint32_t restrictions) {
     std::vector<legacy_hal::wifi_coex_unsafe_channel> legacy_unsafe_channels;
-    if (!hidl_struct_util::convertHidlVectorOfCoexUnsafeChannelToLegacy(
-            unsafe_channels, &legacy_unsafe_channels)) {
+    if (!hidl_struct_util::convertHidlVectorOfCoexUnsafeChannelToLegacy(unsafe_channels,
+                                                                        &legacy_unsafe_channels)) {
         return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
     }
     uint32_t legacy_restrictions = 0;
@@ -1534,35 +1399,31 @@
     if (restrictions & CoexRestriction::WIFI_AWARE) {
         legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_AWARE;
     }
-    auto legacy_status = legacy_hal_.lock()->setCoexUnsafeChannels(
-        legacy_unsafe_channels, legacy_restrictions);
+    auto legacy_status =
+            legacy_hal_.lock()->setCoexUnsafeChannels(legacy_unsafe_channels, legacy_restrictions);
     return createWifiStatusFromLegacyError(legacy_status);
 }
 
 WifiStatus WifiChip::setCountryCodeInternal(const std::array<int8_t, 2>& code) {
-    auto legacy_status =
-        legacy_hal_.lock()->setCountryCode(getFirstActiveWlanIfaceName(), code);
+    auto legacy_status = legacy_hal_.lock()->setCountryCode(getFirstActiveWlanIfaceName(), code);
     return createWifiStatusFromLegacyError(legacy_status);
 }
 
-std::pair<WifiStatus, std::vector<WifiUsableChannel>>
-WifiChip::getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask,
-                                    uint32_t filterMask) {
+std::pair<WifiStatus, std::vector<WifiUsableChannel>> WifiChip::getUsableChannelsInternal(
+        WifiBand band, uint32_t ifaceModeMask, uint32_t filterMask) {
     legacy_hal::wifi_error legacy_status;
     std::vector<legacy_hal::wifi_usable_channel> legacy_usable_channels;
-    std::tie(legacy_status, legacy_usable_channels) =
-        legacy_hal_.lock()->getUsableChannels(
+    std::tie(legacy_status, legacy_usable_channels) = legacy_hal_.lock()->getUsableChannels(
             hidl_struct_util::convertHidlWifiBandToLegacyMacBand(band),
             hidl_struct_util::convertHidlWifiIfaceModeToLegacy(ifaceModeMask),
-            hidl_struct_util::convertHidlUsableChannelFilterToLegacy(
-                filterMask));
+            hidl_struct_util::convertHidlUsableChannelFilterToLegacy(filterMask));
 
     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
         return {createWifiStatusFromLegacyError(legacy_status), {}};
     }
     std::vector<WifiUsableChannel> hidl_usable_channels;
-    if (!hidl_struct_util::convertLegacyWifiUsableChannelsToHidl(
-            legacy_usable_channels, &hidl_usable_channels)) {
+    if (!hidl_struct_util::convertLegacyWifiUsableChannelsToHidl(legacy_usable_channels,
+                                                                 &hidl_usable_channels)) {
         return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
     }
     return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_usable_channels};
@@ -1574,19 +1435,15 @@
 }
 
 WifiStatus WifiChip::handleChipConfiguration(
-    /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
-    ChipModeId mode_id) {
+        /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id) {
     // If the chip is already configured in a different mode, stop
     // the legacy HAL and then start it after firmware mode change.
     if (isValidModeId(current_mode_id_)) {
-        LOG(INFO) << "Reconfiguring chip from mode " << current_mode_id_
-                  << " to mode " << mode_id;
+        LOG(INFO) << "Reconfiguring chip from mode " << current_mode_id_ << " to mode " << mode_id;
         invalidateAndRemoveAllIfaces();
-        legacy_hal::wifi_error legacy_status =
-            legacy_hal_.lock()->stop(lock, []() {});
+        legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stop(lock, []() {});
         if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-            LOG(ERROR) << "Failed to stop legacy HAL: "
-                       << legacyErrorToString(legacy_status);
+            LOG(ERROR) << "Failed to stop legacy HAL: " << legacyErrorToString(legacy_status);
             return createWifiStatusFromLegacyError(legacy_status);
         }
     }
@@ -1602,8 +1459,7 @@
     }
     legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start();
     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        LOG(ERROR) << "Failed to start legacy HAL: "
-                   << legacyErrorToString(legacy_status);
+        LOG(ERROR) << "Failed to start legacy HAL: " << legacyErrorToString(legacy_status);
         return createWifiStatusFromLegacyError(legacy_status);
     }
     // Every time the HAL is restarted, we need to register the
@@ -1619,8 +1475,7 @@
     if (WifiStatusCode::SUCCESS == version_info.first.code) {
         property_set("vendor.wlan.firmware.version",
                      version_info.second.firmwareDescription.c_str());
-        property_set("vendor.wlan.driver.version",
-                     version_info.second.driverDescription.c_str());
+        property_set("vendor.wlan.driver.version", version_info.second.driverDescription.c_str());
     }
 
     return createWifiStatus(WifiStatusCode::SUCCESS);
@@ -1633,36 +1488,33 @@
 
     android::wp<WifiChip> weak_ptr_this(this);
     const auto& on_ring_buffer_data_callback =
-        [weak_ptr_this](const std::string& name,
-                        const std::vector<uint8_t>& data,
-                        const legacy_hal::wifi_ring_buffer_status& status) {
-            const auto shared_ptr_this = weak_ptr_this.promote();
-            if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                LOG(ERROR) << "Callback invoked on an invalid object";
-                return;
-            }
-            WifiDebugRingBufferStatus hidl_status;
-            if (!hidl_struct_util::convertLegacyDebugRingBufferStatusToHidl(
-                    status, &hidl_status)) {
-                LOG(ERROR) << "Error converting ring buffer status";
-                return;
-            }
-            {
-                std::unique_lock<std::mutex> lk(shared_ptr_this->lock_t);
-                const auto& target =
-                    shared_ptr_this->ringbuffer_map_.find(name);
-                if (target != shared_ptr_this->ringbuffer_map_.end()) {
-                    Ringbuffer& cur_buffer = target->second;
-                    cur_buffer.append(data);
-                } else {
-                    LOG(ERROR) << "Ringname " << name << " not found";
+            [weak_ptr_this](const std::string& name, const std::vector<uint8_t>& data,
+                            const legacy_hal::wifi_ring_buffer_status& status) {
+                const auto shared_ptr_this = weak_ptr_this.promote();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
                     return;
                 }
-                // unique_lock unlocked here
-            }
-        };
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->registerRingBufferCallbackHandler(
+                WifiDebugRingBufferStatus hidl_status;
+                if (!hidl_struct_util::convertLegacyDebugRingBufferStatusToHidl(status,
+                                                                                &hidl_status)) {
+                    LOG(ERROR) << "Error converting ring buffer status";
+                    return;
+                }
+                {
+                    std::unique_lock<std::mutex> lk(shared_ptr_this->lock_t);
+                    const auto& target = shared_ptr_this->ringbuffer_map_.find(name);
+                    if (target != shared_ptr_this->ringbuffer_map_.end()) {
+                        Ringbuffer& cur_buffer = target->second;
+                        cur_buffer.append(data);
+                    } else {
+                        LOG(ERROR) << "Ringname " << name << " not found";
+                        return;
+                    }
+                    // unique_lock unlocked here
+                }
+            };
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->registerRingBufferCallbackHandler(
             getFirstActiveWlanIfaceName(), on_ring_buffer_data_callback);
 
     if (legacy_status == legacy_hal::WIFI_SUCCESS) {
@@ -1674,35 +1526,32 @@
 WifiStatus WifiChip::registerRadioModeChangeCallback() {
     android::wp<WifiChip> weak_ptr_this(this);
     const auto& on_radio_mode_change_callback =
-        [weak_ptr_this](const std::vector<legacy_hal::WifiMacInfo>& mac_infos) {
-            const auto shared_ptr_this = weak_ptr_this.promote();
-            if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                LOG(ERROR) << "Callback invoked on an invalid object";
-                return;
-            }
-            std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo>
-                hidl_radio_mode_infos;
-            if (!hidl_struct_util::convertLegacyWifiMacInfosToHidl(
-                    mac_infos, &hidl_radio_mode_infos)) {
-                LOG(ERROR) << "Error converting wifi mac info";
-                return;
-            }
-            for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                if (!callback->onRadioModeChange_1_4(hidl_radio_mode_infos)
-                         .isOk()) {
-                    LOG(ERROR) << "Failed to invoke onRadioModeChange_1_4"
-                               << " callback on: " << toString(callback);
+            [weak_ptr_this](const std::vector<legacy_hal::WifiMacInfo>& mac_infos) {
+                const auto shared_ptr_this = weak_ptr_this.promote();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
                 }
-            }
-        };
+                std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo> hidl_radio_mode_infos;
+                if (!hidl_struct_util::convertLegacyWifiMacInfosToHidl(mac_infos,
+                                                                       &hidl_radio_mode_infos)) {
+                    LOG(ERROR) << "Error converting wifi mac info";
+                    return;
+                }
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->onRadioModeChange_1_4(hidl_radio_mode_infos).isOk()) {
+                        LOG(ERROR) << "Failed to invoke onRadioModeChange_1_4"
+                                   << " callback on: " << toString(callback);
+                    }
+                }
+            };
     legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->registerRadioModeChangeCallbackHandler(
-            getFirstActiveWlanIfaceName(), on_radio_mode_change_callback);
+            legacy_hal_.lock()->registerRadioModeChangeCallbackHandler(
+                    getFirstActiveWlanIfaceName(), on_radio_mode_change_callback);
     return createWifiStatusFromLegacyError(legacy_status);
 }
 
-std::vector<V1_4::IWifiChip::ChipIfaceCombination>
-WifiChip::getCurrentModeIfaceCombinations() {
+std::vector<V1_4::IWifiChip::ChipIfaceCombination> WifiChip::getCurrentModeIfaceCombinations() {
     if (!isValidModeId(current_mode_id_)) {
         LOG(ERROR) << "Chip not configured in a mode yet";
         return {};
@@ -1732,7 +1581,7 @@
 // of ifaces of each type in the combination.
 // This method is a port of HalDeviceManager.expandIfaceCombos() from framework.
 std::vector<std::map<IfaceType, size_t>> WifiChip::expandIfaceCombinations(
-    const V1_4::IWifiChip::ChipIfaceCombination& combination) {
+        const V1_4::IWifiChip::ChipIfaceCombination& combination) {
     uint32_t num_expanded_combos = 1;
     for (const auto& limit : combination.limits) {
         for (uint32_t i = 0; i < limit.maxIfaces; i++) {
@@ -1745,8 +1594,7 @@
     std::vector<std::map<IfaceType, size_t>> expanded_combos;
     expanded_combos.resize(num_expanded_combos);
     for (auto& expanded_combo : expanded_combos) {
-        for (const auto type :
-             {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) {
+        for (const auto type : {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) {
             expanded_combo[type] = 0;
         }
     }
@@ -1755,8 +1603,7 @@
         for (uint32_t i = 0; i < limit.maxIfaces; i++) {
             span /= limit.types.size();
             for (uint32_t k = 0; k < num_expanded_combos; ++k) {
-                const auto iface_type =
-                    limit.types[(k / span) % limit.types.size()];
+                const auto iface_type = limit.types[(k / span) % limit.types.size()];
                 expanded_combos[k][iface_type]++;
             }
         }
@@ -1765,13 +1612,11 @@
 }
 
 bool WifiChip::canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces(
-    const std::map<IfaceType, size_t>& expanded_combo,
-    IfaceType requested_type) {
+        const std::map<IfaceType, size_t>& expanded_combo, IfaceType requested_type) {
     const auto current_combo = getCurrentIfaceCombination();
 
     // Check if we have space for 1 more iface of |type| in this combo
-    for (const auto type :
-         {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) {
+    for (const auto type : {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) {
         size_t num_ifaces_needed = current_combo.at(type);
         if (type == requested_type) {
             num_ifaces_needed++;
@@ -1789,8 +1634,7 @@
 //    ChipIfaceCombination.
 // b) Check if the requested iface type can be added to the current mode
 //    with the iface combination that is already active.
-bool WifiChip::canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(
-    IfaceType requested_type) {
+bool WifiChip::canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType requested_type) {
     if (!isValidModeId(current_mode_id_)) {
         LOG(ERROR) << "Chip not configured in a mode yet";
         return false;
@@ -1799,8 +1643,8 @@
     for (const auto& combination : combinations) {
         const auto expanded_combos = expandIfaceCombinations(combination);
         for (const auto& expanded_combo : expanded_combos) {
-            if (canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces(
-                    expanded_combo, requested_type)) {
+            if (canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces(expanded_combo,
+                                                                         requested_type)) {
                 return true;
             }
         }
@@ -1811,11 +1655,10 @@
 // Note: This does not consider ifaces already active. It only checks if the
 // provided expanded iface combination can support the requested combo.
 bool WifiChip::canExpandedIfaceComboSupportIfaceCombo(
-    const std::map<IfaceType, size_t>& expanded_combo,
-    const std::map<IfaceType, size_t>& req_combo) {
+        const std::map<IfaceType, size_t>& expanded_combo,
+        const std::map<IfaceType, size_t>& req_combo) {
     // Check if we have space for 1 more iface of |type| in this combo
-    for (const auto type :
-         {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) {
+    for (const auto type : {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) {
         if (req_combo.count(type) == 0) {
             // Iface of "type" not in the req_combo.
             continue;
@@ -1834,8 +1677,7 @@
 // b) Check if the requested iface combo can be added to the current mode.
 // Note: This does not consider ifaces already active. It only checks if the
 // current mode can support the requested combo.
-bool WifiChip::canCurrentModeSupportIfaceCombo(
-    const std::map<IfaceType, size_t>& req_combo) {
+bool WifiChip::canCurrentModeSupportIfaceCombo(const std::map<IfaceType, size_t>& req_combo) {
     if (!isValidModeId(current_mode_id_)) {
         LOG(ERROR) << "Chip not configured in a mode yet";
         return false;
@@ -1844,8 +1686,7 @@
     for (const auto& combination : combinations) {
         const auto expanded_combos = expandIfaceCombinations(combination);
         for (const auto& expanded_combo : expanded_combos) {
-            if (canExpandedIfaceComboSupportIfaceCombo(expanded_combo,
-                                                       req_combo)) {
+            if (canExpandedIfaceComboSupportIfaceCombo(expanded_combo, req_combo)) {
                 return true;
             }
         }
@@ -1909,8 +1750,7 @@
 // Return the first wlan (wlan0, wlan1 etc.) starting from |start_idx|
 // not already in use.
 // Note: This doesn't check the actual presence of these interfaces.
-std::string WifiChip::allocateApOrStaIfaceName(IfaceType type,
-                                               uint32_t start_idx) {
+std::string WifiChip::allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx) {
     for (unsigned idx = start_idx; idx < kMaxWlanIfaces; idx++) {
         const auto ifname = getWlanIfaceNameWithType(type, idx);
         if (findUsingNameFromBridgedApInstances(ifname)) continue;
@@ -1955,8 +1795,8 @@
     } else {
         int num_ifaces_need_to_allocate = 2 - instances.size();
         for (int i = 0; i < num_ifaces_need_to_allocate; i++) {
-            std::string instance_name = allocateApOrStaIfaceName(
-                IfaceType::AP, startIdxOfApIface() + i);
+            std::string instance_name =
+                    allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface() + i);
             if (!instance_name.empty()) {
                 instances.push_back(instance_name);
             }
@@ -1984,8 +1824,7 @@
             if (cur_buffer.getData().empty()) {
                 continue;
             }
-            const std::string file_path_raw =
-                kTombstoneFolderPath + item.first + "XXXXXXXXXX";
+            const std::string file_path_raw = kTombstoneFolderPath + item.first + "XXXXXXXXXX";
             const int dump_fd = mkstemp(makeCharVec(file_path_raw).data());
             if (dump_fd == -1) {
                 PLOG(ERROR) << "create file failed";
@@ -1993,8 +1832,8 @@
             }
             unique_fd file_auto_closer(dump_fd);
             for (const auto& cur_block : cur_buffer.getData()) {
-                if (write(dump_fd, cur_block.data(),
-                          sizeof(cur_block[0]) * cur_block.size()) == -1) {
+                if (write(dump_fd, cur_block.data(), sizeof(cur_block[0]) * cur_block.size()) ==
+                    -1) {
                     PLOG(ERROR) << "Error writing to file";
                 }
             }
@@ -2009,8 +1848,7 @@
     std::string ifname;
 
     // let the legacy hal override the interface name
-    legacy_hal::wifi_error err =
-        legacy_hal_.lock()->getSupportedIfaceName((uint32_t)type, ifname);
+    legacy_hal::wifi_error err = legacy_hal_.lock()->getSupportedIfaceName((uint32_t)type, ifname);
     if (err == legacy_hal::WIFI_SUCCESS) return ifname;
 
     return getWlanIfaceName(idx);
@@ -2059,7 +1897,7 @@
 }
 
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.6/default/wifi_chip.h b/wifi/1.6/default/wifi_chip.h
new file mode 100644
index 0000000..8a06898
--- /dev/null
+++ b/wifi/1.6/default/wifi_chip.h
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 WIFI_CHIP_H_
+#define WIFI_CHIP_H_
+
+#include <list>
+#include <map>
+#include <mutex>
+
+#include <android-base/macros.h>
+#include <android/hardware/wifi/1.4/IWifiRttController.h>
+#include <android/hardware/wifi/1.5/IWifiChip.h>
+
+#include "hidl_callback_util.h"
+#include "ringbuffer.h"
+#include "wifi_ap_iface.h"
+#include "wifi_feature_flags.h"
+#include "wifi_legacy_hal.h"
+#include "wifi_mode_controller.h"
+#include "wifi_nan_iface.h"
+#include "wifi_p2p_iface.h"
+#include "wifi_rtt_controller.h"
+#include "wifi_sta_iface.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+using namespace android::hardware::wifi::V1_0;
+using V1_5::WifiBand;
+using V1_5::WifiUsableChannel;
+
+/**
+ * HIDL interface object used to control a Wifi HAL chip instance.
+ * Since there is only a single chip instance used today, there is no
+ * identifying handle information stored here.
+ */
+class WifiChip : public V1_5::IWifiChip {
+  public:
+    WifiChip(ChipId chip_id, bool is_primary,
+             const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+             const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
+             const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
+             const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
+             const std::function<void(const std::string&)>& subsystemCallbackHandler);
+    // HIDL does not provide a built-in mechanism to let the server invalidate
+    // a HIDL interface object after creation. If any client process holds onto
+    // a reference to the object in their context, any method calls on that
+    // reference will continue to be directed to the server.
+    //
+    // However Wifi HAL needs to control the lifetime of these objects. So, add
+    // a public |invalidate| method to |WifiChip| and it's child objects. This
+    // will be used to mark an object invalid when either:
+    // a) Wifi HAL is stopped, or
+    // b) Wifi Chip is reconfigured.
+    //
+    // All HIDL method implementations should check if the object is still
+    // marked valid before processing them.
+    void invalidate();
+    bool isValid();
+    std::set<sp<V1_4::IWifiChipEventCallback>> getEventCallbacks();
+
+    // HIDL methods exposed.
+    Return<void> getId(getId_cb hidl_status_cb) override;
+    // Deprecated support for this callback
+    Return<void> registerEventCallback(const sp<V1_0::IWifiChipEventCallback>& event_callback,
+                                       registerEventCallback_cb hidl_status_cb) override;
+    Return<void> getCapabilities(getCapabilities_cb hidl_status_cb) override;
+    Return<void> getAvailableModes(getAvailableModes_cb hidl_status_cb) override;
+    Return<void> configureChip(ChipModeId mode_id, configureChip_cb hidl_status_cb) override;
+    Return<void> getMode(getMode_cb hidl_status_cb) override;
+    Return<void> requestChipDebugInfo(requestChipDebugInfo_cb hidl_status_cb) override;
+    Return<void> requestDriverDebugDump(requestDriverDebugDump_cb hidl_status_cb) override;
+    Return<void> requestFirmwareDebugDump(requestFirmwareDebugDump_cb hidl_status_cb) override;
+    Return<void> createApIface(createApIface_cb hidl_status_cb) override;
+    Return<void> createBridgedApIface(createBridgedApIface_cb hidl_status_cb) override;
+    Return<void> getApIfaceNames(getApIfaceNames_cb hidl_status_cb) override;
+    Return<void> getApIface(const hidl_string& ifname, getApIface_cb hidl_status_cb) override;
+    Return<void> removeApIface(const hidl_string& ifname, removeApIface_cb hidl_status_cb) override;
+    Return<void> removeIfaceInstanceFromBridgedApIface(
+            const hidl_string& brIfaceName, const hidl_string& ifaceInstanceName,
+            removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) override;
+    Return<void> createNanIface(createNanIface_cb hidl_status_cb) override;
+    Return<void> getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) override;
+    Return<void> getNanIface(const hidl_string& ifname, getNanIface_cb hidl_status_cb) override;
+    Return<void> removeNanIface(const hidl_string& ifname,
+                                removeNanIface_cb hidl_status_cb) override;
+    Return<void> createP2pIface(createP2pIface_cb hidl_status_cb) override;
+    Return<void> getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) override;
+    Return<void> getP2pIface(const hidl_string& ifname, getP2pIface_cb hidl_status_cb) override;
+    Return<void> removeP2pIface(const hidl_string& ifname,
+                                removeP2pIface_cb hidl_status_cb) override;
+    Return<void> createStaIface(createStaIface_cb hidl_status_cb) override;
+    Return<void> getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) override;
+    Return<void> getStaIface(const hidl_string& ifname, getStaIface_cb hidl_status_cb) override;
+    Return<void> removeStaIface(const hidl_string& ifname,
+                                removeStaIface_cb hidl_status_cb) override;
+    Return<void> createRttController(const sp<IWifiIface>& bound_iface,
+                                     createRttController_cb hidl_status_cb) override;
+    Return<void> getDebugRingBuffersStatus(getDebugRingBuffersStatus_cb hidl_status_cb) override;
+    Return<void> startLoggingToDebugRingBuffer(
+            const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
+            uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes,
+            startLoggingToDebugRingBuffer_cb hidl_status_cb) override;
+    Return<void> forceDumpToDebugRingBuffer(const hidl_string& ring_name,
+                                            forceDumpToDebugRingBuffer_cb hidl_status_cb) override;
+    Return<void> flushRingBufferToFile(flushRingBufferToFile_cb hidl_status_cb) override;
+    Return<void> stopLoggingToDebugRingBuffer(
+            stopLoggingToDebugRingBuffer_cb hidl_status_cb) override;
+    Return<void> getDebugHostWakeReasonStats(
+            getDebugHostWakeReasonStats_cb hidl_status_cb) override;
+    Return<void> enableDebugErrorAlerts(bool enable,
+                                        enableDebugErrorAlerts_cb hidl_status_cb) override;
+    Return<void> selectTxPowerScenario(V1_1::IWifiChip::TxPowerScenario scenario,
+                                       selectTxPowerScenario_cb hidl_status_cb) override;
+    Return<void> resetTxPowerScenario(resetTxPowerScenario_cb hidl_status_cb) override;
+    Return<void> setLatencyMode(LatencyMode mode, setLatencyMode_cb hidl_status_cb) override;
+    Return<void> registerEventCallback_1_2(const sp<V1_2::IWifiChipEventCallback>& event_callback,
+                                           registerEventCallback_1_2_cb hidl_status_cb) override;
+    Return<void> selectTxPowerScenario_1_2(TxPowerScenario scenario,
+                                           selectTxPowerScenario_cb hidl_status_cb) override;
+    Return<void> getCapabilities_1_3(getCapabilities_cb hidl_status_cb) override;
+    Return<void> getCapabilities_1_5(getCapabilities_1_5_cb hidl_status_cb) override;
+    Return<void> debug(const hidl_handle& handle, const hidl_vec<hidl_string>& options) override;
+    Return<void> createRttController_1_4(const sp<IWifiIface>& bound_iface,
+                                         createRttController_1_4_cb hidl_status_cb) override;
+    Return<void> registerEventCallback_1_4(const sp<V1_4::IWifiChipEventCallback>& event_callback,
+                                           registerEventCallback_1_4_cb hidl_status_cb) override;
+    Return<void> setMultiStaPrimaryConnection(
+            const hidl_string& ifname, setMultiStaPrimaryConnection_cb hidl_status_cb) override;
+    Return<void> setMultiStaUseCase(MultiStaUseCase use_case,
+                                    setMultiStaUseCase_cb hidl_status_cb) override;
+    Return<void> setCoexUnsafeChannels(const hidl_vec<CoexUnsafeChannel>& unsafe_channels,
+                                       hidl_bitfield<IfaceType> restrictions,
+                                       setCoexUnsafeChannels_cb hidl_status_cb) override;
+    Return<void> setCountryCode(const hidl_array<int8_t, 2>& code,
+                                setCountryCode_cb _hidl_cb) override;
+    Return<void> getUsableChannels(WifiBand band, hidl_bitfield<V1_5::WifiIfaceMode> ifaceModeMask,
+                                   hidl_bitfield<UsableChannelFilter> filterMask,
+                                   getUsableChannels_cb _hidl_cb) override;
+    Return<void> triggerSubsystemRestart(triggerSubsystemRestart_cb hidl_status_cb) override;
+
+  private:
+    void invalidateAndRemoveAllIfaces();
+    // When a STA iface is removed any dependent NAN-ifaces/RTT-controllers are
+    // invalidated & removed.
+    void invalidateAndRemoveDependencies(const std::string& removed_iface_name);
+
+    // Corresponding worker functions for the HIDL methods.
+    std::pair<WifiStatus, ChipId> getIdInternal();
+    // Deprecated support for this callback
+    WifiStatus registerEventCallbackInternal(
+            const sp<V1_0::IWifiChipEventCallback>& event_callback);
+    std::pair<WifiStatus, uint32_t> getCapabilitiesInternal();
+    std::pair<WifiStatus, std::vector<ChipMode>> getAvailableModesInternal();
+    WifiStatus configureChipInternal(std::unique_lock<std::recursive_mutex>* lock,
+                                     ChipModeId mode_id);
+    std::pair<WifiStatus, uint32_t> getModeInternal();
+    std::pair<WifiStatus, IWifiChip::ChipDebugInfo> requestChipDebugInfoInternal();
+    std::pair<WifiStatus, std::vector<uint8_t>> requestDriverDebugDumpInternal();
+    std::pair<WifiStatus, std::vector<uint8_t>> requestFirmwareDebugDumpInternal();
+    sp<WifiApIface> newWifiApIface(std::string& ifname);
+    WifiStatus createVirtualApInterface(const std::string& apVirtIf);
+    std::pair<WifiStatus, sp<V1_5::IWifiApIface>> createApIfaceInternal();
+    std::pair<WifiStatus, sp<V1_5::IWifiApIface>> createBridgedApIfaceInternal();
+    std::pair<WifiStatus, std::vector<hidl_string>> getApIfaceNamesInternal();
+    std::pair<WifiStatus, sp<V1_5::IWifiApIface>> getApIfaceInternal(const std::string& ifname);
+    WifiStatus removeApIfaceInternal(const std::string& ifname);
+    WifiStatus removeIfaceInstanceFromBridgedApIfaceInternal(const std::string& brIfaceName,
+                                                             const std::string& ifInstanceName);
+    std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> createNanIfaceInternal();
+    std::pair<WifiStatus, std::vector<hidl_string>> getNanIfaceNamesInternal();
+    std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> getNanIfaceInternal(const std::string& ifname);
+    WifiStatus removeNanIfaceInternal(const std::string& ifname);
+    std::pair<WifiStatus, sp<IWifiP2pIface>> createP2pIfaceInternal();
+    std::pair<WifiStatus, std::vector<hidl_string>> getP2pIfaceNamesInternal();
+    std::pair<WifiStatus, sp<IWifiP2pIface>> getP2pIfaceInternal(const std::string& ifname);
+    WifiStatus removeP2pIfaceInternal(const std::string& ifname);
+    std::pair<WifiStatus, sp<V1_5::IWifiStaIface>> createStaIfaceInternal();
+    std::pair<WifiStatus, std::vector<hidl_string>> getStaIfaceNamesInternal();
+    std::pair<WifiStatus, sp<V1_5::IWifiStaIface>> getStaIfaceInternal(const std::string& ifname);
+    WifiStatus removeStaIfaceInternal(const std::string& ifname);
+    std::pair<WifiStatus, sp<V1_0::IWifiRttController>> createRttControllerInternal(
+            const sp<IWifiIface>& bound_iface);
+    std::pair<WifiStatus, std::vector<WifiDebugRingBufferStatus>>
+    getDebugRingBuffersStatusInternal();
+    WifiStatus startLoggingToDebugRingBufferInternal(const hidl_string& ring_name,
+                                                     WifiDebugRingBufferVerboseLevel verbose_level,
+                                                     uint32_t max_interval_in_sec,
+                                                     uint32_t min_data_size_in_bytes);
+    WifiStatus forceDumpToDebugRingBufferInternal(const hidl_string& ring_name);
+    WifiStatus flushRingBufferToFileInternal();
+    WifiStatus stopLoggingToDebugRingBufferInternal();
+    std::pair<WifiStatus, WifiDebugHostWakeReasonStats> getDebugHostWakeReasonStatsInternal();
+    WifiStatus enableDebugErrorAlertsInternal(bool enable);
+    WifiStatus selectTxPowerScenarioInternal(V1_1::IWifiChip::TxPowerScenario scenario);
+    WifiStatus resetTxPowerScenarioInternal();
+    WifiStatus setLatencyModeInternal(LatencyMode mode);
+    WifiStatus registerEventCallbackInternal_1_2(
+            const sp<V1_2::IWifiChipEventCallback>& event_callback);
+    WifiStatus selectTxPowerScenarioInternal_1_2(TxPowerScenario scenario);
+    std::pair<WifiStatus, uint32_t> getCapabilitiesInternal_1_3();
+    std::pair<WifiStatus, uint32_t> getCapabilitiesInternal_1_5();
+    std::pair<WifiStatus, sp<V1_4::IWifiRttController>> createRttControllerInternal_1_4(
+            const sp<IWifiIface>& bound_iface);
+    WifiStatus registerEventCallbackInternal_1_4(
+            const sp<V1_4::IWifiChipEventCallback>& event_callback);
+    WifiStatus setMultiStaPrimaryConnectionInternal(const std::string& ifname);
+    WifiStatus setMultiStaUseCaseInternal(MultiStaUseCase use_case);
+    WifiStatus setCoexUnsafeChannelsInternal(std::vector<CoexUnsafeChannel> unsafe_channels,
+                                             uint32_t restrictions);
+    WifiStatus setCountryCodeInternal(const std::array<int8_t, 2>& code);
+    std::pair<WifiStatus, std::vector<WifiUsableChannel>> getUsableChannelsInternal(
+            WifiBand band, uint32_t ifaceModeMask, uint32_t filterMask);
+    WifiStatus handleChipConfiguration(std::unique_lock<std::recursive_mutex>* lock,
+                                       ChipModeId mode_id);
+    WifiStatus registerDebugRingBufferCallback();
+    WifiStatus registerRadioModeChangeCallback();
+
+    std::vector<V1_4::IWifiChip::ChipIfaceCombination> getCurrentModeIfaceCombinations();
+    std::map<IfaceType, size_t> getCurrentIfaceCombination();
+    std::vector<std::map<IfaceType, size_t>> expandIfaceCombinations(
+            const V1_4::IWifiChip::ChipIfaceCombination& combination);
+    bool canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces(
+            const std::map<IfaceType, size_t>& expanded_combo, IfaceType requested_type);
+    bool canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType requested_type);
+    bool canExpandedIfaceComboSupportIfaceCombo(const std::map<IfaceType, size_t>& expanded_combo,
+                                                const std::map<IfaceType, size_t>& req_combo);
+    bool canCurrentModeSupportIfaceCombo(const std::map<IfaceType, size_t>& req_combo);
+    bool canCurrentModeSupportIfaceOfType(IfaceType requested_type);
+    bool isValidModeId(ChipModeId mode_id);
+    bool isStaApConcurrencyAllowedInCurrentMode();
+    bool isDualStaConcurrencyAllowedInCurrentMode();
+    uint32_t startIdxOfApIface();
+    std::string getFirstActiveWlanIfaceName();
+    std::string allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx);
+    std::string allocateApIfaceName();
+    std::vector<std::string> allocateBridgedApInstanceNames();
+    std::string allocateStaIfaceName();
+    bool writeRingbufferFilesInternal();
+    std::string getWlanIfaceNameWithType(IfaceType type, unsigned idx);
+    void invalidateAndClearBridgedApAll();
+    void invalidateAndClearBridgedAp(const std::string& br_name);
+    bool findUsingNameFromBridgedApInstances(const std::string& name);
+    WifiStatus triggerSubsystemRestartInternal();
+
+    ChipId chip_id_;
+    std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+    std::weak_ptr<mode_controller::WifiModeController> mode_controller_;
+    std::shared_ptr<iface_util::WifiIfaceUtil> iface_util_;
+    std::vector<sp<WifiApIface>> ap_ifaces_;
+    std::vector<sp<WifiNanIface>> nan_ifaces_;
+    std::vector<sp<WifiP2pIface>> p2p_ifaces_;
+    std::vector<sp<WifiStaIface>> sta_ifaces_;
+    std::vector<sp<WifiRttController>> rtt_controllers_;
+    std::map<std::string, Ringbuffer> ringbuffer_map_;
+    bool is_valid_;
+    // Members pertaining to chip configuration.
+    uint32_t current_mode_id_;
+    std::mutex lock_t;
+    std::vector<V1_4::IWifiChip::ChipMode> modes_;
+    // The legacy ring buffer callback API has only a global callback
+    // registration mechanism. Use this to check if we have already
+    // registered a callback.
+    bool debug_ring_buffer_cb_registered_;
+    hidl_callback_util::HidlCallbackHandler<V1_4::IWifiChipEventCallback> event_cb_handler_;
+
+    const std::function<void(const std::string&)> subsystemCallbackHandler_;
+    std::map<std::string, std::vector<std::string>> br_ifaces_ap_instances_;
+    DISALLOW_COPY_AND_ASSIGN(WifiChip);
+};
+
+}  // namespace implementation
+}  // namespace V1_6
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+
+#endif  // WIFI_CHIP_H_
diff --git a/wifi/1.5/default/wifi_feature_flags.cpp b/wifi/1.6/default/wifi_feature_flags.cpp
similarity index 87%
rename from wifi/1.5/default/wifi_feature_flags.cpp
rename to wifi/1.6/default/wifi_feature_flags.cpp
index 70ce55a..71319e1 100644
--- a/wifi/1.5/default/wifi_feature_flags.cpp
+++ b/wifi/1.6/default/wifi_feature_flags.cpp
@@ -24,7 +24,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 namespace feature_flags {
 
@@ -117,18 +117,16 @@
  * The main point here is to simplify the syntax required by
  * WIFI_HAL_INTERFACE_COMBINATIONS.
  */
-struct ChipIfaceCombination
-    : public hidl_vec<IWifiChip::ChipIfaceCombinationLimit> {
-    ChipIfaceCombination(
-        const std::initializer_list<IWifiChip::ChipIfaceCombinationLimit> list)
+struct ChipIfaceCombination : public hidl_vec<IWifiChip::ChipIfaceCombinationLimit> {
+    ChipIfaceCombination(const std::initializer_list<IWifiChip::ChipIfaceCombinationLimit> list)
         : hidl_vec(list) {}
 
     operator IWifiChip::ChipIfaceCombination() const { return {*this}; }
 
     static hidl_vec<IWifiChip::ChipIfaceCombination> make_vec(
-        const std::initializer_list<ChipIfaceCombination> list) {
+            const std::initializer_list<ChipIfaceCombination> list) {
         return hidl_vec<IWifiChip::ChipIfaceCombination>(  //
-            std::begin(list), std::end(list));
+                std::begin(list), std::end(list));
     }
 };
 
@@ -137,23 +135,22 @@
 #define P2P IfaceType::P2P
 #define NAN IfaceType::NAN
 static const std::vector<IWifiChip::ChipMode> kChipModesPrimary{
-    {kMainModeId,
-     ChipIfaceCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS})},
+        {kMainModeId, ChipIfaceCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS})},
 #ifdef WIFI_HAL_INTERFACE_COMBINATIONS_AP
-    {chip_mode_ids::kV1Ap,
-     ChipIfaceCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS_AP})},
+        {chip_mode_ids::kV1Ap,
+         ChipIfaceCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS_AP})},
 #endif
 };
 
 static const std::vector<IWifiChip::ChipMode> kChipModesSecondary{
 #ifdef WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP
-    {chip_mode_ids::kV3, ChipIfaceCombination::make_vec(
-                             {WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP})},
+        {chip_mode_ids::kV3,
+         ChipIfaceCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP})},
 #endif
 };
 
 constexpr char kDebugPresetInterfaceCombinationIdxProperty[] =
-    "persist.vendor.debug.wifi.hal.preset_interface_combination_idx";
+        "persist.vendor.debug.wifi.hal.preset_interface_combination_idx";
 // List of pre-defined interface combinations that can be enabled at runtime via
 // setting the property: "kDebugPresetInterfaceCombinationIdxProperty" to the
 // corresponding index value.
@@ -200,19 +197,18 @@
 #undef NAN
 
 #ifdef WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
-#pragma message                                                               \
-    "WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION is deprecated; override " \
-    "'config_wifi_ap_randomization_supported' in "                            \
-    "frameworks/base/core/res/res/values/config.xml in the device overlay "   \
-    "instead"
+#pragma message                                                                   \
+        "WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION is deprecated; override " \
+        "'config_wifi_ap_randomization_supported' in "                            \
+        "frameworks/base/core/res/res/values/config.xml in the device overlay "   \
+        "instead"
 #endif  // WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
 
 WifiFeatureFlags::WifiFeatureFlags() {}
 
 std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModesForPrimary() {
     std::array<char, PROPERTY_VALUE_MAX> buffer;
-    auto res = property_get(kDebugPresetInterfaceCombinationIdxProperty,
-                            buffer.data(), nullptr);
+    auto res = property_get(kDebugPresetInterfaceCombinationIdxProperty, buffer.data(), nullptr);
     // Debug propety not set, use the device preset interface combination.
     if (res <= 0) return kChipModesPrimary;
 
@@ -226,19 +222,18 @@
     std::string name;
     std::vector<IWifiChip::ChipMode> chip_modes;
     std::tie(name, chip_modes) = kDebugChipModes[idx];
-    LOG(INFO) << "Using debug chip mode: <" << name << "> set via property: "
-              << kDebugPresetInterfaceCombinationIdxProperty;
+    LOG(INFO) << "Using debug chip mode: <" << name
+              << "> set via property: " << kDebugPresetInterfaceCombinationIdxProperty;
     return chip_modes;
 }
 
-std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModes(
-    bool is_primary) {
+std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModes(bool is_primary) {
     return (is_primary) ? getChipModesForPrimary() : kChipModesSecondary;
 }
 
 }  // namespace feature_flags
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/wifi_feature_flags.h b/wifi/1.6/default/wifi_feature_flags.h
similarity index 94%
rename from wifi/1.5/default/wifi_feature_flags.h
rename to wifi/1.6/default/wifi_feature_flags.h
index 7d561fc..d5844d9 100644
--- a/wifi/1.5/default/wifi_feature_flags.h
+++ b/wifi/1.6/default/wifi_feature_flags.h
@@ -22,7 +22,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 namespace feature_flags {
 
@@ -38,20 +38,19 @@
 }  // namespace chip_mode_ids
 
 class WifiFeatureFlags {
-   public:
+  public:
     WifiFeatureFlags();
     virtual ~WifiFeatureFlags() = default;
 
-    virtual std::vector<V1_0::IWifiChip::ChipMode> getChipModes(
-        bool is_primary);
+    virtual std::vector<V1_0::IWifiChip::ChipMode> getChipModes(bool is_primary);
 
-   private:
+  private:
     std::vector<V1_0::IWifiChip::ChipMode> getChipModesForPrimary();
 };
 
 }  // namespace feature_flags
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/wifi_iface_util.cpp b/wifi/1.6/default/wifi_iface_util.cpp
similarity index 85%
rename from wifi/1.5/default/wifi_iface_util.cpp
rename to wifi/1.6/default/wifi_iface_util.cpp
index 0977026..d55e4f8 100644
--- a/wifi/1.5/default/wifi_iface_util.cpp
+++ b/wifi/1.6/default/wifi_iface_util.cpp
@@ -36,20 +36,18 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 namespace iface_util {
 
-WifiIfaceUtil::WifiIfaceUtil(
-    const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
-    const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
+WifiIfaceUtil::WifiIfaceUtil(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
+                             const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
     : iface_tool_(iface_tool),
       legacy_hal_(legacy_hal),
       random_mac_address_(nullptr),
       event_handlers_map_() {}
 
-std::array<uint8_t, 6> WifiIfaceUtil::getFactoryMacAddress(
-    const std::string& iface_name) {
+std::array<uint8_t, 6> WifiIfaceUtil::getFactoryMacAddress(const std::string& iface_name) {
     return iface_tool_.lock()->GetFactoryMacAddress(iface_name.c_str());
 }
 
@@ -59,7 +57,7 @@
     legacy_hal::wifi_error legacy_status;
     uint64_t legacy_feature_set;
     std::tie(legacy_status, legacy_feature_set) =
-        legacy_hal_.lock()->getSupportedFeatureSet(iface_name);
+            legacy_hal_.lock()->getSupportedFeatureSet(iface_name);
 
     if (!(legacy_feature_set & WIFI_FEATURE_DYNAMIC_SET_MAC) &&
         !iface_tool_.lock()->SetUpState(iface_name.c_str(), false)) {
@@ -73,8 +71,7 @@
         !iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) {
         LOG(ERROR) << "SetUpState(true) failed. Wait for driver ready.";
         // Wait for driver ready and try to set iface UP again
-        if (legacy_hal_.lock()->waitForDriverReady() !=
-            legacy_hal::WIFI_SUCCESS) {
+        if (legacy_hal_.lock()->waitForDriverReady() != legacy_hal::WIFI_SUCCESS) {
             LOG(ERROR) << "SetUpState(true) wait for driver ready failed.";
             return false;
         }
@@ -104,8 +101,7 @@
     if (random_mac_address_) {
         return *random_mac_address_.get();
     }
-    random_mac_address_ =
-        std::make_unique<std::array<uint8_t, 6>>(createRandomMacAddress());
+    random_mac_address_ = std::make_unique<std::array<uint8_t, 6>>(createRandomMacAddress());
     return *random_mac_address_.get();
 }
 
@@ -114,8 +110,7 @@
     event_handlers_map_[iface_name] = handlers;
 }
 
-void WifiIfaceUtil::unregisterIfaceEventHandlers(
-    const std::string& iface_name) {
+void WifiIfaceUtil::unregisterIfaceEventHandlers(const std::string& iface_name) {
     event_handlers_map_.erase(iface_name);
 }
 
@@ -123,9 +118,8 @@
     std::array<uint8_t, 6> address = {};
     std::random_device rd;
     std::default_random_engine engine(rd());
-    std::uniform_int_distribution<uint8_t> dist(
-        std::numeric_limits<uint8_t>::min(),
-        std::numeric_limits<uint8_t>::max());
+    std::uniform_int_distribution<uint8_t> dist(std::numeric_limits<uint8_t>::min(),
+                                                std::numeric_limits<uint8_t>::max());
     for (size_t i = 0; i < address.size(); i++) {
         address[i] = dist(engine);
     }
@@ -166,19 +160,17 @@
     return iface_tool_.lock()->deleteBridge(br_name);
 }
 
-bool WifiIfaceUtil::addIfaceToBridge(const std::string& br_name,
-                                     const std::string& if_name) {
+bool WifiIfaceUtil::addIfaceToBridge(const std::string& br_name, const std::string& if_name) {
     return iface_tool_.lock()->addIfaceToBridge(br_name, if_name);
 }
 
-bool WifiIfaceUtil::removeIfaceFromBridge(const std::string& br_name,
-                                          const std::string& if_name) {
+bool WifiIfaceUtil::removeIfaceFromBridge(const std::string& br_name, const std::string& if_name) {
     return iface_tool_.lock()->removeIfaceFromBridge(br_name, if_name);
 }
 
 }  // namespace iface_util
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/wifi_iface_util.h b/wifi/1.6/default/wifi_iface_util.h
similarity index 85%
rename from wifi/1.5/default/wifi_iface_util.h
rename to wifi/1.6/default/wifi_iface_util.h
index 544f575..c5db5de 100644
--- a/wifi/1.5/default/wifi_iface_util.h
+++ b/wifi/1.6/default/wifi_iface_util.h
@@ -26,7 +26,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 namespace iface_util {
 
@@ -41,15 +41,13 @@
  * Util class for common iface operations.
  */
 class WifiIfaceUtil {
-   public:
+  public:
     WifiIfaceUtil(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
                   const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
     virtual ~WifiIfaceUtil() = default;
 
-    virtual std::array<uint8_t, 6> getFactoryMacAddress(
-        const std::string& iface_name);
-    virtual bool setMacAddress(const std::string& iface_name,
-                               const std::array<uint8_t, 6>& mac);
+    virtual std::array<uint8_t, 6> getFactoryMacAddress(const std::string& iface_name);
+    virtual bool setMacAddress(const std::string& iface_name, const std::array<uint8_t, 6>& mac);
     // Get or create a random MAC address. The MAC address returned from
     // this method will remain the same throughout the lifetime of the HAL
     // daemon. (So, changes on every reboot)
@@ -66,15 +64,13 @@
 
     virtual bool deleteBridge(const std::string& br_name);
 
-    virtual bool addIfaceToBridge(const std::string& br_name,
-                                  const std::string& if_name);
+    virtual bool addIfaceToBridge(const std::string& br_name, const std::string& if_name);
 
-    virtual bool removeIfaceFromBridge(const std::string& br_name,
-                                       const std::string& if_name);
+    virtual bool removeIfaceFromBridge(const std::string& br_name, const std::string& if_name);
     // Get a random MAC address.
     virtual std::array<uint8_t, 6> createRandomMacAddress();
 
-   private:
+  private:
     std::weak_ptr<wifi_system::InterfaceTool> iface_tool_;
     std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
     std::unique_ptr<std::array<uint8_t, 6>> random_mac_address_;
@@ -83,7 +79,7 @@
 
 }  // namespace iface_util
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.6/default/wifi_legacy_hal.cpp b/wifi/1.6/default/wifi_legacy_hal.cpp
new file mode 100644
index 0000000..e6e8141
--- /dev/null
+++ b/wifi/1.6/default/wifi_legacy_hal.cpp
@@ -0,0 +1,1578 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <array>
+#include <chrono>
+
+#include <android-base/logging.h>
+#include <cutils/properties.h>
+#include <net/if.h>
+
+#include "hidl_sync_util.h"
+#include "wifi_legacy_hal.h"
+#include "wifi_legacy_hal_stubs.h"
+
+namespace {
+// Constants ported over from the legacy HAL calling code
+// (com_android_server_wifi_WifiNative.cpp). This will all be thrown
+// away when this shim layer is replaced by the real vendor
+// implementation.
+static constexpr uint32_t kMaxVersionStringLength = 256;
+static constexpr uint32_t kMaxCachedGscanResults = 64;
+static constexpr uint32_t kMaxGscanFrequenciesForBand = 64;
+static constexpr uint32_t kLinkLayerStatsDataMpduSizeThreshold = 128;
+static constexpr uint32_t kMaxWakeReasonStatsArraySize = 32;
+static constexpr uint32_t kMaxRingBuffers = 10;
+static constexpr uint32_t kMaxWifiUsableChannels = 256;
+// need a long timeout (1000ms) for chips that unload their driver.
+static constexpr uint32_t kMaxStopCompleteWaitMs = 1000;
+static constexpr char kDriverPropName[] = "wlan.driver.status";
+
+// Helper function to create a non-const char* for legacy Hal API's.
+std::vector<char> makeCharVec(const std::string& str) {
+    std::vector<char> vec(str.size() + 1);
+    vec.assign(str.begin(), str.end());
+    vec.push_back('\0');
+    return vec;
+}
+}  // namespace
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+namespace legacy_hal {
+
+// Legacy HAL functions accept "C" style function pointers, so use global
+// functions to pass to the legacy HAL function and store the corresponding
+// std::function methods to be invoked.
+//
+// Callback to be invoked once |stop| is complete
+std::function<void(wifi_handle handle)> on_stop_complete_internal_callback;
+void onAsyncStopComplete(wifi_handle handle) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_stop_complete_internal_callback) {
+        on_stop_complete_internal_callback(handle);
+        // Invalidate this callback since we don't want this firing again.
+        on_stop_complete_internal_callback = nullptr;
+    }
+}
+
+// Callback to be invoked for driver dump.
+std::function<void(char*, int)> on_driver_memory_dump_internal_callback;
+void onSyncDriverMemoryDump(char* buffer, int buffer_size) {
+    if (on_driver_memory_dump_internal_callback) {
+        on_driver_memory_dump_internal_callback(buffer, buffer_size);
+    }
+}
+
+// Callback to be invoked for firmware dump.
+std::function<void(char*, int)> on_firmware_memory_dump_internal_callback;
+void onSyncFirmwareMemoryDump(char* buffer, int buffer_size) {
+    if (on_firmware_memory_dump_internal_callback) {
+        on_firmware_memory_dump_internal_callback(buffer, buffer_size);
+    }
+}
+
+// Callback to be invoked for Gscan events.
+std::function<void(wifi_request_id, wifi_scan_event)> on_gscan_event_internal_callback;
+void onAsyncGscanEvent(wifi_request_id id, wifi_scan_event event) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_gscan_event_internal_callback) {
+        on_gscan_event_internal_callback(id, event);
+    }
+}
+
+// Callback to be invoked for Gscan full results.
+std::function<void(wifi_request_id, wifi_scan_result*, uint32_t)>
+        on_gscan_full_result_internal_callback;
+void onAsyncGscanFullResult(wifi_request_id id, wifi_scan_result* result,
+                            uint32_t buckets_scanned) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_gscan_full_result_internal_callback) {
+        on_gscan_full_result_internal_callback(id, result, buckets_scanned);
+    }
+}
+
+// Callback to be invoked for link layer stats results.
+std::function<void((wifi_request_id, wifi_iface_stat*, int, wifi_radio_stat*))>
+        on_link_layer_stats_result_internal_callback;
+void onSyncLinkLayerStatsResult(wifi_request_id id, wifi_iface_stat* iface_stat, int num_radios,
+                                wifi_radio_stat* radio_stat) {
+    if (on_link_layer_stats_result_internal_callback) {
+        on_link_layer_stats_result_internal_callback(id, iface_stat, num_radios, radio_stat);
+    }
+}
+
+// Callback to be invoked for rssi threshold breach.
+std::function<void((wifi_request_id, uint8_t*, int8_t))>
+        on_rssi_threshold_breached_internal_callback;
+void onAsyncRssiThresholdBreached(wifi_request_id id, uint8_t* bssid, int8_t rssi) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_rssi_threshold_breached_internal_callback) {
+        on_rssi_threshold_breached_internal_callback(id, bssid, rssi);
+    }
+}
+
+// Callback to be invoked for ring buffer data indication.
+std::function<void(char*, char*, int, wifi_ring_buffer_status*)>
+        on_ring_buffer_data_internal_callback;
+void onAsyncRingBufferData(char* ring_name, char* buffer, int buffer_size,
+                           wifi_ring_buffer_status* status) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_ring_buffer_data_internal_callback) {
+        on_ring_buffer_data_internal_callback(ring_name, buffer, buffer_size, status);
+    }
+}
+
+// Callback to be invoked for error alert indication.
+std::function<void(wifi_request_id, char*, int, int)> on_error_alert_internal_callback;
+void onAsyncErrorAlert(wifi_request_id id, char* buffer, int buffer_size, int err_code) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_error_alert_internal_callback) {
+        on_error_alert_internal_callback(id, buffer, buffer_size, err_code);
+    }
+}
+
+// Callback to be invoked for radio mode change indication.
+std::function<void(wifi_request_id, uint32_t, wifi_mac_info*)>
+        on_radio_mode_change_internal_callback;
+void onAsyncRadioModeChange(wifi_request_id id, uint32_t num_macs, wifi_mac_info* mac_infos) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_radio_mode_change_internal_callback) {
+        on_radio_mode_change_internal_callback(id, num_macs, mac_infos);
+    }
+}
+
+// Callback to be invoked to report subsystem restart
+std::function<void(const char*)> on_subsystem_restart_internal_callback;
+void onAsyncSubsystemRestart(const char* error) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_subsystem_restart_internal_callback) {
+        on_subsystem_restart_internal_callback(error);
+    }
+}
+
+// Callback to be invoked for rtt results results.
+std::function<void(wifi_request_id, unsigned num_results, wifi_rtt_result* rtt_results[])>
+        on_rtt_results_internal_callback;
+void onAsyncRttResults(wifi_request_id id, unsigned num_results, wifi_rtt_result* rtt_results[]) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_rtt_results_internal_callback) {
+        on_rtt_results_internal_callback(id, num_results, rtt_results);
+        on_rtt_results_internal_callback = nullptr;
+    }
+}
+
+// Callbacks for the various NAN operations.
+// NOTE: These have very little conversions to perform before invoking the user
+// callbacks.
+// So, handle all of them here directly to avoid adding an unnecessary layer.
+std::function<void(transaction_id, const NanResponseMsg&)> on_nan_notify_response_user_callback;
+void onAysncNanNotifyResponse(transaction_id id, NanResponseMsg* msg) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_nan_notify_response_user_callback && msg) {
+        on_nan_notify_response_user_callback(id, *msg);
+    }
+}
+
+std::function<void(const NanPublishRepliedInd&)> on_nan_event_publish_replied_user_callback;
+void onAysncNanEventPublishReplied(NanPublishRepliedInd* /* event */) {
+    LOG(ERROR) << "onAysncNanEventPublishReplied triggered";
+}
+
+std::function<void(const NanPublishTerminatedInd&)> on_nan_event_publish_terminated_user_callback;
+void onAysncNanEventPublishTerminated(NanPublishTerminatedInd* event) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_publish_terminated_user_callback && event) {
+        on_nan_event_publish_terminated_user_callback(*event);
+    }
+}
+
+std::function<void(const NanMatchInd&)> on_nan_event_match_user_callback;
+void onAysncNanEventMatch(NanMatchInd* event) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_match_user_callback && event) {
+        on_nan_event_match_user_callback(*event);
+    }
+}
+
+std::function<void(const NanMatchExpiredInd&)> on_nan_event_match_expired_user_callback;
+void onAysncNanEventMatchExpired(NanMatchExpiredInd* event) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_match_expired_user_callback && event) {
+        on_nan_event_match_expired_user_callback(*event);
+    }
+}
+
+std::function<void(const NanSubscribeTerminatedInd&)>
+        on_nan_event_subscribe_terminated_user_callback;
+void onAysncNanEventSubscribeTerminated(NanSubscribeTerminatedInd* event) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_subscribe_terminated_user_callback && event) {
+        on_nan_event_subscribe_terminated_user_callback(*event);
+    }
+}
+
+std::function<void(const NanFollowupInd&)> on_nan_event_followup_user_callback;
+void onAysncNanEventFollowup(NanFollowupInd* event) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_followup_user_callback && event) {
+        on_nan_event_followup_user_callback(*event);
+    }
+}
+
+std::function<void(const NanDiscEngEventInd&)> on_nan_event_disc_eng_event_user_callback;
+void onAysncNanEventDiscEngEvent(NanDiscEngEventInd* event) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_disc_eng_event_user_callback && event) {
+        on_nan_event_disc_eng_event_user_callback(*event);
+    }
+}
+
+std::function<void(const NanDisabledInd&)> on_nan_event_disabled_user_callback;
+void onAysncNanEventDisabled(NanDisabledInd* event) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_disabled_user_callback && event) {
+        on_nan_event_disabled_user_callback(*event);
+    }
+}
+
+std::function<void(const NanTCAInd&)> on_nan_event_tca_user_callback;
+void onAysncNanEventTca(NanTCAInd* event) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_tca_user_callback && event) {
+        on_nan_event_tca_user_callback(*event);
+    }
+}
+
+std::function<void(const NanBeaconSdfPayloadInd&)> on_nan_event_beacon_sdf_payload_user_callback;
+void onAysncNanEventBeaconSdfPayload(NanBeaconSdfPayloadInd* event) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_beacon_sdf_payload_user_callback && event) {
+        on_nan_event_beacon_sdf_payload_user_callback(*event);
+    }
+}
+
+std::function<void(const NanDataPathRequestInd&)> on_nan_event_data_path_request_user_callback;
+void onAysncNanEventDataPathRequest(NanDataPathRequestInd* event) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_data_path_request_user_callback && event) {
+        on_nan_event_data_path_request_user_callback(*event);
+    }
+}
+std::function<void(const NanDataPathConfirmInd&)> on_nan_event_data_path_confirm_user_callback;
+void onAysncNanEventDataPathConfirm(NanDataPathConfirmInd* event) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_data_path_confirm_user_callback && event) {
+        on_nan_event_data_path_confirm_user_callback(*event);
+    }
+}
+
+std::function<void(const NanDataPathEndInd&)> on_nan_event_data_path_end_user_callback;
+void onAysncNanEventDataPathEnd(NanDataPathEndInd* event) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_data_path_end_user_callback && event) {
+        on_nan_event_data_path_end_user_callback(*event);
+    }
+}
+
+std::function<void(const NanTransmitFollowupInd&)> on_nan_event_transmit_follow_up_user_callback;
+void onAysncNanEventTransmitFollowUp(NanTransmitFollowupInd* event) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_transmit_follow_up_user_callback && event) {
+        on_nan_event_transmit_follow_up_user_callback(*event);
+    }
+}
+
+std::function<void(const NanRangeRequestInd&)> on_nan_event_range_request_user_callback;
+void onAysncNanEventRangeRequest(NanRangeRequestInd* event) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_range_request_user_callback && event) {
+        on_nan_event_range_request_user_callback(*event);
+    }
+}
+
+std::function<void(const NanRangeReportInd&)> on_nan_event_range_report_user_callback;
+void onAysncNanEventRangeReport(NanRangeReportInd* event) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_range_report_user_callback && event) {
+        on_nan_event_range_report_user_callback(*event);
+    }
+}
+
+std::function<void(const NanDataPathScheduleUpdateInd&)> on_nan_event_schedule_update_user_callback;
+void onAsyncNanEventScheduleUpdate(NanDataPathScheduleUpdateInd* event) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_schedule_update_user_callback && event) {
+        on_nan_event_schedule_update_user_callback(*event);
+    }
+}
+
+// Callbacks for the various TWT operations.
+std::function<void(const TwtSetupResponse&)> on_twt_event_setup_response_callback;
+void onAsyncTwtEventSetupResponse(TwtSetupResponse* event) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_twt_event_setup_response_callback && event) {
+        on_twt_event_setup_response_callback(*event);
+    }
+}
+
+std::function<void(const TwtTeardownCompletion&)> on_twt_event_teardown_completion_callback;
+void onAsyncTwtEventTeardownCompletion(TwtTeardownCompletion* event) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_twt_event_teardown_completion_callback && event) {
+        on_twt_event_teardown_completion_callback(*event);
+    }
+}
+
+std::function<void(const TwtInfoFrameReceived&)> on_twt_event_info_frame_received_callback;
+void onAsyncTwtEventInfoFrameReceived(TwtInfoFrameReceived* event) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_twt_event_info_frame_received_callback && event) {
+        on_twt_event_info_frame_received_callback(*event);
+    }
+}
+
+std::function<void(const TwtDeviceNotify&)> on_twt_event_device_notify_callback;
+void onAsyncTwtEventDeviceNotify(TwtDeviceNotify* event) {
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (on_twt_event_device_notify_callback && event) {
+        on_twt_event_device_notify_callback(*event);
+    }
+}
+
+// End of the free-standing "C" style callbacks.
+
+WifiLegacyHal::WifiLegacyHal(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
+                             const wifi_hal_fn& fn, bool is_primary)
+    : global_func_table_(fn),
+      global_handle_(nullptr),
+      awaiting_event_loop_termination_(false),
+      is_started_(false),
+      iface_tool_(iface_tool),
+      is_primary_(is_primary) {}
+
+wifi_error WifiLegacyHal::initialize() {
+    LOG(DEBUG) << "Initialize legacy HAL";
+    // this now does nothing, since HAL function table is provided
+    // to the constructor
+    return WIFI_SUCCESS;
+}
+
+wifi_error WifiLegacyHal::start() {
+    // Ensure that we're starting in a good state.
+    CHECK(global_func_table_.wifi_initialize && !global_handle_ && iface_name_to_handle_.empty() &&
+          !awaiting_event_loop_termination_);
+    if (is_started_) {
+        LOG(DEBUG) << "Legacy HAL already started";
+        return WIFI_SUCCESS;
+    }
+    LOG(DEBUG) << "Waiting for the driver ready";
+    wifi_error status = global_func_table_.wifi_wait_for_driver_ready();
+    if (status == WIFI_ERROR_TIMED_OUT || status == WIFI_ERROR_UNKNOWN) {
+        LOG(ERROR) << "Failed or timed out awaiting driver ready";
+        return status;
+    }
+
+    if (is_primary_) {
+        property_set(kDriverPropName, "ok");
+
+        if (!iface_tool_.lock()->SetWifiUpState(true)) {
+            LOG(ERROR) << "Failed to set WiFi interface up";
+            return WIFI_ERROR_UNKNOWN;
+        }
+    }
+
+    LOG(DEBUG) << "Starting legacy HAL";
+    status = global_func_table_.wifi_initialize(&global_handle_);
+    if (status != WIFI_SUCCESS || !global_handle_) {
+        LOG(ERROR) << "Failed to retrieve global handle";
+        return status;
+    }
+    std::thread(&WifiLegacyHal::runEventLoop, this).detach();
+    status = retrieveIfaceHandles();
+    if (status != WIFI_SUCCESS || iface_name_to_handle_.empty()) {
+        LOG(ERROR) << "Failed to retrieve wlan interface handle";
+        return status;
+    }
+    LOG(DEBUG) << "Legacy HAL start complete";
+    is_started_ = true;
+    return WIFI_SUCCESS;
+}
+
+wifi_error WifiLegacyHal::stop(
+        /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
+        const std::function<void()>& on_stop_complete_user_callback) {
+    if (!is_started_) {
+        LOG(DEBUG) << "Legacy HAL already stopped";
+        on_stop_complete_user_callback();
+        return WIFI_SUCCESS;
+    }
+    LOG(DEBUG) << "Stopping legacy HAL";
+    on_stop_complete_internal_callback = [on_stop_complete_user_callback,
+                                          this](wifi_handle handle) {
+        CHECK_EQ(global_handle_, handle) << "Handle mismatch";
+        LOG(INFO) << "Legacy HAL stop complete callback received";
+        // Invalidate all the internal pointers now that the HAL is
+        // stopped.
+        invalidate();
+        if (is_primary_) iface_tool_.lock()->SetWifiUpState(false);
+        on_stop_complete_user_callback();
+        is_started_ = false;
+    };
+    awaiting_event_loop_termination_ = true;
+    global_func_table_.wifi_cleanup(global_handle_, onAsyncStopComplete);
+    const auto status =
+            stop_wait_cv_.wait_for(*lock, std::chrono::milliseconds(kMaxStopCompleteWaitMs),
+                                   [this] { return !awaiting_event_loop_termination_; });
+    if (!status) {
+        LOG(ERROR) << "Legacy HAL stop failed or timed out";
+        return WIFI_ERROR_UNKNOWN;
+    }
+    LOG(DEBUG) << "Legacy HAL stop complete";
+    return WIFI_SUCCESS;
+}
+
+bool WifiLegacyHal::isStarted() {
+    return is_started_;
+}
+
+wifi_error WifiLegacyHal::waitForDriverReady() {
+    return global_func_table_.wifi_wait_for_driver_ready();
+}
+
+std::pair<wifi_error, std::string> WifiLegacyHal::getDriverVersion(const std::string& iface_name) {
+    std::array<char, kMaxVersionStringLength> buffer;
+    buffer.fill(0);
+    wifi_error status = global_func_table_.wifi_get_driver_version(getIfaceHandle(iface_name),
+                                                                   buffer.data(), buffer.size());
+    return {status, buffer.data()};
+}
+
+std::pair<wifi_error, std::string> WifiLegacyHal::getFirmwareVersion(
+        const std::string& iface_name) {
+    std::array<char, kMaxVersionStringLength> buffer;
+    buffer.fill(0);
+    wifi_error status = global_func_table_.wifi_get_firmware_version(getIfaceHandle(iface_name),
+                                                                     buffer.data(), buffer.size());
+    return {status, buffer.data()};
+}
+
+std::pair<wifi_error, std::vector<uint8_t>> WifiLegacyHal::requestDriverMemoryDump(
+        const std::string& iface_name) {
+    std::vector<uint8_t> driver_dump;
+    on_driver_memory_dump_internal_callback = [&driver_dump](char* buffer, int buffer_size) {
+        driver_dump.insert(driver_dump.end(), reinterpret_cast<uint8_t*>(buffer),
+                           reinterpret_cast<uint8_t*>(buffer) + buffer_size);
+    };
+    wifi_error status = global_func_table_.wifi_get_driver_memory_dump(getIfaceHandle(iface_name),
+                                                                       {onSyncDriverMemoryDump});
+    on_driver_memory_dump_internal_callback = nullptr;
+    return {status, std::move(driver_dump)};
+}
+
+std::pair<wifi_error, std::vector<uint8_t>> WifiLegacyHal::requestFirmwareMemoryDump(
+        const std::string& iface_name) {
+    std::vector<uint8_t> firmware_dump;
+    on_firmware_memory_dump_internal_callback = [&firmware_dump](char* buffer, int buffer_size) {
+        firmware_dump.insert(firmware_dump.end(), reinterpret_cast<uint8_t*>(buffer),
+                             reinterpret_cast<uint8_t*>(buffer) + buffer_size);
+    };
+    wifi_error status = global_func_table_.wifi_get_firmware_memory_dump(
+            getIfaceHandle(iface_name), {onSyncFirmwareMemoryDump});
+    on_firmware_memory_dump_internal_callback = nullptr;
+    return {status, std::move(firmware_dump)};
+}
+
+std::pair<wifi_error, uint64_t> WifiLegacyHal::getSupportedFeatureSet(
+        const std::string& iface_name) {
+    feature_set set = 0, chip_set = 0;
+    wifi_error status = WIFI_SUCCESS;
+
+    static_assert(sizeof(set) == sizeof(uint64_t),
+                  "Some feature_flags can not be represented in output");
+    wifi_interface_handle iface_handle = getIfaceHandle(iface_name);
+
+    global_func_table_.wifi_get_chip_feature_set(
+            global_handle_, &chip_set); /* ignore error, chip_set will stay 0 */
+
+    if (iface_handle) {
+        status = global_func_table_.wifi_get_supported_feature_set(iface_handle, &set);
+    }
+    return {status, static_cast<uint64_t>(set | chip_set)};
+}
+
+std::pair<wifi_error, PacketFilterCapabilities> WifiLegacyHal::getPacketFilterCapabilities(
+        const std::string& iface_name) {
+    PacketFilterCapabilities caps;
+    wifi_error status = global_func_table_.wifi_get_packet_filter_capabilities(
+            getIfaceHandle(iface_name), &caps.version, &caps.max_len);
+    return {status, caps};
+}
+
+wifi_error WifiLegacyHal::setPacketFilter(const std::string& iface_name,
+                                          const std::vector<uint8_t>& program) {
+    return global_func_table_.wifi_set_packet_filter(getIfaceHandle(iface_name), program.data(),
+                                                     program.size());
+}
+
+std::pair<wifi_error, std::vector<uint8_t>> WifiLegacyHal::readApfPacketFilterData(
+        const std::string& iface_name) {
+    PacketFilterCapabilities caps;
+    wifi_error status = global_func_table_.wifi_get_packet_filter_capabilities(
+            getIfaceHandle(iface_name), &caps.version, &caps.max_len);
+    if (status != WIFI_SUCCESS) {
+        return {status, {}};
+    }
+
+    // Size the buffer to read the entire program & work memory.
+    std::vector<uint8_t> buffer(caps.max_len);
+
+    status = global_func_table_.wifi_read_packet_filter(
+            getIfaceHandle(iface_name), /*src_offset=*/0, buffer.data(), buffer.size());
+    return {status, move(buffer)};
+}
+
+std::pair<wifi_error, wifi_gscan_capabilities> WifiLegacyHal::getGscanCapabilities(
+        const std::string& iface_name) {
+    wifi_gscan_capabilities caps;
+    wifi_error status =
+            global_func_table_.wifi_get_gscan_capabilities(getIfaceHandle(iface_name), &caps);
+    return {status, caps};
+}
+
+wifi_error WifiLegacyHal::startGscan(
+        const std::string& iface_name, wifi_request_id id, const wifi_scan_cmd_params& params,
+        const std::function<void(wifi_request_id)>& on_failure_user_callback,
+        const on_gscan_results_callback& on_results_user_callback,
+        const on_gscan_full_result_callback& on_full_result_user_callback) {
+    // If there is already an ongoing background scan, reject new scan requests.
+    if (on_gscan_event_internal_callback || on_gscan_full_result_internal_callback) {
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+
+    // This callback will be used to either trigger |on_results_user_callback|
+    // or |on_failure_user_callback|.
+    on_gscan_event_internal_callback = [iface_name, on_failure_user_callback,
+                                        on_results_user_callback,
+                                        this](wifi_request_id id, wifi_scan_event event) {
+        switch (event) {
+            case WIFI_SCAN_RESULTS_AVAILABLE:
+            case WIFI_SCAN_THRESHOLD_NUM_SCANS:
+            case WIFI_SCAN_THRESHOLD_PERCENT: {
+                wifi_error status;
+                std::vector<wifi_cached_scan_results> cached_scan_results;
+                std::tie(status, cached_scan_results) = getGscanCachedResults(iface_name);
+                if (status == WIFI_SUCCESS) {
+                    on_results_user_callback(id, cached_scan_results);
+                    return;
+                }
+                FALLTHROUGH_INTENDED;
+            }
+            // Fall through if failed. Failure to retrieve cached scan
+            // results should trigger a background scan failure.
+            case WIFI_SCAN_FAILED:
+                on_failure_user_callback(id);
+                on_gscan_event_internal_callback = nullptr;
+                on_gscan_full_result_internal_callback = nullptr;
+                return;
+        }
+        LOG(FATAL) << "Unexpected gscan event received: " << event;
+    };
+
+    on_gscan_full_result_internal_callback = [on_full_result_user_callback](
+                                                     wifi_request_id id, wifi_scan_result* result,
+                                                     uint32_t buckets_scanned) {
+        if (result) {
+            on_full_result_user_callback(id, result, buckets_scanned);
+        }
+    };
+
+    wifi_scan_result_handler handler = {onAsyncGscanFullResult, onAsyncGscanEvent};
+    wifi_error status =
+            global_func_table_.wifi_start_gscan(id, getIfaceHandle(iface_name), params, handler);
+    if (status != WIFI_SUCCESS) {
+        on_gscan_event_internal_callback = nullptr;
+        on_gscan_full_result_internal_callback = nullptr;
+    }
+    return status;
+}
+
+wifi_error WifiLegacyHal::stopGscan(const std::string& iface_name, wifi_request_id id) {
+    // If there is no an ongoing background scan, reject stop requests.
+    // TODO(b/32337212): This needs to be handled by the HIDL object because we
+    // need to return the NOT_STARTED error code.
+    if (!on_gscan_event_internal_callback && !on_gscan_full_result_internal_callback) {
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+    wifi_error status = global_func_table_.wifi_stop_gscan(id, getIfaceHandle(iface_name));
+    // If the request Id is wrong, don't stop the ongoing background scan. Any
+    // other error should be treated as the end of background scan.
+    if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
+        on_gscan_event_internal_callback = nullptr;
+        on_gscan_full_result_internal_callback = nullptr;
+    }
+    return status;
+}
+
+std::pair<wifi_error, std::vector<uint32_t>> WifiLegacyHal::getValidFrequenciesForBand(
+        const std::string& iface_name, wifi_band band) {
+    static_assert(sizeof(uint32_t) >= sizeof(wifi_channel),
+                  "Wifi Channel cannot be represented in output");
+    std::vector<uint32_t> freqs;
+    freqs.resize(kMaxGscanFrequenciesForBand);
+    int32_t num_freqs = 0;
+    wifi_error status = global_func_table_.wifi_get_valid_channels(
+            getIfaceHandle(iface_name), band, freqs.size(),
+            reinterpret_cast<wifi_channel*>(freqs.data()), &num_freqs);
+    CHECK(num_freqs >= 0 && static_cast<uint32_t>(num_freqs) <= kMaxGscanFrequenciesForBand);
+    freqs.resize(num_freqs);
+    return {status, std::move(freqs)};
+}
+
+wifi_error WifiLegacyHal::setDfsFlag(const std::string& iface_name, bool dfs_on) {
+    return global_func_table_.wifi_set_nodfs_flag(getIfaceHandle(iface_name), dfs_on ? 0 : 1);
+}
+
+wifi_error WifiLegacyHal::enableLinkLayerStats(const std::string& iface_name, bool debug) {
+    wifi_link_layer_params params;
+    params.mpdu_size_threshold = kLinkLayerStatsDataMpduSizeThreshold;
+    params.aggressive_statistics_gathering = debug;
+    return global_func_table_.wifi_set_link_stats(getIfaceHandle(iface_name), params);
+}
+
+wifi_error WifiLegacyHal::disableLinkLayerStats(const std::string& iface_name) {
+    // TODO: Do we care about these responses?
+    uint32_t clear_mask_rsp;
+    uint8_t stop_rsp;
+    return global_func_table_.wifi_clear_link_stats(getIfaceHandle(iface_name), 0xFFFFFFFF,
+                                                    &clear_mask_rsp, 1, &stop_rsp);
+}
+
+std::pair<wifi_error, LinkLayerStats> WifiLegacyHal::getLinkLayerStats(
+        const std::string& iface_name) {
+    LinkLayerStats link_stats{};
+    LinkLayerStats* link_stats_ptr = &link_stats;
+
+    on_link_layer_stats_result_internal_callback = [&link_stats_ptr](
+                                                           wifi_request_id /* id */,
+                                                           wifi_iface_stat* iface_stats_ptr,
+                                                           int num_radios,
+                                                           wifi_radio_stat* radio_stats_ptr) {
+        wifi_radio_stat* l_radio_stats_ptr;
+        wifi_peer_info* l_peer_info_stats_ptr;
+
+        if (iface_stats_ptr != nullptr) {
+            link_stats_ptr->iface = *iface_stats_ptr;
+            l_peer_info_stats_ptr = iface_stats_ptr->peer_info;
+            for (uint32_t i = 0; i < iface_stats_ptr->num_peers; i++) {
+                WifiPeerInfo peer;
+                peer.peer_info = *l_peer_info_stats_ptr;
+                if (l_peer_info_stats_ptr->num_rate > 0) {
+                    /* Copy the rate stats */
+                    peer.rate_stats.assign(
+                            l_peer_info_stats_ptr->rate_stats,
+                            l_peer_info_stats_ptr->rate_stats + l_peer_info_stats_ptr->num_rate);
+                }
+                peer.peer_info.num_rate = 0;
+                link_stats_ptr->peers.push_back(peer);
+                l_peer_info_stats_ptr =
+                        (wifi_peer_info*)((u8*)l_peer_info_stats_ptr + sizeof(wifi_peer_info) +
+                                          (sizeof(wifi_rate_stat) *
+                                           l_peer_info_stats_ptr->num_rate));
+            }
+            link_stats_ptr->iface.num_peers = 0;
+        } else {
+            LOG(ERROR) << "Invalid iface stats in link layer stats";
+        }
+        if (num_radios <= 0 || radio_stats_ptr == nullptr) {
+            LOG(ERROR) << "Invalid radio stats in link layer stats";
+            return;
+        }
+        l_radio_stats_ptr = radio_stats_ptr;
+        for (int i = 0; i < num_radios; i++) {
+            LinkLayerRadioStats radio;
+
+            radio.stats = *l_radio_stats_ptr;
+            // Copy over the tx level array to the separate vector.
+            if (l_radio_stats_ptr->num_tx_levels > 0 &&
+                l_radio_stats_ptr->tx_time_per_levels != nullptr) {
+                radio.tx_time_per_levels.assign(
+                        l_radio_stats_ptr->tx_time_per_levels,
+                        l_radio_stats_ptr->tx_time_per_levels + l_radio_stats_ptr->num_tx_levels);
+            }
+            radio.stats.num_tx_levels = 0;
+            radio.stats.tx_time_per_levels = nullptr;
+            /* Copy over the channel stat to separate vector */
+            if (l_radio_stats_ptr->num_channels > 0) {
+                /* Copy the channel stats */
+                radio.channel_stats.assign(
+                        l_radio_stats_ptr->channels,
+                        l_radio_stats_ptr->channels + l_radio_stats_ptr->num_channels);
+            }
+            link_stats_ptr->radios.push_back(radio);
+            l_radio_stats_ptr =
+                    (wifi_radio_stat*)((u8*)l_radio_stats_ptr + sizeof(wifi_radio_stat) +
+                                       (sizeof(wifi_channel_stat) *
+                                        l_radio_stats_ptr->num_channels));
+        }
+    };
+
+    wifi_error status = global_func_table_.wifi_get_link_stats(0, getIfaceHandle(iface_name),
+                                                               {onSyncLinkLayerStatsResult});
+    on_link_layer_stats_result_internal_callback = nullptr;
+    return {status, link_stats};
+}
+
+wifi_error WifiLegacyHal::startRssiMonitoring(
+        const std::string& iface_name, wifi_request_id id, int8_t max_rssi, int8_t min_rssi,
+        const on_rssi_threshold_breached_callback& on_threshold_breached_user_callback) {
+    if (on_rssi_threshold_breached_internal_callback) {
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+    on_rssi_threshold_breached_internal_callback = [on_threshold_breached_user_callback](
+                                                           wifi_request_id id, uint8_t* bssid_ptr,
+                                                           int8_t rssi) {
+        if (!bssid_ptr) {
+            return;
+        }
+        std::array<uint8_t, 6> bssid_arr;
+        // |bssid_ptr| pointer is assumed to have 6 bytes for the mac
+        // address.
+        std::copy(bssid_ptr, bssid_ptr + 6, std::begin(bssid_arr));
+        on_threshold_breached_user_callback(id, bssid_arr, rssi);
+    };
+    wifi_error status = global_func_table_.wifi_start_rssi_monitoring(
+            id, getIfaceHandle(iface_name), max_rssi, min_rssi, {onAsyncRssiThresholdBreached});
+    if (status != WIFI_SUCCESS) {
+        on_rssi_threshold_breached_internal_callback = nullptr;
+    }
+    return status;
+}
+
+wifi_error WifiLegacyHal::stopRssiMonitoring(const std::string& iface_name, wifi_request_id id) {
+    if (!on_rssi_threshold_breached_internal_callback) {
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+    wifi_error status =
+            global_func_table_.wifi_stop_rssi_monitoring(id, getIfaceHandle(iface_name));
+    // If the request Id is wrong, don't stop the ongoing rssi monitoring. Any
+    // other error should be treated as the end of background scan.
+    if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
+        on_rssi_threshold_breached_internal_callback = nullptr;
+    }
+    return status;
+}
+
+std::pair<wifi_error, wifi_roaming_capabilities> WifiLegacyHal::getRoamingCapabilities(
+        const std::string& iface_name) {
+    wifi_roaming_capabilities caps;
+    wifi_error status =
+            global_func_table_.wifi_get_roaming_capabilities(getIfaceHandle(iface_name), &caps);
+    return {status, caps};
+}
+
+wifi_error WifiLegacyHal::configureRoaming(const std::string& iface_name,
+                                           const wifi_roaming_config& config) {
+    wifi_roaming_config config_internal = config;
+    return global_func_table_.wifi_configure_roaming(getIfaceHandle(iface_name), &config_internal);
+}
+
+wifi_error WifiLegacyHal::enableFirmwareRoaming(const std::string& iface_name,
+                                                fw_roaming_state_t state) {
+    return global_func_table_.wifi_enable_firmware_roaming(getIfaceHandle(iface_name), state);
+}
+
+wifi_error WifiLegacyHal::configureNdOffload(const std::string& iface_name, bool enable) {
+    return global_func_table_.wifi_configure_nd_offload(getIfaceHandle(iface_name), enable);
+}
+
+wifi_error WifiLegacyHal::startSendingOffloadedPacket(const std::string& iface_name,
+                                                      uint32_t cmd_id, uint16_t ether_type,
+                                                      const std::vector<uint8_t>& ip_packet_data,
+                                                      const std::array<uint8_t, 6>& src_address,
+                                                      const std::array<uint8_t, 6>& dst_address,
+                                                      uint32_t period_in_ms) {
+    std::vector<uint8_t> ip_packet_data_internal(ip_packet_data);
+    std::vector<uint8_t> src_address_internal(src_address.data(),
+                                              src_address.data() + src_address.size());
+    std::vector<uint8_t> dst_address_internal(dst_address.data(),
+                                              dst_address.data() + dst_address.size());
+    return global_func_table_.wifi_start_sending_offloaded_packet(
+            cmd_id, getIfaceHandle(iface_name), ether_type, ip_packet_data_internal.data(),
+            ip_packet_data_internal.size(), src_address_internal.data(),
+            dst_address_internal.data(), period_in_ms);
+}
+
+wifi_error WifiLegacyHal::stopSendingOffloadedPacket(const std::string& iface_name,
+                                                     uint32_t cmd_id) {
+    return global_func_table_.wifi_stop_sending_offloaded_packet(cmd_id,
+                                                                 getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::selectTxPowerScenario(const std::string& iface_name,
+                                                wifi_power_scenario scenario) {
+    return global_func_table_.wifi_select_tx_power_scenario(getIfaceHandle(iface_name), scenario);
+}
+
+wifi_error WifiLegacyHal::resetTxPowerScenario(const std::string& iface_name) {
+    return global_func_table_.wifi_reset_tx_power_scenario(getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::setLatencyMode(const std::string& iface_name, wifi_latency_mode mode) {
+    return global_func_table_.wifi_set_latency_mode(getIfaceHandle(iface_name), mode);
+}
+
+wifi_error WifiLegacyHal::setThermalMitigationMode(wifi_thermal_mode mode,
+                                                   uint32_t completion_window) {
+    return global_func_table_.wifi_set_thermal_mitigation_mode(global_handle_, mode,
+                                                               completion_window);
+}
+
+wifi_error WifiLegacyHal::setDscpToAccessCategoryMapping(uint32_t start, uint32_t end,
+                                                         uint32_t access_category) {
+    return global_func_table_.wifi_map_dscp_access_category(global_handle_, start, end,
+                                                            access_category);
+}
+
+wifi_error WifiLegacyHal::resetDscpToAccessCategoryMapping() {
+    return global_func_table_.wifi_reset_dscp_mapping(global_handle_);
+}
+
+std::pair<wifi_error, uint32_t> WifiLegacyHal::getLoggerSupportedFeatureSet(
+        const std::string& iface_name) {
+    uint32_t supported_feature_flags = 0;
+    wifi_error status = WIFI_SUCCESS;
+
+    wifi_interface_handle iface_handle = getIfaceHandle(iface_name);
+
+    if (iface_handle) {
+        status = global_func_table_.wifi_get_logger_supported_feature_set(iface_handle,
+                                                                          &supported_feature_flags);
+    }
+    return {status, supported_feature_flags};
+}
+
+wifi_error WifiLegacyHal::startPktFateMonitoring(const std::string& iface_name) {
+    return global_func_table_.wifi_start_pkt_fate_monitoring(getIfaceHandle(iface_name));
+}
+
+std::pair<wifi_error, std::vector<wifi_tx_report>> WifiLegacyHal::getTxPktFates(
+        const std::string& iface_name) {
+    std::vector<wifi_tx_report> tx_pkt_fates;
+    tx_pkt_fates.resize(MAX_FATE_LOG_LEN);
+    size_t num_fates = 0;
+    wifi_error status = global_func_table_.wifi_get_tx_pkt_fates(
+            getIfaceHandle(iface_name), tx_pkt_fates.data(), tx_pkt_fates.size(), &num_fates);
+    CHECK(num_fates <= MAX_FATE_LOG_LEN);
+    tx_pkt_fates.resize(num_fates);
+    return {status, std::move(tx_pkt_fates)};
+}
+
+std::pair<wifi_error, std::vector<wifi_rx_report>> WifiLegacyHal::getRxPktFates(
+        const std::string& iface_name) {
+    std::vector<wifi_rx_report> rx_pkt_fates;
+    rx_pkt_fates.resize(MAX_FATE_LOG_LEN);
+    size_t num_fates = 0;
+    wifi_error status = global_func_table_.wifi_get_rx_pkt_fates(
+            getIfaceHandle(iface_name), rx_pkt_fates.data(), rx_pkt_fates.size(), &num_fates);
+    CHECK(num_fates <= MAX_FATE_LOG_LEN);
+    rx_pkt_fates.resize(num_fates);
+    return {status, std::move(rx_pkt_fates)};
+}
+
+std::pair<wifi_error, WakeReasonStats> WifiLegacyHal::getWakeReasonStats(
+        const std::string& iface_name) {
+    WakeReasonStats stats;
+    stats.cmd_event_wake_cnt.resize(kMaxWakeReasonStatsArraySize);
+    stats.driver_fw_local_wake_cnt.resize(kMaxWakeReasonStatsArraySize);
+
+    // This legacy struct needs separate memory to store the variable sized wake
+    // reason types.
+    stats.wake_reason_cnt.cmd_event_wake_cnt =
+            reinterpret_cast<int32_t*>(stats.cmd_event_wake_cnt.data());
+    stats.wake_reason_cnt.cmd_event_wake_cnt_sz = stats.cmd_event_wake_cnt.size();
+    stats.wake_reason_cnt.cmd_event_wake_cnt_used = 0;
+    stats.wake_reason_cnt.driver_fw_local_wake_cnt =
+            reinterpret_cast<int32_t*>(stats.driver_fw_local_wake_cnt.data());
+    stats.wake_reason_cnt.driver_fw_local_wake_cnt_sz = stats.driver_fw_local_wake_cnt.size();
+    stats.wake_reason_cnt.driver_fw_local_wake_cnt_used = 0;
+
+    wifi_error status = global_func_table_.wifi_get_wake_reason_stats(getIfaceHandle(iface_name),
+                                                                      &stats.wake_reason_cnt);
+
+    CHECK(stats.wake_reason_cnt.cmd_event_wake_cnt_used >= 0 &&
+          static_cast<uint32_t>(stats.wake_reason_cnt.cmd_event_wake_cnt_used) <=
+                  kMaxWakeReasonStatsArraySize);
+    stats.cmd_event_wake_cnt.resize(stats.wake_reason_cnt.cmd_event_wake_cnt_used);
+    stats.wake_reason_cnt.cmd_event_wake_cnt = nullptr;
+
+    CHECK(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used >= 0 &&
+          static_cast<uint32_t>(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used) <=
+                  kMaxWakeReasonStatsArraySize);
+    stats.driver_fw_local_wake_cnt.resize(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used);
+    stats.wake_reason_cnt.driver_fw_local_wake_cnt = nullptr;
+
+    return {status, stats};
+}
+
+wifi_error WifiLegacyHal::registerRingBufferCallbackHandler(
+        const std::string& iface_name, const on_ring_buffer_data_callback& on_user_data_callback) {
+    if (on_ring_buffer_data_internal_callback) {
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+    on_ring_buffer_data_internal_callback = [on_user_data_callback](
+                                                    char* ring_name, char* buffer, int buffer_size,
+                                                    wifi_ring_buffer_status* status) {
+        if (status && buffer) {
+            std::vector<uint8_t> buffer_vector(reinterpret_cast<uint8_t*>(buffer),
+                                               reinterpret_cast<uint8_t*>(buffer) + buffer_size);
+            on_user_data_callback(ring_name, buffer_vector, *status);
+        }
+    };
+    wifi_error status = global_func_table_.wifi_set_log_handler(0, getIfaceHandle(iface_name),
+                                                                {onAsyncRingBufferData});
+    if (status != WIFI_SUCCESS) {
+        on_ring_buffer_data_internal_callback = nullptr;
+    }
+    return status;
+}
+
+wifi_error WifiLegacyHal::deregisterRingBufferCallbackHandler(const std::string& iface_name) {
+    if (!on_ring_buffer_data_internal_callback) {
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+    on_ring_buffer_data_internal_callback = nullptr;
+    return global_func_table_.wifi_reset_log_handler(0, getIfaceHandle(iface_name));
+}
+
+std::pair<wifi_error, std::vector<wifi_ring_buffer_status>> WifiLegacyHal::getRingBuffersStatus(
+        const std::string& iface_name) {
+    std::vector<wifi_ring_buffer_status> ring_buffers_status;
+    ring_buffers_status.resize(kMaxRingBuffers);
+    uint32_t num_rings = kMaxRingBuffers;
+    wifi_error status = global_func_table_.wifi_get_ring_buffers_status(
+            getIfaceHandle(iface_name), &num_rings, ring_buffers_status.data());
+    CHECK(num_rings <= kMaxRingBuffers);
+    ring_buffers_status.resize(num_rings);
+    return {status, std::move(ring_buffers_status)};
+}
+
+wifi_error WifiLegacyHal::startRingBufferLogging(const std::string& iface_name,
+                                                 const std::string& ring_name,
+                                                 uint32_t verbose_level, uint32_t max_interval_sec,
+                                                 uint32_t min_data_size) {
+    return global_func_table_.wifi_start_logging(getIfaceHandle(iface_name), verbose_level, 0,
+                                                 max_interval_sec, min_data_size,
+                                                 makeCharVec(ring_name).data());
+}
+
+wifi_error WifiLegacyHal::getRingBufferData(const std::string& iface_name,
+                                            const std::string& ring_name) {
+    return global_func_table_.wifi_get_ring_data(getIfaceHandle(iface_name),
+                                                 makeCharVec(ring_name).data());
+}
+
+wifi_error WifiLegacyHal::registerErrorAlertCallbackHandler(
+        const std::string& iface_name, const on_error_alert_callback& on_user_alert_callback) {
+    if (on_error_alert_internal_callback) {
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+    on_error_alert_internal_callback = [on_user_alert_callback](wifi_request_id id, char* buffer,
+                                                                int buffer_size, int err_code) {
+        if (buffer) {
+            CHECK(id == 0);
+            on_user_alert_callback(
+                    err_code,
+                    std::vector<uint8_t>(reinterpret_cast<uint8_t*>(buffer),
+                                         reinterpret_cast<uint8_t*>(buffer) + buffer_size));
+        }
+    };
+    wifi_error status = global_func_table_.wifi_set_alert_handler(0, getIfaceHandle(iface_name),
+                                                                  {onAsyncErrorAlert});
+    if (status != WIFI_SUCCESS) {
+        on_error_alert_internal_callback = nullptr;
+    }
+    return status;
+}
+
+wifi_error WifiLegacyHal::deregisterErrorAlertCallbackHandler(const std::string& iface_name) {
+    if (!on_error_alert_internal_callback) {
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+    on_error_alert_internal_callback = nullptr;
+    return global_func_table_.wifi_reset_alert_handler(0, getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::registerRadioModeChangeCallbackHandler(
+        const std::string& iface_name,
+        const on_radio_mode_change_callback& on_user_change_callback) {
+    if (on_radio_mode_change_internal_callback) {
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+    on_radio_mode_change_internal_callback = [on_user_change_callback](
+                                                     wifi_request_id /* id */, uint32_t num_macs,
+                                                     wifi_mac_info* mac_infos_arr) {
+        if (num_macs > 0 && mac_infos_arr) {
+            std::vector<WifiMacInfo> mac_infos_vec;
+            for (uint32_t i = 0; i < num_macs; i++) {
+                WifiMacInfo mac_info;
+                mac_info.wlan_mac_id = mac_infos_arr[i].wlan_mac_id;
+                mac_info.mac_band = mac_infos_arr[i].mac_band;
+                for (int32_t j = 0; j < mac_infos_arr[i].num_iface; j++) {
+                    WifiIfaceInfo iface_info;
+                    iface_info.name = mac_infos_arr[i].iface_info[j].iface_name;
+                    iface_info.channel = mac_infos_arr[i].iface_info[j].channel;
+                    mac_info.iface_infos.push_back(iface_info);
+                }
+                mac_infos_vec.push_back(mac_info);
+            }
+            on_user_change_callback(mac_infos_vec);
+        }
+    };
+    wifi_error status = global_func_table_.wifi_set_radio_mode_change_handler(
+            0, getIfaceHandle(iface_name), {onAsyncRadioModeChange});
+    if (status != WIFI_SUCCESS) {
+        on_radio_mode_change_internal_callback = nullptr;
+    }
+    return status;
+}
+
+wifi_error WifiLegacyHal::registerSubsystemRestartCallbackHandler(
+        const on_subsystem_restart_callback& on_restart_callback) {
+    if (on_subsystem_restart_internal_callback) {
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+    on_subsystem_restart_internal_callback = [on_restart_callback](const char* error) {
+        on_restart_callback(error);
+    };
+    wifi_error status = global_func_table_.wifi_set_subsystem_restart_handler(
+            global_handle_, {onAsyncSubsystemRestart});
+    if (status != WIFI_SUCCESS) {
+        on_subsystem_restart_internal_callback = nullptr;
+    }
+    return status;
+}
+
+wifi_error WifiLegacyHal::startRttRangeRequest(
+        const std::string& iface_name, wifi_request_id id,
+        const std::vector<wifi_rtt_config>& rtt_configs,
+        const on_rtt_results_callback& on_results_user_callback) {
+    if (on_rtt_results_internal_callback) {
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+
+    on_rtt_results_internal_callback = [on_results_user_callback](wifi_request_id id,
+                                                                  unsigned num_results,
+                                                                  wifi_rtt_result* rtt_results[]) {
+        if (num_results > 0 && !rtt_results) {
+            LOG(ERROR) << "Unexpected nullptr in RTT results";
+            return;
+        }
+        std::vector<const wifi_rtt_result*> rtt_results_vec;
+        std::copy_if(rtt_results, rtt_results + num_results, back_inserter(rtt_results_vec),
+                     [](wifi_rtt_result* rtt_result) { return rtt_result != nullptr; });
+        on_results_user_callback(id, rtt_results_vec);
+    };
+
+    std::vector<wifi_rtt_config> rtt_configs_internal(rtt_configs);
+    wifi_error status = global_func_table_.wifi_rtt_range_request(
+            id, getIfaceHandle(iface_name), rtt_configs.size(), rtt_configs_internal.data(),
+            {onAsyncRttResults});
+    if (status != WIFI_SUCCESS) {
+        on_rtt_results_internal_callback = nullptr;
+    }
+    return status;
+}
+
+wifi_error WifiLegacyHal::cancelRttRangeRequest(
+        const std::string& iface_name, wifi_request_id id,
+        const std::vector<std::array<uint8_t, 6>>& mac_addrs) {
+    if (!on_rtt_results_internal_callback) {
+        return WIFI_ERROR_NOT_AVAILABLE;
+    }
+    static_assert(sizeof(mac_addr) == sizeof(std::array<uint8_t, 6>), "MAC address size mismatch");
+    // TODO: How do we handle partial cancels (i.e only a subset of enabled mac
+    // addressed are cancelled).
+    std::vector<std::array<uint8_t, 6>> mac_addrs_internal(mac_addrs);
+    wifi_error status = global_func_table_.wifi_rtt_range_cancel(
+            id, getIfaceHandle(iface_name), mac_addrs.size(),
+            reinterpret_cast<mac_addr*>(mac_addrs_internal.data()));
+    // If the request Id is wrong, don't stop the ongoing range request. Any
+    // other error should be treated as the end of rtt ranging.
+    if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
+        on_rtt_results_internal_callback = nullptr;
+    }
+    return status;
+}
+
+std::pair<wifi_error, wifi_rtt_capabilities> WifiLegacyHal::getRttCapabilities(
+        const std::string& iface_name) {
+    wifi_rtt_capabilities rtt_caps;
+    wifi_error status =
+            global_func_table_.wifi_get_rtt_capabilities(getIfaceHandle(iface_name), &rtt_caps);
+    return {status, rtt_caps};
+}
+
+std::pair<wifi_error, wifi_rtt_responder> WifiLegacyHal::getRttResponderInfo(
+        const std::string& iface_name) {
+    wifi_rtt_responder rtt_responder;
+    wifi_error status = global_func_table_.wifi_rtt_get_responder_info(getIfaceHandle(iface_name),
+                                                                       &rtt_responder);
+    return {status, rtt_responder};
+}
+
+wifi_error WifiLegacyHal::enableRttResponder(const std::string& iface_name, wifi_request_id id,
+                                             const wifi_channel_info& channel_hint,
+                                             uint32_t max_duration_secs,
+                                             const wifi_rtt_responder& info) {
+    wifi_rtt_responder info_internal(info);
+    return global_func_table_.wifi_enable_responder(id, getIfaceHandle(iface_name), channel_hint,
+                                                    max_duration_secs, &info_internal);
+}
+
+wifi_error WifiLegacyHal::disableRttResponder(const std::string& iface_name, wifi_request_id id) {
+    return global_func_table_.wifi_disable_responder(id, getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::setRttLci(const std::string& iface_name, wifi_request_id id,
+                                    const wifi_lci_information& info) {
+    wifi_lci_information info_internal(info);
+    return global_func_table_.wifi_set_lci(id, getIfaceHandle(iface_name), &info_internal);
+}
+
+wifi_error WifiLegacyHal::setRttLcr(const std::string& iface_name, wifi_request_id id,
+                                    const wifi_lcr_information& info) {
+    wifi_lcr_information info_internal(info);
+    return global_func_table_.wifi_set_lcr(id, getIfaceHandle(iface_name), &info_internal);
+}
+
+wifi_error WifiLegacyHal::nanRegisterCallbackHandlers(const std::string& iface_name,
+                                                      const NanCallbackHandlers& user_callbacks) {
+    on_nan_notify_response_user_callback = user_callbacks.on_notify_response;
+    on_nan_event_publish_terminated_user_callback = user_callbacks.on_event_publish_terminated;
+    on_nan_event_match_user_callback = user_callbacks.on_event_match;
+    on_nan_event_match_expired_user_callback = user_callbacks.on_event_match_expired;
+    on_nan_event_subscribe_terminated_user_callback = user_callbacks.on_event_subscribe_terminated;
+    on_nan_event_followup_user_callback = user_callbacks.on_event_followup;
+    on_nan_event_disc_eng_event_user_callback = user_callbacks.on_event_disc_eng_event;
+    on_nan_event_disabled_user_callback = user_callbacks.on_event_disabled;
+    on_nan_event_tca_user_callback = user_callbacks.on_event_tca;
+    on_nan_event_beacon_sdf_payload_user_callback = user_callbacks.on_event_beacon_sdf_payload;
+    on_nan_event_data_path_request_user_callback = user_callbacks.on_event_data_path_request;
+    on_nan_event_data_path_confirm_user_callback = user_callbacks.on_event_data_path_confirm;
+    on_nan_event_data_path_end_user_callback = user_callbacks.on_event_data_path_end;
+    on_nan_event_transmit_follow_up_user_callback = user_callbacks.on_event_transmit_follow_up;
+    on_nan_event_range_request_user_callback = user_callbacks.on_event_range_request;
+    on_nan_event_range_report_user_callback = user_callbacks.on_event_range_report;
+    on_nan_event_schedule_update_user_callback = user_callbacks.on_event_schedule_update;
+
+    return global_func_table_.wifi_nan_register_handler(
+            getIfaceHandle(iface_name),
+            {onAysncNanNotifyResponse, onAysncNanEventPublishReplied,
+             onAysncNanEventPublishTerminated, onAysncNanEventMatch, onAysncNanEventMatchExpired,
+             onAysncNanEventSubscribeTerminated, onAysncNanEventFollowup,
+             onAysncNanEventDiscEngEvent, onAysncNanEventDisabled, onAysncNanEventTca,
+             onAysncNanEventBeaconSdfPayload, onAysncNanEventDataPathRequest,
+             onAysncNanEventDataPathConfirm, onAysncNanEventDataPathEnd,
+             onAysncNanEventTransmitFollowUp, onAysncNanEventRangeRequest,
+             onAysncNanEventRangeReport, onAsyncNanEventScheduleUpdate});
+}
+
+wifi_error WifiLegacyHal::nanEnableRequest(const std::string& iface_name, transaction_id id,
+                                           const NanEnableRequest& msg) {
+    NanEnableRequest msg_internal(msg);
+    return global_func_table_.wifi_nan_enable_request(id, getIfaceHandle(iface_name),
+                                                      &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanDisableRequest(const std::string& iface_name, transaction_id id) {
+    return global_func_table_.wifi_nan_disable_request(id, getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::nanPublishRequest(const std::string& iface_name, transaction_id id,
+                                            const NanPublishRequest& msg) {
+    NanPublishRequest msg_internal(msg);
+    return global_func_table_.wifi_nan_publish_request(id, getIfaceHandle(iface_name),
+                                                       &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanPublishCancelRequest(const std::string& iface_name, transaction_id id,
+                                                  const NanPublishCancelRequest& msg) {
+    NanPublishCancelRequest msg_internal(msg);
+    return global_func_table_.wifi_nan_publish_cancel_request(id, getIfaceHandle(iface_name),
+                                                              &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanSubscribeRequest(const std::string& iface_name, transaction_id id,
+                                              const NanSubscribeRequest& msg) {
+    NanSubscribeRequest msg_internal(msg);
+    return global_func_table_.wifi_nan_subscribe_request(id, getIfaceHandle(iface_name),
+                                                         &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanSubscribeCancelRequest(const std::string& iface_name,
+                                                    transaction_id id,
+                                                    const NanSubscribeCancelRequest& msg) {
+    NanSubscribeCancelRequest msg_internal(msg);
+    return global_func_table_.wifi_nan_subscribe_cancel_request(id, getIfaceHandle(iface_name),
+                                                                &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanTransmitFollowupRequest(const std::string& iface_name,
+                                                     transaction_id id,
+                                                     const NanTransmitFollowupRequest& msg) {
+    NanTransmitFollowupRequest msg_internal(msg);
+    return global_func_table_.wifi_nan_transmit_followup_request(id, getIfaceHandle(iface_name),
+                                                                 &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanStatsRequest(const std::string& iface_name, transaction_id id,
+                                          const NanStatsRequest& msg) {
+    NanStatsRequest msg_internal(msg);
+    return global_func_table_.wifi_nan_stats_request(id, getIfaceHandle(iface_name), &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanConfigRequest(const std::string& iface_name, transaction_id id,
+                                           const NanConfigRequest& msg) {
+    NanConfigRequest msg_internal(msg);
+    return global_func_table_.wifi_nan_config_request(id, getIfaceHandle(iface_name),
+                                                      &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanTcaRequest(const std::string& iface_name, transaction_id id,
+                                        const NanTCARequest& msg) {
+    NanTCARequest msg_internal(msg);
+    return global_func_table_.wifi_nan_tca_request(id, getIfaceHandle(iface_name), &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanBeaconSdfPayloadRequest(const std::string& iface_name,
+                                                     transaction_id id,
+                                                     const NanBeaconSdfPayloadRequest& msg) {
+    NanBeaconSdfPayloadRequest msg_internal(msg);
+    return global_func_table_.wifi_nan_beacon_sdf_payload_request(id, getIfaceHandle(iface_name),
+                                                                  &msg_internal);
+}
+
+std::pair<wifi_error, NanVersion> WifiLegacyHal::nanGetVersion() {
+    NanVersion version;
+    wifi_error status = global_func_table_.wifi_nan_get_version(global_handle_, &version);
+    return {status, version};
+}
+
+wifi_error WifiLegacyHal::nanGetCapabilities(const std::string& iface_name, transaction_id id) {
+    return global_func_table_.wifi_nan_get_capabilities(id, getIfaceHandle(iface_name));
+}
+
+wifi_error WifiLegacyHal::nanDataInterfaceCreate(const std::string& iface_name, transaction_id id,
+                                                 const std::string& data_iface_name) {
+    return global_func_table_.wifi_nan_data_interface_create(id, getIfaceHandle(iface_name),
+                                                             makeCharVec(data_iface_name).data());
+}
+
+wifi_error WifiLegacyHal::nanDataInterfaceDelete(const std::string& iface_name, transaction_id id,
+                                                 const std::string& data_iface_name) {
+    return global_func_table_.wifi_nan_data_interface_delete(id, getIfaceHandle(iface_name),
+                                                             makeCharVec(data_iface_name).data());
+}
+
+wifi_error WifiLegacyHal::nanDataRequestInitiator(const std::string& iface_name, transaction_id id,
+                                                  const NanDataPathInitiatorRequest& msg) {
+    NanDataPathInitiatorRequest msg_internal(msg);
+    return global_func_table_.wifi_nan_data_request_initiator(id, getIfaceHandle(iface_name),
+                                                              &msg_internal);
+}
+
+wifi_error WifiLegacyHal::nanDataIndicationResponse(const std::string& iface_name,
+                                                    transaction_id id,
+                                                    const NanDataPathIndicationResponse& msg) {
+    NanDataPathIndicationResponse msg_internal(msg);
+    return global_func_table_.wifi_nan_data_indication_response(id, getIfaceHandle(iface_name),
+                                                                &msg_internal);
+}
+
+typedef struct {
+    u8 num_ndp_instances;
+    NanDataPathId ndp_instance_id;
+} NanDataPathEndSingleNdpIdRequest;
+
+wifi_error WifiLegacyHal::nanDataEnd(const std::string& iface_name, transaction_id id,
+                                     uint32_t ndpInstanceId) {
+    NanDataPathEndSingleNdpIdRequest msg;
+    msg.num_ndp_instances = 1;
+    msg.ndp_instance_id = ndpInstanceId;
+    wifi_error status = global_func_table_.wifi_nan_data_end(id, getIfaceHandle(iface_name),
+                                                             (NanDataPathEndRequest*)&msg);
+    return status;
+}
+
+wifi_error WifiLegacyHal::setCountryCode(const std::string& iface_name,
+                                         std::array<int8_t, 2> code) {
+    std::string code_str(code.data(), code.data() + code.size());
+    return global_func_table_.wifi_set_country_code(getIfaceHandle(iface_name), code_str.c_str());
+}
+
+wifi_error WifiLegacyHal::retrieveIfaceHandles() {
+    wifi_interface_handle* iface_handles = nullptr;
+    int num_iface_handles = 0;
+    wifi_error status =
+            global_func_table_.wifi_get_ifaces(global_handle_, &num_iface_handles, &iface_handles);
+    if (status != WIFI_SUCCESS) {
+        LOG(ERROR) << "Failed to enumerate interface handles";
+        return status;
+    }
+    iface_name_to_handle_.clear();
+    for (int i = 0; i < num_iface_handles; ++i) {
+        std::array<char, IFNAMSIZ> iface_name_arr = {};
+        status = global_func_table_.wifi_get_iface_name(iface_handles[i], iface_name_arr.data(),
+                                                        iface_name_arr.size());
+        if (status != WIFI_SUCCESS) {
+            LOG(WARNING) << "Failed to get interface handle name";
+            continue;
+        }
+        // Assuming the interface name is null terminated since the legacy HAL
+        // API does not return a size.
+        std::string iface_name(iface_name_arr.data());
+        LOG(INFO) << "Adding interface handle for " << iface_name;
+        iface_name_to_handle_[iface_name] = iface_handles[i];
+    }
+    return WIFI_SUCCESS;
+}
+
+wifi_interface_handle WifiLegacyHal::getIfaceHandle(const std::string& iface_name) {
+    const auto iface_handle_iter = iface_name_to_handle_.find(iface_name);
+    if (iface_handle_iter == iface_name_to_handle_.end()) {
+        LOG(ERROR) << "Unknown iface name: " << iface_name;
+        return nullptr;
+    }
+    return iface_handle_iter->second;
+}
+
+void WifiLegacyHal::runEventLoop() {
+    LOG(DEBUG) << "Starting legacy HAL event loop";
+    global_func_table_.wifi_event_loop(global_handle_);
+    const auto lock = hidl_sync_util::acquireGlobalLock();
+    if (!awaiting_event_loop_termination_) {
+        LOG(FATAL) << "Legacy HAL event loop terminated, but HAL was not stopping";
+    }
+    LOG(DEBUG) << "Legacy HAL event loop terminated";
+    awaiting_event_loop_termination_ = false;
+    stop_wait_cv_.notify_one();
+}
+
+std::pair<wifi_error, std::vector<wifi_cached_scan_results>> WifiLegacyHal::getGscanCachedResults(
+        const std::string& iface_name) {
+    std::vector<wifi_cached_scan_results> cached_scan_results;
+    cached_scan_results.resize(kMaxCachedGscanResults);
+    int32_t num_results = 0;
+    wifi_error status = global_func_table_.wifi_get_cached_gscan_results(
+            getIfaceHandle(iface_name), true /* always flush */, cached_scan_results.size(),
+            cached_scan_results.data(), &num_results);
+    CHECK(num_results >= 0 && static_cast<uint32_t>(num_results) <= kMaxCachedGscanResults);
+    cached_scan_results.resize(num_results);
+    // Check for invalid IE lengths in these cached scan results and correct it.
+    for (auto& cached_scan_result : cached_scan_results) {
+        int num_scan_results = cached_scan_result.num_results;
+        for (int i = 0; i < num_scan_results; i++) {
+            auto& scan_result = cached_scan_result.results[i];
+            if (scan_result.ie_length > 0) {
+                LOG(DEBUG) << "Cached scan result has non-zero IE length " << scan_result.ie_length;
+                scan_result.ie_length = 0;
+            }
+        }
+    }
+    return {status, std::move(cached_scan_results)};
+}
+
+wifi_error WifiLegacyHal::createVirtualInterface(const std::string& ifname,
+                                                 wifi_interface_type iftype) {
+    // Create the interface if it doesn't exist. If interface already exist,
+    // Vendor Hal should return WIFI_SUCCESS.
+    wifi_error status = global_func_table_.wifi_virtual_interface_create(global_handle_,
+                                                                         ifname.c_str(), iftype);
+    return handleVirtualInterfaceCreateOrDeleteStatus(ifname, status);
+}
+
+wifi_error WifiLegacyHal::deleteVirtualInterface(const std::string& ifname) {
+    // Delete the interface if it was created dynamically.
+    wifi_error status =
+            global_func_table_.wifi_virtual_interface_delete(global_handle_, ifname.c_str());
+    return handleVirtualInterfaceCreateOrDeleteStatus(ifname, status);
+}
+
+wifi_error WifiLegacyHal::handleVirtualInterfaceCreateOrDeleteStatus(const std::string& ifname,
+                                                                     wifi_error status) {
+    if (status == WIFI_SUCCESS) {
+        // refresh list of handlers now.
+        status = retrieveIfaceHandles();
+    } else if (status == WIFI_ERROR_NOT_SUPPORTED) {
+        // Vendor hal does not implement this API. Such vendor implementations
+        // are expected to create / delete interface by other means.
+
+        // check if interface exists.
+        if (if_nametoindex(ifname.c_str())) {
+            status = retrieveIfaceHandles();
+        }
+    }
+    return status;
+}
+
+wifi_error WifiLegacyHal::getSupportedIfaceName(uint32_t iface_type, std::string& ifname) {
+    std::array<char, IFNAMSIZ> buffer;
+
+    wifi_error res = global_func_table_.wifi_get_supported_iface_name(
+            global_handle_, (uint32_t)iface_type, buffer.data(), buffer.size());
+    if (res == WIFI_SUCCESS) ifname = buffer.data();
+
+    return res;
+}
+
+wifi_error WifiLegacyHal::multiStaSetPrimaryConnection(const std::string& ifname) {
+    return global_func_table_.wifi_multi_sta_set_primary_connection(global_handle_,
+                                                                    getIfaceHandle(ifname));
+}
+
+wifi_error WifiLegacyHal::multiStaSetUseCase(wifi_multi_sta_use_case use_case) {
+    return global_func_table_.wifi_multi_sta_set_use_case(global_handle_, use_case);
+}
+
+wifi_error WifiLegacyHal::setCoexUnsafeChannels(
+        std::vector<wifi_coex_unsafe_channel> unsafe_channels, uint32_t restrictions) {
+    return global_func_table_.wifi_set_coex_unsafe_channels(global_handle_, unsafe_channels.size(),
+                                                            unsafe_channels.data(), restrictions);
+}
+
+wifi_error WifiLegacyHal::setVoipMode(const std::string& iface_name, wifi_voip_mode mode) {
+    return global_func_table_.wifi_set_voip_mode(getIfaceHandle(iface_name), mode);
+}
+
+wifi_error WifiLegacyHal::twtRegisterHandler(const std::string& iface_name,
+                                             const TwtCallbackHandlers& user_callbacks) {
+    on_twt_event_setup_response_callback = user_callbacks.on_setup_response;
+    on_twt_event_teardown_completion_callback = user_callbacks.on_teardown_completion;
+    on_twt_event_info_frame_received_callback = user_callbacks.on_info_frame_received;
+    on_twt_event_device_notify_callback = user_callbacks.on_device_notify;
+
+    return global_func_table_.wifi_twt_register_handler(
+            getIfaceHandle(iface_name),
+            {onAsyncTwtEventSetupResponse, onAsyncTwtEventTeardownCompletion,
+             onAsyncTwtEventInfoFrameReceived, onAsyncTwtEventDeviceNotify});
+}
+
+std::pair<wifi_error, TwtCapabilitySet> WifiLegacyHal::twtGetCapability(
+        const std::string& iface_name) {
+    TwtCapabilitySet capSet;
+    wifi_error status =
+            global_func_table_.wifi_twt_get_capability(getIfaceHandle(iface_name), &capSet);
+    return {status, capSet};
+}
+
+wifi_error WifiLegacyHal::twtSetupRequest(const std::string& iface_name,
+                                          const TwtSetupRequest& msg) {
+    TwtSetupRequest msgInternal(msg);
+    return global_func_table_.wifi_twt_setup_request(getIfaceHandle(iface_name), &msgInternal);
+}
+
+wifi_error WifiLegacyHal::twtTearDownRequest(const std::string& iface_name,
+                                             const TwtTeardownRequest& msg) {
+    TwtTeardownRequest msgInternal(msg);
+    return global_func_table_.wifi_twt_teardown_request(getIfaceHandle(iface_name), &msgInternal);
+}
+
+wifi_error WifiLegacyHal::twtInfoFrameRequest(const std::string& iface_name,
+                                              const TwtInfoFrameRequest& msg) {
+    TwtInfoFrameRequest msgInternal(msg);
+    return global_func_table_.wifi_twt_info_frame_request(getIfaceHandle(iface_name), &msgInternal);
+}
+
+std::pair<wifi_error, TwtStats> WifiLegacyHal::twtGetStats(const std::string& iface_name,
+                                                           uint8_t configId) {
+    TwtStats stats;
+    wifi_error status =
+            global_func_table_.wifi_twt_get_stats(getIfaceHandle(iface_name), configId, &stats);
+    return {status, stats};
+}
+
+wifi_error WifiLegacyHal::twtClearStats(const std::string& iface_name, uint8_t configId) {
+    return global_func_table_.wifi_twt_clear_stats(getIfaceHandle(iface_name), configId);
+}
+
+wifi_error WifiLegacyHal::setDtimConfig(const std::string& iface_name, uint32_t multiplier) {
+    return global_func_table_.wifi_set_dtim_config(getIfaceHandle(iface_name), multiplier);
+}
+
+std::pair<wifi_error, std::vector<wifi_usable_channel>> WifiLegacyHal::getUsableChannels(
+        uint32_t band_mask, uint32_t iface_mode_mask, uint32_t filter_mask) {
+    std::vector<wifi_usable_channel> channels;
+    channels.resize(kMaxWifiUsableChannels);
+    uint32_t size = 0;
+    wifi_error status = global_func_table_.wifi_get_usable_channels(
+            global_handle_, band_mask, iface_mode_mask, filter_mask, channels.size(), &size,
+            reinterpret_cast<wifi_usable_channel*>(channels.data()));
+    CHECK(size >= 0 && size <= kMaxWifiUsableChannels);
+    channels.resize(size);
+    return {status, std::move(channels)};
+}
+
+wifi_error WifiLegacyHal::triggerSubsystemRestart() {
+    return global_func_table_.wifi_trigger_subsystem_restart(global_handle_);
+}
+
+void WifiLegacyHal::invalidate() {
+    global_handle_ = nullptr;
+    iface_name_to_handle_.clear();
+    on_driver_memory_dump_internal_callback = nullptr;
+    on_firmware_memory_dump_internal_callback = nullptr;
+    on_gscan_event_internal_callback = nullptr;
+    on_gscan_full_result_internal_callback = nullptr;
+    on_link_layer_stats_result_internal_callback = nullptr;
+    on_rssi_threshold_breached_internal_callback = nullptr;
+    on_ring_buffer_data_internal_callback = nullptr;
+    on_error_alert_internal_callback = nullptr;
+    on_radio_mode_change_internal_callback = nullptr;
+    on_subsystem_restart_internal_callback = nullptr;
+    on_rtt_results_internal_callback = nullptr;
+    on_nan_notify_response_user_callback = nullptr;
+    on_nan_event_publish_terminated_user_callback = nullptr;
+    on_nan_event_match_user_callback = nullptr;
+    on_nan_event_match_expired_user_callback = nullptr;
+    on_nan_event_subscribe_terminated_user_callback = nullptr;
+    on_nan_event_followup_user_callback = nullptr;
+    on_nan_event_disc_eng_event_user_callback = nullptr;
+    on_nan_event_disabled_user_callback = nullptr;
+    on_nan_event_tca_user_callback = nullptr;
+    on_nan_event_beacon_sdf_payload_user_callback = nullptr;
+    on_nan_event_data_path_request_user_callback = nullptr;
+    on_nan_event_data_path_confirm_user_callback = nullptr;
+    on_nan_event_data_path_end_user_callback = nullptr;
+    on_nan_event_transmit_follow_up_user_callback = nullptr;
+    on_nan_event_range_request_user_callback = nullptr;
+    on_nan_event_range_report_user_callback = nullptr;
+    on_nan_event_schedule_update_user_callback = nullptr;
+    on_twt_event_setup_response_callback = nullptr;
+    on_twt_event_teardown_completion_callback = nullptr;
+    on_twt_event_info_frame_received_callback = nullptr;
+    on_twt_event_device_notify_callback = nullptr;
+}
+
+}  // namespace legacy_hal
+}  // namespace implementation
+}  // namespace V1_6
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
diff --git a/wifi/1.5/default/wifi_legacy_hal.h b/wifi/1.6/default/wifi_legacy_hal.h
similarity index 73%
rename from wifi/1.5/default/wifi_legacy_hal.h
rename to wifi/1.6/default/wifi_legacy_hal.h
index 2bb7631..d87242c 100644
--- a/wifi/1.5/default/wifi_legacy_hal.h
+++ b/wifi/1.6/default/wifi_legacy_hal.h
@@ -29,7 +29,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 // This is in a separate namespace to prevent typename conflicts between
 // the legacy HAL types and the HIDL interface types.
@@ -366,63 +366,53 @@
 // NAN response and event callbacks struct.
 struct NanCallbackHandlers {
     // NotifyResponse invoked to notify the status of the Request.
-    std::function<void(transaction_id, const NanResponseMsg&)>
-        on_notify_response;
+    std::function<void(transaction_id, const NanResponseMsg&)> on_notify_response;
     // Various event callbacks.
-    std::function<void(const NanPublishTerminatedInd&)>
-        on_event_publish_terminated;
+    std::function<void(const NanPublishTerminatedInd&)> on_event_publish_terminated;
     std::function<void(const NanMatchInd&)> on_event_match;
     std::function<void(const NanMatchExpiredInd&)> on_event_match_expired;
-    std::function<void(const NanSubscribeTerminatedInd&)>
-        on_event_subscribe_terminated;
+    std::function<void(const NanSubscribeTerminatedInd&)> on_event_subscribe_terminated;
     std::function<void(const NanFollowupInd&)> on_event_followup;
     std::function<void(const NanDiscEngEventInd&)> on_event_disc_eng_event;
     std::function<void(const NanDisabledInd&)> on_event_disabled;
     std::function<void(const NanTCAInd&)> on_event_tca;
-    std::function<void(const NanBeaconSdfPayloadInd&)>
-        on_event_beacon_sdf_payload;
-    std::function<void(const NanDataPathRequestInd&)>
-        on_event_data_path_request;
-    std::function<void(const NanDataPathConfirmInd&)>
-        on_event_data_path_confirm;
+    std::function<void(const NanBeaconSdfPayloadInd&)> on_event_beacon_sdf_payload;
+    std::function<void(const NanDataPathRequestInd&)> on_event_data_path_request;
+    std::function<void(const NanDataPathConfirmInd&)> on_event_data_path_confirm;
     std::function<void(const NanDataPathEndInd&)> on_event_data_path_end;
-    std::function<void(const NanTransmitFollowupInd&)>
-        on_event_transmit_follow_up;
+    std::function<void(const NanTransmitFollowupInd&)> on_event_transmit_follow_up;
     std::function<void(const NanRangeRequestInd&)> on_event_range_request;
     std::function<void(const NanRangeReportInd&)> on_event_range_report;
-    std::function<void(const NanDataPathScheduleUpdateInd&)>
-        on_event_schedule_update;
+    std::function<void(const NanDataPathScheduleUpdateInd&)> on_event_schedule_update;
 };
 
 // Full scan results contain IE info and are hence passed by reference, to
 // preserve the variable length array member |ie_data|. Callee must not retain
 // the pointer.
 using on_gscan_full_result_callback =
-    std::function<void(wifi_request_id, const wifi_scan_result*, uint32_t)>;
+        std::function<void(wifi_request_id, const wifi_scan_result*, uint32_t)>;
 // These scan results don't contain any IE info, so no need to pass by
 // reference.
-using on_gscan_results_callback = std::function<void(
-    wifi_request_id, const std::vector<wifi_cached_scan_results>&)>;
+using on_gscan_results_callback =
+        std::function<void(wifi_request_id, const std::vector<wifi_cached_scan_results>&)>;
 
 // Invoked when the rssi value breaches the thresholds set.
 using on_rssi_threshold_breached_callback =
-    std::function<void(wifi_request_id, std::array<uint8_t, 6>, int8_t)>;
+        std::function<void(wifi_request_id, std::array<uint8_t, 6>, int8_t)>;
 
 // Callback for RTT range request results.
 // Rtt results contain IE info and are hence passed by reference, to
 // preserve the |LCI| and |LCR| pointers. Callee must not retain
 // the pointer.
-using on_rtt_results_callback = std::function<void(
-    wifi_request_id, const std::vector<const wifi_rtt_result*>&)>;
+using on_rtt_results_callback =
+        std::function<void(wifi_request_id, const std::vector<const wifi_rtt_result*>&)>;
 
 // Callback for ring buffer data.
-using on_ring_buffer_data_callback =
-    std::function<void(const std::string&, const std::vector<uint8_t>&,
-                       const wifi_ring_buffer_status&)>;
+using on_ring_buffer_data_callback = std::function<void(
+        const std::string&, const std::vector<uint8_t>&, const wifi_ring_buffer_status&)>;
 
 // Callback for alerts.
-using on_error_alert_callback =
-    std::function<void(int32_t, const std::vector<uint8_t>&)>;
+using on_error_alert_callback = std::function<void(int32_t, const std::vector<uint8_t>&)>;
 
 // Callback for subsystem restart
 using on_subsystem_restart_callback = std::function<void(const std::string&)>;
@@ -443,8 +433,7 @@
 } WifiMacInfo;
 
 // Callback for radio mode change
-using on_radio_mode_change_callback =
-    std::function<void(const std::vector<WifiMacInfo>&)>;
+using on_radio_mode_change_callback = std::function<void(const std::vector<WifiMacInfo>&)>;
 
 // TWT response and event callbacks struct.
 struct TwtCallbackHandlers {
@@ -466,9 +455,9 @@
  * object and will be valid for the lifetime of the process.
  */
 class WifiLegacyHal {
-   public:
-    WifiLegacyHal(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
-                  const wifi_hal_fn& fn, bool is_primary);
+  public:
+    WifiLegacyHal(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool, const wifi_hal_fn& fn,
+                  bool is_primary);
     virtual ~WifiLegacyHal() = default;
 
     // Initialize the legacy HAL function table.
@@ -483,26 +472,22 @@
     // Checks if legacy HAL has successfully started
     bool isStarted();
     // Wrappers for all the functions in the legacy HAL function table.
-    virtual std::pair<wifi_error, std::string> getDriverVersion(
-        const std::string& iface_name);
-    virtual std::pair<wifi_error, std::string> getFirmwareVersion(
-        const std::string& iface_name);
+    virtual std::pair<wifi_error, std::string> getDriverVersion(const std::string& iface_name);
+    virtual std::pair<wifi_error, std::string> getFirmwareVersion(const std::string& iface_name);
     std::pair<wifi_error, std::vector<uint8_t>> requestDriverMemoryDump(
-        const std::string& iface_name);
+            const std::string& iface_name);
     std::pair<wifi_error, std::vector<uint8_t>> requestFirmwareMemoryDump(
-        const std::string& iface_name);
-    std::pair<wifi_error, uint64_t> getSupportedFeatureSet(
-        const std::string& iface_name);
+            const std::string& iface_name);
+    std::pair<wifi_error, uint64_t> getSupportedFeatureSet(const std::string& iface_name);
     // APF functions.
     std::pair<wifi_error, PacketFilterCapabilities> getPacketFilterCapabilities(
-        const std::string& iface_name);
-    wifi_error setPacketFilter(const std::string& iface_name,
-                               const std::vector<uint8_t>& program);
+            const std::string& iface_name);
+    wifi_error setPacketFilter(const std::string& iface_name, const std::vector<uint8_t>& program);
     std::pair<wifi_error, std::vector<uint8_t>> readApfPacketFilterData(
-        const std::string& iface_name);
+            const std::string& iface_name);
     // Gscan functions.
     std::pair<wifi_error, wifi_gscan_capabilities> getGscanCapabilities(
-        const std::string& iface_name);
+            const std::string& iface_name);
     // These API's provides a simplified interface over the legacy Gscan API's:
     // a) All scan events from the legacy HAL API other than the
     //    |WIFI_SCAN_FAILED| are treated as notification of results.
@@ -514,162 +499,121 @@
     //    triggers the externally provided |on_failure_user_callback|.
     // c) Full scan result event triggers the externally provided
     //    |on_full_result_user_callback|.
-    wifi_error startGscan(
-        const std::string& iface_name, wifi_request_id id,
-        const wifi_scan_cmd_params& params,
-        const std::function<void(wifi_request_id)>& on_failure_callback,
-        const on_gscan_results_callback& on_results_callback,
-        const on_gscan_full_result_callback& on_full_result_callback);
+    wifi_error startGscan(const std::string& iface_name, wifi_request_id id,
+                          const wifi_scan_cmd_params& params,
+                          const std::function<void(wifi_request_id)>& on_failure_callback,
+                          const on_gscan_results_callback& on_results_callback,
+                          const on_gscan_full_result_callback& on_full_result_callback);
     wifi_error stopGscan(const std::string& iface_name, wifi_request_id id);
     std::pair<wifi_error, std::vector<uint32_t>> getValidFrequenciesForBand(
-        const std::string& iface_name, wifi_band band);
+            const std::string& iface_name, wifi_band band);
     virtual wifi_error setDfsFlag(const std::string& iface_name, bool dfs_on);
     // Link layer stats functions.
     wifi_error enableLinkLayerStats(const std::string& iface_name, bool debug);
     wifi_error disableLinkLayerStats(const std::string& iface_name);
-    std::pair<wifi_error, LinkLayerStats> getLinkLayerStats(
-        const std::string& iface_name);
+    std::pair<wifi_error, LinkLayerStats> getLinkLayerStats(const std::string& iface_name);
     // RSSI monitor functions.
-    wifi_error startRssiMonitoring(const std::string& iface_name,
-                                   wifi_request_id id, int8_t max_rssi,
-                                   int8_t min_rssi,
-                                   const on_rssi_threshold_breached_callback&
-                                       on_threshold_breached_callback);
-    wifi_error stopRssiMonitoring(const std::string& iface_name,
-                                  wifi_request_id id);
+    wifi_error startRssiMonitoring(
+            const std::string& iface_name, wifi_request_id id, int8_t max_rssi, int8_t min_rssi,
+            const on_rssi_threshold_breached_callback& on_threshold_breached_callback);
+    wifi_error stopRssiMonitoring(const std::string& iface_name, wifi_request_id id);
     std::pair<wifi_error, wifi_roaming_capabilities> getRoamingCapabilities(
-        const std::string& iface_name);
-    wifi_error configureRoaming(const std::string& iface_name,
-                                const wifi_roaming_config& config);
-    wifi_error enableFirmwareRoaming(const std::string& iface_name,
-                                     fw_roaming_state_t state);
+            const std::string& iface_name);
+    wifi_error configureRoaming(const std::string& iface_name, const wifi_roaming_config& config);
+    wifi_error enableFirmwareRoaming(const std::string& iface_name, fw_roaming_state_t state);
     wifi_error configureNdOffload(const std::string& iface_name, bool enable);
-    wifi_error startSendingOffloadedPacket(
-        const std::string& iface_name, uint32_t cmd_id, uint16_t ether_type,
-        const std::vector<uint8_t>& ip_packet_data,
-        const std::array<uint8_t, 6>& src_address,
-        const std::array<uint8_t, 6>& dst_address, uint32_t period_in_ms);
-    wifi_error stopSendingOffloadedPacket(const std::string& iface_name,
-                                          uint32_t cmd_id);
+    wifi_error startSendingOffloadedPacket(const std::string& iface_name, uint32_t cmd_id,
+                                           uint16_t ether_type,
+                                           const std::vector<uint8_t>& ip_packet_data,
+                                           const std::array<uint8_t, 6>& src_address,
+                                           const std::array<uint8_t, 6>& dst_address,
+                                           uint32_t period_in_ms);
+    wifi_error stopSendingOffloadedPacket(const std::string& iface_name, uint32_t cmd_id);
     virtual wifi_error selectTxPowerScenario(const std::string& iface_name,
                                              wifi_power_scenario scenario);
     virtual wifi_error resetTxPowerScenario(const std::string& iface_name);
-    wifi_error setLatencyMode(const std::string& iface_name,
-                              wifi_latency_mode mode);
-    wifi_error setThermalMitigationMode(wifi_thermal_mode mode,
-                                        uint32_t completion_window);
+    wifi_error setLatencyMode(const std::string& iface_name, wifi_latency_mode mode);
+    wifi_error setThermalMitigationMode(wifi_thermal_mode mode, uint32_t completion_window);
     wifi_error setDscpToAccessCategoryMapping(uint32_t start, uint32_t end,
                                               uint32_t access_category);
     wifi_error resetDscpToAccessCategoryMapping();
     // Logger/debug functions.
-    std::pair<wifi_error, uint32_t> getLoggerSupportedFeatureSet(
-        const std::string& iface_name);
+    std::pair<wifi_error, uint32_t> getLoggerSupportedFeatureSet(const std::string& iface_name);
     wifi_error startPktFateMonitoring(const std::string& iface_name);
-    std::pair<wifi_error, std::vector<wifi_tx_report>> getTxPktFates(
-        const std::string& iface_name);
-    std::pair<wifi_error, std::vector<wifi_rx_report>> getRxPktFates(
-        const std::string& iface_name);
-    std::pair<wifi_error, WakeReasonStats> getWakeReasonStats(
-        const std::string& iface_name);
+    std::pair<wifi_error, std::vector<wifi_tx_report>> getTxPktFates(const std::string& iface_name);
+    std::pair<wifi_error, std::vector<wifi_rx_report>> getRxPktFates(const std::string& iface_name);
+    std::pair<wifi_error, WakeReasonStats> getWakeReasonStats(const std::string& iface_name);
     wifi_error registerRingBufferCallbackHandler(
-        const std::string& iface_name,
-        const on_ring_buffer_data_callback& on_data_callback);
-    wifi_error deregisterRingBufferCallbackHandler(
-        const std::string& iface_name);
+            const std::string& iface_name, const on_ring_buffer_data_callback& on_data_callback);
+    wifi_error deregisterRingBufferCallbackHandler(const std::string& iface_name);
     wifi_error registerSubsystemRestartCallbackHandler(
-        const on_subsystem_restart_callback& on_restart_callback);
-    std::pair<wifi_error, std::vector<wifi_ring_buffer_status>>
-    getRingBuffersStatus(const std::string& iface_name);
-    wifi_error startRingBufferLogging(const std::string& iface_name,
-                                      const std::string& ring_name,
-                                      uint32_t verbose_level,
-                                      uint32_t max_interval_sec,
+            const on_subsystem_restart_callback& on_restart_callback);
+    std::pair<wifi_error, std::vector<wifi_ring_buffer_status>> getRingBuffersStatus(
+            const std::string& iface_name);
+    wifi_error startRingBufferLogging(const std::string& iface_name, const std::string& ring_name,
+                                      uint32_t verbose_level, uint32_t max_interval_sec,
                                       uint32_t min_data_size);
-    wifi_error getRingBufferData(const std::string& iface_name,
-                                 const std::string& ring_name);
-    wifi_error registerErrorAlertCallbackHandler(
-        const std::string& iface_name,
-        const on_error_alert_callback& on_alert_callback);
-    wifi_error deregisterErrorAlertCallbackHandler(
-        const std::string& iface_name);
+    wifi_error getRingBufferData(const std::string& iface_name, const std::string& ring_name);
+    wifi_error registerErrorAlertCallbackHandler(const std::string& iface_name,
+                                                 const on_error_alert_callback& on_alert_callback);
+    wifi_error deregisterErrorAlertCallbackHandler(const std::string& iface_name);
     // Radio mode functions.
     virtual wifi_error registerRadioModeChangeCallbackHandler(
-        const std::string& iface_name,
-        const on_radio_mode_change_callback& on_user_change_callback);
+            const std::string& iface_name,
+            const on_radio_mode_change_callback& on_user_change_callback);
     // RTT functions.
-    wifi_error startRttRangeRequest(
-        const std::string& iface_name, wifi_request_id id,
-        const std::vector<wifi_rtt_config>& rtt_configs,
-        const on_rtt_results_callback& on_results_callback);
-    wifi_error cancelRttRangeRequest(
-        const std::string& iface_name, wifi_request_id id,
-        const std::vector<std::array<uint8_t, 6>>& mac_addrs);
-    std::pair<wifi_error, wifi_rtt_capabilities> getRttCapabilities(
-        const std::string& iface_name);
-    std::pair<wifi_error, wifi_rtt_responder> getRttResponderInfo(
-        const std::string& iface_name);
-    wifi_error enableRttResponder(const std::string& iface_name,
-                                  wifi_request_id id,
-                                  const wifi_channel_info& channel_hint,
-                                  uint32_t max_duration_secs,
+    wifi_error startRttRangeRequest(const std::string& iface_name, wifi_request_id id,
+                                    const std::vector<wifi_rtt_config>& rtt_configs,
+                                    const on_rtt_results_callback& on_results_callback);
+    wifi_error cancelRttRangeRequest(const std::string& iface_name, wifi_request_id id,
+                                     const std::vector<std::array<uint8_t, 6>>& mac_addrs);
+    std::pair<wifi_error, wifi_rtt_capabilities> getRttCapabilities(const std::string& iface_name);
+    std::pair<wifi_error, wifi_rtt_responder> getRttResponderInfo(const std::string& iface_name);
+    wifi_error enableRttResponder(const std::string& iface_name, wifi_request_id id,
+                                  const wifi_channel_info& channel_hint, uint32_t max_duration_secs,
                                   const wifi_rtt_responder& info);
-    wifi_error disableRttResponder(const std::string& iface_name,
-                                   wifi_request_id id);
+    wifi_error disableRttResponder(const std::string& iface_name, wifi_request_id id);
     wifi_error setRttLci(const std::string& iface_name, wifi_request_id id,
                          const wifi_lci_information& info);
     wifi_error setRttLcr(const std::string& iface_name, wifi_request_id id,
                          const wifi_lcr_information& info);
     // NAN functions.
-    virtual wifi_error nanRegisterCallbackHandlers(
-        const std::string& iface_name, const NanCallbackHandlers& callbacks);
-    wifi_error nanEnableRequest(const std::string& iface_name,
-                                transaction_id id, const NanEnableRequest& msg);
-    virtual wifi_error nanDisableRequest(const std::string& iface_name,
-                                         transaction_id id);
-    wifi_error nanPublishRequest(const std::string& iface_name,
-                                 transaction_id id,
+    virtual wifi_error nanRegisterCallbackHandlers(const std::string& iface_name,
+                                                   const NanCallbackHandlers& callbacks);
+    wifi_error nanEnableRequest(const std::string& iface_name, transaction_id id,
+                                const NanEnableRequest& msg);
+    virtual wifi_error nanDisableRequest(const std::string& iface_name, transaction_id id);
+    wifi_error nanPublishRequest(const std::string& iface_name, transaction_id id,
                                  const NanPublishRequest& msg);
-    wifi_error nanPublishCancelRequest(const std::string& iface_name,
-                                       transaction_id id,
+    wifi_error nanPublishCancelRequest(const std::string& iface_name, transaction_id id,
                                        const NanPublishCancelRequest& msg);
-    wifi_error nanSubscribeRequest(const std::string& iface_name,
-                                   transaction_id id,
+    wifi_error nanSubscribeRequest(const std::string& iface_name, transaction_id id,
                                    const NanSubscribeRequest& msg);
-    wifi_error nanSubscribeCancelRequest(const std::string& iface_name,
-                                         transaction_id id,
+    wifi_error nanSubscribeCancelRequest(const std::string& iface_name, transaction_id id,
                                          const NanSubscribeCancelRequest& msg);
-    wifi_error nanTransmitFollowupRequest(
-        const std::string& iface_name, transaction_id id,
-        const NanTransmitFollowupRequest& msg);
+    wifi_error nanTransmitFollowupRequest(const std::string& iface_name, transaction_id id,
+                                          const NanTransmitFollowupRequest& msg);
     wifi_error nanStatsRequest(const std::string& iface_name, transaction_id id,
                                const NanStatsRequest& msg);
-    wifi_error nanConfigRequest(const std::string& iface_name,
-                                transaction_id id, const NanConfigRequest& msg);
+    wifi_error nanConfigRequest(const std::string& iface_name, transaction_id id,
+                                const NanConfigRequest& msg);
     wifi_error nanTcaRequest(const std::string& iface_name, transaction_id id,
                              const NanTCARequest& msg);
-    wifi_error nanBeaconSdfPayloadRequest(
-        const std::string& iface_name, transaction_id id,
-        const NanBeaconSdfPayloadRequest& msg);
+    wifi_error nanBeaconSdfPayloadRequest(const std::string& iface_name, transaction_id id,
+                                          const NanBeaconSdfPayloadRequest& msg);
     std::pair<wifi_error, NanVersion> nanGetVersion();
-    wifi_error nanGetCapabilities(const std::string& iface_name,
-                                  transaction_id id);
-    wifi_error nanDataInterfaceCreate(const std::string& iface_name,
-                                      transaction_id id,
+    wifi_error nanGetCapabilities(const std::string& iface_name, transaction_id id);
+    wifi_error nanDataInterfaceCreate(const std::string& iface_name, transaction_id id,
                                       const std::string& data_iface_name);
-    virtual wifi_error nanDataInterfaceDelete(
-        const std::string& iface_name, transaction_id id,
-        const std::string& data_iface_name);
-    wifi_error nanDataRequestInitiator(const std::string& iface_name,
-                                       transaction_id id,
+    virtual wifi_error nanDataInterfaceDelete(const std::string& iface_name, transaction_id id,
+                                              const std::string& data_iface_name);
+    wifi_error nanDataRequestInitiator(const std::string& iface_name, transaction_id id,
                                        const NanDataPathInitiatorRequest& msg);
-    wifi_error nanDataIndicationResponse(
-        const std::string& iface_name, transaction_id id,
-        const NanDataPathIndicationResponse& msg);
-    wifi_error nanDataEnd(const std::string& iface_name, transaction_id id,
-                          uint32_t ndpInstanceId);
+    wifi_error nanDataIndicationResponse(const std::string& iface_name, transaction_id id,
+                                         const NanDataPathIndicationResponse& msg);
+    wifi_error nanDataEnd(const std::string& iface_name, transaction_id id, uint32_t ndpInstanceId);
     // AP functions.
-    wifi_error setCountryCode(const std::string& iface_name,
-                              std::array<int8_t, 2> code);
+    wifi_error setCountryCode(const std::string& iface_name, std::array<int8_t, 2> code);
 
     // interface functions.
     virtual wifi_error createVirtualInterface(const std::string& ifname,
@@ -682,43 +626,36 @@
     virtual wifi_error multiStaSetUseCase(wifi_multi_sta_use_case use_case);
 
     // Coex functions.
-    virtual wifi_error setCoexUnsafeChannels(
-        std::vector<wifi_coex_unsafe_channel> unsafe_channels,
-        uint32_t restrictions);
+    virtual wifi_error setCoexUnsafeChannels(std::vector<wifi_coex_unsafe_channel> unsafe_channels,
+                                             uint32_t restrictions);
 
     wifi_error setVoipMode(const std::string& iface_name, wifi_voip_mode mode);
 
     wifi_error twtRegisterHandler(const std::string& iface_name,
                                   const TwtCallbackHandlers& handler);
 
-    std::pair<wifi_error, TwtCapabilitySet> twtGetCapability(
-        const std::string& iface_name);
+    std::pair<wifi_error, TwtCapabilitySet> twtGetCapability(const std::string& iface_name);
 
-    wifi_error twtSetupRequest(const std::string& iface_name,
-                               const TwtSetupRequest& msg);
+    wifi_error twtSetupRequest(const std::string& iface_name, const TwtSetupRequest& msg);
 
-    wifi_error twtTearDownRequest(const std::string& iface_name,
-                                  const TwtTeardownRequest& msg);
+    wifi_error twtTearDownRequest(const std::string& iface_name, const TwtTeardownRequest& msg);
 
-    wifi_error twtInfoFrameRequest(const std::string& iface_name,
-                                   const TwtInfoFrameRequest& msg);
+    wifi_error twtInfoFrameRequest(const std::string& iface_name, const TwtInfoFrameRequest& msg);
 
-    std::pair<wifi_error, TwtStats> twtGetStats(const std::string& iface_name,
-                                                uint8_t configId);
+    std::pair<wifi_error, TwtStats> twtGetStats(const std::string& iface_name, uint8_t configId);
 
     wifi_error twtClearStats(const std::string& iface_name, uint8_t configId);
 
-    wifi_error setDtimConfig(const std::string& iface_name,
-                             uint32_t multiplier);
+    wifi_error setDtimConfig(const std::string& iface_name, uint32_t multiplier);
 
     // Retrieve the list of usable channels in the requested bands
     // for the requested modes
     std::pair<wifi_error, std::vector<wifi_usable_channel>> getUsableChannels(
-        uint32_t band_mask, uint32_t iface_mode_mask, uint32_t filter_mask);
+            uint32_t band_mask, uint32_t iface_mode_mask, uint32_t filter_mask);
 
     wifi_error triggerSubsystemRestart();
 
-   private:
+  private:
     // Retrieve interface handles for all the available interfaces.
     wifi_error retrieveIfaceHandles();
     wifi_interface_handle getIfaceHandle(const std::string& iface_name);
@@ -726,12 +663,12 @@
     void runEventLoop();
     // Retrieve the cached gscan results to pass the results back to the
     // external callbacks.
-    std::pair<wifi_error, std::vector<wifi_cached_scan_results>>
-    getGscanCachedResults(const std::string& iface_name);
+    std::pair<wifi_error, std::vector<wifi_cached_scan_results>> getGscanCachedResults(
+            const std::string& iface_name);
     void invalidate();
     // Handles wifi (error) status of Virtual interface create/delete
-    wifi_error handleVirtualInterfaceCreateOrDeleteStatus(
-        const std::string& ifname, wifi_error status);
+    wifi_error handleVirtualInterfaceCreateOrDeleteStatus(const std::string& ifname,
+                                                          wifi_error status);
 
     // Global function table of legacy HAL.
     wifi_hal_fn global_func_table_;
@@ -755,7 +692,7 @@
 
 }  // namespace legacy_hal
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/wifi_legacy_hal_factory.cpp b/wifi/1.6/default/wifi_legacy_hal_factory.cpp
similarity index 87%
rename from wifi/1.5/default/wifi_legacy_hal_factory.cpp
rename to wifi/1.6/default/wifi_legacy_hal_factory.cpp
index fbaa284..147bf4d 100644
--- a/wifi/1.5/default/wifi_legacy_hal_factory.cpp
+++ b/wifi/1.6/default/wifi_legacy_hal_factory.cpp
@@ -62,22 +62,20 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 namespace legacy_hal {
 
 WifiLegacyHalFactory::WifiLegacyHalFactory(
-    const std::weak_ptr<wifi_system::InterfaceTool> iface_tool)
+        const std::weak_ptr<wifi_system::InterfaceTool> iface_tool)
     : iface_tool_(iface_tool) {}
 
 std::vector<std::shared_ptr<WifiLegacyHal>> WifiLegacyHalFactory::getHals() {
     if (legacy_hals_.empty()) {
-        if (!initVendorHalDescriptorFromLinked())
-            initVendorHalsDescriptorList();
+        if (!initVendorHalDescriptorFromLinked()) initVendorHalsDescriptorList();
         for (auto& desc : descs_) {
             std::shared_ptr<WifiLegacyHal> hal =
-                std::make_shared<WifiLegacyHal>(iface_tool_, desc.fn,
-                                                desc.primary);
+                    std::make_shared<WifiLegacyHal>(iface_tool_, desc.fn, desc.primary);
             legacy_hals_.push_back(hal);
         }
     }
@@ -99,8 +97,8 @@
 bool WifiLegacyHalFactory::initLinkedHalFunctionTable(wifi_hal_fn* hal_fn) {
     init_wifi_vendor_hal_func_table_t initfn;
 
-    initfn = (init_wifi_vendor_hal_func_table_t)dlsym(
-        RTLD_DEFAULT, "init_wifi_vendor_hal_func_table");
+    initfn = (init_wifi_vendor_hal_func_table_t)dlsym(RTLD_DEFAULT,
+                                                      "init_wifi_vendor_hal_func_table");
     if (!initfn) {
         LOG(INFO) << "no vendor HAL library linked, will try dynamic load";
         return false;
@@ -136,8 +134,7 @@
     xmlChar* value;
     wifi_hal_lib_desc desc;
 
-    LOG(INFO) << "processing vendor HALs descriptions in "
-              << kVendorHalsDescPath;
+    LOG(INFO) << "processing vendor HALs descriptions in " << kVendorHalsDescPath;
     DIR* dirPtr = ::opendir(kVendorHalsDescPath);
     if (dirPtr == NULL) {
         LOG(ERROR) << "failed to open " << kVendorHalsDescPath;
@@ -157,26 +154,23 @@
         fullPath.append(entryPtr->d_name);
         xml = xmlReadFile(fullPath.c_str(), "UTF-8", XML_PARSE_RECOVER);
         if (!xml) {
-            LOG(ERROR) << "failed to parse: " << entryPtr->d_name
-                       << " skipping...";
+            LOG(ERROR) << "failed to parse: " << entryPtr->d_name << " skipping...";
             continue;
         }
         node = xmlDocGetRootElement(xml);
         if (!node) {
-            LOG(ERROR) << "empty config file: " << entryPtr->d_name
-                       << " skipping...";
+            LOG(ERROR) << "empty config file: " << entryPtr->d_name << " skipping...";
             goto skip;
         }
         if (xmlStrcmp(node->name, BAD_CAST "WifiVendorHal")) {
-            LOG(ERROR) << "bad config, root element not WifiVendorHal: "
-                       << entryPtr->d_name << " skipping...";
+            LOG(ERROR) << "bad config, root element not WifiVendorHal: " << entryPtr->d_name
+                       << " skipping...";
             goto skip;
         }
         version = (char*)xmlGetProp(node, BAD_CAST "version");
         if (!version || strtoul(version, NULL, 0) != kVendorHalsDescVersion) {
             LOG(ERROR) << "conf file: " << entryPtr->d_name
-                       << "must have version: " << kVendorHalsDescVersion
-                       << ", skipping...";
+                       << "must have version: " << kVendorHalsDescVersion << ", skipping...";
             goto skip;
         }
         cnode = node->children;
@@ -195,8 +189,8 @@
             cnode = cnode->next;
         }
         if (path.empty()) {
-            LOG(ERROR) << "hal library path not provided in: "
-                       << entryPtr->d_name << ", skipping...";
+            LOG(ERROR) << "hal library path not provided in: " << entryPtr->d_name
+                       << ", skipping...";
             goto skip;
         }
         if (loadVendorHalLib(path, desc)) {
@@ -211,8 +205,7 @@
     ::closedir(dirPtr);
 }
 
-bool WifiLegacyHalFactory::loadVendorHalLib(const std::string& path,
-                                            wifi_hal_lib_desc& desc) {
+bool WifiLegacyHalFactory::loadVendorHalLib(const std::string& path, wifi_hal_lib_desc& desc) {
     void* h = dlopen(path.c_str(), RTLD_NOW | RTLD_LOCAL);
     init_wifi_vendor_hal_func_table_t initfn;
     wifi_error res;
@@ -221,8 +214,7 @@
         LOG(ERROR) << "failed to open vendor hal library: " << path;
         return false;
     }
-    initfn = (init_wifi_vendor_hal_func_table_t)dlsym(
-        h, "init_wifi_vendor_hal_func_table");
+    initfn = (init_wifi_vendor_hal_func_table_t)dlsym(h, "init_wifi_vendor_hal_func_table");
     if (!initfn) {
         LOG(ERROR) << "init_wifi_vendor_hal_func_table not found in: " << path;
         goto out_err;
@@ -243,8 +235,7 @@
     // vendor HALs which do not implement early_initialize will return
     // WIFI_ERROR_NOT_SUPPORTED, treat this as success.
     if (res != WIFI_SUCCESS && res != WIFI_ERROR_NOT_SUPPORTED) {
-        LOG(ERROR) << "early initialization failed in: " << path
-                   << " error: " << res;
+        LOG(ERROR) << "early initialization failed in: " << path << " error: " << res;
         goto out_err;
     }
 
@@ -257,7 +248,7 @@
 
 }  // namespace legacy_hal
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/wifi_legacy_hal_factory.h b/wifi/1.6/default/wifi_legacy_hal_factory.h
similarity index 92%
rename from wifi/1.5/default/wifi_legacy_hal_factory.h
rename to wifi/1.6/default/wifi_legacy_hal_factory.h
index e3440fa..9f4423e 100644
--- a/wifi/1.5/default/wifi_legacy_hal_factory.h
+++ b/wifi/1.6/default/wifi_legacy_hal_factory.h
@@ -24,7 +24,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 // This is in a separate namespace to prevent typename conflicts between
 // the legacy HAL types and the HIDL interface types.
@@ -33,14 +33,13 @@
  * Class that creates WifiLegacyHal objects for vendor HALs in the system.
  */
 class WifiLegacyHalFactory {
-   public:
-    WifiLegacyHalFactory(
-        const std::weak_ptr<wifi_system::InterfaceTool> iface_tool);
+  public:
+    WifiLegacyHalFactory(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool);
     virtual ~WifiLegacyHalFactory() = default;
 
     std::vector<std::shared_ptr<WifiLegacyHal>> getHals();
 
-   private:
+  private:
     typedef struct {
         wifi_hal_fn fn;
         bool primary;
@@ -59,7 +58,7 @@
 
 }  // namespace legacy_hal
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp b/wifi/1.6/default/wifi_legacy_hal_stubs.cpp
similarity index 99%
rename from wifi/1.5/default/wifi_legacy_hal_stubs.cpp
rename to wifi/1.6/default/wifi_legacy_hal_stubs.cpp
index dd860d6..e03e1ae 100644
--- a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp
+++ b/wifi/1.6/default/wifi_legacy_hal_stubs.cpp
@@ -20,7 +20,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 namespace legacy_hal {
 template <typename>
@@ -165,7 +165,7 @@
 }
 }  // namespace legacy_hal
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/wifi_legacy_hal_stubs.h b/wifi/1.6/default/wifi_legacy_hal_stubs.h
similarity index 96%
rename from wifi/1.5/default/wifi_legacy_hal_stubs.h
rename to wifi/1.6/default/wifi_legacy_hal_stubs.h
index 480389b..c9a03bf 100644
--- a/wifi/1.5/default/wifi_legacy_hal_stubs.h
+++ b/wifi/1.6/default/wifi_legacy_hal_stubs.h
@@ -22,14 +22,14 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 namespace legacy_hal {
 
 bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn);
 }  // namespace legacy_hal
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/wifi_mode_controller.cpp b/wifi/1.6/default/wifi_mode_controller.cpp
similarity index 90%
rename from wifi/1.5/default/wifi_mode_controller.cpp
rename to wifi/1.6/default/wifi_mode_controller.cpp
index b1db8b3..4b8ac7d 100644
--- a/wifi/1.5/default/wifi_mode_controller.cpp
+++ b/wifi/1.6/default/wifi_mode_controller.cpp
@@ -48,15 +48,14 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 namespace mode_controller {
 
 WifiModeController::WifiModeController() : driver_tool_(new DriverTool) {}
 
 bool WifiModeController::isFirmwareModeChangeNeeded(IfaceType type) {
-    return driver_tool_->IsFirmwareModeChangeNeeded(
-        convertIfaceTypeToFirmwareMode(type));
+    return driver_tool_->IsFirmwareModeChangeNeeded(convertIfaceTypeToFirmwareMode(type));
 }
 
 bool WifiModeController::initialize() {
@@ -68,8 +67,7 @@
 }
 
 bool WifiModeController::changeFirmwareMode(IfaceType type) {
-    if (!driver_tool_->ChangeFirmwareMode(
-            convertIfaceTypeToFirmwareMode(type))) {
+    if (!driver_tool_->ChangeFirmwareMode(convertIfaceTypeToFirmwareMode(type))) {
         LOG(ERROR) << "Failed to change firmware mode";
         return false;
     }
@@ -85,7 +83,7 @@
 }
 }  // namespace mode_controller
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/wifi_mode_controller.h b/wifi/1.6/default/wifi_mode_controller.h
similarity index 96%
rename from wifi/1.5/default/wifi_mode_controller.h
rename to wifi/1.6/default/wifi_mode_controller.h
index 2eeca78..fee2b66 100644
--- a/wifi/1.5/default/wifi_mode_controller.h
+++ b/wifi/1.6/default/wifi_mode_controller.h
@@ -24,7 +24,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 namespace mode_controller {
 using namespace android::hardware::wifi::V1_0;
@@ -35,7 +35,7 @@
  * required state (essentially a wrapper over DriverTool).
  */
 class WifiModeController {
-   public:
+  public:
     WifiModeController();
     virtual ~WifiModeController() = default;
 
@@ -49,13 +49,13 @@
     // invoked.
     virtual bool deinitialize();
 
-   private:
+  private:
     std::unique_ptr<wifi_hal::DriverTool> driver_tool_;
 };
 
 }  // namespace mode_controller
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.6/default/wifi_nan_iface.cpp b/wifi/1.6/default/wifi_nan_iface.cpp
new file mode 100644
index 0000000..236cb64
--- /dev/null
+++ b/wifi/1.6/default/wifi_nan_iface.cpp
@@ -0,0 +1,905 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "hidl_return_util.h"
+#include "hidl_struct_util.h"
+#include "wifi_nan_iface.h"
+#include "wifi_status_util.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+using hidl_return_util::validateAndCall;
+
+WifiNanIface::WifiNanIface(const std::string& ifname, bool is_dedicated_iface,
+                           const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+                           const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
+    : ifname_(ifname),
+      is_dedicated_iface_(is_dedicated_iface),
+      legacy_hal_(legacy_hal),
+      iface_util_(iface_util),
+      is_valid_(true) {
+    if (is_dedicated_iface_) {
+        // If using a dedicated iface, set the iface up first.
+        if (!iface_util_.lock()->setUpState(ifname_, true)) {
+            // Fatal failure, invalidate the iface object.
+            invalidate();
+            return;
+        }
+    }
+    // Register all the callbacks here. these should be valid for the lifetime
+    // of the object. Whenever the mode changes legacy HAL will remove
+    // all of these callbacks.
+    legacy_hal::NanCallbackHandlers callback_handlers;
+    android::wp<WifiNanIface> weak_ptr_this(this);
+
+    // Callback for response.
+    callback_handlers.on_notify_response = [weak_ptr_this](legacy_hal::transaction_id id,
+                                                           const legacy_hal::NanResponseMsg& msg) {
+        const auto shared_ptr_this = weak_ptr_this.promote();
+        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+            LOG(ERROR) << "Callback invoked on an invalid object";
+            return;
+        }
+        WifiNanStatus wifiNanStatus;
+        if (!hidl_struct_util::convertLegacyNanResponseHeaderToHidl(msg, &wifiNanStatus)) {
+            LOG(ERROR) << "Failed to convert nan response header";
+            return;
+        }
+
+        switch (msg.response_type) {
+            case legacy_hal::NAN_RESPONSE_ENABLED: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyEnableResponse(id, wifiNanStatus).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_RESPONSE_DISABLED: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyDisableResponse(id, wifiNanStatus).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_RESPONSE_PUBLISH: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyStartPublishResponse(id, wifiNanStatus,
+                                                              msg.body.publish_response.publish_id)
+                                 .isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_RESPONSE_PUBLISH_CANCEL: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyStopPublishResponse(id, wifiNanStatus).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_RESPONSE_TRANSMIT_FOLLOWUP: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyTransmitFollowupResponse(id, wifiNanStatus).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_RESPONSE_SUBSCRIBE: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyStartSubscribeResponse(
+                                         id, wifiNanStatus,
+                                         msg.body.subscribe_response.subscribe_id)
+                                 .isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_RESPONSE_SUBSCRIBE_CANCEL: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyStopSubscribeResponse(id, wifiNanStatus).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_RESPONSE_CONFIG: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyConfigResponse(id, wifiNanStatus).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_GET_CAPABILITIES: {
+                V1_5::NanCapabilities hidl_struct;
+                if (!hidl_struct_util::convertLegacyNanCapabilitiesResponseToHidl(
+                            msg.body.nan_capabilities, &hidl_struct)) {
+                    LOG(ERROR) << "Failed to convert nan capabilities response";
+                    return;
+                }
+                for (const auto& callback : shared_ptr_this->getEventCallbacks_1_5()) {
+                    if (!callback->notifyCapabilitiesResponse_1_5(id, wifiNanStatus, hidl_struct)
+                                 .isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_DP_INTERFACE_CREATE: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyCreateDataInterfaceResponse(id, wifiNanStatus).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_DP_INTERFACE_DELETE: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyDeleteDataInterfaceResponse(id, wifiNanStatus).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_DP_INITIATOR_RESPONSE: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyInitiateDataPathResponse(
+                                         id, wifiNanStatus,
+                                         msg.body.data_request_response.ndp_instance_id)
+                                 .isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_DP_RESPONDER_RESPONSE: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyRespondToDataPathIndicationResponse(id, wifiNanStatus)
+                                 .isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_DP_END: {
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->notifyTerminateDataPathResponse(id, wifiNanStatus).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+                break;
+            }
+            case legacy_hal::NAN_RESPONSE_BEACON_SDF_PAYLOAD:
+            /* fall through */
+            case legacy_hal::NAN_RESPONSE_TCA:
+            /* fall through */
+            case legacy_hal::NAN_RESPONSE_STATS:
+            /* fall through */
+            case legacy_hal::NAN_RESPONSE_ERROR:
+            /* fall through */
+            default:
+                LOG(ERROR) << "Unknown or unhandled response type: " << msg.response_type;
+                return;
+        }
+    };
+
+    callback_handlers.on_event_disc_eng_event =
+            [weak_ptr_this](const legacy_hal::NanDiscEngEventInd& msg) {
+                const auto shared_ptr_this = weak_ptr_this.promote();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                NanClusterEventInd hidl_struct;
+                // event types defined identically - hence can be cast
+                hidl_struct.eventType = (NanClusterEventType)msg.event_type;
+                hidl_struct.addr = msg.data.mac_addr.addr;
+
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->eventClusterEvent(hidl_struct).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+            };
+
+    callback_handlers.on_event_disabled = [weak_ptr_this](const legacy_hal::NanDisabledInd& msg) {
+        const auto shared_ptr_this = weak_ptr_this.promote();
+        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+            LOG(ERROR) << "Callback invoked on an invalid object";
+            return;
+        }
+        WifiNanStatus status;
+        hidl_struct_util::convertToWifiNanStatus(msg.reason, msg.nan_reason, sizeof(msg.nan_reason),
+                                                 &status);
+
+        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+            if (!callback->eventDisabled(status).isOk()) {
+                LOG(ERROR) << "Failed to invoke the callback";
+            }
+        }
+    };
+
+    callback_handlers.on_event_publish_terminated =
+            [weak_ptr_this](const legacy_hal::NanPublishTerminatedInd& msg) {
+                const auto shared_ptr_this = weak_ptr_this.promote();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                WifiNanStatus status;
+                hidl_struct_util::convertToWifiNanStatus(msg.reason, msg.nan_reason,
+                                                         sizeof(msg.nan_reason), &status);
+
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->eventPublishTerminated(msg.publish_id, status).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+            };
+
+    callback_handlers.on_event_subscribe_terminated =
+            [weak_ptr_this](const legacy_hal::NanSubscribeTerminatedInd& msg) {
+                const auto shared_ptr_this = weak_ptr_this.promote();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                WifiNanStatus status;
+                hidl_struct_util::convertToWifiNanStatus(msg.reason, msg.nan_reason,
+                                                         sizeof(msg.nan_reason), &status);
+
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->eventSubscribeTerminated(msg.subscribe_id, status).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+            };
+
+    callback_handlers.on_event_match = [weak_ptr_this](const legacy_hal::NanMatchInd& msg) {
+        const auto shared_ptr_this = weak_ptr_this.promote();
+        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+            LOG(ERROR) << "Callback invoked on an invalid object";
+            return;
+        }
+        NanMatchInd hidl_struct;
+        if (!hidl_struct_util::convertLegacyNanMatchIndToHidl(msg, &hidl_struct)) {
+            LOG(ERROR) << "Failed to convert nan capabilities response";
+            return;
+        }
+
+        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+            if (!callback->eventMatch(hidl_struct).isOk()) {
+                LOG(ERROR) << "Failed to invoke the callback";
+            }
+        }
+    };
+
+    callback_handlers.on_event_match_expired = [weak_ptr_this](
+                                                       const legacy_hal::NanMatchExpiredInd& msg) {
+        const auto shared_ptr_this = weak_ptr_this.promote();
+        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+            LOG(ERROR) << "Callback invoked on an invalid object";
+            return;
+        }
+        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+            if (!callback->eventMatchExpired(msg.publish_subscribe_id, msg.requestor_instance_id)
+                         .isOk()) {
+                LOG(ERROR) << "Failed to invoke the callback";
+            }
+        }
+    };
+
+    callback_handlers.on_event_followup = [weak_ptr_this](const legacy_hal::NanFollowupInd& msg) {
+        const auto shared_ptr_this = weak_ptr_this.promote();
+        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+            LOG(ERROR) << "Callback invoked on an invalid object";
+            return;
+        }
+        NanFollowupReceivedInd hidl_struct;
+        if (!hidl_struct_util::convertLegacyNanFollowupIndToHidl(msg, &hidl_struct)) {
+            LOG(ERROR) << "Failed to convert nan capabilities response";
+            return;
+        }
+
+        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+            if (!callback->eventFollowupReceived(hidl_struct).isOk()) {
+                LOG(ERROR) << "Failed to invoke the callback";
+            }
+        }
+    };
+
+    callback_handlers.on_event_transmit_follow_up =
+            [weak_ptr_this](const legacy_hal::NanTransmitFollowupInd& msg) {
+                const auto shared_ptr_this = weak_ptr_this.promote();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                WifiNanStatus status;
+                hidl_struct_util::convertToWifiNanStatus(msg.reason, msg.nan_reason,
+                                                         sizeof(msg.nan_reason), &status);
+
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->eventTransmitFollowup(msg.id, status).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+            };
+
+    callback_handlers.on_event_data_path_request =
+            [weak_ptr_this](const legacy_hal::NanDataPathRequestInd& msg) {
+                const auto shared_ptr_this = weak_ptr_this.promote();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                NanDataPathRequestInd hidl_struct;
+                if (!hidl_struct_util::convertLegacyNanDataPathRequestIndToHidl(msg,
+                                                                                &hidl_struct)) {
+                    LOG(ERROR) << "Failed to convert nan capabilities response";
+                    return;
+                }
+
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->eventDataPathRequest(hidl_struct).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+            };
+
+    callback_handlers.on_event_data_path_confirm =
+            [weak_ptr_this](const legacy_hal::NanDataPathConfirmInd& msg) {
+                const auto shared_ptr_this = weak_ptr_this.promote();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                V1_2::NanDataPathConfirmInd hidl_struct;
+                if (!hidl_struct_util::convertLegacyNanDataPathConfirmIndToHidl(msg,
+                                                                                &hidl_struct)) {
+                    LOG(ERROR) << "Failed to convert nan capabilities response";
+                    return;
+                }
+
+                for (const auto& callback : shared_ptr_this->getEventCallbacks_1_2()) {
+                    if (!callback->eventDataPathConfirm_1_2(hidl_struct).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+            };
+
+    callback_handlers.on_event_data_path_end =
+            [weak_ptr_this](const legacy_hal::NanDataPathEndInd& msg) {
+                const auto shared_ptr_this = weak_ptr_this.promote();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    for (int i = 0; i < msg.num_ndp_instances; ++i) {
+                        if (!callback->eventDataPathTerminated(msg.ndp_instance_id[i]).isOk()) {
+                            LOG(ERROR) << "Failed to invoke the callback";
+                        }
+                    }
+                }
+            };
+
+    callback_handlers.on_event_beacon_sdf_payload =
+            [weak_ptr_this](const legacy_hal::NanBeaconSdfPayloadInd& /* msg */) {
+                LOG(ERROR) << "on_event_beacon_sdf_payload - should not be called";
+            };
+
+    callback_handlers.on_event_range_request =
+            [weak_ptr_this](const legacy_hal::NanRangeRequestInd& /* msg */) {
+                LOG(ERROR) << "on_event_range_request - should not be called";
+            };
+
+    callback_handlers.on_event_range_report =
+            [weak_ptr_this](const legacy_hal::NanRangeReportInd& /* msg */) {
+                LOG(ERROR) << "on_event_range_report - should not be called";
+            };
+
+    callback_handlers.on_event_schedule_update =
+            [weak_ptr_this](const legacy_hal::NanDataPathScheduleUpdateInd& msg) {
+                const auto shared_ptr_this = weak_ptr_this.promote();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                V1_2::NanDataPathScheduleUpdateInd hidl_struct;
+                if (!hidl_struct_util::convertLegacyNanDataPathScheduleUpdateIndToHidl(
+                            msg, &hidl_struct)) {
+                    LOG(ERROR) << "Failed to convert nan capabilities response";
+                    return;
+                }
+
+                for (const auto& callback : shared_ptr_this->getEventCallbacks_1_2()) {
+                    if (!callback->eventDataPathScheduleUpdate(hidl_struct).isOk()) {
+                        LOG(ERROR) << "Failed to invoke the callback";
+                    }
+                }
+            };
+
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanRegisterCallbackHandlers(ifname_, callback_handlers);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        LOG(ERROR) << "Failed to register nan callbacks. Invalidating object";
+        invalidate();
+    }
+
+    // Register for iface state toggle events.
+    iface_util::IfaceEventHandlers event_handlers = {};
+    event_handlers.on_state_toggle_off_on = [weak_ptr_this](const std::string& /* iface_name */) {
+        const auto shared_ptr_this = weak_ptr_this.promote();
+        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+            LOG(ERROR) << "Callback invoked on an invalid object";
+            return;
+        }
+        // Tell framework that NAN has been disabled.
+        WifiNanStatus status = {NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""};
+        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+            if (!callback->eventDisabled(status).isOk()) {
+                LOG(ERROR) << "Failed to invoke the callback";
+            }
+        }
+    };
+    iface_util_.lock()->registerIfaceEventHandlers(ifname_, event_handlers);
+}
+
+void WifiNanIface::invalidate() {
+    if (!isValid()) {
+        return;
+    }
+    // send commands to HAL to actually disable and destroy interfaces
+    legacy_hal_.lock()->nanDisableRequest(ifname_, 0xFFFF);
+    legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFE, "aware_data0");
+    legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFD, "aware_data1");
+    iface_util_.lock()->unregisterIfaceEventHandlers(ifname_);
+    legacy_hal_.reset();
+    event_cb_handler_.invalidate();
+    event_cb_handler_1_2_.invalidate();
+    event_cb_handler_1_5_.invalidate();
+    is_valid_ = false;
+    if (is_dedicated_iface_) {
+        // If using a dedicated iface, set the iface down.
+        iface_util_.lock()->setUpState(ifname_, false);
+    }
+}
+
+bool WifiNanIface::isValid() {
+    return is_valid_;
+}
+
+std::string WifiNanIface::getName() {
+    return ifname_;
+}
+
+std::set<sp<V1_0::IWifiNanIfaceEventCallback>> WifiNanIface::getEventCallbacks() {
+    return event_cb_handler_.getCallbacks();
+}
+
+std::set<sp<V1_2::IWifiNanIfaceEventCallback>> WifiNanIface::getEventCallbacks_1_2() {
+    return event_cb_handler_1_2_.getCallbacks();
+}
+
+std::set<sp<V1_5::IWifiNanIfaceEventCallback>> WifiNanIface::getEventCallbacks_1_5() {
+    return event_cb_handler_1_5_.getCallbacks();
+}
+
+Return<void> WifiNanIface::getName(getName_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::getNameInternal, hidl_status_cb);
+}
+
+Return<void> WifiNanIface::getType(getType_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::getTypeInternal, hidl_status_cb);
+}
+
+Return<void> WifiNanIface::registerEventCallback(
+        const sp<V1_0::IWifiNanIfaceEventCallback>& callback,
+        registerEventCallback_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::registerEventCallbackInternal, hidl_status_cb, callback);
+}
+
+Return<void> WifiNanIface::getCapabilitiesRequest(uint16_t cmd_id,
+                                                  getCapabilitiesRequest_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::getCapabilitiesRequestInternal, hidl_status_cb, cmd_id);
+}
+
+Return<void> WifiNanIface::enableRequest(uint16_t cmd_id, const V1_0::NanEnableRequest& msg,
+                                         enableRequest_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::enableRequestInternal, hidl_status_cb, cmd_id, msg);
+}
+
+Return<void> WifiNanIface::configRequest(uint16_t cmd_id, const V1_0::NanConfigRequest& msg,
+                                         configRequest_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::configRequestInternal, hidl_status_cb, cmd_id, msg);
+}
+
+Return<void> WifiNanIface::disableRequest(uint16_t cmd_id, disableRequest_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::disableRequestInternal, hidl_status_cb, cmd_id);
+}
+
+Return<void> WifiNanIface::startPublishRequest(uint16_t cmd_id, const NanPublishRequest& msg,
+                                               startPublishRequest_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::startPublishRequestInternal, hidl_status_cb, cmd_id, msg);
+}
+
+Return<void> WifiNanIface::stopPublishRequest(uint16_t cmd_id, uint8_t sessionId,
+                                              stopPublishRequest_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::stopPublishRequestInternal, hidl_status_cb, cmd_id,
+                           sessionId);
+}
+
+Return<void> WifiNanIface::startSubscribeRequest(uint16_t cmd_id, const NanSubscribeRequest& msg,
+                                                 startSubscribeRequest_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::startSubscribeRequestInternal, hidl_status_cb, cmd_id,
+                           msg);
+}
+
+Return<void> WifiNanIface::stopSubscribeRequest(uint16_t cmd_id, uint8_t sessionId,
+                                                stopSubscribeRequest_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::stopSubscribeRequestInternal, hidl_status_cb, cmd_id,
+                           sessionId);
+}
+
+Return<void> WifiNanIface::transmitFollowupRequest(uint16_t cmd_id,
+                                                   const NanTransmitFollowupRequest& msg,
+                                                   transmitFollowupRequest_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::transmitFollowupRequestInternal, hidl_status_cb, cmd_id,
+                           msg);
+}
+
+Return<void> WifiNanIface::createDataInterfaceRequest(
+        uint16_t cmd_id, const hidl_string& iface_name,
+        createDataInterfaceRequest_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::createDataInterfaceRequestInternal, hidl_status_cb,
+                           cmd_id, iface_name);
+}
+
+Return<void> WifiNanIface::deleteDataInterfaceRequest(
+        uint16_t cmd_id, const hidl_string& iface_name,
+        deleteDataInterfaceRequest_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::deleteDataInterfaceRequestInternal, hidl_status_cb,
+                           cmd_id, iface_name);
+}
+
+Return<void> WifiNanIface::initiateDataPathRequest(uint16_t cmd_id,
+                                                   const NanInitiateDataPathRequest& msg,
+                                                   initiateDataPathRequest_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::initiateDataPathRequestInternal, hidl_status_cb, cmd_id,
+                           msg);
+}
+
+Return<void> WifiNanIface::respondToDataPathIndicationRequest(
+        uint16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg,
+        respondToDataPathIndicationRequest_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::respondToDataPathIndicationRequestInternal,
+                           hidl_status_cb, cmd_id, msg);
+}
+
+Return<void> WifiNanIface::terminateDataPathRequest(uint16_t cmd_id, uint32_t ndpInstanceId,
+                                                    terminateDataPathRequest_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::terminateDataPathRequestInternal, hidl_status_cb, cmd_id,
+                           ndpInstanceId);
+}
+
+Return<void> WifiNanIface::registerEventCallback_1_2(
+        const sp<V1_2::IWifiNanIfaceEventCallback>& callback,
+        registerEventCallback_1_2_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::registerEventCallback_1_2Internal, hidl_status_cb,
+                           callback);
+}
+
+Return<void> WifiNanIface::enableRequest_1_2(uint16_t cmd_id, const V1_0::NanEnableRequest& msg1,
+                                             const V1_2::NanConfigRequestSupplemental& msg2,
+                                             enableRequest_1_2_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::enableRequest_1_2Internal, hidl_status_cb, cmd_id, msg1,
+                           msg2);
+}
+
+Return<void> WifiNanIface::configRequest_1_2(uint16_t cmd_id, const V1_0::NanConfigRequest& msg1,
+                                             const V1_2::NanConfigRequestSupplemental& msg2,
+                                             configRequest_1_2_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::configRequest_1_2Internal, hidl_status_cb, cmd_id, msg1,
+                           msg2);
+}
+
+Return<void> WifiNanIface::enableRequest_1_4(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
+                                             const V1_2::NanConfigRequestSupplemental& msg2,
+                                             enableRequest_1_4_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::enableRequest_1_4Internal, hidl_status_cb, cmd_id, msg1,
+                           msg2);
+}
+
+Return<void> WifiNanIface::configRequest_1_4(uint16_t cmd_id, const V1_4::NanConfigRequest& msg1,
+                                             const V1_2::NanConfigRequestSupplemental& msg2,
+                                             configRequest_1_4_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::configRequest_1_4Internal, hidl_status_cb, cmd_id, msg1,
+                           msg2);
+}
+
+Return<void> WifiNanIface::registerEventCallback_1_5(
+        const sp<V1_5::IWifiNanIfaceEventCallback>& callback,
+        registerEventCallback_1_5_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::registerEventCallback_1_5Internal, hidl_status_cb,
+                           callback);
+}
+
+Return<void> WifiNanIface::enableRequest_1_5(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
+                                             const V1_5::NanConfigRequestSupplemental& msg2,
+                                             enableRequest_1_5_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::enableRequest_1_5Internal, hidl_status_cb, cmd_id, msg1,
+                           msg2);
+}
+
+Return<void> WifiNanIface::configRequest_1_5(uint16_t cmd_id, const V1_4::NanConfigRequest& msg1,
+                                             const V1_5::NanConfigRequestSupplemental& msg2,
+                                             configRequest_1_5_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::configRequest_1_5Internal, hidl_status_cb, cmd_id, msg1,
+                           msg2);
+}
+
+Return<void> WifiNanIface::getCapabilitiesRequest_1_5(
+        uint16_t cmd_id, getCapabilitiesRequest_1_5_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiNanIface::getCapabilitiesRequest_1_5Internal, hidl_status_cb,
+                           cmd_id);
+}
+
+std::pair<WifiStatus, std::string> WifiNanIface::getNameInternal() {
+    return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_};
+}
+
+std::pair<WifiStatus, IfaceType> WifiNanIface::getTypeInternal() {
+    return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::NAN};
+}
+
+WifiStatus WifiNanIface::registerEventCallbackInternal(
+        const sp<V1_0::IWifiNanIfaceEventCallback>& callback) {
+    if (!event_cb_handler_.addCallback(callback)) {
+        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+    }
+    return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+WifiStatus WifiNanIface::getCapabilitiesRequestInternal(uint16_t /* cmd_id */) {
+    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiNanIface::enableRequestInternal(uint16_t /* cmd_id */,
+                                               const V1_0::NanEnableRequest& /* msg */) {
+    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiNanIface::configRequestInternal(uint16_t /* cmd_id */,
+                                               const V1_0::NanConfigRequest& /* msg */) {
+    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiNanIface::disableRequestInternal(uint16_t cmd_id) {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->nanDisableRequest(ifname_, cmd_id);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiNanIface::startPublishRequestInternal(uint16_t cmd_id,
+                                                     const NanPublishRequest& msg) {
+    legacy_hal::NanPublishRequest legacy_msg;
+    if (!hidl_struct_util::convertHidlNanPublishRequestToLegacy(msg, &legacy_msg)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanPublishRequest(ifname_, cmd_id, legacy_msg);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiNanIface::stopPublishRequestInternal(uint16_t cmd_id, uint8_t sessionId) {
+    legacy_hal::NanPublishCancelRequest legacy_msg;
+    legacy_msg.publish_id = sessionId;
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanPublishCancelRequest(ifname_, cmd_id, legacy_msg);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiNanIface::startSubscribeRequestInternal(uint16_t cmd_id,
+                                                       const NanSubscribeRequest& msg) {
+    legacy_hal::NanSubscribeRequest legacy_msg;
+    if (!hidl_struct_util::convertHidlNanSubscribeRequestToLegacy(msg, &legacy_msg)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanSubscribeRequest(ifname_, cmd_id, legacy_msg);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiNanIface::stopSubscribeRequestInternal(uint16_t cmd_id, uint8_t sessionId) {
+    legacy_hal::NanSubscribeCancelRequest legacy_msg;
+    legacy_msg.subscribe_id = sessionId;
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanSubscribeCancelRequest(ifname_, cmd_id, legacy_msg);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiNanIface::transmitFollowupRequestInternal(uint16_t cmd_id,
+                                                         const NanTransmitFollowupRequest& msg) {
+    legacy_hal::NanTransmitFollowupRequest legacy_msg;
+    if (!hidl_struct_util::convertHidlNanTransmitFollowupRequestToLegacy(msg, &legacy_msg)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanTransmitFollowupRequest(ifname_, cmd_id, legacy_msg);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiNanIface::createDataInterfaceRequestInternal(uint16_t cmd_id,
+                                                            const std::string& iface_name) {
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanDataInterfaceCreate(ifname_, cmd_id, iface_name);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+WifiStatus WifiNanIface::deleteDataInterfaceRequestInternal(uint16_t cmd_id,
+                                                            const std::string& iface_name) {
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, cmd_id, iface_name);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+WifiStatus WifiNanIface::initiateDataPathRequestInternal(uint16_t cmd_id,
+                                                         const NanInitiateDataPathRequest& msg) {
+    legacy_hal::NanDataPathInitiatorRequest legacy_msg;
+    if (!hidl_struct_util::convertHidlNanDataPathInitiatorRequestToLegacy(msg, &legacy_msg)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanDataRequestInitiator(ifname_, cmd_id, legacy_msg);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+WifiStatus WifiNanIface::respondToDataPathIndicationRequestInternal(
+        uint16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg) {
+    legacy_hal::NanDataPathIndicationResponse legacy_msg;
+    if (!hidl_struct_util::convertHidlNanDataPathIndicationResponseToLegacy(msg, &legacy_msg)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanDataIndicationResponse(ifname_, cmd_id, legacy_msg);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+WifiStatus WifiNanIface::terminateDataPathRequestInternal(uint16_t cmd_id, uint32_t ndpInstanceId) {
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanDataEnd(ifname_, cmd_id, ndpInstanceId);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiNanIface::registerEventCallback_1_2Internal(
+        const sp<V1_2::IWifiNanIfaceEventCallback>& callback) {
+    sp<V1_0::IWifiNanIfaceEventCallback> callback_1_0 = callback;
+    if (!event_cb_handler_.addCallback(callback_1_0)) {
+        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+    }
+    if (!event_cb_handler_1_2_.addCallback(callback)) {
+        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+    }
+    return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+WifiStatus WifiNanIface::enableRequest_1_2Internal(
+        uint16_t /* cmd_id */, const V1_0::NanEnableRequest& /* msg1 */,
+        const V1_2::NanConfigRequestSupplemental& /* msg2 */) {
+    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiNanIface::configRequest_1_2Internal(
+        uint16_t /* cmd_id */, const V1_0::NanConfigRequest& /* msg1 */,
+        const V1_2::NanConfigRequestSupplemental& /* msg2 */) {
+    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiNanIface::enableRequest_1_4Internal(
+        uint16_t /* cmd_id */, const V1_4::NanEnableRequest& /* msg1 */,
+        const V1_2::NanConfigRequestSupplemental& /* msg2 */) {
+    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiNanIface::configRequest_1_4Internal(
+        uint16_t /* cmd_id */, const V1_4::NanConfigRequest& /* msg1 */,
+        const V1_2::NanConfigRequestSupplemental& /* msg2 */) {
+    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiNanIface::registerEventCallback_1_5Internal(
+        const sp<V1_5::IWifiNanIfaceEventCallback>& callback) {
+    sp<V1_0::IWifiNanIfaceEventCallback> callback_1_0 = callback;
+    if (!event_cb_handler_.addCallback(callback_1_0)) {
+        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+    }
+    sp<V1_2::IWifiNanIfaceEventCallback> callback_1_2 = callback;
+    if (!event_cb_handler_1_2_.addCallback(callback_1_2)) {
+        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+    }
+    if (!event_cb_handler_1_5_.addCallback(callback)) {
+        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+    }
+    return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+WifiStatus WifiNanIface::getCapabilitiesRequest_1_5Internal(uint16_t cmd_id) {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->nanGetCapabilities(ifname_, cmd_id);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiNanIface::enableRequest_1_5Internal(uint16_t cmd_id,
+                                                   const V1_4::NanEnableRequest& msg1,
+                                                   const V1_5::NanConfigRequestSupplemental& msg2) {
+    legacy_hal::NanEnableRequest legacy_msg;
+    if (!hidl_struct_util::convertHidlNanEnableRequest_1_5ToLegacy(msg1, msg2, &legacy_msg)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanEnableRequest(ifname_, cmd_id, legacy_msg);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiNanIface::configRequest_1_5Internal(uint16_t cmd_id,
+                                                   const V1_4::NanConfigRequest& msg1,
+                                                   const V1_5::NanConfigRequestSupplemental& msg2) {
+    legacy_hal::NanConfigRequest legacy_msg;
+    if (!hidl_struct_util::convertHidlNanConfigRequest_1_5ToLegacy(msg1, msg2, &legacy_msg)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->nanConfigRequest(ifname_, cmd_id, legacy_msg);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+}  // namespace implementation
+}  // namespace V1_6
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
diff --git a/wifi/1.6/default/wifi_nan_iface.h b/wifi/1.6/default/wifi_nan_iface.h
new file mode 100644
index 0000000..c445afc
--- /dev/null
+++ b/wifi/1.6/default/wifi_nan_iface.h
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 WIFI_NAN_IFACE_H_
+#define WIFI_NAN_IFACE_H_
+
+#include <android-base/macros.h>
+#include <android/hardware/wifi/1.5/IWifiNanIface.h>
+#include <android/hardware/wifi/1.5/IWifiNanIfaceEventCallback.h>
+
+#include "hidl_callback_util.h"
+#include "wifi_iface_util.h"
+#include "wifi_legacy_hal.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+using namespace android::hardware::wifi::V1_0;
+using namespace android::hardware::wifi::V1_2;
+
+/**
+ * HIDL interface object used to control a NAN Iface instance.
+ */
+class WifiNanIface : public V1_5::IWifiNanIface {
+  public:
+    WifiNanIface(const std::string& ifname, bool is_dedicated_iface,
+                 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+                 const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
+    // Refer to |WifiChip::invalidate()|.
+    void invalidate();
+    bool isValid();
+    std::string getName();
+
+    // HIDL methods exposed.
+    Return<void> getName(getName_cb hidl_status_cb) override;
+    Return<void> getType(getType_cb hidl_status_cb) override;
+    Return<void> registerEventCallback(const sp<V1_0::IWifiNanIfaceEventCallback>& callback,
+                                       registerEventCallback_cb hidl_status_cb) override;
+    Return<void> getCapabilitiesRequest(uint16_t cmd_id,
+                                        getCapabilitiesRequest_cb hidl_status_cb) override;
+    Return<void> enableRequest(uint16_t cmd_id, const V1_0::NanEnableRequest& msg,
+                               enableRequest_cb hidl_status_cb) override;
+    Return<void> configRequest(uint16_t cmd_id, const V1_0::NanConfigRequest& msg,
+                               configRequest_cb hidl_status_cb) override;
+    Return<void> disableRequest(uint16_t cmd_id, disableRequest_cb hidl_status_cb) override;
+    Return<void> startPublishRequest(uint16_t cmd_id, const NanPublishRequest& msg,
+                                     startPublishRequest_cb hidl_status_cb) override;
+    Return<void> stopPublishRequest(uint16_t cmd_id, uint8_t sessionId,
+                                    stopPublishRequest_cb hidl_status_cb) override;
+    Return<void> startSubscribeRequest(uint16_t cmd_id, const NanSubscribeRequest& msg,
+                                       startSubscribeRequest_cb hidl_status_cb) override;
+    Return<void> stopSubscribeRequest(uint16_t cmd_id, uint8_t sessionId,
+                                      stopSubscribeRequest_cb hidl_status_cb) override;
+    Return<void> transmitFollowupRequest(uint16_t cmd_id, const NanTransmitFollowupRequest& msg,
+                                         transmitFollowupRequest_cb hidl_status_cb) override;
+    Return<void> createDataInterfaceRequest(uint16_t cmd_id, const hidl_string& iface_name,
+                                            createDataInterfaceRequest_cb hidl_status_cb) override;
+    Return<void> deleteDataInterfaceRequest(uint16_t cmd_id, const hidl_string& iface_name,
+                                            deleteDataInterfaceRequest_cb hidl_status_cb) override;
+    Return<void> initiateDataPathRequest(uint16_t cmd_id, const NanInitiateDataPathRequest& msg,
+                                         initiateDataPathRequest_cb hidl_status_cb) override;
+    Return<void> respondToDataPathIndicationRequest(
+            uint16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg,
+            respondToDataPathIndicationRequest_cb hidl_status_cb) override;
+    Return<void> terminateDataPathRequest(uint16_t cmd_id, uint32_t ndpInstanceId,
+                                          terminateDataPathRequest_cb hidl_status_cb) override;
+
+    Return<void> registerEventCallback_1_2(const sp<V1_2::IWifiNanIfaceEventCallback>& callback,
+                                           registerEventCallback_1_2_cb hidl_status_cb) override;
+    Return<void> enableRequest_1_2(uint16_t cmd_id, const V1_0::NanEnableRequest& msg1,
+                                   const V1_2::NanConfigRequestSupplemental& msg2,
+                                   enableRequest_1_2_cb hidl_status_cb) override;
+    Return<void> configRequest_1_2(uint16_t cmd_id, const V1_0::NanConfigRequest& msg1,
+                                   const V1_2::NanConfigRequestSupplemental& msg2,
+                                   configRequest_1_2_cb hidl_status_cb) override;
+    Return<void> enableRequest_1_4(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
+                                   const V1_2::NanConfigRequestSupplemental& msg2,
+                                   enableRequest_1_4_cb hidl_status_cb) override;
+    Return<void> configRequest_1_4(uint16_t cmd_id, const V1_4::NanConfigRequest& msg1,
+                                   const V1_2::NanConfigRequestSupplemental& msg2,
+                                   configRequest_1_4_cb hidl_status_cb) override;
+    Return<void> registerEventCallback_1_5(const sp<V1_5::IWifiNanIfaceEventCallback>& callback,
+                                           registerEventCallback_1_5_cb hidl_status_cb) override;
+    Return<void> enableRequest_1_5(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
+                                   const V1_5::NanConfigRequestSupplemental& msg2,
+                                   enableRequest_1_4_cb hidl_status_cb) override;
+    Return<void> configRequest_1_5(uint16_t cmd_id, const V1_4::NanConfigRequest& msg1,
+                                   const V1_5::NanConfigRequestSupplemental& msg2,
+                                   configRequest_1_4_cb hidl_status_cb) override;
+    Return<void> getCapabilitiesRequest_1_5(uint16_t cmd_id,
+                                            getCapabilitiesRequest_cb hidl_status_cb) override;
+
+  private:
+    // Corresponding worker functions for the HIDL methods.
+    std::pair<WifiStatus, std::string> getNameInternal();
+    std::pair<WifiStatus, IfaceType> getTypeInternal();
+    WifiStatus registerEventCallbackInternal(const sp<V1_0::IWifiNanIfaceEventCallback>& callback);
+    WifiStatus getCapabilitiesRequestInternal(uint16_t cmd_id);
+    WifiStatus enableRequestInternal(uint16_t cmd_id, const V1_0::NanEnableRequest& msg);
+    WifiStatus configRequestInternal(uint16_t cmd_id, const V1_0::NanConfigRequest& msg);
+    WifiStatus disableRequestInternal(uint16_t cmd_id);
+    WifiStatus startPublishRequestInternal(uint16_t cmd_id, const NanPublishRequest& msg);
+    WifiStatus stopPublishRequestInternal(uint16_t cmd_id, uint8_t sessionId);
+    WifiStatus startSubscribeRequestInternal(uint16_t cmd_id, const NanSubscribeRequest& msg);
+    WifiStatus stopSubscribeRequestInternal(uint16_t cmd_id, uint8_t sessionId);
+    WifiStatus transmitFollowupRequestInternal(uint16_t cmd_id,
+                                               const NanTransmitFollowupRequest& msg);
+    WifiStatus createDataInterfaceRequestInternal(uint16_t cmd_id, const std::string& iface_name);
+    WifiStatus deleteDataInterfaceRequestInternal(uint16_t cmd_id, const std::string& iface_name);
+    WifiStatus initiateDataPathRequestInternal(uint16_t cmd_id,
+                                               const NanInitiateDataPathRequest& msg);
+    WifiStatus respondToDataPathIndicationRequestInternal(
+            uint16_t cmd_id, const NanRespondToDataPathIndicationRequest& msg);
+    WifiStatus terminateDataPathRequestInternal(uint16_t cmd_id, uint32_t ndpInstanceId);
+
+    WifiStatus registerEventCallback_1_2Internal(
+            const sp<V1_2::IWifiNanIfaceEventCallback>& callback);
+    WifiStatus enableRequest_1_2Internal(uint16_t cmd_id, const V1_0::NanEnableRequest& msg1,
+                                         const V1_2::NanConfigRequestSupplemental& msg2);
+    WifiStatus configRequest_1_2Internal(uint16_t cmd_id, const V1_0::NanConfigRequest& msg,
+                                         const V1_2::NanConfigRequestSupplemental& msg2);
+    WifiStatus enableRequest_1_4Internal(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
+                                         const V1_2::NanConfigRequestSupplemental& msg2);
+    WifiStatus configRequest_1_4Internal(uint16_t cmd_id, const V1_4::NanConfigRequest& msg,
+                                         const V1_2::NanConfigRequestSupplemental& msg2);
+    WifiStatus registerEventCallback_1_5Internal(
+            const sp<V1_5::IWifiNanIfaceEventCallback>& callback);
+    WifiStatus enableRequest_1_5Internal(uint16_t cmd_id, const V1_4::NanEnableRequest& msg1,
+                                         const V1_5::NanConfigRequestSupplemental& msg2);
+    WifiStatus configRequest_1_5Internal(uint16_t cmd_id, const V1_4::NanConfigRequest& msg,
+                                         const V1_5::NanConfigRequestSupplemental& msg2);
+    WifiStatus getCapabilitiesRequest_1_5Internal(uint16_t cmd_id);
+
+    // all 1_0 and descendant callbacks
+    std::set<sp<V1_0::IWifiNanIfaceEventCallback>> getEventCallbacks();
+    // all 1_2 and descendant callbacks
+    std::set<sp<V1_2::IWifiNanIfaceEventCallback>> getEventCallbacks_1_2();
+    // all 1_5 and descendant callbacks
+    std::set<sp<V1_5::IWifiNanIfaceEventCallback>> getEventCallbacks_1_5();
+
+    std::string ifname_;
+    bool is_dedicated_iface_;
+    std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+    std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
+    bool is_valid_;
+    hidl_callback_util::HidlCallbackHandler<V1_0::IWifiNanIfaceEventCallback> event_cb_handler_;
+    hidl_callback_util::HidlCallbackHandler<V1_2::IWifiNanIfaceEventCallback> event_cb_handler_1_2_;
+    hidl_callback_util::HidlCallbackHandler<V1_5::IWifiNanIfaceEventCallback> event_cb_handler_1_5_;
+
+    DISALLOW_COPY_AND_ASSIGN(WifiNanIface);
+};
+
+}  // namespace implementation
+}  // namespace V1_6
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+
+#endif  // WIFI_NAN_IFACE_H_
diff --git a/wifi/1.5/default/wifi_p2p_iface.cpp b/wifi/1.6/default/wifi_p2p_iface.cpp
similarity index 86%
rename from wifi/1.5/default/wifi_p2p_iface.cpp
rename to wifi/1.6/default/wifi_p2p_iface.cpp
index b8893da..d4b1fca 100644
--- a/wifi/1.5/default/wifi_p2p_iface.cpp
+++ b/wifi/1.6/default/wifi_p2p_iface.cpp
@@ -23,13 +23,12 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 using hidl_return_util::validateAndCall;
 
-WifiP2pIface::WifiP2pIface(
-    const std::string& ifname,
-    const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
+WifiP2pIface::WifiP2pIface(const std::string& ifname,
+                           const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
     : ifname_(ifname), legacy_hal_(legacy_hal), is_valid_(true) {}
 
 void WifiP2pIface::invalidate() {
@@ -37,9 +36,13 @@
     is_valid_ = false;
 }
 
-bool WifiP2pIface::isValid() { return is_valid_; }
+bool WifiP2pIface::isValid() {
+    return is_valid_;
+}
 
-std::string WifiP2pIface::getName() { return ifname_; }
+std::string WifiP2pIface::getName() {
+    return ifname_;
+}
 
 Return<void> WifiP2pIface::getName(getName_cb hidl_status_cb) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
@@ -60,7 +63,7 @@
 }
 
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/wifi_p2p_iface.h b/wifi/1.6/default/wifi_p2p_iface.h
similarity index 96%
rename from wifi/1.5/default/wifi_p2p_iface.h
rename to wifi/1.6/default/wifi_p2p_iface.h
index c1adc50..0089443 100644
--- a/wifi/1.5/default/wifi_p2p_iface.h
+++ b/wifi/1.6/default/wifi_p2p_iface.h
@@ -25,7 +25,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 using namespace android::hardware::wifi::V1_0;
 
@@ -33,7 +33,7 @@
  * HIDL interface object used to control a P2P Iface instance.
  */
 class WifiP2pIface : public V1_0::IWifiP2pIface {
-   public:
+  public:
     WifiP2pIface(const std::string& ifname,
                  const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
     // Refer to |WifiChip::invalidate()|.
@@ -45,7 +45,7 @@
     Return<void> getName(getName_cb hidl_status_cb) override;
     Return<void> getType(getType_cb hidl_status_cb) override;
 
-   private:
+  private:
     // Corresponding worker functions for the HIDL methods.
     std::pair<WifiStatus, std::string> getNameInternal();
     std::pair<WifiStatus, IfaceType> getTypeInternal();
@@ -58,7 +58,7 @@
 };
 
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.6/default/wifi_rtt_controller.cpp b/wifi/1.6/default/wifi_rtt_controller.cpp
new file mode 100644
index 0000000..f5e1d5a
--- /dev/null
+++ b/wifi/1.6/default/wifi_rtt_controller.cpp
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "hidl_return_util.h"
+#include "hidl_struct_util.h"
+#include "wifi_rtt_controller.h"
+#include "wifi_status_util.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+using hidl_return_util::validateAndCall;
+
+WifiRttController::WifiRttController(const std::string& iface_name,
+                                     const sp<IWifiIface>& bound_iface,
+                                     const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
+    : ifname_(iface_name), bound_iface_(bound_iface), legacy_hal_(legacy_hal), is_valid_(true) {}
+
+void WifiRttController::invalidate() {
+    legacy_hal_.reset();
+    event_callbacks_.clear();
+    is_valid_ = false;
+}
+
+bool WifiRttController::isValid() {
+    return is_valid_;
+}
+
+std::vector<sp<V1_4::IWifiRttControllerEventCallback>> WifiRttController::getEventCallbacks() {
+    return event_callbacks_;
+}
+
+std::string WifiRttController::getIfaceName() {
+    return ifname_;
+}
+
+Return<void> WifiRttController::getBoundIface(getBoundIface_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::getBoundIfaceInternal, hidl_status_cb);
+}
+
+Return<void> WifiRttController::registerEventCallback(
+        const sp<V1_0::IWifiRttControllerEventCallback>& callback,
+        registerEventCallback_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::registerEventCallbackInternal, hidl_status_cb,
+                           callback);
+}
+
+Return<void> WifiRttController::rangeRequest(uint32_t cmd_id,
+                                             const hidl_vec<V1_0::RttConfig>& rtt_configs,
+                                             rangeRequest_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::rangeRequestInternal, hidl_status_cb, cmd_id,
+                           rtt_configs);
+}
+
+Return<void> WifiRttController::rangeCancel(uint32_t cmd_id,
+                                            const hidl_vec<hidl_array<uint8_t, 6>>& addrs,
+                                            rangeCancel_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::rangeCancelInternal, hidl_status_cb, cmd_id, addrs);
+}
+
+Return<void> WifiRttController::getCapabilities(getCapabilities_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::getCapabilitiesInternal, hidl_status_cb);
+}
+
+Return<void> WifiRttController::setLci(uint32_t cmd_id, const RttLciInformation& lci,
+                                       setLci_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::setLciInternal, hidl_status_cb, cmd_id, lci);
+}
+
+Return<void> WifiRttController::setLcr(uint32_t cmd_id, const RttLcrInformation& lcr,
+                                       setLcr_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::setLcrInternal, hidl_status_cb, cmd_id, lcr);
+}
+
+Return<void> WifiRttController::getResponderInfo(getResponderInfo_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::getResponderInfoInternal, hidl_status_cb);
+}
+
+Return<void> WifiRttController::enableResponder(uint32_t cmd_id,
+                                                const WifiChannelInfo& channel_hint,
+                                                uint32_t max_duration_seconds,
+                                                const V1_0::RttResponder& info,
+                                                enableResponder_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::enableResponderInternal, hidl_status_cb, cmd_id,
+                           channel_hint, max_duration_seconds, info);
+}
+
+Return<void> WifiRttController::disableResponder(uint32_t cmd_id,
+                                                 disableResponder_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::disableResponderInternal, hidl_status_cb, cmd_id);
+}
+
+Return<void> WifiRttController::registerEventCallback_1_4(
+        const sp<V1_4::IWifiRttControllerEventCallback>& callback,
+        registerEventCallback_1_4_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::registerEventCallbackInternal_1_4, hidl_status_cb,
+                           callback);
+}
+
+Return<void> WifiRttController::rangeRequest_1_4(uint32_t cmd_id,
+                                                 const hidl_vec<V1_4::RttConfig>& rtt_configs,
+                                                 rangeRequest_1_4_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::rangeRequestInternal_1_4, hidl_status_cb, cmd_id,
+                           rtt_configs);
+}
+
+Return<void> WifiRttController::getCapabilities_1_4(getCapabilities_1_4_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::getCapabilitiesInternal_1_4, hidl_status_cb);
+}
+
+Return<void> WifiRttController::getResponderInfo_1_4(getResponderInfo_1_4_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::getResponderInfoInternal_1_4, hidl_status_cb);
+}
+
+Return<void> WifiRttController::enableResponder_1_4(uint32_t cmd_id,
+                                                    const WifiChannelInfo& channel_hint,
+                                                    uint32_t max_duration_seconds,
+                                                    const V1_4::RttResponder& info,
+                                                    enableResponder_1_4_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::enableResponderInternal_1_4, hidl_status_cb, cmd_id,
+                           channel_hint, max_duration_seconds, info);
+}
+
+std::pair<WifiStatus, sp<IWifiIface>> WifiRttController::getBoundIfaceInternal() {
+    return {createWifiStatus(WifiStatusCode::SUCCESS), bound_iface_};
+}
+
+WifiStatus WifiRttController::registerEventCallbackInternal(
+        const sp<V1_0::IWifiRttControllerEventCallback>& /* callback */) {
+    // Deprecated support for this api
+    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiRttController::rangeRequestInternal(
+        uint32_t /* cmd_id */, const std::vector<V1_0::RttConfig>& /* rtt_configs */) {
+    // Deprecated support for this api
+    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiRttController::rangeCancelInternal(
+        uint32_t cmd_id, const std::vector<hidl_array<uint8_t, 6>>& addrs) {
+    std::vector<std::array<uint8_t, 6>> legacy_addrs;
+    for (const auto& addr : addrs) {
+        legacy_addrs.push_back(addr);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->cancelRttRangeRequest(ifname_, cmd_id, legacy_addrs);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<WifiStatus, V1_0::RttCapabilities> WifiRttController::getCapabilitiesInternal() {
+    // Deprecated support for this api
+    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
+}
+
+WifiStatus WifiRttController::setLciInternal(uint32_t cmd_id, const RttLciInformation& lci) {
+    legacy_hal::wifi_lci_information legacy_lci;
+    if (!hidl_struct_util::convertHidlRttLciInformationToLegacy(lci, &legacy_lci)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->setRttLci(ifname_, cmd_id, legacy_lci);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiRttController::setLcrInternal(uint32_t cmd_id, const RttLcrInformation& lcr) {
+    legacy_hal::wifi_lcr_information legacy_lcr;
+    if (!hidl_struct_util::convertHidlRttLcrInformationToLegacy(lcr, &legacy_lcr)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->setRttLcr(ifname_, cmd_id, legacy_lcr);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<WifiStatus, V1_0::RttResponder> WifiRttController::getResponderInfoInternal() {
+    // Deprecated support for this api
+    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
+}
+
+WifiStatus WifiRttController::enableResponderInternal(uint32_t /* cmd_id */,
+                                                      const WifiChannelInfo& /* channel_hint */,
+                                                      uint32_t /* max_duration_seconds */,
+                                                      const V1_0::RttResponder& /* info */) {
+    // Deprecated support for this api
+    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED)};
+}
+
+WifiStatus WifiRttController::disableResponderInternal(uint32_t cmd_id) {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->disableRttResponder(ifname_, cmd_id);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiRttController::registerEventCallbackInternal_1_4(
+        const sp<V1_4::IWifiRttControllerEventCallback>& callback) {
+    // TODO(b/31632518): remove the callback when the client is destroyed
+    event_callbacks_.emplace_back(callback);
+    return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+WifiStatus WifiRttController::rangeRequestInternal_1_4(
+        uint32_t cmd_id, const std::vector<V1_4::RttConfig>& rtt_configs) {
+    std::vector<legacy_hal::wifi_rtt_config> legacy_configs;
+    if (!hidl_struct_util::convertHidlVectorOfRttConfigToLegacy(rtt_configs, &legacy_configs)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    android::wp<WifiRttController> weak_ptr_this(this);
+    const auto& on_results_callback =
+            [weak_ptr_this](legacy_hal::wifi_request_id id,
+                            const std::vector<const legacy_hal::wifi_rtt_result*>& results) {
+                const auto shared_ptr_this = weak_ptr_this.promote();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                std::vector<V1_4::RttResult> hidl_results;
+                if (!hidl_struct_util::convertLegacyVectorOfRttResultToHidl(results,
+                                                                            &hidl_results)) {
+                    LOG(ERROR) << "Failed to convert rtt results to HIDL structs";
+                    return;
+                }
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    callback->onResults_1_4(id, hidl_results);
+                }
+            };
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRttRangeRequest(
+            ifname_, cmd_id, legacy_configs, on_results_callback);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<WifiStatus, V1_4::RttCapabilities> WifiRttController::getCapabilitiesInternal_1_4() {
+    legacy_hal::wifi_error legacy_status;
+    legacy_hal::wifi_rtt_capabilities legacy_caps;
+    std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getRttCapabilities(ifname_);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {createWifiStatusFromLegacyError(legacy_status), {}};
+    }
+    V1_4::RttCapabilities hidl_caps;
+    if (!hidl_struct_util::convertLegacyRttCapabilitiesToHidl(legacy_caps, &hidl_caps)) {
+        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
+    }
+    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
+}
+
+std::pair<WifiStatus, V1_4::RttResponder> WifiRttController::getResponderInfoInternal_1_4() {
+    legacy_hal::wifi_error legacy_status;
+    legacy_hal::wifi_rtt_responder legacy_responder;
+    std::tie(legacy_status, legacy_responder) = legacy_hal_.lock()->getRttResponderInfo(ifname_);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {createWifiStatusFromLegacyError(legacy_status), {}};
+    }
+    V1_4::RttResponder hidl_responder;
+    if (!hidl_struct_util::convertLegacyRttResponderToHidl(legacy_responder, &hidl_responder)) {
+        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
+    }
+    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_responder};
+}
+
+WifiStatus WifiRttController::enableResponderInternal_1_4(uint32_t cmd_id,
+                                                          const WifiChannelInfo& channel_hint,
+                                                          uint32_t max_duration_seconds,
+                                                          const V1_4::RttResponder& info) {
+    legacy_hal::wifi_channel_info legacy_channel_info;
+    if (!hidl_struct_util::convertHidlWifiChannelInfoToLegacy(channel_hint, &legacy_channel_info)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_rtt_responder legacy_responder;
+    if (!hidl_struct_util::convertHidlRttResponderToLegacy(info, &legacy_responder)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableRttResponder(
+            ifname_, cmd_id, legacy_channel_info, max_duration_seconds, legacy_responder);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+}  // namespace implementation
+}  // namespace V1_6
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
diff --git a/wifi/1.6/default/wifi_rtt_controller.h b/wifi/1.6/default/wifi_rtt_controller.h
new file mode 100644
index 0000000..b4a2116
--- /dev/null
+++ b/wifi/1.6/default/wifi_rtt_controller.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 WIFI_RTT_CONTROLLER_H_
+#define WIFI_RTT_CONTROLLER_H_
+
+#include <android-base/macros.h>
+#include <android/hardware/wifi/1.0/IWifiIface.h>
+#include <android/hardware/wifi/1.4/IWifiRttController.h>
+#include <android/hardware/wifi/1.4/IWifiRttControllerEventCallback.h>
+
+#include "wifi_legacy_hal.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+
+/**
+ * HIDL interface object used to control all RTT operations.
+ */
+class WifiRttController : public V1_4::IWifiRttController {
+  public:
+    WifiRttController(const std::string& iface_name, const sp<IWifiIface>& bound_iface,
+                      const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
+    // Refer to |WifiChip::invalidate()|.
+    void invalidate();
+    bool isValid();
+    std::vector<sp<V1_4::IWifiRttControllerEventCallback>> getEventCallbacks();
+    std::string getIfaceName();
+
+    // HIDL methods exposed.
+    Return<void> getBoundIface(getBoundIface_cb hidl_status_cb) override;
+    Return<void> registerEventCallback(const sp<V1_0::IWifiRttControllerEventCallback>& callback,
+                                       registerEventCallback_cb hidl_status_cb) override;
+    Return<void> rangeRequest(uint32_t cmd_id, const hidl_vec<V1_0::RttConfig>& rtt_configs,
+                              rangeRequest_cb hidl_status_cb) override;
+    Return<void> rangeCancel(uint32_t cmd_id, const hidl_vec<hidl_array<uint8_t, 6>>& addrs,
+                             rangeCancel_cb hidl_status_cb) override;
+    Return<void> getCapabilities(getCapabilities_cb hidl_status_cb) override;
+    Return<void> setLci(uint32_t cmd_id, const RttLciInformation& lci,
+                        setLci_cb hidl_status_cb) override;
+    Return<void> setLcr(uint32_t cmd_id, const RttLcrInformation& lcr,
+                        setLcr_cb hidl_status_cb) override;
+    Return<void> getResponderInfo(getResponderInfo_cb hidl_status_cb) override;
+    Return<void> enableResponder(uint32_t cmd_id, const WifiChannelInfo& channel_hint,
+                                 uint32_t max_duration_seconds, const V1_0::RttResponder& info,
+                                 enableResponder_cb hidl_status_cb) override;
+    Return<void> disableResponder(uint32_t cmd_id, disableResponder_cb hidl_status_cb) override;
+    Return<void> registerEventCallback_1_4(
+            const sp<V1_4::IWifiRttControllerEventCallback>& callback,
+            registerEventCallback_1_4_cb hidl_status_cb) override;
+    Return<void> rangeRequest_1_4(uint32_t cmd_id, const hidl_vec<V1_4::RttConfig>& rtt_configs,
+                                  rangeRequest_1_4_cb hidl_status_cb) override;
+    Return<void> getCapabilities_1_4(getCapabilities_1_4_cb hidl_status_cb) override;
+    Return<void> getResponderInfo_1_4(getResponderInfo_1_4_cb hidl_status_cb) override;
+    Return<void> enableResponder_1_4(uint32_t cmd_id, const WifiChannelInfo& channel_hint,
+                                     uint32_t max_duration_seconds, const V1_4::RttResponder& info,
+                                     enableResponder_1_4_cb hidl_status_cb) override;
+
+  private:
+    // Corresponding worker functions for the HIDL methods.
+    std::pair<WifiStatus, sp<IWifiIface>> getBoundIfaceInternal();
+    WifiStatus registerEventCallbackInternal(
+            const sp<V1_0::IWifiRttControllerEventCallback>& callback);
+    WifiStatus rangeRequestInternal(uint32_t cmd_id,
+                                    const std::vector<V1_0::RttConfig>& rtt_configs);
+    WifiStatus rangeCancelInternal(uint32_t cmd_id,
+                                   const std::vector<hidl_array<uint8_t, 6>>& addrs);
+    std::pair<WifiStatus, V1_0::RttCapabilities> getCapabilitiesInternal();
+    WifiStatus setLciInternal(uint32_t cmd_id, const RttLciInformation& lci);
+    WifiStatus setLcrInternal(uint32_t cmd_id, const RttLcrInformation& lcr);
+    std::pair<WifiStatus, V1_0::RttResponder> getResponderInfoInternal();
+    WifiStatus enableResponderInternal(uint32_t cmd_id, const WifiChannelInfo& channel_hint,
+                                       uint32_t max_duration_seconds,
+                                       const V1_0::RttResponder& info);
+    WifiStatus disableResponderInternal(uint32_t cmd_id);
+    WifiStatus registerEventCallbackInternal_1_4(
+            const sp<V1_4::IWifiRttControllerEventCallback>& callback);
+    WifiStatus rangeRequestInternal_1_4(uint32_t cmd_id,
+                                        const std::vector<V1_4::RttConfig>& rtt_configs);
+    std::pair<WifiStatus, V1_4::RttCapabilities> getCapabilitiesInternal_1_4();
+    std::pair<WifiStatus, V1_4::RttResponder> getResponderInfoInternal_1_4();
+    WifiStatus enableResponderInternal_1_4(uint32_t cmd_id, const WifiChannelInfo& channel_hint,
+                                           uint32_t max_duration_seconds,
+                                           const V1_4::RttResponder& info);
+
+    std::string ifname_;
+    sp<IWifiIface> bound_iface_;
+    std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+    std::vector<sp<V1_4::IWifiRttControllerEventCallback>> event_callbacks_;
+    bool is_valid_;
+
+    DISALLOW_COPY_AND_ASSIGN(WifiRttController);
+};
+
+}  // namespace implementation
+}  // namespace V1_6
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+
+#endif  // WIFI_RTT_CONTROLLER_H_
diff --git a/wifi/1.6/default/wifi_sta_iface.cpp b/wifi/1.6/default/wifi_sta_iface.cpp
new file mode 100644
index 0000000..f852d36
--- /dev/null
+++ b/wifi/1.6/default/wifi_sta_iface.cpp
@@ -0,0 +1,583 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "hidl_return_util.h"
+#include "hidl_struct_util.h"
+#include "wifi_sta_iface.h"
+#include "wifi_status_util.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+using hidl_return_util::validateAndCall;
+
+WifiStaIface::WifiStaIface(const std::string& ifname,
+                           const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+                           const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
+    : ifname_(ifname), legacy_hal_(legacy_hal), iface_util_(iface_util), is_valid_(true) {
+    // Turn on DFS channel usage for STA iface.
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setDfsFlag(ifname_, true);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        LOG(ERROR) << "Failed to set DFS flag; DFS channels may be unavailable.";
+    }
+}
+
+void WifiStaIface::invalidate() {
+    legacy_hal_.reset();
+    event_cb_handler_.invalidate();
+    is_valid_ = false;
+}
+
+bool WifiStaIface::isValid() {
+    return is_valid_;
+}
+
+std::string WifiStaIface::getName() {
+    return ifname_;
+}
+
+std::set<sp<IWifiStaIfaceEventCallback>> WifiStaIface::getEventCallbacks() {
+    return event_cb_handler_.getCallbacks();
+}
+
+Return<void> WifiStaIface::getName(getName_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::getNameInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::getType(getType_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::getTypeInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::registerEventCallback(const sp<IWifiStaIfaceEventCallback>& callback,
+                                                 registerEventCallback_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::registerEventCallbackInternal, hidl_status_cb, callback);
+}
+
+Return<void> WifiStaIface::getCapabilities(getCapabilities_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::getCapabilitiesInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::getApfPacketFilterCapabilities(
+        getApfPacketFilterCapabilities_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::getApfPacketFilterCapabilitiesInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::installApfPacketFilter(uint32_t cmd_id, const hidl_vec<uint8_t>& program,
+                                                  installApfPacketFilter_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::installApfPacketFilterInternal, hidl_status_cb, cmd_id,
+                           program);
+}
+
+Return<void> WifiStaIface::readApfPacketFilterData(readApfPacketFilterData_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::readApfPacketFilterDataInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::getBackgroundScanCapabilities(
+        getBackgroundScanCapabilities_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::getBackgroundScanCapabilitiesInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::getValidFrequenciesForBand(
+        V1_0::WifiBand band, getValidFrequenciesForBand_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::getValidFrequenciesForBandInternal, hidl_status_cb, band);
+}
+
+Return<void> WifiStaIface::startBackgroundScan(uint32_t cmd_id,
+                                               const StaBackgroundScanParameters& params,
+                                               startBackgroundScan_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::startBackgroundScanInternal, hidl_status_cb, cmd_id,
+                           params);
+}
+
+Return<void> WifiStaIface::stopBackgroundScan(uint32_t cmd_id,
+                                              stopBackgroundScan_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::stopBackgroundScanInternal, hidl_status_cb, cmd_id);
+}
+
+Return<void> WifiStaIface::enableLinkLayerStatsCollection(
+        bool debug, enableLinkLayerStatsCollection_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::enableLinkLayerStatsCollectionInternal, hidl_status_cb,
+                           debug);
+}
+
+Return<void> WifiStaIface::disableLinkLayerStatsCollection(
+        disableLinkLayerStatsCollection_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::disableLinkLayerStatsCollectionInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::getLinkLayerStats(getLinkLayerStats_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::getLinkLayerStatsInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::getLinkLayerStats_1_3(getLinkLayerStats_1_3_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::getLinkLayerStatsInternal_1_3, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::getLinkLayerStats_1_5(getLinkLayerStats_1_5_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::getLinkLayerStatsInternal_1_5, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::startRssiMonitoring(uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi,
+                                               startRssiMonitoring_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::startRssiMonitoringInternal, hidl_status_cb, cmd_id,
+                           max_rssi, min_rssi);
+}
+
+Return<void> WifiStaIface::stopRssiMonitoring(uint32_t cmd_id,
+                                              stopRssiMonitoring_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::stopRssiMonitoringInternal, hidl_status_cb, cmd_id);
+}
+
+Return<void> WifiStaIface::getRoamingCapabilities(getRoamingCapabilities_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::getRoamingCapabilitiesInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::configureRoaming(const StaRoamingConfig& config,
+                                            configureRoaming_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::configureRoamingInternal, hidl_status_cb, config);
+}
+
+Return<void> WifiStaIface::setRoamingState(StaRoamingState state,
+                                           setRoamingState_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::setRoamingStateInternal, hidl_status_cb, state);
+}
+
+Return<void> WifiStaIface::enableNdOffload(bool enable, enableNdOffload_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::enableNdOffloadInternal, hidl_status_cb, enable);
+}
+
+Return<void> WifiStaIface::startSendingKeepAlivePackets(
+        uint32_t cmd_id, const hidl_vec<uint8_t>& ip_packet_data, uint16_t ether_type,
+        const hidl_array<uint8_t, 6>& src_address, const hidl_array<uint8_t, 6>& dst_address,
+        uint32_t period_in_ms, startSendingKeepAlivePackets_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::startSendingKeepAlivePacketsInternal, hidl_status_cb,
+                           cmd_id, ip_packet_data, ether_type, src_address, dst_address,
+                           period_in_ms);
+}
+
+Return<void> WifiStaIface::stopSendingKeepAlivePackets(
+        uint32_t cmd_id, stopSendingKeepAlivePackets_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::stopSendingKeepAlivePacketsInternal, hidl_status_cb,
+                           cmd_id);
+}
+
+Return<void> WifiStaIface::setScanningMacOui(const hidl_array<uint8_t, 3>& oui,
+                                             setScanningMacOui_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::setScanningMacOuiInternal, hidl_status_cb, oui);
+}
+
+Return<void> WifiStaIface::startDebugPacketFateMonitoring(
+        startDebugPacketFateMonitoring_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::startDebugPacketFateMonitoringInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::getDebugTxPacketFates(getDebugTxPacketFates_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::getDebugTxPacketFatesInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::getDebugRxPacketFates(getDebugRxPacketFates_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::getDebugRxPacketFatesInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::setMacAddress(const hidl_array<uint8_t, 6>& mac,
+                                         setMacAddress_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::setMacAddressInternal, hidl_status_cb, mac);
+}
+
+Return<void> WifiStaIface::getFactoryMacAddress(getFactoryMacAddress_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::getFactoryMacAddressInternal, hidl_status_cb);
+}
+
+Return<void> WifiStaIface::setScanMode(bool enable, setScanMode_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+                           &WifiStaIface::setScanModeInternal, hidl_status_cb, enable);
+}
+
+std::pair<WifiStatus, std::string> WifiStaIface::getNameInternal() {
+    return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_};
+}
+
+std::pair<WifiStatus, IfaceType> WifiStaIface::getTypeInternal() {
+    return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::STA};
+}
+
+WifiStatus WifiStaIface::registerEventCallbackInternal(
+        const sp<IWifiStaIfaceEventCallback>& callback) {
+    if (!event_cb_handler_.addCallback(callback)) {
+        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+    }
+    return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+std::pair<WifiStatus, uint32_t> WifiStaIface::getCapabilitiesInternal() {
+    legacy_hal::wifi_error legacy_status;
+    uint64_t legacy_feature_set;
+    std::tie(legacy_status, legacy_feature_set) =
+            legacy_hal_.lock()->getSupportedFeatureSet(ifname_);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {createWifiStatusFromLegacyError(legacy_status), 0};
+    }
+    uint32_t legacy_logger_feature_set;
+    std::tie(legacy_status, legacy_logger_feature_set) =
+            legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname_);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        // some devices don't support querying logger feature set
+        legacy_logger_feature_set = 0;
+    }
+    uint32_t hidl_caps;
+    if (!hidl_struct_util::convertLegacyFeaturesToHidlStaCapabilities(
+                legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
+        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
+    }
+    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
+}
+
+std::pair<WifiStatus, StaApfPacketFilterCapabilities>
+WifiStaIface::getApfPacketFilterCapabilitiesInternal() {
+    legacy_hal::wifi_error legacy_status;
+    legacy_hal::PacketFilterCapabilities legacy_caps;
+    std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getPacketFilterCapabilities(ifname_);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {createWifiStatusFromLegacyError(legacy_status), {}};
+    }
+    StaApfPacketFilterCapabilities hidl_caps;
+    if (!hidl_struct_util::convertLegacyApfCapabilitiesToHidl(legacy_caps, &hidl_caps)) {
+        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
+    }
+    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
+}
+
+WifiStatus WifiStaIface::installApfPacketFilterInternal(uint32_t /* cmd_id */,
+                                                        const std::vector<uint8_t>& program) {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setPacketFilter(ifname_, program);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<WifiStatus, std::vector<uint8_t>> WifiStaIface::readApfPacketFilterDataInternal() {
+    const std::pair<legacy_hal::wifi_error, std::vector<uint8_t>> legacy_status_and_data =
+            legacy_hal_.lock()->readApfPacketFilterData(ifname_);
+    return {createWifiStatusFromLegacyError(legacy_status_and_data.first),
+            std::move(legacy_status_and_data.second)};
+}
+
+std::pair<WifiStatus, StaBackgroundScanCapabilities>
+WifiStaIface::getBackgroundScanCapabilitiesInternal() {
+    legacy_hal::wifi_error legacy_status;
+    legacy_hal::wifi_gscan_capabilities legacy_caps;
+    std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getGscanCapabilities(ifname_);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {createWifiStatusFromLegacyError(legacy_status), {}};
+    }
+    StaBackgroundScanCapabilities hidl_caps;
+    if (!hidl_struct_util::convertLegacyGscanCapabilitiesToHidl(legacy_caps, &hidl_caps)) {
+        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
+    }
+    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
+}
+
+std::pair<WifiStatus, std::vector<WifiChannelInMhz>>
+WifiStaIface::getValidFrequenciesForBandInternal(V1_0::WifiBand band) {
+    static_assert(sizeof(WifiChannelInMhz) == sizeof(uint32_t), "Size mismatch");
+    legacy_hal::wifi_error legacy_status;
+    std::vector<uint32_t> valid_frequencies;
+    std::tie(legacy_status, valid_frequencies) = legacy_hal_.lock()->getValidFrequenciesForBand(
+            ifname_, hidl_struct_util::convertHidlWifiBandToLegacy(band));
+    return {createWifiStatusFromLegacyError(legacy_status), valid_frequencies};
+}
+
+WifiStatus WifiStaIface::startBackgroundScanInternal(uint32_t cmd_id,
+                                                     const StaBackgroundScanParameters& params) {
+    legacy_hal::wifi_scan_cmd_params legacy_params;
+    if (!hidl_struct_util::convertHidlGscanParamsToLegacy(params, &legacy_params)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    android::wp<WifiStaIface> weak_ptr_this(this);
+    const auto& on_failure_callback = [weak_ptr_this](legacy_hal::wifi_request_id id) {
+        const auto shared_ptr_this = weak_ptr_this.promote();
+        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+            LOG(ERROR) << "Callback invoked on an invalid object";
+            return;
+        }
+        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+            if (!callback->onBackgroundScanFailure(id).isOk()) {
+                LOG(ERROR) << "Failed to invoke onBackgroundScanFailure callback";
+            }
+        }
+    };
+    const auto& on_results_callback =
+            [weak_ptr_this](legacy_hal::wifi_request_id id,
+                            const std::vector<legacy_hal::wifi_cached_scan_results>& results) {
+                const auto shared_ptr_this = weak_ptr_this.promote();
+                if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                    LOG(ERROR) << "Callback invoked on an invalid object";
+                    return;
+                }
+                std::vector<StaScanData> hidl_scan_datas;
+                if (!hidl_struct_util::convertLegacyVectorOfCachedGscanResultsToHidl(
+                            results, &hidl_scan_datas)) {
+                    LOG(ERROR) << "Failed to convert scan results to HIDL structs";
+                    return;
+                }
+                for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                    if (!callback->onBackgroundScanResults(id, hidl_scan_datas).isOk()) {
+                        LOG(ERROR) << "Failed to invoke onBackgroundScanResults callback";
+                    }
+                }
+            };
+    const auto& on_full_result_callback = [weak_ptr_this](
+                                                  legacy_hal::wifi_request_id id,
+                                                  const legacy_hal::wifi_scan_result* result,
+                                                  uint32_t buckets_scanned) {
+        const auto shared_ptr_this = weak_ptr_this.promote();
+        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+            LOG(ERROR) << "Callback invoked on an invalid object";
+            return;
+        }
+        StaScanResult hidl_scan_result;
+        if (!hidl_struct_util::convertLegacyGscanResultToHidl(*result, true, &hidl_scan_result)) {
+            LOG(ERROR) << "Failed to convert full scan results to HIDL structs";
+            return;
+        }
+        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+            if (!callback->onBackgroundFullScanResult(id, buckets_scanned, hidl_scan_result)
+                         .isOk()) {
+                LOG(ERROR) << "Failed to invoke onBackgroundFullScanResult callback";
+            }
+        }
+    };
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->startGscan(ifname_, cmd_id, legacy_params, on_failure_callback,
+                                           on_results_callback, on_full_result_callback);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiStaIface::stopBackgroundScanInternal(uint32_t cmd_id) {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stopGscan(ifname_, cmd_id);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiStaIface::enableLinkLayerStatsCollectionInternal(bool debug) {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableLinkLayerStats(ifname_, debug);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiStaIface::disableLinkLayerStatsCollectionInternal() {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->disableLinkLayerStats(ifname_);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<WifiStatus, V1_0::StaLinkLayerStats> WifiStaIface::getLinkLayerStatsInternal() {
+    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
+}
+
+std::pair<WifiStatus, V1_3::StaLinkLayerStats> WifiStaIface::getLinkLayerStatsInternal_1_3() {
+    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
+}
+
+std::pair<WifiStatus, V1_5::StaLinkLayerStats> WifiStaIface::getLinkLayerStatsInternal_1_5() {
+    legacy_hal::wifi_error legacy_status;
+    legacy_hal::LinkLayerStats legacy_stats;
+    std::tie(legacy_status, legacy_stats) = legacy_hal_.lock()->getLinkLayerStats(ifname_);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {createWifiStatusFromLegacyError(legacy_status), {}};
+    }
+    V1_5::StaLinkLayerStats hidl_stats;
+    if (!hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats, &hidl_stats)) {
+        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
+    }
+    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats};
+}
+
+WifiStatus WifiStaIface::startRssiMonitoringInternal(uint32_t cmd_id, int32_t max_rssi,
+                                                     int32_t min_rssi) {
+    android::wp<WifiStaIface> weak_ptr_this(this);
+    const auto& on_threshold_breached_callback = [weak_ptr_this](legacy_hal::wifi_request_id id,
+                                                                 std::array<uint8_t, 6> bssid,
+                                                                 int8_t rssi) {
+        const auto shared_ptr_this = weak_ptr_this.promote();
+        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+            LOG(ERROR) << "Callback invoked on an invalid object";
+            return;
+        }
+        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+            if (!callback->onRssiThresholdBreached(id, bssid, rssi).isOk()) {
+                LOG(ERROR) << "Failed to invoke onRssiThresholdBreached callback";
+            }
+        }
+    };
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRssiMonitoring(
+            ifname_, cmd_id, max_rssi, min_rssi, on_threshold_breached_callback);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiStaIface::stopRssiMonitoringInternal(uint32_t cmd_id) {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stopRssiMonitoring(ifname_, cmd_id);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<WifiStatus, StaRoamingCapabilities> WifiStaIface::getRoamingCapabilitiesInternal() {
+    legacy_hal::wifi_error legacy_status;
+    legacy_hal::wifi_roaming_capabilities legacy_caps;
+    std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getRoamingCapabilities(ifname_);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {createWifiStatusFromLegacyError(legacy_status), {}};
+    }
+    StaRoamingCapabilities hidl_caps;
+    if (!hidl_struct_util::convertLegacyRoamingCapabilitiesToHidl(legacy_caps, &hidl_caps)) {
+        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
+    }
+    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
+}
+
+WifiStatus WifiStaIface::configureRoamingInternal(const StaRoamingConfig& config) {
+    legacy_hal::wifi_roaming_config legacy_config;
+    if (!hidl_struct_util::convertHidlRoamingConfigToLegacy(config, &legacy_config)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->configureRoaming(ifname_, legacy_config);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiStaIface::setRoamingStateInternal(StaRoamingState state) {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableFirmwareRoaming(
+            ifname_, hidl_struct_util::convertHidlRoamingStateToLegacy(state));
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiStaIface::enableNdOffloadInternal(bool enable) {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->configureNdOffload(ifname_, enable);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiStaIface::startSendingKeepAlivePacketsInternal(
+        uint32_t cmd_id, const std::vector<uint8_t>& ip_packet_data, uint16_t ether_type,
+        const std::array<uint8_t, 6>& src_address, const std::array<uint8_t, 6>& dst_address,
+        uint32_t period_in_ms) {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startSendingOffloadedPacket(
+            ifname_, cmd_id, ether_type, ip_packet_data, src_address, dst_address, period_in_ms);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiStaIface::stopSendingKeepAlivePacketsInternal(uint32_t cmd_id) {
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->stopSendingOffloadedPacket(ifname_, cmd_id);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiStaIface::setScanningMacOuiInternal(const std::array<uint8_t, 3>& /* oui */) {
+    // deprecated.
+    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+WifiStatus WifiStaIface::startDebugPacketFateMonitoringInternal() {
+    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startPktFateMonitoring(ifname_);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<WifiStatus, std::vector<WifiDebugTxPacketFateReport>>
+WifiStaIface::getDebugTxPacketFatesInternal() {
+    legacy_hal::wifi_error legacy_status;
+    std::vector<legacy_hal::wifi_tx_report> legacy_fates;
+    std::tie(legacy_status, legacy_fates) = legacy_hal_.lock()->getTxPktFates(ifname_);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {createWifiStatusFromLegacyError(legacy_status), {}};
+    }
+    std::vector<WifiDebugTxPacketFateReport> hidl_fates;
+    if (!hidl_struct_util::convertLegacyVectorOfDebugTxPacketFateToHidl(legacy_fates,
+                                                                        &hidl_fates)) {
+        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
+    }
+    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_fates};
+}
+
+std::pair<WifiStatus, std::vector<WifiDebugRxPacketFateReport>>
+WifiStaIface::getDebugRxPacketFatesInternal() {
+    legacy_hal::wifi_error legacy_status;
+    std::vector<legacy_hal::wifi_rx_report> legacy_fates;
+    std::tie(legacy_status, legacy_fates) = legacy_hal_.lock()->getRxPktFates(ifname_);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {createWifiStatusFromLegacyError(legacy_status), {}};
+    }
+    std::vector<WifiDebugRxPacketFateReport> hidl_fates;
+    if (!hidl_struct_util::convertLegacyVectorOfDebugRxPacketFateToHidl(legacy_fates,
+                                                                        &hidl_fates)) {
+        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
+    }
+    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_fates};
+}
+
+WifiStatus WifiStaIface::setMacAddressInternal(const std::array<uint8_t, 6>& mac) {
+    bool status = iface_util_.lock()->setMacAddress(ifname_, mac);
+    if (!status) {
+        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
+    }
+    return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+std::pair<WifiStatus, std::array<uint8_t, 6>> WifiStaIface::getFactoryMacAddressInternal() {
+    std::array<uint8_t, 6> mac = iface_util_.lock()->getFactoryMacAddress(ifname_);
+    if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 && mac[4] == 0 && mac[5] == 0) {
+        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), mac};
+    }
+    return {createWifiStatus(WifiStatusCode::SUCCESS), mac};
+}
+
+WifiStatus WifiStaIface::setScanModeInternal(bool enable) {
+    // OEM's need to implement this on their devices if needed.
+    LOG(WARNING) << "setScanModeInternal(" << enable << ") not supported";
+    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
+}
+
+}  // namespace implementation
+}  // namespace V1_6
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
diff --git a/wifi/1.6/default/wifi_sta_iface.h b/wifi/1.6/default/wifi_sta_iface.h
new file mode 100644
index 0000000..37358a5
--- /dev/null
+++ b/wifi/1.6/default/wifi_sta_iface.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 WIFI_STA_IFACE_H_
+#define WIFI_STA_IFACE_H_
+
+#include <android-base/macros.h>
+#include <android/hardware/wifi/1.0/IWifiStaIfaceEventCallback.h>
+#include <android/hardware/wifi/1.5/IWifiStaIface.h>
+
+#include "hidl_callback_util.h"
+#include "wifi_iface_util.h"
+#include "wifi_legacy_hal.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_6 {
+namespace implementation {
+using namespace android::hardware::wifi::V1_0;
+
+/**
+ * HIDL interface object used to control a STA Iface instance.
+ */
+class WifiStaIface : public V1_5::IWifiStaIface {
+  public:
+    WifiStaIface(const std::string& ifname,
+                 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+                 const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
+    // Refer to |WifiChip::invalidate()|.
+    void invalidate();
+    bool isValid();
+    std::set<sp<IWifiStaIfaceEventCallback>> getEventCallbacks();
+    std::string getName();
+
+    // HIDL methods exposed.
+    Return<void> getName(getName_cb hidl_status_cb) override;
+    Return<void> getType(getType_cb hidl_status_cb) override;
+    Return<void> registerEventCallback(const sp<IWifiStaIfaceEventCallback>& callback,
+                                       registerEventCallback_cb hidl_status_cb) override;
+    Return<void> getCapabilities(getCapabilities_cb hidl_status_cb) override;
+    Return<void> getApfPacketFilterCapabilities(
+            getApfPacketFilterCapabilities_cb hidl_status_cb) override;
+    Return<void> installApfPacketFilter(uint32_t cmd_id, const hidl_vec<uint8_t>& program,
+                                        installApfPacketFilter_cb hidl_status_cb) override;
+    Return<void> readApfPacketFilterData(readApfPacketFilterData_cb hidl_status_cb) override;
+    Return<void> getBackgroundScanCapabilities(
+            getBackgroundScanCapabilities_cb hidl_status_cb) override;
+    Return<void> getValidFrequenciesForBand(V1_0::WifiBand band,
+                                            getValidFrequenciesForBand_cb hidl_status_cb) override;
+    Return<void> startBackgroundScan(uint32_t cmd_id, const StaBackgroundScanParameters& params,
+                                     startBackgroundScan_cb hidl_status_cb) override;
+    Return<void> stopBackgroundScan(uint32_t cmd_id, stopBackgroundScan_cb hidl_status_cb) override;
+    Return<void> enableLinkLayerStatsCollection(
+            bool debug, enableLinkLayerStatsCollection_cb hidl_status_cb) override;
+    Return<void> disableLinkLayerStatsCollection(
+            disableLinkLayerStatsCollection_cb hidl_status_cb) override;
+    Return<void> getLinkLayerStats(getLinkLayerStats_cb hidl_status_cb) override;
+    Return<void> getLinkLayerStats_1_3(getLinkLayerStats_1_3_cb hidl_status_cb) override;
+    Return<void> getLinkLayerStats_1_5(getLinkLayerStats_1_5_cb hidl_status_cb) override;
+    Return<void> startRssiMonitoring(uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi,
+                                     startRssiMonitoring_cb hidl_status_cb) override;
+    Return<void> stopRssiMonitoring(uint32_t cmd_id, stopRssiMonitoring_cb hidl_status_cb) override;
+    Return<void> getRoamingCapabilities(getRoamingCapabilities_cb hidl_status_cb) override;
+    Return<void> configureRoaming(const StaRoamingConfig& config,
+                                  configureRoaming_cb hidl_status_cb) override;
+    Return<void> setRoamingState(StaRoamingState state, setRoamingState_cb hidl_status_cb) override;
+    Return<void> enableNdOffload(bool enable, enableNdOffload_cb hidl_status_cb) override;
+    Return<void> startSendingKeepAlivePackets(
+            uint32_t cmd_id, const hidl_vec<uint8_t>& ip_packet_data, uint16_t ether_type,
+            const hidl_array<uint8_t, 6>& src_address, const hidl_array<uint8_t, 6>& dst_address,
+            uint32_t period_in_ms, startSendingKeepAlivePackets_cb hidl_status_cb) override;
+    Return<void> stopSendingKeepAlivePackets(
+            uint32_t cmd_id, stopSendingKeepAlivePackets_cb hidl_status_cb) override;
+    Return<void> setScanningMacOui(const hidl_array<uint8_t, 3>& oui,
+                                   setScanningMacOui_cb hidl_status_cb) override;
+    Return<void> startDebugPacketFateMonitoring(
+            startDebugPacketFateMonitoring_cb hidl_status_cb) override;
+    Return<void> getDebugTxPacketFates(getDebugTxPacketFates_cb hidl_status_cb) override;
+    Return<void> getDebugRxPacketFates(getDebugRxPacketFates_cb hidl_status_cb) override;
+    Return<void> setMacAddress(const hidl_array<uint8_t, 6>& mac,
+                               setMacAddress_cb hidl_status_cb) override;
+    Return<void> getFactoryMacAddress(getFactoryMacAddress_cb hidl_status_cb) override;
+    Return<void> setScanMode(bool enable, setScanMode_cb hidl_status_cb) override;
+
+  private:
+    // Corresponding worker functions for the HIDL methods.
+    std::pair<WifiStatus, std::string> getNameInternal();
+    std::pair<WifiStatus, IfaceType> getTypeInternal();
+    WifiStatus registerEventCallbackInternal(const sp<IWifiStaIfaceEventCallback>& callback);
+    std::pair<WifiStatus, uint32_t> getCapabilitiesInternal();
+    std::pair<WifiStatus, StaApfPacketFilterCapabilities> getApfPacketFilterCapabilitiesInternal();
+    WifiStatus installApfPacketFilterInternal(uint32_t cmd_id, const std::vector<uint8_t>& program);
+    std::pair<WifiStatus, std::vector<uint8_t>> readApfPacketFilterDataInternal();
+    std::pair<WifiStatus, StaBackgroundScanCapabilities> getBackgroundScanCapabilitiesInternal();
+    std::pair<WifiStatus, std::vector<WifiChannelInMhz>> getValidFrequenciesForBandInternal(
+            V1_0::WifiBand band);
+    WifiStatus startBackgroundScanInternal(uint32_t cmd_id,
+                                           const StaBackgroundScanParameters& params);
+    WifiStatus stopBackgroundScanInternal(uint32_t cmd_id);
+    WifiStatus enableLinkLayerStatsCollectionInternal(bool debug);
+    WifiStatus disableLinkLayerStatsCollectionInternal();
+    std::pair<WifiStatus, V1_0::StaLinkLayerStats> getLinkLayerStatsInternal();
+    std::pair<WifiStatus, V1_3::StaLinkLayerStats> getLinkLayerStatsInternal_1_3();
+    std::pair<WifiStatus, V1_5::StaLinkLayerStats> getLinkLayerStatsInternal_1_5();
+    WifiStatus startRssiMonitoringInternal(uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi);
+    WifiStatus stopRssiMonitoringInternal(uint32_t cmd_id);
+    std::pair<WifiStatus, StaRoamingCapabilities> getRoamingCapabilitiesInternal();
+    WifiStatus configureRoamingInternal(const StaRoamingConfig& config);
+    WifiStatus setRoamingStateInternal(StaRoamingState state);
+    WifiStatus enableNdOffloadInternal(bool enable);
+    WifiStatus startSendingKeepAlivePacketsInternal(uint32_t cmd_id,
+                                                    const std::vector<uint8_t>& ip_packet_data,
+                                                    uint16_t ether_type,
+                                                    const std::array<uint8_t, 6>& src_address,
+                                                    const std::array<uint8_t, 6>& dst_address,
+                                                    uint32_t period_in_ms);
+    WifiStatus stopSendingKeepAlivePacketsInternal(uint32_t cmd_id);
+    WifiStatus setScanningMacOuiInternal(const std::array<uint8_t, 3>& oui);
+    WifiStatus startDebugPacketFateMonitoringInternal();
+    std::pair<WifiStatus, std::vector<WifiDebugTxPacketFateReport>> getDebugTxPacketFatesInternal();
+    std::pair<WifiStatus, std::vector<WifiDebugRxPacketFateReport>> getDebugRxPacketFatesInternal();
+    WifiStatus setMacAddressInternal(const std::array<uint8_t, 6>& mac);
+    std::pair<WifiStatus, std::array<uint8_t, 6>> getFactoryMacAddressInternal();
+    WifiStatus setScanModeInternal(bool enable);
+
+    std::string ifname_;
+    std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+    std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
+    bool is_valid_;
+    hidl_callback_util::HidlCallbackHandler<IWifiStaIfaceEventCallback> event_cb_handler_;
+
+    DISALLOW_COPY_AND_ASSIGN(WifiStaIface);
+};
+
+}  // namespace implementation
+}  // namespace V1_6
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+
+#endif  // WIFI_STA_IFACE_H_
diff --git a/wifi/1.5/default/wifi_status_util.cpp b/wifi/1.6/default/wifi_status_util.cpp
similarity index 87%
rename from wifi/1.5/default/wifi_status_util.cpp
rename to wifi/1.6/default/wifi_status_util.cpp
index eb8c869..3b18e53 100644
--- a/wifi/1.5/default/wifi_status_util.cpp
+++ b/wifi/1.6/default/wifi_status_util.cpp
@@ -19,7 +19,7 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 
 std::string legacyErrorToString(legacy_hal::wifi_error error) {
@@ -51,8 +51,7 @@
     }
 }
 
-WifiStatus createWifiStatus(WifiStatusCode code,
-                            const std::string& description) {
+WifiStatus createWifiStatus(WifiStatusCode code, const std::string& description) {
     return {code, description};
 }
 
@@ -60,8 +59,7 @@
     return createWifiStatus(code, "");
 }
 
-WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error,
-                                           const std::string& desc) {
+WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error, const std::string& desc) {
     switch (error) {
         case legacy_hal::WIFI_ERROR_UNINITIALIZED:
         case legacy_hal::WIFI_ERROR_NOT_AVAILABLE:
@@ -75,16 +73,13 @@
             return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS, desc);
 
         case legacy_hal::WIFI_ERROR_TIMED_OUT:
-            return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN,
-                                    desc + ", timed out");
+            return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, desc + ", timed out");
 
         case legacy_hal::WIFI_ERROR_TOO_MANY_REQUESTS:
-            return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN,
-                                    desc + ", too many requests");
+            return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, desc + ", too many requests");
 
         case legacy_hal::WIFI_ERROR_OUT_OF_MEMORY:
-            return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN,
-                                    desc + ", out of memory");
+            return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, desc + ", out of memory");
 
         case legacy_hal::WIFI_ERROR_BUSY:
             return createWifiStatus(WifiStatusCode::ERROR_BUSY);
@@ -96,8 +91,7 @@
             return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, "unknown");
 
         default:
-            return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN,
-                                    "unknown error");
+            return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, "unknown error");
     }
 }
 
@@ -106,7 +100,7 @@
 }
 
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/1.5/default/wifi_status_util.h b/wifi/1.6/default/wifi_status_util.h
similarity index 89%
rename from wifi/1.5/default/wifi_status_util.h
rename to wifi/1.6/default/wifi_status_util.h
index 68f2168..ea1c294 100644
--- a/wifi/1.5/default/wifi_status_util.h
+++ b/wifi/1.6/default/wifi_status_util.h
@@ -24,20 +24,19 @@
 namespace android {
 namespace hardware {
 namespace wifi {
-namespace V1_5 {
+namespace V1_6 {
 namespace implementation {
 using namespace android::hardware::wifi::V1_0;
 
 std::string legacyErrorToString(legacy_hal::wifi_error error);
-WifiStatus createWifiStatus(WifiStatusCode code,
-                            const std::string& description);
+WifiStatus createWifiStatus(WifiStatusCode code, const std::string& description);
 WifiStatus createWifiStatus(WifiStatusCode code);
 WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error,
                                            const std::string& description);
 WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error);
 
 }  // namespace implementation
-}  // namespace V1_5
+}  // namespace V1_6
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
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/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 dad7085..cd7ff82 100644
--- a/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
+++ b/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
@@ -431,6 +431,7 @@
     EXPECT_TRUE(status.isOk());
 }
 
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HostapdAidl);
 INSTANTIATE_TEST_SUITE_P(
     Hostapd, HostapdAidl,
     testing::ValuesIn(android::getAidlHalInstanceNames(IHostapd::descriptor)),
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
index ed435e2..826d916 100644
--- 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
@@ -50,4 +50,5 @@
   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/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
index 4f7584d..6276a35 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
@@ -38,4 +38,5 @@
   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);
+  oneway void onServerCertificateAvailable(in int depth, in byte[] subject, in byte[] certHash, in byte[] certBlob);
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
index 43772af..9a0a924 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
@@ -38,4 +38,5 @@
   OCE = 2,
   SAE_PK = 4,
   WFD_R2 = 8,
+  TRUST_ON_FIRST_USE = 16,
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AuthAlgMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AuthAlgMask.aidl
index e8101ea..039d41d 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AuthAlgMask.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AuthAlgMask.aidl
@@ -19,7 +19,7 @@
 /**
  * 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).
+ * the historical values (starting at WPA_AUTH_ALG_OPEN).
  */
 @VintfStability
 @Backing(type="int")
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/GroupCipherMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/GroupCipherMask.aidl
index d5b26ad..99e9da0 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/GroupCipherMask.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/GroupCipherMask.aidl
@@ -19,7 +19,7 @@
 /**
  * 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).
+ * the historical values (starting at WPA_CIPHER_WEP40).
  */
 @VintfStability
 @Backing(type="int")
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
index f0cabd6..2b58cc2 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
@@ -205,4 +205,12 @@
      * @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/ISupplicantStaNetworkCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
index c28b494..4024c35 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
@@ -62,4 +62,13 @@
      * Used to notify WPA3 transition disable.
      */
     oneway void onTransitionDisable(in TransitionDisableIndication ind);
+
+    /**
+     * Used to notify EAP certificate event.
+     *
+     * On receiving a server certifidate from TLS handshake, send this certificate
+     * to the framework for Trust On First Use.
+     */
+    oneway void onServerCertificateAvailable(
+            in int depth, in byte[] subject, in byte[] certHash, in byte[] certBlob);
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
index 3225585..f0c3345 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
@@ -19,7 +19,7 @@
 /**
  * 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).
+ * the historical values (starting at WPA_KEY_MGMT_IEEE8021X).
  */
 @VintfStability
 @Backing(type="int")
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl
index ad134fa..7179fea 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl
@@ -19,7 +19,7 @@
 /**
  * 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).
+ * the historical values (starting at WPA_CIPHER_NONE).
  */
 @VintfStability
 @Backing(type="int")
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ProtoMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ProtoMask.aidl
index 65c832b..dc3d80b 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ProtoMask.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ProtoMask.aidl
@@ -19,7 +19,7 @@
 /**
  * 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).
+ * the historical values (starting at WPA_PROTO_WPA).
  */
 @VintfStability
 @Backing(type="int")
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
index e174199..08006cf 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
@@ -38,4 +38,8 @@
      * Wi-Fi Display R2
      */
     WFD_R2 = 1 << 3,
+    /**
+     * Trust On First Use
+     */
+    TRUST_ON_FIRST_USE = 1 << 4,
 }
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
index 2f4f06d..10aab4d 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
@@ -159,6 +159,10 @@
         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> {
@@ -620,6 +624,7 @@
         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)),
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
index f51c07f..6e6955f 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
@@ -769,6 +769,7 @@
     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)),
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
index 66c8807..0a35f66 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
@@ -92,6 +92,12 @@
         TransitionDisableIndication /* ind */) override {
         return ndk::ScopedAStatus::ok();
     }
+    ::ndk::ScopedAStatus onServerCertificateAvailable(
+            int32_t /* depth */, const std::vector<uint8_t>& /* subject */,
+            const std::vector<uint8_t>& /* certHash */,
+            const std::vector<uint8_t>& /* certBlob */) override {
+        return ndk::ScopedAStatus::ok();
+    }
 };
 
 class SupplicantStaNetworkAidlTest
@@ -778,6 +784,7 @@
     EXPECT_NE(retrievedToken.size(), 0);
 }
 
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaNetworkAidlTest);
 INSTANTIATE_TEST_SUITE_P(Supplicant, SupplicantStaNetworkAidlTest,
                          testing::ValuesIn(android::getAidlHalInstanceNames(
                              ISupplicant::descriptor)),