Bug 1005901 - [bluedroid] Always do cleanup after disable. r=btian

This commit is contained in:
Shawn Huang 2014-05-16 04:48:00 -04:00
Родитель 4c2943887d
Коммит 619acef8fd
5 изменённых файлов: 84 добавлений и 39 удалений

Просмотреть файл

@ -504,35 +504,32 @@ static btrc_callbacks_t sBtAvrcpCallbacks = {
* It is required to register a2dp callbacks before a2dp media task
* starts up.
*/
bool
BluetoothA2dpManager::Init()
// static
void
BluetoothA2dpManager::InitA2dpInterface()
{
const bt_interface_t* btInf = GetBluetoothInterface();
NS_ENSURE_TRUE(btInf, false);
NS_ENSURE_TRUE_VOID(btInf);
sBtA2dpInterface = (btav_interface_t *)btInf->
get_profile_interface(BT_PROFILE_ADVANCED_AUDIO_ID);
NS_ENSURE_TRUE(sBtA2dpInterface, false);
NS_ENSURE_TRUE_VOID(sBtA2dpInterface);
int ret = sBtA2dpInterface->init(&sBtA2dpCallbacks);
if (ret != BT_STATUS_SUCCESS) {
BT_LOGR("Warning: failed to init a2dp module");
return false;
}
#if ANDROID_VERSION > 17
sBtAvrcpInterface = (btrc_interface_t *)btInf->
get_profile_interface(BT_PROFILE_AV_RC_ID);
NS_ENSURE_TRUE(sBtAvrcpInterface, false);
NS_ENSURE_TRUE_VOID(sBtAvrcpInterface);
ret = sBtAvrcpInterface->init(&sBtAvrcpCallbacks);
if (ret != BT_STATUS_SUCCESS) {
BT_LOGR("Warning: failed to init avrcp module");
return false;
}
#endif
return true;
}
BluetoothA2dpManager::~BluetoothA2dpManager()
@ -602,12 +599,28 @@ BluetoothA2dpManager::Get()
// Create a new instance, register, and return
BluetoothA2dpManager* manager = new BluetoothA2dpManager();
NS_ENSURE_TRUE(manager->Init(), nullptr);
sBluetoothA2dpManager = manager;
return sBluetoothA2dpManager;
}
// static
void
BluetoothA2dpManager::DeinitA2dpInterface()
{
MOZ_ASSERT(NS_IsMainThread());
if (sBtA2dpInterface) {
sBtA2dpInterface->cleanup();
sBtA2dpInterface = nullptr;
}
#if ANDROID_VERSION > 17
if (sBtAvrcpInterface) {
sBtAvrcpInterface->cleanup();
sBtAvrcpInterface = nullptr;
}
#endif
}
void
BluetoothA2dpManager::HandleShutdown()
{
@ -623,7 +636,7 @@ BluetoothA2dpManager::Connect(const nsAString& aDeviceAddress,
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!aDeviceAddress.IsEmpty());
MOZ_ASSERT(aController && !mController);
MOZ_ASSERT(aController);
BluetoothService* bs = BluetoothService::Get();
if (!bs || sInShutdown) {

Просмотреть файл

@ -30,6 +30,8 @@ public:
};
static BluetoothA2dpManager* Get();
static void InitA2dpInterface();
static void DeinitA2dpInterface();
virtual ~BluetoothA2dpManager();
// A2DP-specific functions
@ -60,7 +62,6 @@ public:
private:
class SinkPropertyChangedHandler;
BluetoothA2dpManager();
bool Init();
void ResetA2dp();
void ResetAvrcp();

Просмотреть файл

@ -135,6 +135,26 @@ public:
}
};
class CleanupTask : public nsRunnable
{
public:
CleanupTask()
{ }
NS_IMETHOD
Run()
{
MOZ_ASSERT(NS_IsMainThread());
// Cleanup bluetooth interfaces after BT state becomes BT_STATE_OFF.
BluetoothHfpManager::DeinitHfpInterface();
BluetoothA2dpManager::DeinitA2dpInterface();
sBtInterface->cleanup();
return NS_OK;
}
};
/**
* Static callback functions
*/
@ -269,6 +289,10 @@ AdapterStateChangeCallback(bt_state_t aStatus)
sIsBtEnabled = (aStatus == BT_STATE_ON);
if (!sIsBtEnabled && NS_FAILED(NS_DispatchToMainThread(new CleanupTask()))) {
BT_WARNING("Failed to dispatch to main thread!");
}
nsRefPtr<nsRunnable> runnable =
new BluetoothService::ToggleBtAck(sIsBtEnabled);
if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
@ -656,15 +680,29 @@ EnsureBluetoothHalLoad()
}
module->methods->open(module, BT_HARDWARE_MODULE_ID, &device);
sBtDevice = (bluetooth_device_t *)device;
NS_ENSURE_TRUE(sBtDevice, false);
sBtInterface = sBtDevice->get_bluetooth_interface();
NS_ENSURE_TRUE(sBtInterface, false);
return true;
}
static bool
EnableInternal()
{
int ret = sBtInterface->init(&sBluetoothCallbacks);
if (ret != BT_STATUS_SUCCESS) {
BT_LOGR("Error while setting the callbacks");
sBtInterface = nullptr;
return false;
}
return true;
// 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();
}
static nsresult
@ -683,7 +721,7 @@ StartStopGonkBluetooth(bool aShouldEnable)
return NS_OK;
}
int ret = aShouldEnable ? sBtInterface->enable() : sBtInterface->disable();
int ret = aShouldEnable ? EnableInternal() : sBtInterface->disable();
NS_ENSURE_TRUE(ret == BT_STATUS_SUCCESS, NS_ERROR_FAILURE);
return NS_OK;
@ -727,11 +765,6 @@ BluetoothServiceBluedroid::BluetoothServiceBluedroid()
BT_LOGR("Error! Failed to load bluedroid library.");
return;
}
// Register all the bluedroid callbacks before enable() get called
// It is required to register a2dp callbacks before a2dp media task starts up.
BluetoothHfpManager::Get();
BluetoothA2dpManager::Get();
}
BluetoothServiceBluedroid::~BluetoothServiceBluedroid()

Просмотреть файл

@ -395,8 +395,6 @@ BluetoothHfpManager::Init()
{
MOZ_ASSERT(NS_IsMainThread());
NS_ENSURE_TRUE(InitHfpInterface(), false);
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
NS_ENSURE_TRUE(obs, false);
@ -430,11 +428,12 @@ BluetoothHfpManager::Init()
return true;
}
bool
// static
void
BluetoothHfpManager::InitHfpInterface()
{
const bt_interface_t* btInf = GetBluetoothInterface();
NS_ENSURE_TRUE(btInf, false);
NS_ENSURE_TRUE_VOID(btInf);
if (sBluetoothHfpInterface) {
sBluetoothHfpInterface->cleanup();
@ -443,13 +442,11 @@ BluetoothHfpManager::InitHfpInterface()
bthf_interface_t *interface = (bthf_interface_t *)
btInf->get_profile_interface(BT_PROFILE_HANDSFREE_ID);
NS_ENSURE_TRUE(interface, false);
NS_ENSURE_TRUE_VOID(interface);
NS_ENSURE_TRUE(BT_STATUS_SUCCESS ==
interface->init(&sBluetoothHfpCallbacks), false);
NS_ENSURE_TRUE_VOID(BT_STATUS_SUCCESS ==
interface->init(&sBluetoothHfpCallbacks));
sBluetoothHfpInterface = interface;
return true;
}
BluetoothHfpManager::~BluetoothHfpManager()
@ -468,9 +465,9 @@ BluetoothHfpManager::~BluetoothHfpManager()
}
hal::UnregisterBatteryObserver(this);
DeinitHfpInterface();
}
// static
void
BluetoothHfpManager::DeinitHfpInterface()
{
@ -1045,13 +1042,14 @@ BluetoothHfpManager::UpdatePhoneCIND(uint32_t aCallIndex)
void
BluetoothHfpManager::UpdateDeviceCIND()
{
NS_ENSURE_TRUE_VOID(sBluetoothHfpInterface);
NS_ENSURE_TRUE_VOID(BT_STATUS_SUCCESS ==
sBluetoothHfpInterface->device_status_notification(
(bthf_network_state_t) mService,
(bthf_service_type_t) mRoam,
mSignal,
mBattChg));
if (sBluetoothHfpInterface) {
NS_ENSURE_TRUE_VOID(BT_STATUS_SUCCESS ==
sBluetoothHfpInterface->device_status_notification(
(bthf_network_state_t) mService,
(bthf_service_type_t) mRoam,
mSignal,
mBattChg));
}
}
uint32_t

Просмотреть файл

@ -84,6 +84,8 @@ public:
static BluetoothHfpManager* Get();
virtual ~BluetoothHfpManager();
static void InitHfpInterface();
static void DeinitHfpInterface();
bool ConnectSco();
bool DisconnectSco();
@ -134,8 +136,6 @@ private:
BluetoothHfpManager();
bool Init();
bool InitHfpInterface();
void DeinitHfpInterface();
void HandleShutdown();
void HandleVolumeChanged(const nsAString& aData);