Bug 1033961: Asynchronous Bluedroid starting and stopping (under bluetooth2/), r=btian

This commit is contained in:
Thomas Zimmermann 2014-07-09 09:38:06 +02:00
parent 1988138e46
commit 5a28ab6e1b
3 changed files with 96 additions and 37 deletions

View File

@ -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 */

View File

@ -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 */

View File

@ -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<nsRunnable> 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<nsRunnable> 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<nsRunnable> runnable =
new BluetoothService::ToggleBtAck(true);
nsRefPtr<nsRunnable> 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<nsRunnable> 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<nsRunnable> runnable =
new BluetoothService::ToggleBtAck(false);
nsRefPtr<nsRunnable> 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;
}