audio_hal_interface: Ensure that offloading_hal_interface is opened

..when get_a2dp_configuration is called.
To that end the reference to the a2dp_source message loop is
cached from the call to audio::a2dp::init
The offloading_hal_interface is re-opened if required in
the implemenetation of get_a2dp_configuration

Bug: 308686081
Bug: 305734815
Test: m com.android.btservices
Test: manual on cuttlefish: \
   disconnect and re-connect peer device from bluetooth settings
Change-Id: I92197f1472edea9c77042c6fad8dd8fbad5c23a4
diff --git a/system/audio_hal_interface/aidl/a2dp_encoding_aidl.cc b/system/audio_hal_interface/aidl/a2dp_encoding_aidl.cc
index af27732..4f4fa29 100644
--- a/system/audio_hal_interface/aidl/a2dp_encoding_aidl.cc
+++ b/system/audio_hal_interface/aidl/a2dp_encoding_aidl.cc
@@ -404,6 +404,35 @@
          SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH;
 }
 
+// Opens the HAL client interface of the specified session type and check
+// that is is valid. Returns nullptr if the client interface did not open
+// properly.
+static BluetoothAudioSinkClientInterface* new_hal_interface(
+    SessionType session_type) {
+  auto a2dp_transport = new A2dpTransport(session_type);
+  auto hal_interface = new BluetoothAudioSinkClientInterface(a2dp_transport);
+  if (hal_interface->IsValid()) {
+    return hal_interface;
+  } else {
+    LOG(ERROR) << __func__ << "BluetoothAudio HAL for a2dp is invalid";
+    delete a2dp_transport;
+    delete hal_interface;
+    return nullptr;
+  }
+}
+
+/// Delete the selected HAL client interface.
+static void delete_hal_interface(
+    BluetoothAudioSinkClientInterface* hal_interface) {
+  if (hal_interface == nullptr) {
+    return;
+  }
+  auto a2dp_transport =
+      static_cast<A2dpTransport*>(hal_interface->GetTransportInstance());
+  delete a2dp_transport;
+  delete hal_interface;
+}
+
 // Initialize BluetoothAudio HAL: openProvider
 bool init(bluetooth::common::MessageLoopThread* /*message_loop*/) {
   LOG(INFO) << __func__;
@@ -423,32 +452,19 @@
     return false;
   }
 
-  auto a2dp_sink =
-      new A2dpTransport(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
-  software_hal_interface = new BluetoothAudioSinkClientInterface(a2dp_sink);
-  if (!software_hal_interface->IsValid()) {
-    LOG(WARNING) << __func__ << ": BluetoothAudio HAL for A2DP is invalid?!";
-    delete software_hal_interface;
-    software_hal_interface = nullptr;
-    delete a2dp_sink;
+  software_hal_interface =
+      new_hal_interface(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
+  if (software_hal_interface == nullptr) {
     return false;
   }
 
-  if (btif_av_is_a2dp_offload_enabled()) {
-    a2dp_sink =
-        new A2dpTransport(SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
-    offloading_hal_interface = new BluetoothAudioSinkClientInterface(a2dp_sink);
-    if (!offloading_hal_interface->IsValid()) {
-      LOG(FATAL) << __func__
-                 << ": BluetoothAudio HAL for A2DP offloading is invalid?!";
-      delete offloading_hal_interface;
-      offloading_hal_interface = nullptr;
-      delete a2dp_sink;
-      a2dp_sink = static_cast<A2dpTransport*>(
-          software_hal_interface->GetTransportInstance());
-      delete software_hal_interface;
+  if (btif_av_is_a2dp_offload_enabled() &&
+      offloading_hal_interface == nullptr) {
+    offloading_hal_interface =
+        new_hal_interface(SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
+    if (offloading_hal_interface == nullptr) {
+      delete_hal_interface(software_hal_interface);
       software_hal_interface = nullptr;
-      delete a2dp_sink;
       return false;
     }
   }
@@ -918,8 +934,10 @@
   }
   LOG(INFO) << "hint: " << hint.toString();
 
-  if (offloading_hal_interface == nullptr) {
-    LOG(ERROR) << __func__ << "the offloading HAL interface was never opened!";
+  if (offloading_hal_interface == nullptr &&
+      (offloading_hal_interface = new_hal_interface(
+           SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH)) == nullptr) {
+    LOG(ERROR) << __func__ << "the offloading HAL interface cannot be opened";
     return std::nullopt;
   }
 
diff --git a/system/audio_hal_interface/aidl/provider_info.cc b/system/audio_hal_interface/aidl/provider_info.cc
index f814df7..0a8200b 100644
--- a/system/audio_hal_interface/aidl/provider_info.cc
+++ b/system/audio_hal_interface/aidl/provider_info.cc
@@ -292,7 +292,6 @@
   return it != assigned_codec_indexes.end()
              ? std::make_optional(it->second->name.c_str())
              : std::nullopt;
-  return std::nullopt;
 }
 
 bool ProviderInfo::SupportsCodec(btav_a2dp_codec_index_t codec_index) const {
diff --git a/system/stack/Android.bp b/system/stack/Android.bp
index 6b49efc..6921a33 100644
--- a/system/stack/Android.bp
+++ b/system/stack/Android.bp
@@ -675,6 +675,7 @@
         "libcrypto",
         "libcutils",
         "libdl",
+        "libevent",
         "libfmq",
         "libhidlbase",
         "liblog",
@@ -689,8 +690,10 @@
         "android.hardware.bluetooth@1.1",
         "android.hardware.common-V2-ndk",
         "android.hardware.common.fmq-V1-ndk",
+        "android.system.suspend-V1-ndk",
         "android.system.suspend.control-V1-ndk",
         "libFraunhoferAAC",
+        "libaudio-a2dp-hw-utils",
         "libbluetooth-dumpsys",
         "libbluetooth-types",
         "libbluetooth_core_rs",
diff --git a/system/stack/test/fuzzers/Android.bp b/system/stack/test/fuzzers/Android.bp
index 1373e9a..4ab36a8 100644
--- a/system/stack/test/fuzzers/Android.bp
+++ b/system/stack/test/fuzzers/Android.bp
@@ -23,6 +23,7 @@
     ],
     static_libs: [
         "libFraunhoferAAC",
+        "libaudio-a2dp-hw-utils",
         "libbluetooth-dumpsys",
         "libbluetooth-types",
         "libbluetooth_core_rs",
@@ -58,6 +59,7 @@
         "android.hardware.bluetooth.audio@2.1",
         "android.hardware.bluetooth@1.0",
         "android.hardware.bluetooth@1.1",
+        "android.system.suspend-V1-ndk",
         "android.system.suspend.control-V1-ndk",
         "libPlatformProperties",
         "libaaudio",
@@ -66,6 +68,7 @@
         "libbinder_ndk",
         "libcrypto",
         "libcutils",
+        "libevent",
         "libfmq",
         "libhidlbase",
         "liblog",