From 3abcc0135c625d4b53ade63e85a8257486d1f1bf Mon Sep 17 00:00:00 2001 From: Cheney Ni Date: Thu, 14 Mar 2019 20:58:59 +0800 Subject: [PATCH] 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 --- audio_hal_interface/Android.bp | 1 + audio_hal_interface/a2dp_encoding.cc | 33 ++++++++++++++-------- audio_hal_interface/a2dp_encoding.h | 2 -- audio_hal_interface/client_interface.cc | 32 +++++++++++++++------ audio_hal_interface/client_interface.h | 4 +++ .../hearing_aid_software_encoding.cc | 33 +++++++++++++++------- .../hearing_aid_software_encoding.h | 2 -- bta/hearing_aid/hearing_aid_audio_source.cc | 16 +++++------ btif/Android.bp | 1 + btif/src/btif_a2dp_source.cc | 5 ++-- 10 files changed, 83 insertions(+), 46 deletions(-) diff --git a/audio_hal_interface/Android.bp b/audio_hal_interface/Android.bp index 11d7dda8c..4b10435db 100644 --- a/audio_hal_interface/Android.bp +++ b/audio_hal_interface/Android.bp @@ -46,6 +46,7 @@ cc_test { "libcutils", "libfmq", "libhidlbase", + "libhidltransport", "liblog", "libutils", ], diff --git a/audio_hal_interface/a2dp_encoding.cc b/audio_hal_interface/a2dp_encoding.cc index bdb46ae4e..5be421482 100644 --- a/audio_hal_interface/a2dp_encoding.cc +++ b/audio_hal_interface/a2dp_encoding.cc @@ -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(remote_delay / 10.0) << " ms"; diff --git a/audio_hal_interface/a2dp_encoding.h b/audio_hal_interface/a2dp_encoding.h index fa0e5a35c..7b104ff39 100644 --- a/audio_hal_interface/a2dp_encoding.h +++ b/audio_hal_interface/a2dp_encoding.h @@ -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(); diff --git a/audio_hal_interface/client_interface.cc b/audio_hal_interface/client_interface.cc index e83ae84be..e6d6a6b6d 100644 --- a/audio_hal_interface/client_interface.cc +++ b/audio_hal_interface/client_interface.cc @@ -20,8 +20,10 @@ #include #include +#include #include #include +#include #include #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& 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 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 f5d21cd4a..11984aa31 100644 --- a/audio_hal_interface/client_interface.h +++ b/audio_hal_interface/client_interface.h @@ -131,6 +131,10 @@ class BluetoothAudioClientInterface { ~BluetoothAudioClientInterface(); + bool IsValid() const { + return provider_ != nullptr; + } + std::vector 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 78871ab46..08922873c 100644 --- a/audio_hal_interface/hearing_aid_software_encoding.cc +++ b/audio_hal_interface/hearing_aid_software_encoding.cc @@ -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; } diff --git a/audio_hal_interface/hearing_aid_software_encoding.h b/audio_hal_interface/hearing_aid_software_encoding.h index f8d8a5332..5723033b1 100644 --- a/audio_hal_interface/hearing_aid_software_encoding.h +++ b/audio_hal_interface/hearing_aid_software_encoding.h @@ -28,8 +28,6 @@ struct StreamCallbacks { std::function 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 3bfb0a4e3..fe44e4c14 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::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); } } diff --git a/btif/Android.bp b/btif/Android.bp index 3b4e57464..cef01d71b 100644 --- a/btif/Android.bp +++ b/btif/Android.bp @@ -132,6 +132,7 @@ cc_test { "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 ba35e9e8e..335e62a4c 100644 --- a/btif/src/btif_a2dp_source.cc +++ b/btif/src/btif_a2dp_source.cc @@ -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); -- 2.11.0