From 4a8768ea72808a9d4305e8d2d06aaba03ee5b2a7 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 3 Jul 2014 09:51:57 +0200 Subject: [PATCH] Bug 1029386: Asynchronous Bluedroid starting and stopping, r=shuang --- .../bluedroid/BluetoothInterface.cpp | 44 +++++++--- dom/bluetooth/bluedroid/BluetoothInterface.h | 9 +- .../bluedroid/BluetoothServiceBluedroid.cpp | 86 ++++++++++++++----- 3 files changed, 101 insertions(+), 38 deletions(-) diff --git a/dom/bluetooth/bluedroid/BluetoothInterface.cpp b/dom/bluetooth/bluedroid/BluetoothInterface.cpp index f8c6ee1b887b..c001c6e10f14 100644 --- a/dom/bluetooth/bluedroid/BluetoothInterface.cpp +++ b/dom/bluetooth/bluedroid/BluetoothInterface.cpp @@ -451,7 +451,11 @@ DispatchBluetoothResult(BluetoothResultHandler* aRes, runnable = new BluetoothErrorRunnable(aRes, &BluetoothResultHandler::OnError, aStatus); } - NS_DispatchToMainThread(runnable); + nsresult rv = NS_DispatchToMainThread(runnable); + if (NS_FAILED(rv)) { + BT_WARNING("NS_DispatchToMainThread failed: %X", rv); + } + return rv; } /* returns the container structure of a variable; _t is the container's @@ -525,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/bluetooth/bluedroid/BluetoothInterface.h b/dom/bluetooth/bluedroid/BluetoothInterface.h index ba636c5fa923..5503c9c436a0 100644 --- a/dom/bluetooth/bluedroid/BluetoothInterface.h +++ b/dom/bluetooth/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/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp index 25d65aeffdf6..963e3d1d8cd4 100644 --- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp +++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp @@ -158,7 +158,7 @@ public: // Cleanup bluetooth interfaces after BT state becomes BT_STATE_OFF. BluetoothHfpManager::DeinitHfpInterface(); BluetoothA2dpManager::DeinitA2dpInterface(); - sBtInterface->Cleanup(); + sBtInterface->Cleanup(nullptr); return NS_OK; } @@ -796,23 +796,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() @@ -826,20 +854,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() { @@ -852,16 +894,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; }