OSDN Git Service

Fallback to the legacy HAL when IBluetoothAudioProvidersFactory is unsupported
authorCheney Ni <cheneyni@google.com>
Thu, 14 Mar 2019 12:58:59 +0000 (20:58 +0800)
committerCheney Ni <cheneyni@google.com>
Mon, 18 Mar 2019 07:15:50 +0000 (15:15 +0800)
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

audio_hal_interface/Android.bp
audio_hal_interface/a2dp_encoding.cc
audio_hal_interface/a2dp_encoding.h
audio_hal_interface/client_interface.cc
audio_hal_interface/client_interface.h
audio_hal_interface/hearing_aid_software_encoding.cc
audio_hal_interface/hearing_aid_software_encoding.h
bta/hearing_aid/hearing_aid_audio_source.cc
btif/Android.bp
btif/src/btif_a2dp_source.cc

index 11d7dda..4b10435 100644 (file)
@@ -46,6 +46,7 @@ cc_test {
         "libcutils",
         "libfmq",
         "libhidlbase",
+        "libhidltransport",
         "liblog",
         "libutils",
     ],
index bdb46ae..5be4214 100644 (file)
@@ -209,7 +209,7 @@ auto session_type = SessionType::UNKNOWN;
 // 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 @@ bool a2dp_get_selected_hal_pcm_config(PcmParameters* pcm_config) {
           pcm_config->channelMode != ChannelMode::UNKNOWN);
 }
 
-}  // namespace
-
-namespace bluetooth {
-namespace audio {
-namespace a2dp {
-
 // Checking if new bluetooth_audio is supported
-bool is_hal_2_0_supported() {
+bool is_hal_2_0_force_disabled() {
   if (!is_configured) {
-    btaudio_a2dp_supported = !osi_property_get_bool(BLUETOOTH_AUDIO_HAL_PROP_DISABLED, false);
+    btaudio_a2dp_disabled = osi_property_get_bool(BLUETOOTH_AUDIO_HAL_PROP_DISABLED, false);
     is_configured = true;
   }
-  return btaudio_a2dp_supported;
+  return btaudio_a2dp_disabled;
 }
 
+}  // namespace
+
+namespace bluetooth {
+namespace audio {
+namespace a2dp {
+
 // Checking if new bluetooth_audio is enabled
 bool is_hal_2_0_enabled() { return a2dp_hal_clientif != nullptr; }
 
@@ -565,8 +565,8 @@ bool is_hal_2_0_enabled() { return a2dp_hal_clientif != nullptr; }
 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 @@ bool init(bluetooth::common::MessageLoopThread* message_loop) {
   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";
index fa0e5a3..7b104ff 100644 (file)
@@ -23,8 +23,6 @@ namespace bluetooth {
 namespace audio {
 namespace a2dp {
 
-bool is_hal_2_0_supported();
-
 // Check if new bluetooth_audio is enabled
 bool is_hal_2_0_enabled();
 
index e83ae84..e6d6a6b 100644 (file)
 
 #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 @@ using DataMQ = ::android::hardware::MessageQueue<
 
 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 @@ class BluetoothAudioDeathRecipient
   }
 };
 
-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 @@ void BluetoothAudioClientInterface::fetch_audio_provider() {
 
   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)");
index f5d21cd..11984aa 100644 (file)
@@ -131,6 +131,10 @@ class BluetoothAudioClientInterface {
 
   ~BluetoothAudioClientInterface();
 
+  bool IsValid() const {
+    return provider_ != nullptr;
+  }
+
   std::vector<AudioCapabilities> GetAudioCapabilities() const;
 
   bool UpdateAudioConfig(const AudioConfiguration& audioConfig);
index 78871ab..0892287 100644 (file)
@@ -131,35 +131,46 @@ HearingAidTransport* hearing_aid_sink = nullptr;
 // 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 @@ void cleanup() {
   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;
 }
 
index f8d8a53..5723033 100644 (file)
@@ -28,8 +28,6 @@ struct StreamCallbacks {
   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();
 
index 3bfb0a4..fe44e4c 100644 (file)
@@ -387,16 +387,14 @@ void HearingAidAudioSource::Stop() {
 }
 
 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);
   }
 }
 
index 3b4e574..cef01d7 100644 (file)
@@ -132,6 +132,7 @@ cc_test {
         "android.hardware.bluetooth.audio@2.0",
         "libfmq",
         "libhidlbase",
+        "libhidltransport",
         "liblog",
         "libprotobuf-cpp-lite",
         "libcutils",
index ba35e9e..335e62a 100644 (file)
@@ -356,9 +356,8 @@ static void btif_a2dp_source_startup_delayed() {
   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);