From 5a28ab6e1b2fd8ec49688f5a1dac986426d7e32e Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 9 Jul 2014 09:38:06 +0200 Subject: [PATCH] Bug 1033961: Asynchronous Bluedroid starting and stopping (under bluetooth2/), r=btian --- .../bluedroid/BluetoothInterface.cpp | 38 +++++--- dom/bluetooth2/bluedroid/BluetoothInterface.h | 9 +- .../bluedroid/BluetoothServiceBluedroid.cpp | 86 ++++++++++++++----- 3 files changed, 96 insertions(+), 37 deletions(-) diff --git a/dom/bluetooth2/bluedroid/BluetoothInterface.cpp b/dom/bluetooth2/bluedroid/BluetoothInterface.cpp index 619555ac6be..b1b42107b07 100644 --- a/dom/bluetooth2/bluedroid/BluetoothInterface.cpp +++ b/dom/bluetooth2/bluedroid/BluetoothInterface.cpp @@ -529,28 +529,46 @@ BluetoothInterface::BluetoothInterface(const bt_interface_t* aInterface) BluetoothInterface::~BluetoothInterface() { } -int -BluetoothInterface::Init(bt_callbacks_t* aCallbacks) +void +BluetoothInterface::Init(bt_callbacks_t* aCallbacks, + BluetoothResultHandler* aRes) { - return mInterface->init(aCallbacks); + int status = mInterface->init(aCallbacks); + + if (aRes) { + DispatchBluetoothResult(aRes, &BluetoothResultHandler::Init, status); + } } void -BluetoothInterface::Cleanup() +BluetoothInterface::Cleanup(BluetoothResultHandler* aRes) { mInterface->cleanup(); + + if (aRes) { + DispatchBluetoothResult(aRes, &BluetoothResultHandler::Cleanup, + BT_STATUS_SUCCESS); + } } -int -BluetoothInterface::Enable() +void +BluetoothInterface::Enable(BluetoothResultHandler* aRes) { - return mInterface->enable(); + int status = mInterface->enable(); + + if (aRes) { + DispatchBluetoothResult(aRes, &BluetoothResultHandler::Enable, status); + } } -int -BluetoothInterface::Disable() +void +BluetoothInterface::Disable(BluetoothResultHandler* aRes) { - return mInterface->disable(); + int status = mInterface->disable(); + + if (aRes) { + DispatchBluetoothResult(aRes, &BluetoothResultHandler::Disable, status); + } } /* Adapter Properties */ diff --git a/dom/bluetooth2/bluedroid/BluetoothInterface.h b/dom/bluetooth2/bluedroid/BluetoothInterface.h index a9673a2c06f..41c797f1f84 100644 --- a/dom/bluetooth2/bluedroid/BluetoothInterface.h +++ b/dom/bluetooth2/bluedroid/BluetoothInterface.h @@ -230,11 +230,12 @@ class BluetoothInterface public: static BluetoothInterface* GetInstance(); - int Init(bt_callbacks_t* aCallbacks); - void Cleanup(); + void Init(bt_callbacks_t* aCallbacks, BluetoothResultHandler* aRes); + void Cleanup(BluetoothResultHandler* aRes); + + void Enable(BluetoothResultHandler* aRes); + void Disable(BluetoothResultHandler* aRes); - int Enable(); - int Disable(); /* Adapter Properties */ diff --git a/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp b/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp index e5e20ef2124..d1bc4f0aee9 100644 --- a/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp +++ b/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp @@ -177,7 +177,7 @@ public: // Cleanup bluetooth interfaces after BT state becomes BT_STATE_OFF. BluetoothHfpManager::DeinitHfpInterface(); BluetoothA2dpManager::DeinitA2dpInterface(); - sBtInterface->Cleanup(); + sBtInterface->Cleanup(nullptr); return NS_OK; } @@ -812,23 +812,51 @@ EnsureBluetoothHalLoad() return true; } -static bool -EnableInternal() +class EnableResultHandler MOZ_FINAL : public BluetoothResultHandler { - int ret = sBtInterface->Init(&sBluetoothCallbacks); - if (ret != BT_STATUS_SUCCESS) { - BT_LOGR("Error while setting the callbacks"); - sBtInterface = nullptr; - return false; +public: + void OnError(int aStatus) MOZ_OVERRIDE + { + MOZ_ASSERT(NS_IsMainThread()); + + BT_LOGR("BluetoothInterface::Enable failed: %d", aStatus); + + nsRefPtr runnable = new BluetoothService::ToggleBtAck(false); + if (NS_FAILED(NS_DispatchToMainThread(runnable))) { + BT_WARNING("Failed to dispatch to main thread!"); + } + } +}; + +class InitResultHandler MOZ_FINAL : public BluetoothResultHandler +{ +public: + void Init() MOZ_OVERRIDE + { + MOZ_ASSERT(NS_IsMainThread()); + + // Register all the bluedroid callbacks before enable() get called + // It is required to register a2dp callbacks before a2dp media task starts up. + // If any interface cannot be initialized, turn on bluetooth core anyway. + BluetoothHfpManager::InitHfpInterface(); + BluetoothA2dpManager::InitA2dpInterface(); + sBtInterface->Enable(new EnableResultHandler()); } - // Register all the bluedroid callbacks before enable() get called - // It is required to register a2dp callbacks before a2dp media task starts up. - // If any interface cannot be initialized, turn on bluetooth core anyway. - BluetoothHfpManager::InitHfpInterface(); - BluetoothA2dpManager::InitA2dpInterface(); - return sBtInterface->Enable(); -} + void OnError(int aStatus) MOZ_OVERRIDE + { + MOZ_ASSERT(NS_IsMainThread()); + + BT_LOGR("BluetoothInterface::Init failed: %d", aStatus); + + sBtInterface = nullptr; + + nsRefPtr runnable = new BluetoothService::ToggleBtAck(false); + if (NS_FAILED(NS_DispatchToMainThread(runnable))) { + BT_WARNING("Failed to dispatch to main thread!"); + } + } +}; static nsresult StartGonkBluetooth() @@ -842,20 +870,34 @@ StartGonkBluetooth() if (bs->IsEnabled()) { // Keep current enable status - nsRefPtr runnable = - new BluetoothService::ToggleBtAck(true); + nsRefPtr runnable = new BluetoothService::ToggleBtAck(true); if (NS_FAILED(NS_DispatchToMainThread(runnable))) { BT_WARNING("Failed to dispatch to main thread!"); } return NS_OK; } - int ret = EnableInternal(); - NS_ENSURE_TRUE(ret == BT_STATUS_SUCCESS, NS_ERROR_FAILURE); + sBtInterface->Init(&sBluetoothCallbacks, new InitResultHandler()); return NS_OK; } +class DisableResultHandler MOZ_FINAL : public BluetoothResultHandler +{ +public: + void OnError(int aStatus) MOZ_OVERRIDE + { + MOZ_ASSERT(NS_IsMainThread()); + + BT_LOGR("BluetoothInterface::Disable failed: %d", aStatus); + + nsRefPtr runnable = new BluetoothService::ToggleBtAck(true); + if (NS_FAILED(NS_DispatchToMainThread(runnable))) { + BT_WARNING("Failed to dispatch to main thread!"); + } + } +}; + static nsresult StopGonkBluetooth() { @@ -868,16 +910,14 @@ StopGonkBluetooth() if (!bs->IsEnabled()) { // Keep current enable status - nsRefPtr runnable = - new BluetoothService::ToggleBtAck(false); + nsRefPtr runnable = new BluetoothService::ToggleBtAck(false); if (NS_FAILED(NS_DispatchToMainThread(runnable))) { BT_WARNING("Failed to dispatch to main thread!"); } return NS_OK; } - int ret = sBtInterface->Disable(); - NS_ENSURE_TRUE(ret == BT_STATUS_SUCCESS, NS_ERROR_FAILURE); + sBtInterface->Disable(new DisableResultHandler()); return NS_OK; }