Merge "Update supplicant callbacks with reccomendations from the ANAPIC review."
diff --git a/audio/7.1/config/api/current.txt b/audio/7.1/config/api/current.txt
index 3a08b71..75fc5c0 100644
--- a/audio/7.1/config/api/current.txt
+++ b/audio/7.1/config/api/current.txt
@@ -359,6 +359,7 @@
     enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_GAME;
     enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_MEDIA;
     enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_NOTIFICATION;
+    enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_NOTIFICATION_EVENT;
     enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
     enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_SAFETY;
     enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_UNKNOWN;
diff --git a/audio/7.1/config/audio_policy_configuration.xsd b/audio/7.1/config/audio_policy_configuration.xsd
index ebc23ed..7e1da90 100644
--- a/audio/7.1/config/audio_policy_configuration.xsd
+++ b/audio/7.1/config/audio_policy_configuration.xsd
@@ -443,6 +443,7 @@
             <xs:enumeration value="AUDIO_USAGE_ALARM" />
             <xs:enumeration value="AUDIO_USAGE_NOTIFICATION" />
             <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE" />
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_EVENT" />
             <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
             <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
             <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
diff --git a/audio/common/all-versions/default/7.0/HidlUtils.cpp b/audio/common/all-versions/default/7.0/HidlUtils.cpp
index 218d7c0..0fd2947 100644
--- a/audio/common/all-versions/default/7.0/HidlUtils.cpp
+++ b/audio/common/all-versions/default/7.0/HidlUtils.cpp
@@ -485,8 +485,12 @@
 status_t HidlUtils::audioUsageFromHal(audio_usage_t halUsage, AudioUsage* usage) {
     if (halUsage == AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST ||
         halUsage == AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT ||
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+        halUsage == AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED) {
+#else
         halUsage == AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED ||
         halUsage == AUDIO_USAGE_NOTIFICATION_EVENT) {
+#endif
         halUsage = AUDIO_USAGE_NOTIFICATION;
     }
     *usage = audio_usage_to_string(halUsage);
diff --git a/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h b/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h
index d2b69af..6ecac70 100644
--- a/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h
+++ b/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h
@@ -754,8 +754,7 @@
         {.config = {.prop = toInt(VehicleProperty::AP_POWER_STATE_REQ),
                     .access = VehiclePropertyAccess::READ,
                     .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .configArray = {3}},
-         .initialValue = {.int32Values = {toInt(VehicleApPowerStateReq::ON), 0}}},
+                    .configArray = {3}}},
 
         {.config = {.prop = toInt(VehicleProperty::AP_POWER_STATE_REPORT),
                     .access = VehiclePropertyAccess::READ_WRITE,
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 0812c2a..3dae9fc 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
@@ -58,7 +58,6 @@
 using ::testing::ContainerEq;
 using ::testing::ContainsRegex;
 using ::testing::Eq;
-using ::testing::IsSubsetOf;
 using ::testing::WhenSortedBy;
 
 constexpr int INVALID_PROP_ID = 0;
@@ -635,16 +634,16 @@
                     .expectedValuesToGet =
                             {
                                     VehiclePropValue{
-                                            .prop = toInt(VehicleProperty::AP_POWER_STATE_REPORT),
-                                            .value.int32Values = {toInt(
-                                                    VehicleApPowerStateReport::DEEP_SLEEP_EXIT)},
-                                    },
-                                    VehiclePropValue{
                                             .prop = toInt(VehicleProperty::AP_POWER_STATE_REQ),
                                             .status = VehiclePropertyStatus::AVAILABLE,
                                             .value.int32Values = {toInt(VehicleApPowerStateReq::ON),
                                                                   0},
                                     },
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::AP_POWER_STATE_REPORT),
+                                            .value.int32Values = {toInt(
+                                                    VehicleApPowerStateReport::DEEP_SLEEP_EXIT)},
+                                    },
                             },
             },
             SetSpecialValueTestCase{
@@ -660,16 +659,16 @@
                     .expectedValuesToGet =
                             {
                                     VehiclePropValue{
-                                            .prop = toInt(VehicleProperty::AP_POWER_STATE_REPORT),
-                                            .value.int32Values = {toInt(
-                                                    VehicleApPowerStateReport::HIBERNATION_EXIT)},
-                                    },
-                                    VehiclePropValue{
                                             .prop = toInt(VehicleProperty::AP_POWER_STATE_REQ),
                                             .status = VehiclePropertyStatus::AVAILABLE,
                                             .value.int32Values = {toInt(VehicleApPowerStateReq::ON),
                                                                   0},
                                     },
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::AP_POWER_STATE_REPORT),
+                                            .value.int32Values = {toInt(
+                                                    VehicleApPowerStateReport::HIBERNATION_EXIT)},
+                                    },
                             },
             },
             SetSpecialValueTestCase{
@@ -685,16 +684,16 @@
                     .expectedValuesToGet =
                             {
                                     VehiclePropValue{
-                                            .prop = toInt(VehicleProperty::AP_POWER_STATE_REPORT),
-                                            .value.int32Values = {toInt(
-                                                    VehicleApPowerStateReport::SHUTDOWN_CANCELLED)},
-                                    },
-                                    VehiclePropValue{
                                             .prop = toInt(VehicleProperty::AP_POWER_STATE_REQ),
                                             .status = VehiclePropertyStatus::AVAILABLE,
                                             .value.int32Values = {toInt(VehicleApPowerStateReq::ON),
                                                                   0},
                                     },
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::AP_POWER_STATE_REPORT),
+                                            .value.int32Values = {toInt(
+                                                    VehicleApPowerStateReport::SHUTDOWN_CANCELLED)},
+                                    },
                             },
             },
             SetSpecialValueTestCase{
@@ -710,16 +709,16 @@
                     .expectedValuesToGet =
                             {
                                     VehiclePropValue{
-                                            .prop = toInt(VehicleProperty::AP_POWER_STATE_REPORT),
-                                            .value.int32Values = {toInt(
-                                                    VehicleApPowerStateReport::WAIT_FOR_VHAL)},
-                                    },
-                                    VehiclePropValue{
                                             .prop = toInt(VehicleProperty::AP_POWER_STATE_REQ),
                                             .status = VehiclePropertyStatus::AVAILABLE,
                                             .value.int32Values = {toInt(VehicleApPowerStateReq::ON),
                                                                   0},
                                     },
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::AP_POWER_STATE_REPORT),
+                                            .value.int32Values = {toInt(
+                                                    VehicleApPowerStateReport::WAIT_FOR_VHAL)},
+                                    },
                             },
             },
             SetSpecialValueTestCase{
@@ -735,16 +734,16 @@
                     .expectedValuesToGet =
                             {
                                     VehiclePropValue{
-                                            .prop = toInt(VehicleProperty::AP_POWER_STATE_REPORT),
-                                            .value.int32Values = {toInt(
-                                                    VehicleApPowerStateReport::DEEP_SLEEP_ENTRY)},
-                                    },
-                                    VehiclePropValue{
                                             .prop = toInt(VehicleProperty::AP_POWER_STATE_REQ),
                                             .status = VehiclePropertyStatus::AVAILABLE,
                                             .value.int32Values =
                                                     {toInt(VehicleApPowerStateReq::FINISHED), 0},
                                     },
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::AP_POWER_STATE_REPORT),
+                                            .value.int32Values = {toInt(
+                                                    VehicleApPowerStateReport::DEEP_SLEEP_ENTRY)},
+                                    },
                             },
             },
             SetSpecialValueTestCase{
@@ -760,16 +759,16 @@
                     .expectedValuesToGet =
                             {
                                     VehiclePropValue{
-                                            .prop = toInt(VehicleProperty::AP_POWER_STATE_REPORT),
-                                            .value.int32Values = {toInt(
-                                                    VehicleApPowerStateReport::HIBERNATION_ENTRY)},
-                                    },
-                                    VehiclePropValue{
                                             .prop = toInt(VehicleProperty::AP_POWER_STATE_REQ),
                                             .status = VehiclePropertyStatus::AVAILABLE,
                                             .value.int32Values =
                                                     {toInt(VehicleApPowerStateReq::FINISHED), 0},
                                     },
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::AP_POWER_STATE_REPORT),
+                                            .value.int32Values = {toInt(
+                                                    VehicleApPowerStateReport::HIBERNATION_ENTRY)},
+                                    },
                             },
             },
             SetSpecialValueTestCase{
@@ -785,16 +784,16 @@
                     .expectedValuesToGet =
                             {
                                     VehiclePropValue{
-                                            .prop = toInt(VehicleProperty::AP_POWER_STATE_REPORT),
-                                            .value.int32Values = {toInt(
-                                                    VehicleApPowerStateReport::SHUTDOWN_START)},
-                                    },
-                                    VehiclePropValue{
                                             .prop = toInt(VehicleProperty::AP_POWER_STATE_REQ),
                                             .status = VehiclePropertyStatus::AVAILABLE,
                                             .value.int32Values =
                                                     {toInt(VehicleApPowerStateReq::FINISHED), 0},
                                     },
+                                    VehiclePropValue{
+                                            .prop = toInt(VehicleProperty::AP_POWER_STATE_REPORT),
+                                            .value.int32Values = {toInt(
+                                                    VehicleApPowerStateReport::SHUTDOWN_START)},
+                                    },
                             },
             },
             SetSpecialValueTestCase{
@@ -915,7 +914,7 @@
     // Some of the updated properties might be the same as default config, thus not causing
     // a property change event. So the changed properties should be a subset of all the updated
     // properties.
-    ASSERT_THAT(getChangedProperties(), WhenSortedBy(mPropValueCmp, IsSubsetOf(gotValues)));
+    ASSERT_THAT(getChangedProperties(), WhenSortedBy(mPropValueCmp, Eq(gotValues)));
 }
 
 INSTANTIATE_TEST_SUITE_P(
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
index cc3c641..0033fee 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
@@ -41,5 +41,4 @@
   void updateSourceMetadata(in android.hardware.audio.common.SourceMetadata sourceMetadata);
   void updateSinkMetadata(in android.hardware.audio.common.SinkMetadata sinkMetadata);
   void setLatencyMode(in android.hardware.bluetooth.audio.LatencyMode latencyMode);
-  void setCodecType(in android.hardware.bluetooth.audio.CodecType codecType);
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
index 81c2ce2..9f8007b 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
@@ -87,11 +87,4 @@
      * @param latencyMode latency mode from audio
      */
     void setLatencyMode(in LatencyMode latencyMode);
-
-    /**
-     * Called when codec type is changed.
-     *
-     * @param codecType codec type from audio
-     */
-    void setCodecType(in CodecType codecType);
 }
diff --git a/bluetooth/audio/aidl/vts/Android.bp b/bluetooth/audio/aidl/vts/Android.bp
new file mode 100644
index 0000000..a662aaa
--- /dev/null
+++ b/bluetooth/audio/aidl/vts/Android.bp
@@ -0,0 +1,31 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+    name: "VtsHalBluetoothAudioTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: ["VtsHalBluetoothAudioTargetTest.cpp"],
+    shared_libs: [
+        "android.hardware.audio.common-V1-ndk",
+        "android.hardware.bluetooth.audio-V1-ndk",
+        "android.hardware.common-V2-ndk",
+        "android.hardware.common.fmq-V1-ndk",
+        "libbase",
+        "libbinder_ndk",
+        "libcutils",
+        "libfmq",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
diff --git a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
new file mode 100644
index 0000000..307403b
--- /dev/null
+++ b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
@@ -0,0 +1,1498 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/bluetooth/audio/BnBluetoothAudioPort.h>
+#include <aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.h>
+#include <aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.h>
+#include <android/binder_auto_utils.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <fmq/AidlMessageQueue.h>
+
+#include <cstdint>
+#include <future>
+#include <unordered_set>
+#include <vector>
+
+using aidl::android::hardware::audio::common::SinkMetadata;
+using aidl::android::hardware::audio::common::SourceMetadata;
+using aidl::android::hardware::bluetooth::audio::AacCapabilities;
+using aidl::android::hardware::bluetooth::audio::AacConfiguration;
+using aidl::android::hardware::bluetooth::audio::AptxCapabilities;
+using aidl::android::hardware::bluetooth::audio::AptxConfiguration;
+using aidl::android::hardware::bluetooth::audio::AudioCapabilities;
+using aidl::android::hardware::bluetooth::audio::AudioConfiguration;
+using aidl::android::hardware::bluetooth::audio::BnBluetoothAudioPort;
+using aidl::android::hardware::bluetooth::audio::ChannelMode;
+using aidl::android::hardware::bluetooth::audio::CodecCapabilities;
+using aidl::android::hardware::bluetooth::audio::CodecConfiguration;
+using aidl::android::hardware::bluetooth::audio::CodecType;
+using aidl::android::hardware::bluetooth::audio::IBluetoothAudioPort;
+using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider;
+using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProviderFactory;
+using aidl::android::hardware::bluetooth::audio::LatencyMode;
+using aidl::android::hardware::bluetooth::audio::Lc3Capabilities;
+using aidl::android::hardware::bluetooth::audio::Lc3Configuration;
+using aidl::android::hardware::bluetooth::audio::LdacCapabilities;
+using aidl::android::hardware::bluetooth::audio::LdacConfiguration;
+using aidl::android::hardware::bluetooth::audio::
+    LeAudioCodecCapabilitiesSetting;
+using aidl::android::hardware::bluetooth::audio::LeAudioCodecConfiguration;
+using aidl::android::hardware::bluetooth::audio::LeAudioConfiguration;
+using aidl::android::hardware::bluetooth::audio::PcmConfiguration;
+using aidl::android::hardware::bluetooth::audio::PresentationPosition;
+using aidl::android::hardware::bluetooth::audio::SbcAllocMethod;
+using aidl::android::hardware::bluetooth::audio::SbcCapabilities;
+using aidl::android::hardware::bluetooth::audio::SbcChannelMode;
+using aidl::android::hardware::bluetooth::audio::SbcConfiguration;
+using aidl::android::hardware::bluetooth::audio::SessionType;
+using aidl::android::hardware::bluetooth::audio::UnicastCapability;
+using aidl::android::hardware::common::fmq::MQDescriptor;
+using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using android::AidlMessageQueue;
+using android::ProcessState;
+using android::String16;
+using ndk::ScopedAStatus;
+using ndk::SpAIBinder;
+
+using MqDataType = int8_t;
+using MqDataMode = SynchronizedReadWrite;
+using DataMQ = AidlMessageQueue<MqDataType, MqDataMode>;
+using DataMQDesc = MQDescriptor<MqDataType, MqDataMode>;
+
+// Constants
+
+static constexpr int32_t a2dp_sample_rates[] = {0, 44100, 48000, 88200, 96000};
+static constexpr int8_t a2dp_bits_per_samples[] = {0, 16, 24, 32};
+static constexpr ChannelMode a2dp_channel_modes[] = {
+    ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
+static constexpr CodecType a2dp_codec_types[] = {
+    CodecType::UNKNOWN, CodecType::SBC,          CodecType::AAC,
+    CodecType::APTX,    CodecType::APTX_HD,      CodecType::LDAC,
+    CodecType::LC3,     CodecType::APTX_ADAPTIVE};
+
+// Helpers
+
+template <typename T>
+struct identity {
+  typedef T type;
+};
+
+template <class T>
+bool contained_in_vector(const std::vector<T>& vector,
+                         const typename identity<T>::type& target) {
+  return std::find(vector.begin(), vector.end(), target) != vector.end();
+}
+
+void copy_codec_specific(CodecConfiguration::CodecSpecific& dst,
+                         const CodecConfiguration::CodecSpecific& src) {
+  switch (src.getTag()) {
+    case CodecConfiguration::CodecSpecific::sbcConfig:
+      dst.set<CodecConfiguration::CodecSpecific::sbcConfig>(
+          src.get<CodecConfiguration::CodecSpecific::sbcConfig>());
+      break;
+    case CodecConfiguration::CodecSpecific::aacConfig:
+      dst.set<CodecConfiguration::CodecSpecific::aacConfig>(
+          src.get<CodecConfiguration::CodecSpecific::aacConfig>());
+      break;
+    case CodecConfiguration::CodecSpecific::ldacConfig:
+      dst.set<CodecConfiguration::CodecSpecific::ldacConfig>(
+          src.get<CodecConfiguration::CodecSpecific::ldacConfig>());
+      break;
+    case CodecConfiguration::CodecSpecific::aptxConfig:
+      dst.set<CodecConfiguration::CodecSpecific::aptxConfig>(
+          src.get<CodecConfiguration::CodecSpecific::aptxConfig>());
+      break;
+    case CodecConfiguration::CodecSpecific::lc3Config:
+      dst.set<CodecConfiguration::CodecSpecific::lc3Config>(
+          src.get<CodecConfiguration::CodecSpecific::lc3Config>());
+      break;
+    case CodecConfiguration::CodecSpecific::aptxAdaptiveConfig:
+      dst.set<CodecConfiguration::CodecSpecific::aptxAdaptiveConfig>(
+          src.get<CodecConfiguration::CodecSpecific::aptxAdaptiveConfig>());
+      break;
+    default:
+      break;
+  }
+}
+
+class BluetoothAudioPort : public BnBluetoothAudioPort {
+ public:
+  BluetoothAudioPort() {}
+
+  ndk::ScopedAStatus startStream() { return ScopedAStatus::ok(); }
+
+  ndk::ScopedAStatus suspendStream() { return ScopedAStatus::ok(); }
+
+  ndk::ScopedAStatus stopStream() { return ScopedAStatus::ok(); }
+
+  ndk::ScopedAStatus getPresentationPosition(PresentationPosition*) {
+    return ScopedAStatus::ok();
+  }
+
+  ndk::ScopedAStatus updateSourceMetadata(const SourceMetadata&) {
+    return ScopedAStatus::ok();
+  }
+
+  ndk::ScopedAStatus updateSinkMetadata(const SinkMetadata&) {
+    return ScopedAStatus::ok();
+  }
+
+  ndk::ScopedAStatus setLatencyMode(const LatencyMode) {
+    return ScopedAStatus::ok();
+  }
+
+  ndk::ScopedAStatus setCodecType(const CodecType) {
+    return ScopedAStatus::ok();
+  }
+
+ protected:
+  virtual ~BluetoothAudioPort() = default;
+};
+
+class BluetoothAudioProviderFactoryAidl
+    : public testing::TestWithParam<std::string> {
+ public:
+  virtual void SetUp() override {
+    provider_factory_ = IBluetoothAudioProviderFactory::fromBinder(
+        SpAIBinder(AServiceManager_getService(GetParam().c_str())));
+    audio_provider_ = nullptr;
+    ASSERT_NE(provider_factory_, nullptr);
+  }
+
+  virtual void TearDown() override { provider_factory_ = nullptr; }
+
+  void GetProviderCapabilitiesHelper(const SessionType& session_type) {
+    temp_provider_capabilities_.clear();
+    auto aidl_retval = provider_factory_->getProviderCapabilities(
+        session_type, &temp_provider_capabilities_);
+    // AIDL calls should not be failed and callback has to be executed
+    ASSERT_TRUE(aidl_retval.isOk());
+    switch (session_type) {
+      case SessionType::UNKNOWN: {
+        ASSERT_TRUE(temp_provider_capabilities_.empty());
+      } break;
+      case SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH:
+      case SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
+      case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
+      case SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH:
+      case SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH: {
+        // All software paths are mandatory and must have exact 1
+        // "PcmParameters"
+        ASSERT_EQ(temp_provider_capabilities_.size(), 1);
+        ASSERT_EQ(temp_provider_capabilities_[0].getTag(),
+                  AudioCapabilities::pcmCapabilities);
+      } break;
+      case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH: {
+        std::unordered_set<CodecType> codec_types;
+        // empty capability means offload is unsupported
+        for (auto& audio_capability : temp_provider_capabilities_) {
+          ASSERT_EQ(audio_capability.getTag(),
+                    AudioCapabilities::a2dpCapabilities);
+          const auto& codec_capabilities =
+              audio_capability.get<AudioCapabilities::a2dpCapabilities>();
+          // Every codec can present once at most
+          ASSERT_EQ(codec_types.count(codec_capabilities.codecType), 0);
+          switch (codec_capabilities.codecType) {
+            case CodecType::SBC:
+              ASSERT_EQ(codec_capabilities.capabilities.getTag(),
+                        CodecCapabilities::Capabilities::sbcCapabilities);
+              break;
+            case CodecType::AAC:
+              ASSERT_EQ(codec_capabilities.capabilities.getTag(),
+                        CodecCapabilities::Capabilities::aacCapabilities);
+              break;
+            case CodecType::APTX:
+            case CodecType::APTX_HD:
+              ASSERT_EQ(codec_capabilities.capabilities.getTag(),
+                        CodecCapabilities::Capabilities::aptxCapabilities);
+              break;
+            case CodecType::LDAC:
+              ASSERT_EQ(codec_capabilities.capabilities.getTag(),
+                        CodecCapabilities::Capabilities::ldacCapabilities);
+              break;
+            case CodecType::LC3:
+              ASSERT_EQ(codec_capabilities.capabilities.getTag(),
+                        CodecCapabilities::Capabilities::lc3Capabilities);
+              break;
+            case CodecType::APTX_ADAPTIVE:
+            case CodecType::VENDOR:
+            case CodecType::UNKNOWN:
+              break;
+          }
+          codec_types.insert(codec_capabilities.codecType);
+        }
+      } break;
+      case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
+      case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
+      case SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH: {
+        ASSERT_FALSE(temp_provider_capabilities_.empty());
+        for (auto audio_capability : temp_provider_capabilities_) {
+          ASSERT_EQ(audio_capability.getTag(),
+                    AudioCapabilities::leAudioCapabilities);
+        }
+      } break;
+    }
+  }
+
+  /***
+   * This helps to open the specified provider and check the openProvider()
+   * has corruct return values. BUT, to keep it simple, it does not consider
+   * the capability, and please do so at the SetUp of each session's test.
+   ***/
+  void OpenProviderHelper(const SessionType& session_type) {
+    auto aidl_retval =
+        provider_factory_->openProvider(session_type, &audio_provider_);
+    if (aidl_retval.isOk()) {
+      ASSERT_NE(session_type, SessionType::UNKNOWN);
+      ASSERT_NE(audio_provider_, nullptr);
+      audio_port_ = ndk::SharedRefBase::make<BluetoothAudioPort>();
+    } else {
+      // Hardware offloading is optional
+      ASSERT_TRUE(
+          session_type == SessionType::UNKNOWN ||
+          session_type ==
+              SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+          session_type ==
+              SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
+          session_type ==
+              SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+          session_type ==
+              SessionType::
+                  LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
+      ASSERT_EQ(audio_provider_, nullptr);
+    }
+  }
+
+  bool IsPcmConfigSupported(const PcmConfiguration& pcm_config) {
+    if (temp_provider_capabilities_.size() != 1 ||
+        temp_provider_capabilities_[0].getTag() !=
+            AudioCapabilities::pcmCapabilities) {
+      return false;
+    }
+    auto pcm_capability = temp_provider_capabilities_[0]
+                              .get<AudioCapabilities::pcmCapabilities>();
+    return (contained_in_vector(pcm_capability.channelMode,
+                                pcm_config.channelMode) &&
+            contained_in_vector(pcm_capability.sampleRateHz,
+                                pcm_config.sampleRateHz) &&
+            contained_in_vector(pcm_capability.bitsPerSample,
+                                pcm_config.bitsPerSample));
+  }
+
+  std::shared_ptr<IBluetoothAudioProviderFactory> provider_factory_;
+  std::shared_ptr<IBluetoothAudioProvider> audio_provider_;
+  std::shared_ptr<IBluetoothAudioPort> audio_port_;
+  std::vector<AudioCapabilities> temp_provider_capabilities_;
+
+  static constexpr SessionType kSessionTypes[] = {
+      SessionType::UNKNOWN,
+      SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
+      SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+      SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
+      SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
+      SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
+      SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+      SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+      SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
+      SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+  };
+};
+
+/**
+ * Test whether we can get the FactoryService from HIDL
+ */
+TEST_P(BluetoothAudioProviderFactoryAidl, GetProviderFactoryService) {}
+
+/**
+ * Test whether we can open a provider for each provider returned by
+ * getProviderCapabilities() with non-empty capabalities
+ */
+TEST_P(BluetoothAudioProviderFactoryAidl,
+       OpenProviderAndCheckCapabilitiesBySession) {
+  for (auto session_type : kSessionTypes) {
+    GetProviderCapabilitiesHelper(session_type);
+    OpenProviderHelper(session_type);
+    // We must be able to open a provider if its getProviderCapabilities()
+    // returns non-empty list.
+    EXPECT_TRUE(temp_provider_capabilities_.empty() ||
+                audio_provider_ != nullptr);
+  }
+}
+
+/**
+ * openProvider A2DP_SOFTWARE_ENCODING_DATAPATH
+ */
+class BluetoothAudioProviderA2dpSoftwareAidl
+    : public BluetoothAudioProviderFactoryAidl {
+ public:
+  virtual void SetUp() override {
+    BluetoothAudioProviderFactoryAidl::SetUp();
+    GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
+    OpenProviderHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
+    ASSERT_NE(audio_provider_, nullptr);
+  }
+
+  virtual void TearDown() override {
+    audio_port_ = nullptr;
+    audio_provider_ = nullptr;
+    BluetoothAudioProviderFactoryAidl::TearDown();
+  }
+};
+
+/**
+ * Test whether we can open a provider of type
+ */
+TEST_P(BluetoothAudioProviderA2dpSoftwareAidl, OpenA2dpSoftwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
+ * different PCM config
+ */
+TEST_P(BluetoothAudioProviderA2dpSoftwareAidl,
+       StartAndEndA2dpSoftwareSessionWithPossiblePcmConfig) {
+  for (auto sample_rate : a2dp_sample_rates) {
+    for (auto bits_per_sample : a2dp_bits_per_samples) {
+      for (auto channel_mode : a2dp_channel_modes) {
+        PcmConfiguration pcm_config{
+            .sampleRateHz = sample_rate,
+            .bitsPerSample = bits_per_sample,
+            .channelMode = channel_mode,
+        };
+        bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
+        DataMQDesc mq_desc;
+        auto aidl_retval = audio_provider_->startSession(
+            audio_port_, AudioConfiguration(pcm_config), &mq_desc);
+        DataMQ data_mq(mq_desc);
+
+        EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
+        if (is_codec_config_valid) {
+          EXPECT_TRUE(data_mq.isValid());
+        }
+        EXPECT_TRUE(audio_provider_->endSession().isOk());
+      }
+    }
+  }
+}
+
+/**
+ * openProvider A2DP_HARDWARE_OFFLOAD_DATAPATH
+ */
+class BluetoothAudioProviderA2dpHardwareAidl
+    : public BluetoothAudioProviderFactoryAidl {
+ public:
+  virtual void SetUp() override {
+    BluetoothAudioProviderFactoryAidl::SetUp();
+    GetProviderCapabilitiesHelper(
+        SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
+    OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
+    ASSERT_TRUE(temp_provider_capabilities_.empty() ||
+                audio_provider_ != nullptr);
+  }
+
+  virtual void TearDown() override {
+    audio_port_ = nullptr;
+    audio_provider_ = nullptr;
+    BluetoothAudioProviderFactoryAidl::TearDown();
+  }
+
+  bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
+
+  void GetA2dpOffloadCapabilityHelper(const CodecType& codec_type) {
+    temp_codec_capabilities_ = nullptr;
+    for (auto codec_capability : temp_provider_capabilities_) {
+      auto& a2dp_capabilities =
+          codec_capability.get<AudioCapabilities::a2dpCapabilities>();
+      if (a2dp_capabilities.codecType != codec_type) {
+        continue;
+      }
+      temp_codec_capabilities_ = &a2dp_capabilities;
+    }
+  }
+
+  std::vector<CodecConfiguration::CodecSpecific>
+  GetSbcCodecSpecificSupportedList(bool supported) {
+    std::vector<CodecConfiguration::CodecSpecific> sbc_codec_specifics;
+    if (!supported) {
+      SbcConfiguration sbc_config{.sampleRateHz = 0, .bitsPerSample = 0};
+      sbc_codec_specifics.push_back(
+          CodecConfiguration::CodecSpecific(sbc_config));
+      return sbc_codec_specifics;
+    }
+    GetA2dpOffloadCapabilityHelper(CodecType::SBC);
+    if (temp_codec_capabilities_ == nullptr ||
+        temp_codec_capabilities_->codecType != CodecType::SBC) {
+      return sbc_codec_specifics;
+    }
+    // parse the capability
+    auto& sbc_capability =
+        temp_codec_capabilities_->capabilities
+            .get<CodecCapabilities::Capabilities::sbcCapabilities>();
+    if (sbc_capability.minBitpool > sbc_capability.maxBitpool) {
+      return sbc_codec_specifics;
+    }
+
+    // combine those parameters into one list of
+    // CodecConfiguration::CodecSpecific
+    for (int32_t sample_rate : sbc_capability.sampleRateHz) {
+      for (int8_t block_length : sbc_capability.blockLength) {
+        for (int8_t num_subbands : sbc_capability.numSubbands) {
+          for (int8_t bits_per_sample : sbc_capability.bitsPerSample) {
+            for (auto channel_mode : sbc_capability.channelMode) {
+              for (auto alloc_method : sbc_capability.allocMethod) {
+                SbcConfiguration sbc_data = {
+                    .sampleRateHz = sample_rate,
+                    .channelMode = channel_mode,
+                    .blockLength = block_length,
+                    .numSubbands = num_subbands,
+                    .allocMethod = alloc_method,
+                    .bitsPerSample = bits_per_sample,
+                    .minBitpool = sbc_capability.minBitpool,
+                    .maxBitpool = sbc_capability.maxBitpool};
+                sbc_codec_specifics.push_back(
+                    CodecConfiguration::CodecSpecific(sbc_data));
+              }
+            }
+          }
+        }
+      }
+    }
+    return sbc_codec_specifics;
+  }
+
+  std::vector<CodecConfiguration::CodecSpecific>
+  GetAacCodecSpecificSupportedList(bool supported) {
+    std::vector<CodecConfiguration::CodecSpecific> aac_codec_specifics;
+    if (!supported) {
+      AacConfiguration aac_config{.sampleRateHz = 0, .bitsPerSample = 0};
+      aac_codec_specifics.push_back(
+          CodecConfiguration::CodecSpecific(aac_config));
+      return aac_codec_specifics;
+    }
+    GetA2dpOffloadCapabilityHelper(CodecType::AAC);
+    if (temp_codec_capabilities_ == nullptr ||
+        temp_codec_capabilities_->codecType != CodecType::AAC) {
+      return aac_codec_specifics;
+    }
+    // parse the capability
+    auto& aac_capability =
+        temp_codec_capabilities_->capabilities
+            .get<CodecCapabilities::Capabilities::aacCapabilities>();
+
+    std::vector<bool> variable_bit_rate_enableds = {false};
+    if (aac_capability.variableBitRateSupported) {
+      variable_bit_rate_enableds.push_back(true);
+    }
+
+    // combine those parameters into one list of
+    // CodecConfiguration::CodecSpecific
+    for (auto object_type : aac_capability.objectType) {
+      for (int32_t sample_rate : aac_capability.sampleRateHz) {
+        for (auto channel_mode : aac_capability.channelMode) {
+          for (int8_t bits_per_sample : aac_capability.bitsPerSample) {
+            for (auto variable_bit_rate_enabled : variable_bit_rate_enableds) {
+              AacConfiguration aac_data{
+                  .objectType = object_type,
+                  .sampleRateHz = sample_rate,
+                  .channelMode = channel_mode,
+                  .variableBitRateEnabled = variable_bit_rate_enabled,
+                  .bitsPerSample = bits_per_sample};
+              aac_codec_specifics.push_back(
+                  CodecConfiguration::CodecSpecific(aac_data));
+            }
+          }
+        }
+      }
+    }
+    return aac_codec_specifics;
+  }
+
+  std::vector<CodecConfiguration::CodecSpecific>
+  GetLdacCodecSpecificSupportedList(bool supported) {
+    std::vector<CodecConfiguration::CodecSpecific> ldac_codec_specifics;
+    if (!supported) {
+      LdacConfiguration ldac_config{.sampleRateHz = 0, .bitsPerSample = 0};
+      ldac_codec_specifics.push_back(
+          CodecConfiguration::CodecSpecific(ldac_config));
+      return ldac_codec_specifics;
+    }
+    GetA2dpOffloadCapabilityHelper(CodecType::LDAC);
+    if (temp_codec_capabilities_ == nullptr ||
+        temp_codec_capabilities_->codecType != CodecType::LDAC) {
+      return ldac_codec_specifics;
+    }
+    // parse the capability
+    auto& ldac_capability =
+        temp_codec_capabilities_->capabilities
+            .get<CodecCapabilities::Capabilities::ldacCapabilities>();
+
+    // combine those parameters into one list of
+    // CodecConfiguration::CodecSpecific
+    for (int32_t sample_rate : ldac_capability.sampleRateHz) {
+      for (int8_t bits_per_sample : ldac_capability.bitsPerSample) {
+        for (auto channel_mode : ldac_capability.channelMode) {
+          for (auto quality_index : ldac_capability.qualityIndex) {
+            LdacConfiguration ldac_data{.sampleRateHz = sample_rate,
+                                        .channelMode = channel_mode,
+                                        .qualityIndex = quality_index,
+                                        .bitsPerSample = bits_per_sample};
+            ldac_codec_specifics.push_back(
+                CodecConfiguration::CodecSpecific(ldac_data));
+          }
+        }
+      }
+    }
+    return ldac_codec_specifics;
+  }
+
+  std::vector<CodecConfiguration::CodecSpecific>
+  GetAptxCodecSpecificSupportedList(bool is_hd, bool supported) {
+    std::vector<CodecConfiguration::CodecSpecific> aptx_codec_specifics;
+    if (!supported) {
+      AptxConfiguration aptx_config{.sampleRateHz = 0, .bitsPerSample = 0};
+      aptx_codec_specifics.push_back(
+          CodecConfiguration::CodecSpecific(aptx_config));
+      return aptx_codec_specifics;
+    }
+    GetA2dpOffloadCapabilityHelper(
+        (is_hd ? CodecType::APTX_HD : CodecType::APTX));
+    if (temp_codec_capabilities_ == nullptr) {
+      return aptx_codec_specifics;
+    }
+    if ((is_hd && temp_codec_capabilities_->codecType != CodecType::APTX_HD) ||
+        (!is_hd && temp_codec_capabilities_->codecType != CodecType::APTX)) {
+      return aptx_codec_specifics;
+    }
+
+    // parse the capability
+    auto& aptx_capability =
+        temp_codec_capabilities_->capabilities
+            .get<CodecCapabilities::Capabilities::aptxCapabilities>();
+
+    // combine those parameters into one list of
+    // CodecConfiguration::CodecSpecific
+    for (int8_t bits_per_sample : aptx_capability.bitsPerSample) {
+      for (int32_t sample_rate : aptx_capability.sampleRateHz) {
+        for (auto channel_mode : aptx_capability.channelMode) {
+          AptxConfiguration aptx_data{.sampleRateHz = sample_rate,
+                                      .channelMode = channel_mode,
+                                      .bitsPerSample = bits_per_sample};
+          aptx_codec_specifics.push_back(
+              CodecConfiguration::CodecSpecific(aptx_data));
+        }
+      }
+    }
+    return aptx_codec_specifics;
+  }
+
+  std::vector<CodecConfiguration::CodecSpecific>
+  GetLc3CodecSpecificSupportedList(bool supported) {
+    std::vector<CodecConfiguration::CodecSpecific> lc3_codec_specifics;
+    if (!supported) {
+      Lc3Configuration lc3_config{.samplingFrequencyHz = 0,
+                                  .frameDurationUs = 0};
+      lc3_codec_specifics.push_back(
+          CodecConfiguration::CodecSpecific(lc3_config));
+      return lc3_codec_specifics;
+    }
+    GetA2dpOffloadCapabilityHelper(CodecType::LC3);
+    if (temp_codec_capabilities_ == nullptr ||
+        temp_codec_capabilities_->codecType != CodecType::LC3) {
+      return lc3_codec_specifics;
+    }
+    // parse the capability
+    auto& lc3_capability =
+        temp_codec_capabilities_->capabilities
+            .get<CodecCapabilities::Capabilities::lc3Capabilities>();
+
+    // combine those parameters into one list of
+    // CodecConfiguration::CodecSpecific
+    for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
+      for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
+        for (auto channel_mode : lc3_capability.channelMode) {
+          Lc3Configuration lc3_data{.samplingFrequencyHz = samplingFrequencyHz,
+                                    .channelMode = channel_mode,
+                                    .frameDurationUs = frameDurationUs};
+          lc3_codec_specifics.push_back(
+              CodecConfiguration::CodecSpecific(lc3_data));
+        }
+      }
+    }
+    return lc3_codec_specifics;
+  }
+
+  // temp storage saves the specified codec capability by
+  // GetOffloadCodecCapabilityHelper()
+  CodecCapabilities* temp_codec_capabilities_;
+};
+
+/**
+ * Test whether we can open a provider of type
+ */
+TEST_P(BluetoothAudioProviderA2dpHardwareAidl, OpenA2dpHardwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
+ * SBC hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderA2dpHardwareAidl,
+       StartAndEndA2dpSbcHardwareSession) {
+  if (!IsOffloadSupported()) {
+    return;
+  }
+
+  CodecConfiguration codec_config = {
+      .codecType = CodecType::SBC,
+      .encodedAudioBitrate = 328000,
+      .peerMtu = 1005,
+      .isScmstEnabled = false,
+  };
+  auto sbc_codec_specifics = GetSbcCodecSpecificSupportedList(true);
+
+  for (auto& codec_specific : sbc_codec_specifics) {
+    copy_codec_specific(codec_config.config, codec_specific);
+    DataMQDesc mq_desc;
+    auto aidl_retval = audio_provider_->startSession(
+        audio_port_, AudioConfiguration(codec_config), &mq_desc);
+
+    ASSERT_TRUE(aidl_retval.isOk());
+    EXPECT_TRUE(audio_provider_->endSession().isOk());
+  }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
+ * AAC hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderA2dpHardwareAidl,
+       StartAndEndA2dpAacHardwareSession) {
+  if (!IsOffloadSupported()) {
+    return;
+  }
+
+  CodecConfiguration codec_config = {
+      .codecType = CodecType::AAC,
+      .encodedAudioBitrate = 320000,
+      .peerMtu = 1005,
+      .isScmstEnabled = false,
+  };
+  auto aac_codec_specifics = GetAacCodecSpecificSupportedList(true);
+
+  for (auto& codec_specific : aac_codec_specifics) {
+    copy_codec_specific(codec_config.config, codec_specific);
+    DataMQDesc mq_desc;
+    auto aidl_retval = audio_provider_->startSession(
+        audio_port_, AudioConfiguration(codec_config), &mq_desc);
+
+    ASSERT_TRUE(aidl_retval.isOk());
+    EXPECT_TRUE(audio_provider_->endSession().isOk());
+  }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
+ * LDAC hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderA2dpHardwareAidl,
+       StartAndEndA2dpLdacHardwareSession) {
+  if (!IsOffloadSupported()) {
+    return;
+  }
+
+  CodecConfiguration codec_config = {
+      .codecType = CodecType::LDAC,
+      .encodedAudioBitrate = 990000,
+      .peerMtu = 1005,
+      .isScmstEnabled = false,
+  };
+  auto ldac_codec_specifics = GetLdacCodecSpecificSupportedList(true);
+
+  for (auto& codec_specific : ldac_codec_specifics) {
+    copy_codec_specific(codec_config.config, codec_specific);
+    DataMQDesc mq_desc;
+    auto aidl_retval = audio_provider_->startSession(
+        audio_port_, AudioConfiguration(codec_config), &mq_desc);
+
+    ASSERT_TRUE(aidl_retval.isOk());
+    EXPECT_TRUE(audio_provider_->endSession().isOk());
+  }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
+ * LDAC hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderA2dpHardwareAidl,
+       StartAndEndA2dpLc3HardwareSession) {
+  if (!IsOffloadSupported()) {
+    return;
+  }
+
+  CodecConfiguration codec_config = {
+      .codecType = CodecType::LC3,
+      .encodedAudioBitrate = 990000,
+      .peerMtu = 1005,
+      .isScmstEnabled = false,
+  };
+  auto lc3_codec_specifics = GetLc3CodecSpecificSupportedList(true);
+
+  for (auto& codec_specific : lc3_codec_specifics) {
+    copy_codec_specific(codec_config.config, codec_specific);
+    DataMQDesc mq_desc;
+    auto aidl_retval = audio_provider_->startSession(
+        audio_port_, AudioConfiguration(codec_config), &mq_desc);
+
+    ASSERT_TRUE(aidl_retval.isOk());
+    EXPECT_TRUE(audio_provider_->endSession().isOk());
+  }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
+ * AptX hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderA2dpHardwareAidl,
+       StartAndEndA2dpAptxHardwareSession) {
+  if (!IsOffloadSupported()) {
+    return;
+  }
+
+  for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
+    CodecConfiguration codec_config = {
+        .codecType = codec_type,
+        .encodedAudioBitrate =
+            (codec_type == CodecType::APTX ? 352000 : 576000),
+        .peerMtu = 1005,
+        .isScmstEnabled = false,
+    };
+
+    auto aptx_codec_specifics = GetAptxCodecSpecificSupportedList(
+        (codec_type == CodecType::APTX_HD ? true : false), true);
+
+    for (auto& codec_specific : aptx_codec_specifics) {
+      copy_codec_specific(codec_config.config, codec_specific);
+      DataMQDesc mq_desc;
+      auto aidl_retval = audio_provider_->startSession(
+          audio_port_, AudioConfiguration(codec_config), &mq_desc);
+
+      ASSERT_TRUE(aidl_retval.isOk());
+      EXPECT_TRUE(audio_provider_->endSession().isOk());
+    }
+  }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
+ * an invalid codec config
+ */
+TEST_P(BluetoothAudioProviderA2dpHardwareAidl,
+       StartAndEndA2dpHardwareSessionInvalidCodecConfig) {
+  if (!IsOffloadSupported()) {
+    return;
+  }
+  ASSERT_NE(audio_provider_, nullptr);
+
+  std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
+  for (auto codec_type : a2dp_codec_types) {
+    switch (codec_type) {
+      case CodecType::SBC:
+        codec_specifics = GetSbcCodecSpecificSupportedList(false);
+        break;
+      case CodecType::AAC:
+        codec_specifics = GetAacCodecSpecificSupportedList(false);
+        break;
+      case CodecType::LDAC:
+        codec_specifics = GetLdacCodecSpecificSupportedList(false);
+        break;
+      case CodecType::APTX:
+        codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
+        break;
+      case CodecType::APTX_HD:
+        codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
+        break;
+      case CodecType::LC3:
+        codec_specifics = GetLc3CodecSpecificSupportedList(false);
+        continue;
+      case CodecType::APTX_ADAPTIVE:
+      case CodecType::VENDOR:
+      case CodecType::UNKNOWN:
+        codec_specifics.clear();
+        break;
+    }
+    if (codec_specifics.empty()) {
+      continue;
+    }
+
+    CodecConfiguration codec_config = {
+        .codecType = codec_type,
+        .encodedAudioBitrate = 328000,
+        .peerMtu = 1005,
+        .isScmstEnabled = false,
+    };
+    for (auto codec_specific : codec_specifics) {
+      copy_codec_specific(codec_config.config, codec_specific);
+      DataMQDesc mq_desc;
+      auto aidl_retval = audio_provider_->startSession(
+          audio_port_, AudioConfiguration(codec_config), &mq_desc);
+
+      // AIDL call should fail on invalid codec
+      ASSERT_FALSE(aidl_retval.isOk());
+      EXPECT_TRUE(audio_provider_->endSession().isOk());
+    }
+  }
+}
+
+/**
+ * openProvider HEARING_AID_SOFTWARE_ENCODING_DATAPATH
+ */
+class BluetoothAudioProviderHearingAidSoftwareAidl
+    : public BluetoothAudioProviderFactoryAidl {
+ public:
+  virtual void SetUp() override {
+    BluetoothAudioProviderFactoryAidl::SetUp();
+    GetProviderCapabilitiesHelper(
+        SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
+    OpenProviderHelper(SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
+    ASSERT_NE(audio_provider_, nullptr);
+  }
+
+  virtual void TearDown() override {
+    audio_port_ = nullptr;
+    audio_provider_ = nullptr;
+    BluetoothAudioProviderFactoryAidl::TearDown();
+  }
+
+  static constexpr int32_t hearing_aid_sample_rates_[] = {0, 16000, 24000};
+  static constexpr int8_t hearing_aid_bits_per_samples_[] = {0, 16, 24};
+  static constexpr ChannelMode hearing_aid_channel_modes_[] = {
+      ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
+};
+
+/**
+ * Test whether we can open a provider of type
+ */
+TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
+       OpenHearingAidSoftwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH can be started and
+ * stopped with different PCM config
+ */
+TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
+       StartAndEndHearingAidSessionWithPossiblePcmConfig) {
+  for (int32_t sample_rate : hearing_aid_sample_rates_) {
+    for (int8_t bits_per_sample : hearing_aid_bits_per_samples_) {
+      for (auto channel_mode : hearing_aid_channel_modes_) {
+        PcmConfiguration pcm_config{
+            .sampleRateHz = sample_rate,
+            .bitsPerSample = bits_per_sample,
+            .channelMode = channel_mode,
+        };
+        bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
+        DataMQDesc mq_desc;
+        auto aidl_retval = audio_provider_->startSession(
+            audio_port_, AudioConfiguration(pcm_config), &mq_desc);
+        DataMQ data_mq(mq_desc);
+
+        EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
+        if (is_codec_config_valid) {
+          EXPECT_TRUE(data_mq.isValid());
+        }
+        EXPECT_TRUE(audio_provider_->endSession().isOk());
+      }
+    }
+  }
+}
+
+/**
+ * openProvider LE_AUDIO_SOFTWARE_ENCODING_DATAPATH
+ */
+class BluetoothAudioProviderLeAudioOutputSoftwareAidl
+    : public BluetoothAudioProviderFactoryAidl {
+ public:
+  virtual void SetUp() override {
+    BluetoothAudioProviderFactoryAidl::SetUp();
+    GetProviderCapabilitiesHelper(
+        SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
+    OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
+    ASSERT_NE(audio_provider_, nullptr);
+  }
+
+  virtual void TearDown() override {
+    audio_port_ = nullptr;
+    audio_provider_ = nullptr;
+    BluetoothAudioProviderFactoryAidl::TearDown();
+  }
+
+  static constexpr int32_t le_audio_output_sample_rates_[] = {
+      0, 8000, 16000, 24000, 32000, 44100, 48000,
+  };
+  static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
+  static constexpr ChannelMode le_audio_output_channel_modes_[] = {
+      ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
+  static constexpr int32_t le_audio_output_data_interval_us_[] = {
+      0 /* Invalid */, 10000 /* Valid 10ms */};
+};
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
+ * stopped
+ */
+TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
+       OpenLeAudioOutputSoftwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
+ * stopped with different PCM config
+ */
+TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
+       StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
+  for (auto sample_rate : le_audio_output_sample_rates_) {
+    for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
+      for (auto channel_mode : le_audio_output_channel_modes_) {
+        for (auto data_interval_us : le_audio_output_data_interval_us_) {
+          PcmConfiguration pcm_config{
+              .sampleRateHz = sample_rate,
+              .bitsPerSample = bits_per_sample,
+              .channelMode = channel_mode,
+              .dataIntervalUs = data_interval_us,
+          };
+          bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
+          DataMQDesc mq_desc;
+          auto aidl_retval = audio_provider_->startSession(
+              audio_port_, AudioConfiguration(pcm_config), &mq_desc);
+          DataMQ data_mq(mq_desc);
+
+          EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
+          if (is_codec_config_valid) {
+            EXPECT_TRUE(data_mq.isValid());
+          }
+          EXPECT_TRUE(audio_provider_->endSession().isOk());
+        }
+      }
+    }
+  }
+}
+
+/**
+ * openProvider LE_AUDIO_SOFTWARE_DECODED_DATAPATH
+ */
+class BluetoothAudioProviderLeAudioInputSoftwareAidl
+    : public BluetoothAudioProviderFactoryAidl {
+ public:
+  virtual void SetUp() override {
+    BluetoothAudioProviderFactoryAidl::SetUp();
+    GetProviderCapabilitiesHelper(
+        SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
+    OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
+    ASSERT_NE(audio_provider_, nullptr);
+  }
+
+  virtual void TearDown() override {
+    audio_port_ = nullptr;
+    audio_provider_ = nullptr;
+    BluetoothAudioProviderFactoryAidl::TearDown();
+  }
+
+  static constexpr int32_t le_audio_input_sample_rates_[] = {
+      0, 8000, 16000, 24000, 32000, 44100, 48000};
+  static constexpr int8_t le_audio_input_bits_per_samples_[] = {0, 16, 24};
+  static constexpr ChannelMode le_audio_input_channel_modes_[] = {
+      ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
+  static constexpr int32_t le_audio_input_data_interval_us_[] = {
+      0 /* Invalid */, 10000 /* Valid 10ms */};
+};
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH can be started and
+ * stopped
+ */
+TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
+       OpenLeAudioInputSoftwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH can be started and
+ * stopped with different PCM config
+ */
+TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
+       StartAndEndLeAudioInputSessionWithPossiblePcmConfig) {
+  for (auto sample_rate : le_audio_input_sample_rates_) {
+    for (auto bits_per_sample : le_audio_input_bits_per_samples_) {
+      for (auto channel_mode : le_audio_input_channel_modes_) {
+        for (auto data_interval_us : le_audio_input_data_interval_us_) {
+          PcmConfiguration pcm_config{
+              .sampleRateHz = sample_rate,
+              .bitsPerSample = bits_per_sample,
+              .channelMode = channel_mode,
+              .dataIntervalUs = data_interval_us,
+          };
+          bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
+          DataMQDesc mq_desc;
+          auto aidl_retval = audio_provider_->startSession(
+              audio_port_, AudioConfiguration(pcm_config), &mq_desc);
+          DataMQ data_mq(mq_desc);
+
+          EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
+          if (is_codec_config_valid) {
+            EXPECT_TRUE(data_mq.isValid());
+          }
+          EXPECT_TRUE(audio_provider_->endSession().isOk());
+        }
+      }
+    }
+  }
+}
+
+/**
+ * openProvider LE_AUDIO_HARDWARE_OFFLOAD_DECODED_DATAPATH
+ */
+class BluetoothAudioProviderLeAudioOutputHardwareAidl
+    : public BluetoothAudioProviderFactoryAidl {
+ public:
+  virtual void SetUp() override {
+    BluetoothAudioProviderFactoryAidl::SetUp();
+    GetProviderCapabilitiesHelper(
+        SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
+    OpenProviderHelper(
+        SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
+    ASSERT_TRUE(temp_provider_capabilities_.empty() ||
+                audio_provider_ != nullptr);
+  }
+
+  virtual void TearDown() override {
+    audio_port_ = nullptr;
+    audio_provider_ = nullptr;
+    BluetoothAudioProviderFactoryAidl::TearDown();
+  }
+
+  bool IsOffloadOutputSupported() {
+    for (auto& capability : temp_provider_capabilities_) {
+      if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
+        continue;
+      }
+      auto& le_audio_capability =
+          capability.get<AudioCapabilities::leAudioCapabilities>();
+      if (le_audio_capability.unicastEncodeCapability.codecType !=
+          CodecType::UNKNOWN)
+        return true;
+    }
+    return false;
+  }
+
+  std::vector<Lc3Configuration> GetUnicastLc3SupportedList(bool decoding,
+                                                           bool supported) {
+    std::vector<Lc3Configuration> le_audio_codec_configs;
+    if (!supported) {
+      Lc3Configuration lc3_config{.samplingFrequencyHz = 0, .pcmBitDepth = 0};
+      le_audio_codec_configs.push_back(lc3_config);
+      return le_audio_codec_configs;
+    }
+
+    // There might be more than one LeAudioCodecCapabilitiesSetting
+    std::vector<Lc3Capabilities> lc3_capabilities;
+    for (auto& capability : temp_provider_capabilities_) {
+      if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
+        continue;
+      }
+      auto& le_audio_capability =
+          capability.get<AudioCapabilities::leAudioCapabilities>();
+      auto& unicast_capability =
+          decoding ? le_audio_capability.unicastDecodeCapability
+                   : le_audio_capability.unicastEncodeCapability;
+      if (unicast_capability.codecType != CodecType::LC3) {
+        continue;
+      }
+      auto& lc3_capability = unicast_capability.leAudioCodecCapabilities.get<
+          UnicastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
+      lc3_capabilities.push_back(lc3_capability);
+    }
+
+    // Combine those parameters into one list of LeAudioCodecConfiguration
+    // This seems horrible, but usually each Lc3Capability only contains a
+    // single Lc3Configuration, which means every array has a length of 1.
+    for (auto& lc3_capability : lc3_capabilities) {
+      for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
+        for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
+          for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
+            Lc3Configuration lc3_config = {
+                .samplingFrequencyHz = samplingFrequencyHz,
+                .frameDurationUs = frameDurationUs,
+                .octetsPerFrame = octetsPerFrame,
+            };
+            le_audio_codec_configs.push_back(lc3_config);
+          }
+        }
+      }
+    }
+
+    return le_audio_codec_configs;
+  }
+
+  LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
+};
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * stopped
+ */
+TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
+       OpenLeAudioOutputHardwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * stopped with Unicast hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
+       StartAndEndLeAudioOutputSessionWithPossibleUnicastConfig) {
+  if (!IsOffloadOutputSupported()) {
+    return;
+  }
+
+  auto lc3_codec_configs =
+      GetUnicastLc3SupportedList(false /* decoding */, true /* supported */);
+  LeAudioConfiguration le_audio_config = {
+      .codecType = CodecType::LC3,
+      .peerDelayUs = 0,
+  };
+
+  for (auto& lc3_config : lc3_codec_configs) {
+    le_audio_config.leAudioCodecConfig
+        .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
+    DataMQDesc mq_desc;
+    auto aidl_retval = audio_provider_->startSession(
+        audio_port_, AudioConfiguration(le_audio_config), &mq_desc);
+
+    ASSERT_TRUE(aidl_retval.isOk());
+    EXPECT_TRUE(audio_provider_->endSession().isOk());
+  }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * stopped with Unicast hardware encoding config
+ *
+ * Disabled since offload codec checking is not ready
+ */
+TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
+       DISABLED_StartAndEndLeAudioOutputSessionWithInvalidAudioConfiguration) {
+  if (!IsOffloadOutputSupported()) {
+    return;
+  }
+
+  auto lc3_codec_configs =
+      GetUnicastLc3SupportedList(false /* decoding */, false /* supported */);
+  LeAudioConfiguration le_audio_config = {
+      .codecType = CodecType::LC3,
+      .peerDelayUs = 0,
+  };
+
+  for (auto& lc3_config : lc3_codec_configs) {
+    le_audio_config.leAudioCodecConfig
+        .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
+    DataMQDesc mq_desc;
+    auto aidl_retval = audio_provider_->startSession(
+        audio_port_, AudioConfiguration(le_audio_config), &mq_desc);
+
+    // AIDL call should fail on invalid codec
+    ASSERT_FALSE(aidl_retval.isOk());
+    EXPECT_TRUE(audio_provider_->endSession().isOk());
+  }
+}
+
+/**
+ * openProvider LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH
+ */
+class BluetoothAudioProviderLeAudioInputHardwareAidl
+    : public BluetoothAudioProviderLeAudioOutputHardwareAidl {
+ public:
+  virtual void SetUp() override {
+    BluetoothAudioProviderFactoryAidl::SetUp();
+    GetProviderCapabilitiesHelper(
+        SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
+    OpenProviderHelper(
+        SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
+    ASSERT_TRUE(temp_provider_capabilities_.empty() ||
+                audio_provider_ != nullptr);
+  }
+
+  bool IsOffloadInputSupported() {
+    for (auto& capability : temp_provider_capabilities_) {
+      if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
+        continue;
+      }
+      auto& le_audio_capability =
+          capability.get<AudioCapabilities::leAudioCapabilities>();
+      if (le_audio_capability.unicastDecodeCapability.codecType !=
+          CodecType::UNKNOWN)
+        return true;
+    }
+    return false;
+  }
+
+  virtual void TearDown() override {
+    audio_port_ = nullptr;
+    audio_provider_ = nullptr;
+    BluetoothAudioProviderFactoryAidl::TearDown();
+  }
+};
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * stopped
+ */
+TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
+       OpenLeAudioInputHardwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * stopped with Unicast hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
+       StartAndEndLeAudioInputSessionWithPossibleUnicastConfig) {
+  if (!IsOffloadInputSupported()) {
+    return;
+  }
+
+  auto lc3_codec_configs =
+      GetUnicastLc3SupportedList(true /* decoding */, true /* supported */);
+  LeAudioConfiguration le_audio_config = {
+      .codecType = CodecType::LC3,
+      .peerDelayUs = 0,
+  };
+
+  for (auto& lc3_config : lc3_codec_configs) {
+    le_audio_config.leAudioCodecConfig
+        .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
+    DataMQDesc mq_desc;
+    auto aidl_retval = audio_provider_->startSession(
+        audio_port_, AudioConfiguration(le_audio_config), &mq_desc);
+
+    ASSERT_TRUE(aidl_retval.isOk());
+    EXPECT_TRUE(audio_provider_->endSession().isOk());
+  }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * stopped with Unicast hardware encoding config
+ *
+ * Disabled since offload codec checking is not ready
+ */
+TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
+       DISABLED_StartAndEndLeAudioInputSessionWithInvalidAudioConfiguration) {
+  if (!IsOffloadInputSupported()) {
+    return;
+  }
+
+  auto lc3_codec_configs =
+      GetUnicastLc3SupportedList(true /* decoding */, false /* supported */);
+  LeAudioConfiguration le_audio_config = {
+      .codecType = CodecType::LC3,
+      .peerDelayUs = 0,
+  };
+
+  for (auto& lc3_config : lc3_codec_configs) {
+    le_audio_config.leAudioCodecConfig
+        .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
+
+    DataMQDesc mq_desc;
+    auto aidl_retval = audio_provider_->startSession(
+        audio_port_, AudioConfiguration(le_audio_config), &mq_desc);
+
+    // AIDL call should fail on invalid codec
+    ASSERT_FALSE(aidl_retval.isOk());
+    EXPECT_TRUE(audio_provider_->endSession().isOk());
+  }
+}
+
+/**
+ * openProvider LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH
+ */
+class BluetoothAudioProviderLeAudioBroadcastSoftwareAidl
+    : public BluetoothAudioProviderFactoryAidl {
+ public:
+  virtual void SetUp() override {
+    BluetoothAudioProviderFactoryAidl::SetUp();
+    GetProviderCapabilitiesHelper(
+        SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
+    OpenProviderHelper(
+        SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
+    ASSERT_NE(audio_provider_, nullptr);
+  }
+
+  virtual void TearDown() override {
+    audio_port_ = nullptr;
+    audio_provider_ = nullptr;
+    BluetoothAudioProviderFactoryAidl::TearDown();
+  }
+
+  static constexpr int32_t le_audio_output_sample_rates_[] = {
+      0, 8000, 16000, 24000, 32000, 44100, 48000,
+  };
+  static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
+  static constexpr ChannelMode le_audio_output_channel_modes_[] = {
+      ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
+  static constexpr int32_t le_audio_output_data_interval_us_[] = {
+      0 /* Invalid */, 10000 /* Valid 10ms */};
+};
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started and
+ * stopped
+ */
+TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
+       DISABLED_OpenLeAudioOutputSoftwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started and
+ * stopped with different PCM config
+ */
+TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
+       DISABLED_StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
+  for (auto sample_rate : le_audio_output_sample_rates_) {
+    for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
+      for (auto channel_mode : le_audio_output_channel_modes_) {
+        for (auto data_interval_us : le_audio_output_data_interval_us_) {
+          PcmConfiguration pcm_config{
+              .sampleRateHz = sample_rate,
+              .bitsPerSample = bits_per_sample,
+              .channelMode = channel_mode,
+              .dataIntervalUs = data_interval_us,
+          };
+          bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
+          DataMQDesc mq_desc;
+          auto aidl_retval = audio_provider_->startSession(
+              audio_port_, AudioConfiguration(pcm_config), &mq_desc);
+          DataMQ data_mq(mq_desc);
+
+          EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
+          if (is_codec_config_valid) {
+            EXPECT_TRUE(data_mq.isValid());
+          }
+          EXPECT_TRUE(audio_provider_->endSession().isOk());
+        }
+      }
+    }
+  }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+    BluetoothAudioProviderFactoryAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderFactoryAidl,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(
+                             IBluetoothAudioProviderFactory::descriptor)),
+                         android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+    BluetoothAudioProviderA2dpSoftwareAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderA2dpSoftwareAidl,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(
+                             IBluetoothAudioProviderFactory::descriptor)),
+                         android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+    BluetoothAudioProviderA2dpHardwareAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderA2dpHardwareAidl,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(
+                             IBluetoothAudioProviderFactory::descriptor)),
+                         android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+    BluetoothAudioProviderHearingAidSoftwareAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+                         BluetoothAudioProviderHearingAidSoftwareAidl,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(
+                             IBluetoothAudioProviderFactory::descriptor)),
+                         android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+    BluetoothAudioProviderLeAudioOutputSoftwareAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+                         BluetoothAudioProviderLeAudioOutputSoftwareAidl,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(
+                             IBluetoothAudioProviderFactory::descriptor)),
+                         android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+    BluetoothAudioProviderLeAudioInputSoftwareAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+                         BluetoothAudioProviderLeAudioInputSoftwareAidl,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(
+                             IBluetoothAudioProviderFactory::descriptor)),
+                         android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+    BluetoothAudioProviderLeAudioOutputHardwareAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+                         BluetoothAudioProviderLeAudioOutputHardwareAidl,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(
+                             IBluetoothAudioProviderFactory::descriptor)),
+                         android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+    BluetoothAudioProviderLeAudioInputHardwareAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+                         BluetoothAudioProviderLeAudioInputHardwareAidl,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(
+                             IBluetoothAudioProviderFactory::descriptor)),
+                         android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+    BluetoothAudioProviderLeAudioBroadcastSoftwareAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+                         BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(
+                             IBluetoothAudioProviderFactory::descriptor)),
+                         android::PrintInstanceNameToString);
+
+// TODO(219668925): Add LE Audio Broadcast VTS
+// GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+//     BluetoothAudioProviderLeAudioBroadcastHardwareAidl);
+// INSTANTIATE_TEST_SUITE_P(PerInstance,
+//                          BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
+//                          testing::ValuesIn(android::getAidlHalInstanceNames(
+//                              IBluetoothAudioProviderFactory::descriptor)),
+//                          android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  ABinderProcess_setThreadPoolMaxThreadCount(1);
+  ABinderProcess_startThreadPool();
+  return RUN_ALL_TESTS();
+}
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
index b90a656..7187828 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
@@ -545,21 +545,6 @@
   }
 }
 
-void BluetoothAudioSession::SetCodecType(CodecType codec_type) {
-  std::lock_guard<std::recursive_mutex> guard(mutex_);
-  if (!IsSessionReady()) {
-    LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
-               << " has NO session";
-    return;
-  }
-
-  auto hal_retval = stack_iface_->setCodecType(codec_type);
-  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 =
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h
index 7725331..6e390cc 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h
@@ -182,7 +182,6 @@
   void UpdateSourceMetadata(const struct source_metadata& source_metadata);
   void UpdateSinkMetadata(const struct sink_metadata& sink_metadata);
   void SetLatencyMode(LatencyMode latency_mode);
-  void SetCodecType(CodecType codec_type);
 
   // The control function writes stream to FMQ
   size_t OutWritePcmData(const void* buffer, size_t bytes);
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Luminance.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerBrightness.aidl
similarity index 96%
rename from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Luminance.aidl
rename to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerBrightness.aidl
index adb49a8..a726cc1 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Luminance.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerBrightness.aidl
@@ -33,6 +33,6 @@
 
 package android.hardware.graphics.composer3;
 @VintfStability
-parcelable Luminance {
-  float nits;
+parcelable LayerBrightness {
+  float brightness;
 }
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 c1c0117..0c5fac9 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
@@ -50,7 +50,7 @@
   @nullable android.hardware.graphics.common.Rect[] visibleRegion;
   @nullable android.hardware.graphics.composer3.ZOrder z;
   @nullable float[] colorTransform;
-  @nullable android.hardware.graphics.composer3.Luminance whitePointNits;
+  @nullable android.hardware.graphics.composer3.LayerBrightness brightness;
   @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/DisplayCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl
index f1ce1a7..b6df147 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl
@@ -77,15 +77,7 @@
      * the display brightness, for example when internally switching the display between multiple
      * power modes to achieve higher luminance. In those cases, the underlying display panel's real
      * brightness may not be applied atomically; however, layer dimming when mixing HDR and SDR
-     * content must be synchronized.
-     *
-     * As an illustrative example: suppose two layers have white
-     * points of 200 nits and 1000 nits respectively, the old display luminance is 200 nits, and the
-     * new display luminance is 1000 nits. If the new display luminance takes two frames to apply,
-     * then: In the first frame, there must not be any relative dimming of layers (treat both layers
-     * as 200 nits as the maximum luminance of the display is 200 nits). In the second frame, there
-     * dimming should be applied to ensure that the first layer does not become perceptually
-     * brighter during the transition.
+     * content must be synchronized to ensure that there is no user-perceptable flicker.
      *
      * The display luminance must be updated by this command even if there is not pending validate
      * or present command.
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/Luminance.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerBrightness.aidl
similarity index 76%
rename from graphics/composer/aidl/android/hardware/graphics/composer3/Luminance.aidl
rename to graphics/composer/aidl/android/hardware/graphics/composer3/LayerBrightness.aidl
index 5b1c1b4..146e012 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/Luminance.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerBrightness.aidl
@@ -17,10 +17,10 @@
 package android.hardware.graphics.composer3;
 
 @VintfStability
-parcelable Luminance {
+parcelable LayerBrightness {
     /**
-     * Photometric measure of luminous intensity per unit area of light.
-     * Units are nits, or cd/m^2.
+     * Brightness of the current layer, ranging from 0 to 1, where 0 is the minimum brightness of
+     * the display, and 1 is the current brightness of the display.
      */
-    float nits;
+    float brightness;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
index 6f6894f..f3b67a9 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
@@ -22,7 +22,7 @@
 import android.hardware.graphics.common.Rect;
 import android.hardware.graphics.composer3.Buffer;
 import android.hardware.graphics.composer3.Color;
-import android.hardware.graphics.composer3.Luminance;
+import android.hardware.graphics.composer3.LayerBrightness;
 import android.hardware.graphics.composer3.ParcelableBlendMode;
 import android.hardware.graphics.composer3.ParcelableComposition;
 import android.hardware.graphics.composer3.ParcelableDataspace;
@@ -221,12 +221,12 @@
     @nullable float[] colorTransform;
 
     /**
-     * Sets the desired white point for the layer. This is intended to be used when presenting
-     * an SDR layer alongside HDR content. The HDR content will be presented at the display
-     * brightness in nits, and accordingly SDR content shall be dimmed to the desired white point
-     * provided.
+     * Sets the desired brightness for the layer. This is intended to be used for instance when
+     * presenting an SDR layer alongside HDR content. The HDR content will be presented at the
+     * display brightness in nits, and accordingly SDR content shall be dimmed according to the
+     * provided brightness ratio.
      */
-    @nullable Luminance whitePointNits;
+    @nullable LayerBrightness brightness;
 
     /**
      * Sets the PerFrameMetadata for the display. This metadata must be used
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp
index 45a8f6f..686299a 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp
@@ -62,9 +62,6 @@
         }
         mComposerClient->setVsyncAllowed(/*isAllowed*/ false);
 
-        // set up gralloc
-        mGraphicBuffer = allocate();
-
         EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
 
         ASSERT_NO_FATAL_FAILURE(
@@ -112,15 +109,18 @@
 
     int32_t getDisplayHeight() const { return getPrimaryDisplay().getDisplayHeight(); }
 
-    ::android::sp<::android::GraphicBuffer> allocate() {
+    std::pair<bool, ::android::sp<::android::GraphicBuffer>> allocateBuffer(uint32_t usage) {
         const auto width = static_cast<uint32_t>(getDisplayWidth());
         const auto height = static_cast<uint32_t>(getDisplayHeight());
-        const auto usage = static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
-                           static_cast<uint32_t>(common::BufferUsage::CPU_READ_OFTEN);
 
-        return ::android::sp<::android::GraphicBuffer>::make(
+        const auto& graphicBuffer = ::android::sp<::android::GraphicBuffer>::make(
                 width, height, ::android::PIXEL_FORMAT_RGBA_8888,
                 /*layerCount*/ 1u, usage, "VtsHalGraphicsComposer3_ReadbackTest");
+
+        if (graphicBuffer && ::android::OK == graphicBuffer->initCheck()) {
+            return {true, graphicBuffer};
+        }
+        return {false, graphicBuffer};
     }
 
     uint64_t getStableDisplayId(int64_t display) {
@@ -231,7 +231,6 @@
     std::vector<ColorMode> mTestColorModes;
     ComposerClientWriter mWriter;
     ComposerClientReader mReader;
-    ::android::sp<::android::GraphicBuffer> mGraphicBuffer;
     std::unique_ptr<TestRenderEngine> mTestRenderEngine;
     common::PixelFormat mPixelFormat;
     common::Dataspace mDataspace;
@@ -339,8 +338,8 @@
                 {0, getDisplayHeight() / 2, getDisplayWidth(), getDisplayHeight()}, BLUE);
 
         auto layer = std::make_shared<TestBufferLayer>(
-                mComposerClient, mGraphicBuffer, *mTestRenderEngine, getPrimaryDisplayId(),
-                getDisplayWidth(), getDisplayHeight(), common::PixelFormat::RGBA_8888);
+                mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
+                getDisplayHeight(), common::PixelFormat::RGBA_8888);
         layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setZOrder(10);
         layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
@@ -392,15 +391,12 @@
         layer->write(mWriter);
 
         // This following buffer call should have no effect
-        uint64_t usage =
-                static_cast<uint64_t>(static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
-                                      static_cast<uint64_t>(common::BufferUsage::CPU_WRITE_OFTEN));
-
-        mGraphicBuffer->reallocate(static_cast<uint32_t>(getDisplayWidth()),
-                                   static_cast<uint32_t>(getDisplayHeight()), 1,
-                                   static_cast<uint32_t>(common::PixelFormat::RGBA_8888), usage);
-        mWriter.setLayerBuffer(getPrimaryDisplayId(), layer->getLayer(), /*slot*/ 0,
-                               mGraphicBuffer->handle,
+        const auto usage = static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
+                           static_cast<uint32_t>(common::BufferUsage::CPU_READ_OFTEN);
+        const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(usage);
+        ASSERT_TRUE(graphicBufferStatus);
+        const auto& buffer = graphicBuffer->handle;
+        mWriter.setLayerBuffer(getPrimaryDisplayId(), layer->getLayer(), /*slot*/ 0, buffer,
                                /*acquireFence*/ -1);
 
         // expected color for each pixel
@@ -450,9 +446,11 @@
         return;
     }
 
-    ASSERT_NE(nullptr, mGraphicBuffer);
-    ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
-    const auto& bufferHandle = mGraphicBuffer->handle;
+    const auto usage = static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
+                       static_cast<uint32_t>(common::BufferUsage::CPU_READ_OFTEN);
+    const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(usage);
+    ASSERT_TRUE(graphicBufferStatus);
+    const auto& bufferHandle = graphicBuffer->handle;
     ::ndk::ScopedFileDescriptor fence = ::ndk::ScopedFileDescriptor(-1);
 
     const auto status =
@@ -523,9 +521,9 @@
                 expectedColors, getDisplayWidth(),
                 {0, getDisplayHeight() / 2, getDisplayWidth(), getDisplayHeight()}, BLUE);
 
-        auto layer = std::make_shared<TestBufferLayer>(
-                mComposerClient, mGraphicBuffer, *mTestRenderEngine, getPrimaryDisplayId(),
-                getDisplayWidth(), getDisplayHeight(), PixelFormat::RGBA_FP16);
+        auto layer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
+                                                       getPrimaryDisplayId(), getDisplayWidth(),
+                                                       getDisplayHeight(), PixelFormat::RGBA_FP16);
         layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setZOrder(10);
         layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
@@ -554,30 +552,28 @@
             common::Rect damage{0, 0, getDisplayWidth(), getDisplayHeight()};
 
             // create client target buffer
-            mGraphicBuffer->reallocate(layer->getWidth(), layer->getHeight(),
-                                       static_cast<int32_t>(common::PixelFormat::RGBA_8888),
-                                       layer->getLayerCount(), clientUsage);
-
-            ASSERT_NE(nullptr, mGraphicBuffer->handle);
-
+            const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(clientUsage);
+            ASSERT_TRUE(graphicBufferStatus);
+            const auto& buffer = graphicBuffer->handle;
             void* clientBufData;
-            mGraphicBuffer->lock(clientUsage, layer->getAccessRegion(), &clientBufData);
+            const auto stride = static_cast<uint32_t>(graphicBuffer->stride);
+            graphicBuffer->lock(clientUsage, layer->getAccessRegion(), &clientBufData);
 
             ASSERT_NO_FATAL_FAILURE(
-                    ReadbackHelper::fillBuffer(layer->getWidth(), layer->getHeight(),
-                                               static_cast<uint32_t>(mGraphicBuffer->stride),
+                    ReadbackHelper::fillBuffer(layer->getWidth(), layer->getHeight(), stride,
                                                clientBufData, clientFormat, expectedColors));
-            EXPECT_EQ(::android::OK, mGraphicBuffer->unlock());
+            int32_t clientFence;
+            const auto unlockStatus = graphicBuffer->unlockAsync(&clientFence);
+            ASSERT_EQ(::android::OK, unlockStatus);
+            if (clientFence >= 0) {
+                sync_wait(clientFence, -1);
+                close(clientFence);
+            }
 
-            const auto& [status, bufferFence] =
-                    mComposerClient->getReadbackBufferFence(getPrimaryDisplayId());
-            EXPECT_TRUE(status.isOk());
-
+            mWriter.setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, buffer, clientFence,
+                                    clientDataspace, std::vector<common::Rect>(1, damage));
             layer->setToClientComposition(mWriter);
-            mWriter.acceptDisplayChanges(getPrimaryDisplayId());
-            mWriter.setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, mGraphicBuffer->handle,
-                                    bufferFence.get(), clientDataspace,
-                                    std::vector<common::Rect>(1, damage));
+            mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
             execute();
             changedCompositionTypes = mReader.takeChangedCompositionTypes(getPrimaryDisplayId());
             ASSERT_TRUE(changedCompositionTypes.empty());
@@ -623,8 +619,8 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         auto deviceLayer = std::make_shared<TestBufferLayer>(
-                mComposerClient, mGraphicBuffer, *mTestRenderEngine, getPrimaryDisplayId(),
-                getDisplayWidth(), getDisplayHeight() / 2, PixelFormat::RGBA_8888);
+                mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
+                getDisplayHeight() / 2, PixelFormat::RGBA_8888);
         std::vector<Color> deviceColors(deviceLayer->getWidth() * deviceLayer->getHeight());
         ReadbackHelper::fillColorsArea(deviceColors, static_cast<int32_t>(deviceLayer->getWidth()),
                                        {0, 0, static_cast<int32_t>(deviceLayer->getWidth()),
@@ -647,8 +643,8 @@
         int32_t clientHeight = getDisplayHeight() / 2;
 
         auto clientLayer = std::make_shared<TestBufferLayer>(
-                mComposerClient, mGraphicBuffer, *mTestRenderEngine, getPrimaryDisplayId(),
-                clientWidth, clientHeight, PixelFormat::RGBA_FP16, Composition::DEVICE);
+                mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), clientWidth,
+                clientHeight, PixelFormat::RGBA_FP16, Composition::DEVICE);
         common::Rect clientFrame = {0, getDisplayHeight() / 2, getDisplayWidth(),
                                     getDisplayHeight()};
         clientLayer->setDisplayFrame(clientFrame);
@@ -663,33 +659,32 @@
         }
         // create client target buffer
         ASSERT_EQ(Composition::CLIENT, changedCompositionTypes[0].composition);
-        mGraphicBuffer->reallocate(static_cast<uint32_t>(getDisplayWidth()),
-                                   static_cast<uint32_t>(getDisplayHeight()),
-                                   static_cast<int32_t>(common::PixelFormat::RGBA_8888),
-                                   clientLayer->getLayerCount(), clientUsage);
-        ASSERT_NE(nullptr, mGraphicBuffer->handle);
+        const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(clientUsage);
+        ASSERT_TRUE(graphicBufferStatus);
+        const auto& buffer = graphicBuffer->handle;
 
         void* clientBufData;
-        mGraphicBuffer->lock(clientUsage, {0, 0, getDisplayWidth(), getDisplayHeight()},
-                             &clientBufData);
+        graphicBuffer->lock(clientUsage, {0, 0, getDisplayWidth(), getDisplayHeight()},
+                            &clientBufData);
 
         std::vector<Color> clientColors(
                 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
         ReadbackHelper::fillColorsArea(clientColors, getDisplayWidth(), clientFrame, RED);
         ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(
                 static_cast<uint32_t>(getDisplayWidth()), static_cast<uint32_t>(getDisplayHeight()),
-                mGraphicBuffer->getStride(), clientBufData, clientFormat, clientColors));
-        EXPECT_EQ(::android::OK, mGraphicBuffer->unlock());
+                graphicBuffer->getStride(), clientBufData, clientFormat, clientColors));
+        int32_t clientFence;
+        const auto unlockStatus = graphicBuffer->unlockAsync(&clientFence);
+        ASSERT_EQ(::android::OK, unlockStatus);
+        if (clientFence >= 0) {
+            sync_wait(clientFence, -1);
+            close(clientFence);
+        }
 
-        const auto& [status, bufferFence] =
-                mComposerClient->getReadbackBufferFence(getPrimaryDisplayId());
-        EXPECT_TRUE(status.isOk());
-
+        mWriter.setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, buffer, clientFence,
+                                clientDataspace, std::vector<common::Rect>(1, clientFrame));
         clientLayer->setToClientComposition(mWriter);
-        mWriter.acceptDisplayChanges(getPrimaryDisplayId());
-        mWriter.setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, mGraphicBuffer->handle,
-                                bufferFence.get(), clientDataspace,
-                                std::vector<common::Rect>(1, clientFrame));
+        mWriter.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
         execute();
         changedCompositionTypes = mReader.takeChangedCompositionTypes(getPrimaryDisplayId());
         ASSERT_TRUE(changedCompositionTypes.empty());
@@ -721,9 +716,9 @@
                 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
         ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), redRect, RED);
 
-        auto layer = std::make_shared<TestBufferLayer>(
-                mComposerClient, mGraphicBuffer, *mTestRenderEngine, getPrimaryDisplayId(),
-                getDisplayWidth(), getDisplayHeight(), PixelFormat::RGBA_8888);
+        auto layer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
+                                                       getPrimaryDisplayId(), getDisplayWidth(),
+                                                       getDisplayHeight(), PixelFormat::RGBA_8888);
         layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setZOrder(10);
         layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
@@ -849,9 +844,9 @@
                 expectedColors, getDisplayWidth(),
                 {0, getDisplayHeight() / 2, getDisplayWidth(), getDisplayHeight()}, BLUE);
 
-        auto layer = std::make_shared<TestBufferLayer>(
-                mComposerClient, mGraphicBuffer, *mTestRenderEngine, getPrimaryDisplayId(),
-                getDisplayWidth(), getDisplayHeight(), PixelFormat::RGBA_8888);
+        auto layer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
+                                                       getPrimaryDisplayId(), getDisplayWidth(),
+                                                       getDisplayHeight(), PixelFormat::RGBA_8888);
         layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setZOrder(10);
         layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter);
@@ -965,7 +960,7 @@
     }
 }
 
-TEST_P(GraphicsCompositionTest, SetLayerWhitePointDims) {
+TEST_P(GraphicsCompositionTest, SetLayerBrightnessDims) {
     const auto& [status, capabilities] =
             mComposerClient->getDisplayCapabilities(getPrimaryDisplayId());
     ASSERT_TRUE(status.isOk());
@@ -1013,6 +1008,7 @@
         redLayer->setColor(RED);
         redLayer->setDisplayFrame(redRect);
         redLayer->setWhitePointNits(maxBrightnessNits);
+        redLayer->setBrightness(1.f);
 
         const auto dimmerRedLayer =
                 std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
@@ -1022,6 +1018,7 @@
         // kick into GPU composition to apply dithering when the dimming ratio is high.
         static constexpr float kDimmingRatio = 0.9f;
         dimmerRedLayer->setWhitePointNits(maxBrightnessNits * kDimmingRatio);
+        dimmerRedLayer->setBrightness(kDimmingRatio);
 
         const std::vector<std::shared_ptr<TestLayer>> layers = {redLayer, dimmerRedLayer};
         std::vector<Color> expectedColors(
@@ -1083,9 +1080,9 @@
         backgroundLayer->setZOrder(0);
         backgroundLayer->setColor(mBackgroundColor);
 
-        auto layer = std::make_shared<TestBufferLayer>(
-                mComposerClient, mGraphicBuffer, *mTestRenderEngine, getPrimaryDisplayId(),
-                getDisplayWidth(), getDisplayHeight(), PixelFormat::RGBA_8888);
+        auto layer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
+                                                       getPrimaryDisplayId(), getDisplayWidth(),
+                                                       getDisplayHeight(), PixelFormat::RGBA_8888);
         layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setZOrder(10);
         layer->setDataspace(Dataspace::UNKNOWN, mWriter);
@@ -1283,9 +1280,9 @@
         common::Rect redRect = {0, 0, mSideLength / 2, mSideLength / 2};
         common::Rect blueRect = {mSideLength / 2, mSideLength / 2, mSideLength, mSideLength};
 
-        mLayer = std::make_shared<TestBufferLayer>(
-                mComposerClient, mGraphicBuffer, *mTestRenderEngine, getPrimaryDisplayId(),
-                mSideLength, mSideLength, PixelFormat::RGBA_8888);
+        mLayer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
+                                                   getPrimaryDisplayId(), mSideLength, mSideLength,
+                                                   PixelFormat::RGBA_8888);
         mLayer->setDisplayFrame({0, 0, mSideLength, mSideLength});
         mLayer->setZOrder(10);
 
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 17ec885..8d4bc11 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
@@ -1798,26 +1798,37 @@
     EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer).isOk());
 }
 
-TEST_P(GraphicsComposerAidlCommandTest, SetLayerWhitePointNits) {
+TEST_P(GraphicsComposerAidlCommandTest, setLayerBrightness) {
     const auto& [layerStatus, layer] =
             mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
-    EXPECT_TRUE(layerStatus.isOk());
 
-    mWriter.setLayerWhitePointNits(getPrimaryDisplayId(), layer, /*whitePointNits*/ 200.f);
+    mWriter.setLayerBrightness(getPrimaryDisplayId(), layer, 0.2f);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerWhitePointNits(getPrimaryDisplayId(), layer, /*whitePointNits*/ 1000.f);
+    mWriter.setLayerBrightness(getPrimaryDisplayId(), layer, 1.f);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerWhitePointNits(getPrimaryDisplayId(), layer, /*whitePointNits*/ 0.f);
+    mWriter.setLayerBrightness(getPrimaryDisplayId(), layer, 0.f);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerWhitePointNits(getPrimaryDisplayId(), layer, /*whitePointNits*/ -1.f);
+    mWriter.setLayerBrightness(getPrimaryDisplayId(), layer, -1.f);
     execute();
-    ASSERT_TRUE(mReader.takeErrors().empty());
+    {
+        const auto errors = mReader.takeErrors();
+        ASSERT_EQ(1, errors.size());
+        EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode);
+    }
+
+    mWriter.setLayerBrightness(getPrimaryDisplayId(), layer, std::nanf(""));
+    execute();
+    {
+        const auto errors = mReader.takeErrors();
+        ASSERT_EQ(1, errors.size());
+        EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode);
+    }
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetActiveConfigWithConstraints) {
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 1aca76f..553eec3 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
@@ -34,7 +34,7 @@
     writer.setLayerTransform(mDisplay, mLayer, mTransform);
     writer.setLayerPlaneAlpha(mDisplay, mLayer, mAlpha);
     writer.setLayerBlendMode(mDisplay, mLayer, mBlendMode);
-    writer.setLayerWhitePointNits(mDisplay, mLayer, mWhitePointNits);
+    writer.setLayerBrightness(mDisplay, mLayer, mBrightness);
 }
 
 std::string ReadbackHelper::getColorModeString(ColorMode mode) {
@@ -209,14 +209,14 @@
     mAccessRegion.bottom = static_cast<int32_t>(height);
 }
 
-::android::sp<::android::GraphicBuffer> ReadbackBuffer::allocate() {
+::android::sp<::android::GraphicBuffer> ReadbackBuffer::allocateBuffer() {
     return ::android::sp<::android::GraphicBuffer>::make(
             mWidth, mHeight, static_cast<::android::PixelFormat>(mPixelFormat), mLayerCount, mUsage,
-            "ReadbackVts");
+            "ReadbackBuffer");
 }
 
 void ReadbackBuffer::setReadbackBuffer() {
-    mGraphicBuffer = allocate();
+    mGraphicBuffer = allocateBuffer();
     ASSERT_NE(nullptr, mGraphicBuffer);
     ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
     const auto& bufferHandle = mGraphicBuffer->handle;
@@ -262,12 +262,10 @@
 }
 
 TestBufferLayer::TestBufferLayer(const std::shared_ptr<VtsComposerClient>& client,
-                                 const ::android::sp<::android::GraphicBuffer>& graphicBuffer,
                                  TestRenderEngine& renderEngine, int64_t display, uint32_t width,
                                  uint32_t height, common::PixelFormat format,
                                  Composition composition)
     : TestLayer{client, display}, mRenderEngine(renderEngine) {
-    mGraphicBuffer = graphicBuffer;
     mComposition = composition;
     mWidth = width;
     mHeight = height;
@@ -290,8 +288,9 @@
     TestLayer::write(writer);
     writer.setLayerCompositionType(mDisplay, mLayer, mComposition);
     writer.setLayerVisibleRegion(mDisplay, mLayer, std::vector<Rect>(1, mDisplayFrame));
-    if (mGraphicBuffer->handle != nullptr)
-        writer.setLayerBuffer(mDisplay, mLayer, 0, mGraphicBuffer->handle, mFillFence);
+    if (mGraphicBuffer) {
+        writer.setLayerBuffer(mDisplay, mLayer, /*slot*/ 0, mGraphicBuffer->handle, mFillFence);
+    }
 }
 
 LayerSettings TestBufferLayer::toRenderEngineLayerSettings() {
@@ -326,16 +325,26 @@
     EXPECT_EQ(::android::OK, status);
     ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(mWidth, mHeight, stride, bufData,
                                                        mPixelFormat, expectedColors));
-    EXPECT_EQ(::android::OK, mGraphicBuffer->unlock());
+
+    const auto unlockStatus = mGraphicBuffer->unlockAsync(&mFillFence);
+    ASSERT_EQ(::android::OK, unlockStatus);
+    if (mFillFence >= 0) {
+        sync_wait(mFillFence, -1);
+        close(mFillFence);
+    }
 }
 
 void TestBufferLayer::setBuffer(std::vector<Color> colors) {
-    mGraphicBuffer->reallocate(mWidth, mHeight, static_cast<::android::PixelFormat>(mPixelFormat),
-                               mLayerCount, mUsage);
+    mGraphicBuffer = allocateBuffer();
     ASSERT_NE(nullptr, mGraphicBuffer);
-    ASSERT_NE(nullptr, mGraphicBuffer->handle);
-    ASSERT_NO_FATAL_FAILURE(fillBuffer(colors));
     ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
+    ASSERT_NO_FATAL_FAILURE(fillBuffer(colors));
+}
+
+::android::sp<::android::GraphicBuffer> TestBufferLayer::allocateBuffer() {
+    return ::android::sp<::android::GraphicBuffer>::make(
+            mWidth, mHeight, static_cast<::android::PixelFormat>(mPixelFormat), mLayerCount, mUsage,
+            "TestBufferLayer");
 }
 
 void TestBufferLayer::setDataspace(common::Dataspace dataspace, ComposerClientWriter& writer) {
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h
index 7135dca..ee9f0d5 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h
@@ -67,6 +67,7 @@
     void setSourceCrop(FRect crop) { mSourceCrop = crop; }
     void setZOrder(uint32_t z) { mZOrder = z; }
     void setWhitePointNits(float whitePointNits) { mWhitePointNits = whitePointNits; }
+    void setBrightness(float brightness) { mBrightness = brightness; }
 
     void setSurfaceDamage(std::vector<Rect> surfaceDamage) {
         mSurfaceDamage = std::move(surfaceDamage);
@@ -84,12 +85,13 @@
 
     int64_t getLayer() const { return mLayer; }
 
-    float getWhitePointNits() const { return mWhitePointNits; }
+    float getBrightness() const { return mBrightness; }
 
   protected:
     int64_t mDisplay;
     int64_t mLayer;
     Rect mDisplayFrame = {0, 0, 0, 0};
+    float mBrightness = 1.f;
     float mWhitePointNits = -1.f;
     std::vector<Rect> mSurfaceDamage;
     Transform mTransform = static_cast<Transform>(0);
@@ -118,7 +120,6 @@
 class TestBufferLayer : public TestLayer {
   public:
     TestBufferLayer(const std::shared_ptr<VtsComposerClient>& client,
-                    const ::android::sp<::android::GraphicBuffer>& graphicBuffer,
                     TestRenderEngine& renderEngine, int64_t display, uint32_t width,
                     uint32_t height, common::PixelFormat format,
                     Composition composition = Composition::DEVICE);
@@ -154,6 +155,9 @@
     PixelFormat mPixelFormat;
     uint32_t mUsage;
     ::android::Rect mAccessRegion;
+
+  private:
+    ::android::sp<::android::GraphicBuffer> allocateBuffer();
 };
 
 class ReadbackHelper {
@@ -194,8 +198,6 @@
 
     void checkReadbackBuffer(const std::vector<Color>& expectedColors);
 
-    ::android::sp<::android::GraphicBuffer> allocate();
-
   protected:
     uint32_t mWidth;
     uint32_t mHeight;
@@ -208,6 +210,9 @@
     std::shared_ptr<VtsComposerClient> mComposerClient;
     ::android::Rect mAccessRegion;
     native_handle_t mBufferHandle;
+
+  private:
+    ::android::sp<::android::GraphicBuffer> allocateBuffer();
 };
 
 }  // namespace aidl::android::hardware::graphics::composer3::vts
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 a04b982..ae17c51 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
@@ -30,7 +30,7 @@
 #include <aidl/android/hardware/graphics/composer3/Color.h>
 #include <aidl/android/hardware/graphics/composer3/Composition.h>
 #include <aidl/android/hardware/graphics/composer3/DisplayBrightness.h>
-#include <aidl/android/hardware/graphics/composer3/Luminance.h>
+#include <aidl/android/hardware/graphics/composer3/LayerBrightness.h>
 #include <aidl/android/hardware/graphics/composer3/PerFrameMetadata.h>
 #include <aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h>
 
@@ -209,8 +209,9 @@
                 .perFrameMetadataBlob.emplace(metadata.begin(), metadata.end());
     }
 
-    void setLayerWhitePointNits(int64_t display, int64_t layer, float whitePointNits) {
-        getLayerCommand(display, layer).whitePointNits.emplace(Luminance{.nits = whitePointNits});
+    void setLayerBrightness(int64_t display, int64_t layer, float brightness) {
+        getLayerCommand(display, layer)
+                .brightness.emplace(LayerBrightness{.brightness = brightness});
     }
 
     void setLayerBlockingRegion(int64_t display, int64_t layer, const std::vector<Rect>& blocking) {
diff --git a/light/aidl/vts/functional/Android.bp b/light/aidl/vts/functional/Android.bp
index c5a8562..16804ea 100644
--- a/light/aidl/vts/functional/Android.bp
+++ b/light/aidl/vts/functional/Android.bp
@@ -36,7 +36,7 @@
         "libbinder",
     ],
     static_libs: [
-        "android.hardware.light-V1-cpp",
+        "android.hardware.light-V2-cpp",
     ],
     test_suites: [
         "vts",
diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Service.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Service.h
index cb6ff4b..f229165 100644
--- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Service.h
+++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Service.h
@@ -25,7 +25,8 @@
 
 namespace aidl::android::hardware::neuralnetworks::utils {
 
-::android::nn::GeneralResult<::android::nn::SharedDevice> getDevice(const std::string& name);
+::android::nn::GeneralResult<::android::nn::SharedDevice> getDevice(
+        const std::string& name, ::android::nn::Version::Level maxFeatureLevelAllowed);
 
 }  // namespace aidl::android::hardware::neuralnetworks::utils
 
diff --git a/neuralnetworks/aidl/utils/src/Service.cpp b/neuralnetworks/aidl/utils/src/Service.cpp
index e48593c..24fbb53 100644
--- a/neuralnetworks/aidl/utils/src/Service.cpp
+++ b/neuralnetworks/aidl/utils/src/Service.cpp
@@ -55,11 +55,12 @@
 
 }  // namespace
 
-nn::GeneralResult<nn::SharedDevice> getDevice(const std::string& instanceName) {
+nn::GeneralResult<nn::SharedDevice> getDevice(
+        const std::string& instanceName, ::android::nn::Version::Level maxFeatureLevelAllowed) {
     auto fullName = std::string(IDevice::descriptor) + "/" + instanceName;
     hal::utils::ResilientDevice::Factory makeDevice =
-            [instanceName,
-             name = std::move(fullName)](bool blocking) -> nn::GeneralResult<nn::SharedDevice> {
+            [instanceName, name = std::move(fullName),
+             maxFeatureLevelAllowed](bool blocking) -> nn::GeneralResult<nn::SharedDevice> {
         std::add_pointer_t<AIBinder*(const char*)> getService;
         if (blocking) {
             if (__builtin_available(android __NNAPI_AIDL_MIN_ANDROID_API__, *)) {
@@ -79,7 +80,8 @@
                    << " returned nullptr";
         }
         ABinderProcess_startThreadPool();
-        const auto featureLevel = NN_TRY(getAidlServiceFeatureLevel(service.get()));
+        auto featureLevel = NN_TRY(getAidlServiceFeatureLevel(service.get()));
+        featureLevel.level = std::min(featureLevel.level, maxFeatureLevelAllowed);
         return Device::create(instanceName, std::move(service), featureLevel);
     };
 
diff --git a/neuralnetworks/utils/service/include/nnapi/hal/Service.h b/neuralnetworks/utils/service/include/nnapi/hal/Service.h
index 2fd5237..e8b9c10 100644
--- a/neuralnetworks/utils/service/include/nnapi/hal/Service.h
+++ b/neuralnetworks/utils/service/include/nnapi/hal/Service.h
@@ -29,7 +29,18 @@
     bool isDeviceUpdatable = false;
 };
 
-std::vector<SharedDeviceAndUpdatability> getDevices(bool includeUpdatableDrivers);
+/**
+ * @brief Get the NNAPI sAIDL and HIDL services declared in the VINTF.
+ *
+ * @pre maxFeatureLevelAllowed >= Version::Level::FEATURE_LEVEL_5
+ *
+ * @param includeUpdatableDrivers Allow updatable drivers to be used.
+ * @param maxFeatureLevelAllowed Maximum version of driver allowed to be used. Any driver version
+ *     exceeding this must be clamped to `maxFeatureLevelAllowed`.
+ * @return A list of devices and whether each device is updatable or not.
+ */
+std::vector<SharedDeviceAndUpdatability> getDevices(bool includeUpdatableDrivers,
+                                                    nn::Version::Level maxFeatureLevelAllowed);
 
 }  // namespace android::hardware::neuralnetworks::service
 
diff --git a/neuralnetworks/utils/service/src/Service.cpp b/neuralnetworks/utils/service/src/Service.cpp
index 2286288..e0d5f82 100644
--- a/neuralnetworks/utils/service/src/Service.cpp
+++ b/neuralnetworks/utils/service/src/Service.cpp
@@ -74,7 +74,7 @@
 
 void getAidlDevices(std::vector<SharedDeviceAndUpdatability>* devices,
                     std::unordered_set<std::string>* registeredDevices,
-                    bool includeUpdatableDrivers) {
+                    bool includeUpdatableDrivers, nn::Version::Level maxFeatureLevelAllowed) {
     CHECK(devices != nullptr);
     CHECK(registeredDevices != nullptr);
 
@@ -100,7 +100,7 @@
             continue;
         }
         if (const auto [it, unregistered] = registeredDevices->insert(name); unregistered) {
-            auto maybeDevice = aidl_hal::utils::getDevice(name);
+            auto maybeDevice = aidl_hal::utils::getDevice(name, maxFeatureLevelAllowed);
             if (maybeDevice.has_value()) {
                 auto device = std::move(maybeDevice).value();
                 CHECK(device != nullptr);
@@ -116,11 +116,14 @@
 
 }  // namespace
 
-std::vector<SharedDeviceAndUpdatability> getDevices(bool includeUpdatableDrivers) {
+std::vector<SharedDeviceAndUpdatability> getDevices(bool includeUpdatableDrivers,
+                                                    nn::Version::Level maxFeatureLevelAllowed) {
     std::vector<SharedDeviceAndUpdatability> devices;
     std::unordered_set<std::string> registeredDevices;
 
-    getAidlDevices(&devices, &registeredDevices, includeUpdatableDrivers);
+    CHECK_GE(maxFeatureLevelAllowed, nn::Version::Level::FEATURE_LEVEL_5);
+
+    getAidlDevices(&devices, &registeredDevices, includeUpdatableDrivers, maxFeatureLevelAllowed);
 
     getHidlDevicesForVersion(V1_3::IDevice::descriptor, &V1_3::utils::getDevice, &devices,
                              &registeredDevices);
diff --git a/radio/1.0/vts/functional/sap_hidl_hal_test.cpp b/radio/1.0/vts/functional/sap_hidl_hal_test.cpp
index fe10587..5224624 100644
--- a/radio/1.0/vts/functional/sap_hidl_hal_test.cpp
+++ b/radio/1.0/vts/functional/sap_hidl_hal_test.cpp
@@ -16,8 +16,37 @@
 
 #include <sap_hidl_hal_utils.h>
 
+bool isServiceValidForDeviceConfiguration(hidl_string& serviceName) {
+    if (isSsSsEnabled()) {
+        // Device is configured as SSSS.
+        if (serviceName != SAP_SERVICE_SLOT1_NAME) {
+            LOG(DEBUG) << "Not valid for SSSS device.";
+            return false;
+        }
+    } else if (isDsDsEnabled()) {
+        // Device is configured as DSDS.
+        if (serviceName != SAP_SERVICE_SLOT1_NAME && serviceName != SAP_SERVICE_SLOT2_NAME) {
+            LOG(DEBUG) << "Not valid for DSDS device.";
+            return false;
+        }
+    } else if (isTsTsEnabled()) {
+        // Device is configured as TSTS.
+        if (serviceName != SAP_SERVICE_SLOT1_NAME && serviceName != SAP_SERVICE_SLOT2_NAME &&
+            serviceName != SAP_SERVICE_SLOT3_NAME) {
+            LOG(DEBUG) << "Not valid for TSTS device.";
+            return false;
+        }
+    }
+    return true;
+}
+
 void SapHidlTest::SetUp() {
-    sap = ISap::getService(GetParam());
+    hidl_string serviceName = GetParam();
+    if (!isServiceValidForDeviceConfiguration(serviceName)) {
+        LOG(DEBUG) << "Skipped the test due to device configuration.";
+        GTEST_SKIP();
+    }
+    sap = ISap::getService(serviceName);
     ASSERT_NE(sap, nullptr);
 
     sapCb = new SapCallback(*this);
diff --git a/radio/1.0/vts/functional/sap_hidl_hal_utils.h b/radio/1.0/vts/functional/sap_hidl_hal_utils.h
index 2fc9ae3..8e86591 100644
--- a/radio/1.0/vts/functional/sap_hidl_hal_utils.h
+++ b/radio/1.0/vts/functional/sap_hidl_hal_utils.h
@@ -36,7 +36,15 @@
 using ::android::sp;
 
 #define TIMEOUT_PERIOD 40
-#define SAP_SERVICE_NAME "slot1"
+
+// HAL instance name for SIM slot 1 or single SIM device
+#define SAP_SERVICE_SLOT1_NAME "slot1"
+
+// HAL instance name for SIM slot 2 on dual SIM device
+#define SAP_SERVICE_SLOT2_NAME "slot2"
+
+// HAL instance name for SIM slot 3 on triple SIM device
+#define SAP_SERVICE_SLOT3_NAME "slot3"
 
 class SapHidlTest;
 
diff --git a/security/dice/aidl/Android.bp b/security/dice/aidl/Android.bp
index 01bc91e..8c31e26 100644
--- a/security/dice/aidl/Android.bp
+++ b/security/dice/aidl/Android.bp
@@ -38,6 +38,10 @@
                 enabled: true,
             },
             apps_enabled: false,
+            apex_available: [
+                "//apex_available:platform",
+                "com.android.compos",
+            ],
         },
         rust: {
             enabled: true,
diff --git a/sensors/aidl/android/hardware/sensors/Event.aidl b/sensors/aidl/android/hardware/sensors/Event.aidl
index e8550f1..b95299c 100644
--- a/sensors/aidl/android/hardware/sensors/Event.aidl
+++ b/sensors/aidl/android/hardware/sensors/Event.aidl
@@ -204,6 +204,8 @@
              * 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.
+             * If this head tracker sensor instance does not support detecting
+             * velocity, then these fields must be set to 0.
              */
             float vx;
             float vy;
diff --git a/tv/Android.mk b/tv/Android.mk
new file mode 100644
index 0000000..d78614a
--- /dev/null
+++ b/tv/Android.mk
@@ -0,0 +1,2 @@
+$(eval $(call declare-1p-copy-files,hardware/interfaces/tv,tuner_vts_config_1_0.xml))
+$(eval $(call declare-1p-copy-files,hardware/interfaces/tv,tuner_vts_config_1_1.xml))
diff --git a/update-base-files.sh b/update-base-files.sh
index d01847d..bf7f6e4 100755
--- a/update-base-files.sh
+++ b/update-base-files.sh
@@ -45,8 +45,11 @@
          -o $ANDROID_BUILD_TOP/system/media/audio/include/system/audio_common-base.h \
          android.hardware.audio.common@7.0
 hidl-gen $options \
-         -o $ANDROID_BUILD_TOP/system/media/audio/include/system/audio-base.h \
+         -o $ANDROID_BUILD_TOP/system/media/audio/include/system/audio-base-v7.0.h \
          android.hardware.audio@7.0
 hidl-gen $options \
+         -o $ANDROID_BUILD_TOP/system/media/audio/include/system/audio-base-v7.1.h \
+         android.hardware.audio@7.1
+hidl-gen $options \
          -o $ANDROID_BUILD_TOP/system/media/audio/include/system/audio_effect-base.h \
          android.hardware.audio.effect@7.0
diff --git a/vibrator/aidl/OWNERS b/vibrator/aidl/OWNERS
index ae10db6..3982c7b 100644
--- a/vibrator/aidl/OWNERS
+++ b/vibrator/aidl/OWNERS
@@ -1,4 +1,4 @@
 # Bug component: 345036
 include platform/frameworks/base:/services/core/java/com/android/server/vibrator/OWNERS
 chasewu@google.com
-leungv@google.com
+taikuo@google.com