Fallback to the legacy HAL when IBluetoothAudioProvidersFactory is unsupported

Because the stack may run without the new BluetoothAudio HAL like GSI
under old devices, it will be nullptr to getService from the
IBluetoothAudioProvidersFactory in such condition. We take nullptr as
unsupported, and fallback to the legacy HAL.

Bug: 128419724
Test: Manually running A2DP and hearing aid with / without the HAL
Change-Id: I606abc3e5b63b7857c3307c879fd4cbe46dd05d9
diff --git a/audio_hal_interface/Android.bp b/audio_hal_interface/Android.bp
index 11d7dda..4b10435 100644
--- a/audio_hal_interface/Android.bp
+++ b/audio_hal_interface/Android.bp
@@ -46,6 +46,7 @@
         "libcutils",
         "libfmq",
         "libhidlbase",
+        "libhidltransport",
         "liblog",
         "libutils",
     ],
diff --git a/audio_hal_interface/a2dp_encoding.cc b/audio_hal_interface/a2dp_encoding.cc
index bdb46ae..5be4214 100644
--- a/audio_hal_interface/a2dp_encoding.cc
+++ b/audio_hal_interface/a2dp_encoding.cc
@@ -209,7 +209,7 @@
 // initialized
 uint16_t remote_delay = 0;
 
-bool btaudio_a2dp_supported = false;
+bool btaudio_a2dp_disabled = false;
 bool is_configured = false;
 
 BluetoothAudioCtrlAck a2dp_ack_to_bt_audio_ctrl_ack(tA2DP_CTRL_ACK ack) {
@@ -543,21 +543,21 @@
           pcm_config->channelMode != ChannelMode::UNKNOWN);
 }
 
+// Checking if new bluetooth_audio is supported
+bool is_hal_2_0_force_disabled() {
+  if (!is_configured) {
+    btaudio_a2dp_disabled = osi_property_get_bool(BLUETOOTH_AUDIO_HAL_PROP_DISABLED, false);
+    is_configured = true;
+  }
+  return btaudio_a2dp_disabled;
+}
+
 }  // namespace
 
 namespace bluetooth {
 namespace audio {
 namespace a2dp {
 
-// Checking if new bluetooth_audio is supported
-bool is_hal_2_0_supported() {
-  if (!is_configured) {
-    btaudio_a2dp_supported = !osi_property_get_bool(BLUETOOTH_AUDIO_HAL_PROP_DISABLED, false);
-    is_configured = true;
-  }
-  return btaudio_a2dp_supported;
-}
-
 // Checking if new bluetooth_audio is enabled
 bool is_hal_2_0_enabled() { return a2dp_hal_clientif != nullptr; }
 
@@ -565,8 +565,8 @@
 bool init(bluetooth::common::MessageLoopThread* message_loop) {
   LOG(INFO) << __func__;
 
-  if (!is_hal_2_0_supported()) {
-    LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not supported";
+  if (is_hal_2_0_force_disabled()) {
+    LOG(ERROR) << __func__ << ": BluetoothAudio HAL is disabled";
     return false;
   }
 
@@ -578,6 +578,15 @@
   a2dp_sink = new A2dpTransport(session_type);
   a2dp_hal_clientif = new bluetooth::audio::BluetoothAudioClientInterface(
       a2dp_sink, message_loop);
+  if (!a2dp_hal_clientif->IsValid()) {
+    LOG(WARNING) << __func__ << ": BluetoothAudio HAL for A2DP session=" << toString(session_type) << " is invalid?!";
+    delete a2dp_hal_clientif;
+    a2dp_hal_clientif = nullptr;
+    delete a2dp_sink;
+    a2dp_sink = nullptr;
+    return false;
+  }
+
   if (remote_delay != 0) {
     LOG(INFO) << __func__ << ": restore DELAY "
               << static_cast<float>(remote_delay / 10.0) << " ms";
diff --git a/audio_hal_interface/a2dp_encoding.h b/audio_hal_interface/a2dp_encoding.h
index fa0e5a3..7b104ff 100644
--- a/audio_hal_interface/a2dp_encoding.h
+++ b/audio_hal_interface/a2dp_encoding.h
@@ -23,8 +23,6 @@
 namespace audio {
 namespace a2dp {
 
-bool is_hal_2_0_supported();
-
 // Check if new bluetooth_audio is enabled
 bool is_hal_2_0_enabled();
 
diff --git a/audio_hal_interface/client_interface.cc b/audio_hal_interface/client_interface.cc
index e83ae84..e6d6a6b 100644
--- a/audio_hal_interface/client_interface.cc
+++ b/audio_hal_interface/client_interface.cc
@@ -20,8 +20,10 @@
 
 #include <android/hardware/bluetooth/audio/2.0/IBluetoothAudioPort.h>
 #include <android/hardware/bluetooth/audio/2.0/IBluetoothAudioProvidersFactory.h>
+#include <android/hidl/manager/1.2/IServiceManager.h>
 #include <base/logging.h>
 #include <hidl/MQDescriptor.h>
+#include <hidl/ServiceManagement.h>
 #include <future>
 
 #include "osi/include/log.h"
@@ -41,6 +43,8 @@
 
 static constexpr int kDefaultDataReadTimeoutMs = 10;      // 10 ms
 static constexpr int kDefaultDataReadPollIntervalMs = 1;  // non-blocking poll
+static constexpr char kFullyQualifiedInterfaceName[] =
+    "android.hardware.bluetooth.audio@2.0::IBluetoothAudioProvidersFactory";
 
 std::ostream& operator<<(std::ostream& os, const BluetoothAudioCtrlAck& ack) {
   switch (ack) {
@@ -186,14 +190,26 @@
   }
 };
 
-BluetoothAudioClientInterface::BluetoothAudioClientInterface(
-    IBluetoothTransportInstance* sink,
-    bluetooth::common::MessageLoopThread* message_loop)
-    : sink_(sink),
-      session_started_(false),
-      mDataMQ(nullptr),
+BluetoothAudioClientInterface::BluetoothAudioClientInterface(IBluetoothTransportInstance* sink,
+                                                             bluetooth::common::MessageLoopThread* message_loop)
+    : sink_(sink), provider_(nullptr), session_started_(false), mDataMQ(nullptr),
       death_recipient_(new BluetoothAudioDeathRecipient(this, message_loop)) {
-  fetch_audio_provider();
+  auto service_manager = android::hardware::defaultServiceManager1_2();
+  CHECK(service_manager != nullptr);
+  size_t instance_count = 0;
+  auto listManifestByInterface_cb = [&instance_count](const hidl_vec<android::hardware::hidl_string>& instanceNames) {
+    instance_count = instanceNames.size();
+    LOG(INFO) << "listManifestByInterface_cb returns " << instance_count << " instance(s)";
+  };
+  auto hidl_retval = service_manager->listManifestByInterface(kFullyQualifiedInterfaceName, listManifestByInterface_cb);
+  if (!hidl_retval.isOk()) {
+    LOG(FATAL) << __func__ << ": IServiceManager::listByInterface failure: " << hidl_retval.description();
+  }
+  if (instance_count > 0) {
+    fetch_audio_provider();
+  } else {
+    LOG(WARNING) << "IBluetoothAudioProvidersFactory not declared";
+  }
 }
 
 BluetoothAudioClientInterface::~BluetoothAudioClientInterface() {
@@ -217,7 +233,7 @@
 
   android::sp<IBluetoothAudioProvidersFactory> providersFactory =
       IBluetoothAudioProvidersFactory::getService();
-  CHECK(providersFactory != nullptr);
+  CHECK(providersFactory != nullptr) << "IBluetoothAudioProvidersFactory::getService() failed";
   LOG(INFO) << "IBluetoothAudioProvidersFactory::getService() returned "
             << providersFactory.get()
             << (providersFactory->isRemote() ? " (remote)" : " (local)");
diff --git a/audio_hal_interface/client_interface.h b/audio_hal_interface/client_interface.h
index f5d21cd..11984aa 100644
--- a/audio_hal_interface/client_interface.h
+++ b/audio_hal_interface/client_interface.h
@@ -131,6 +131,10 @@
 
   ~BluetoothAudioClientInterface();
 
+  bool IsValid() const {
+    return provider_ != nullptr;
+  }
+
   std::vector<AudioCapabilities> GetAudioCapabilities() const;
 
   bool UpdateAudioConfig(const AudioConfiguration& audioConfig);
diff --git a/audio_hal_interface/hearing_aid_software_encoding.cc b/audio_hal_interface/hearing_aid_software_encoding.cc
index 78871ab..0892287 100644
--- a/audio_hal_interface/hearing_aid_software_encoding.cc
+++ b/audio_hal_interface/hearing_aid_software_encoding.cc
@@ -131,35 +131,46 @@
 // Common interface to call-out into Bluetooth Audio Hal
 bluetooth::audio::BluetoothAudioClientInterface*
     hearing_aid_hal_clientinterface = nullptr;
-bool btaudio_hearing_aid_supported = false;
+bool btaudio_hearing_aid_disabled = false;
 bool is_configured = false;
 
+bool is_hal_2_0_force_disabled() {
+  if (!is_configured) {
+    btaudio_hearing_aid_disabled = osi_property_get_bool(BLUETOOTH_AUDIO_HAL_PROP_DISABLED, false);
+    is_configured = true;
+  }
+  return btaudio_hearing_aid_disabled;
+}
+
 }  // namespace
 
 namespace bluetooth {
 namespace audio {
 namespace hearing_aid {
 
-bool is_hal_2_0_supported() {
-  if (!is_configured) {
-    btaudio_hearing_aid_supported = !osi_property_get_bool(BLUETOOTH_AUDIO_HAL_PROP_DISABLED, false);
-    is_configured = true;
-  }
-  return btaudio_hearing_aid_supported;
-}
-
 bool is_hal_2_0_enabled() { return hearing_aid_hal_clientinterface != nullptr; }
 
 bool init(StreamCallbacks stream_cb,
           bluetooth::common::MessageLoopThread* message_loop) {
   LOG(INFO) << __func__;
 
-  if (!is_hal_2_0_supported()) return false;
+  if (is_hal_2_0_force_disabled()) {
+    LOG(ERROR) << __func__ << ": BluetoothAudio HAL is disabled";
+    return false;
+  }
 
   hearing_aid_sink = new HearingAidTransport(std::move(stream_cb));
   hearing_aid_hal_clientinterface =
       new bluetooth::audio::BluetoothAudioClientInterface(hearing_aid_sink,
                                                           message_loop);
+  if (!hearing_aid_hal_clientinterface->IsValid()) {
+    LOG(WARNING) << __func__ << ": BluetoothAudio HAL for Hearing Aid is invalid?!";
+    delete hearing_aid_hal_clientinterface;
+    hearing_aid_hal_clientinterface = nullptr;
+    delete hearing_aid_sink;
+    hearing_aid_sink = nullptr;
+    return false;
+  }
   return true;
 }
 
@@ -167,7 +178,9 @@
   LOG(INFO) << __func__;
   if (!is_hal_2_0_enabled()) return;
   end_session();
+  delete hearing_aid_hal_clientinterface;
   hearing_aid_hal_clientinterface = nullptr;
+  delete hearing_aid_sink;
   hearing_aid_sink = nullptr;
 }
 
diff --git a/audio_hal_interface/hearing_aid_software_encoding.h b/audio_hal_interface/hearing_aid_software_encoding.h
index f8d8a53..5723033 100644
--- a/audio_hal_interface/hearing_aid_software_encoding.h
+++ b/audio_hal_interface/hearing_aid_software_encoding.h
@@ -28,8 +28,6 @@
   std::function<bool(void)> on_suspend_;
 };
 
-bool is_hal_2_0_supported();
-
 // Check if new bluetooth_audio is enabled
 bool is_hal_2_0_enabled();
 
diff --git a/bta/hearing_aid/hearing_aid_audio_source.cc b/bta/hearing_aid/hearing_aid_audio_source.cc
index 3bfb0a4..fe44e4c 100644
--- a/bta/hearing_aid/hearing_aid_audio_source.cc
+++ b/bta/hearing_aid/hearing_aid_audio_source.cc
@@ -387,16 +387,14 @@
 }
 
 void HearingAidAudioSource::Initialize() {
-  if (bluetooth::audio::hearing_aid::is_hal_2_0_supported()) {
-    auto stream_cb = bluetooth::audio::hearing_aid::StreamCallbacks{
-        .on_resume_ = hearing_aid_on_resume_req,
-        .on_suspend_ = hearing_aid_on_suspend_req,
-    };
-    bluetooth::audio::hearing_aid::init(stream_cb, get_main_thread());
-  } else {
+  auto stream_cb = bluetooth::audio::hearing_aid::StreamCallbacks{
+      .on_resume_ = hearing_aid_on_resume_req,
+      .on_suspend_ = hearing_aid_on_suspend_req,
+  };
+  if (!bluetooth::audio::hearing_aid::init(stream_cb, get_main_thread())) {
+    LOG(WARNING) << __func__ << ": Using legacy HAL";
     uipc_hearing_aid = UIPC_Init();
-    UIPC_Open(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, hearing_aid_ctrl_cb,
-              HEARING_AID_CTRL_PATH);
+    UIPC_Open(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, hearing_aid_ctrl_cb, HEARING_AID_CTRL_PATH);
   }
 }
 
diff --git a/btif/Android.bp b/btif/Android.bp
index 3b4e574..cef01d7 100644
--- a/btif/Android.bp
+++ b/btif/Android.bp
@@ -132,6 +132,7 @@
         "android.hardware.bluetooth.audio@2.0",
         "libfmq",
         "libhidlbase",
+        "libhidltransport",
         "liblog",
         "libprotobuf-cpp-lite",
         "libcutils",
diff --git a/btif/src/btif_a2dp_source.cc b/btif/src/btif_a2dp_source.cc
index ba35e9e..335e62a 100644
--- a/btif/src/btif_a2dp_source.cc
+++ b/btif/src/btif_a2dp_source.cc
@@ -356,9 +356,8 @@
   if (!btif_a2dp_source_thread.EnableRealTimeScheduling()) {
     LOG(FATAL) << __func__ << ": unable to enable real time scheduling";
   }
-  if (bluetooth::audio::a2dp::is_hal_2_0_supported()) {
-    bluetooth::audio::a2dp::init(&btif_a2dp_source_thread);
-  } else {
+  if (!bluetooth::audio::a2dp::init(&btif_a2dp_source_thread)) {
+    LOG(WARNING) << __func__ << ": Using legacy HAL";
     btif_a2dp_control_init();
   }
   btif_a2dp_source_cb.SetState(BtifA2dpSource::kStateRunning);