зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1042691: Asynchronous init and cleanup of A2DP/AVRCP (under bluetooth2/), r=btian
This commit is contained in:
Родитель
6c5cf788bd
Коммит
abbdf7f4d9
|
@ -492,6 +492,85 @@ static btrc_callbacks_t sBtAvrcpCallbacks = {
|
|||
};
|
||||
#endif
|
||||
|
||||
#if ANDROID_VERSION > 17
|
||||
class InitAvrcpResultHandler MOZ_FINAL : public BluetoothAvrcpResultHandler
|
||||
{
|
||||
public:
|
||||
InitAvrcpResultHandler(BluetoothProfileResultHandler* aRes)
|
||||
: mRes(aRes)
|
||||
{ }
|
||||
|
||||
void OnError(bt_status_t aStatus) MOZ_OVERRIDE
|
||||
{
|
||||
BT_WARNING("BluetoothAvrcpInterface::Init failed: %d",
|
||||
(int)aStatus);
|
||||
if (mRes) {
|
||||
mRes->OnError(NS_ERROR_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void Init() MOZ_OVERRIDE
|
||||
{
|
||||
if (mRes) {
|
||||
mRes->Init();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<BluetoothProfileResultHandler> mRes;
|
||||
};
|
||||
#endif
|
||||
|
||||
class InitA2dpResultHandler MOZ_FINAL : public BluetoothA2dpResultHandler
|
||||
{
|
||||
public:
|
||||
InitA2dpResultHandler(BluetoothProfileResultHandler* aRes)
|
||||
: mRes(aRes)
|
||||
{ }
|
||||
|
||||
void OnError(bt_status_t aStatus) MOZ_OVERRIDE
|
||||
{
|
||||
BT_WARNING("BluetoothA2dpInterface::Init failed: %d",
|
||||
(int)aStatus);
|
||||
if (mRes) {
|
||||
mRes->OnError(NS_ERROR_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void Init() MOZ_OVERRIDE
|
||||
{
|
||||
#if ANDROID_VERSION > 17
|
||||
/* Also init AVRCP if it's available, ... */
|
||||
BluetoothInterface* btInf = BluetoothInterface::GetInstance();
|
||||
if (!btInf) {
|
||||
if (mRes) {
|
||||
mRes->OnError(NS_ERROR_FAILURE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
sBtAvrcpInterface = btInf->GetBluetoothAvrcpInterface();
|
||||
if (!sBtAvrcpInterface) {
|
||||
if (mRes) {
|
||||
mRes->OnError(NS_ERROR_FAILURE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
sBtAvrcpInterface->Init(&sBtAvrcpCallbacks,
|
||||
new InitAvrcpResultHandler(mRes));
|
||||
#else
|
||||
/* ...or signal success otherwise. */
|
||||
if (mRes) {
|
||||
mRes->Init();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<BluetoothProfileResultHandler> mRes;
|
||||
};
|
||||
|
||||
/*
|
||||
* This function will be only called when Bluetooth is turning on.
|
||||
* It is important to register a2dp callbacks before enable() gets called.
|
||||
|
@ -520,30 +599,7 @@ BluetoothA2dpManager::InitA2dpInterface(BluetoothProfileResultHandler* aRes)
|
|||
return;
|
||||
}
|
||||
|
||||
int ret = sBtA2dpInterface->Init(&sBtA2dpCallbacks);
|
||||
if (ret != BT_STATUS_SUCCESS) {
|
||||
BT_LOGR("Warning: failed to init a2dp module");
|
||||
}
|
||||
|
||||
#if ANDROID_VERSION > 17
|
||||
sBtAvrcpInterface = btInf->GetBluetoothAvrcpInterface();
|
||||
if (!sBtAvrcpInterface) {
|
||||
BT_LOGR("Error: Bluetooth AVRCP interface not available");
|
||||
if (aRes) {
|
||||
aRes->OnError(NS_ERROR_FAILURE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ret = sBtAvrcpInterface->Init(&sBtAvrcpCallbacks);
|
||||
if (ret != BT_STATUS_SUCCESS) {
|
||||
BT_LOGR("Warning: failed to init avrcp module");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (aRes) {
|
||||
aRes->Init();
|
||||
}
|
||||
sBtA2dpInterface->Init(&sBtA2dpCallbacks, new InitA2dpResultHandler(aRes));
|
||||
}
|
||||
|
||||
BluetoothA2dpManager::~BluetoothA2dpManager()
|
||||
|
@ -617,6 +673,99 @@ BluetoothA2dpManager::Get()
|
|||
return sBluetoothA2dpManager;
|
||||
}
|
||||
|
||||
#if ANDROID_VERSION > 17
|
||||
class CleanupAvrcpResultHandler MOZ_FINAL : public BluetoothAvrcpResultHandler
|
||||
{
|
||||
public:
|
||||
CleanupAvrcpResultHandler(BluetoothProfileResultHandler* aRes)
|
||||
: mRes(aRes)
|
||||
{ }
|
||||
|
||||
void OnError(bt_status_t aStatus) MOZ_OVERRIDE
|
||||
{
|
||||
BT_WARNING("BluetoothAvrcpInterface::Cleanup failed: %d",
|
||||
(int)aStatus);
|
||||
if (mRes) {
|
||||
mRes->OnError(NS_ERROR_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void Cleanup() MOZ_OVERRIDE
|
||||
{
|
||||
sBtAvrcpInterface = nullptr;
|
||||
if (mRes) {
|
||||
mRes->Deinit();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<BluetoothProfileResultHandler> mRes;
|
||||
};
|
||||
#endif
|
||||
|
||||
class CleanupA2dpResultHandler MOZ_FINAL : public BluetoothA2dpResultHandler
|
||||
{
|
||||
public:
|
||||
CleanupA2dpResultHandler(BluetoothProfileResultHandler* aRes)
|
||||
: mRes(aRes)
|
||||
{ }
|
||||
|
||||
void OnError(bt_status_t aStatus) MOZ_OVERRIDE
|
||||
{
|
||||
BT_WARNING("BluetoothA2dpInterface::Cleanup failed: %d",
|
||||
(int)aStatus);
|
||||
if (mRes) {
|
||||
mRes->OnError(NS_ERROR_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void Cleanup() MOZ_OVERRIDE
|
||||
{
|
||||
sBtA2dpInterface = nullptr;
|
||||
#if ANDROID_VERSION > 17
|
||||
/* Cleanup AVRCP if it's available and initialized, ...*/
|
||||
if (sBtAvrcpInterface) {
|
||||
sBtAvrcpInterface->Cleanup(new CleanupAvrcpResultHandler(mRes));
|
||||
} else
|
||||
#endif
|
||||
if (mRes) {
|
||||
/* ...or simply signal success from here. */
|
||||
mRes->Deinit();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<BluetoothProfileResultHandler> mRes;
|
||||
};
|
||||
|
||||
class CleanupA2dpResultHandlerRunnable MOZ_FINAL : public nsRunnable
|
||||
{
|
||||
public:
|
||||
CleanupA2dpResultHandlerRunnable(BluetoothProfileResultHandler* aRes)
|
||||
: mRes(aRes)
|
||||
{ }
|
||||
|
||||
NS_IMETHOD Run() MOZ_OVERRIDE
|
||||
{
|
||||
sBtA2dpInterface = nullptr;
|
||||
#if ANDROID_VERSION > 17
|
||||
/* Cleanup AVRCP if it's available and initialized, ...*/
|
||||
if (sBtAvrcpInterface) {
|
||||
sBtAvrcpInterface->Cleanup(new CleanupAvrcpResultHandler(mRes));
|
||||
} else
|
||||
#endif
|
||||
if (mRes) {
|
||||
/* ...or simply signal success from here. */
|
||||
mRes->Deinit();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<BluetoothProfileResultHandler> mRes;
|
||||
};
|
||||
|
||||
// static
|
||||
void
|
||||
BluetoothA2dpManager::DeinitA2dpInterface(BluetoothProfileResultHandler* aRes)
|
||||
|
@ -624,17 +773,14 @@ BluetoothA2dpManager::DeinitA2dpInterface(BluetoothProfileResultHandler* aRes)
|
|||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (sBtA2dpInterface) {
|
||||
sBtA2dpInterface->Cleanup();
|
||||
sBtA2dpInterface = nullptr;
|
||||
sBtA2dpInterface->Cleanup(new CleanupA2dpResultHandler(aRes));
|
||||
} else if (aRes) {
|
||||
// We dispatch a runnable here to make the profile resource handler
|
||||
// behave as if A2DP was initialized.
|
||||
nsRefPtr<nsRunnable> r = new CleanupA2dpResultHandlerRunnable(aRes);
|
||||
if (NS_FAILED(NS_DispatchToMainThread(r))) {
|
||||
BT_LOGR("Failed to dispatch cleanup-result-handler runnable");
|
||||
}
|
||||
#if ANDROID_VERSION > 17
|
||||
if (sBtAvrcpInterface) {
|
||||
sBtAvrcpInterface->Cleanup();
|
||||
sBtAvrcpInterface = nullptr;
|
||||
}
|
||||
#endif
|
||||
if (aRes) {
|
||||
aRes->Deinit();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -888,16 +888,27 @@ BluetoothA2dpInterface::BluetoothA2dpInterface(
|
|||
BluetoothA2dpInterface::~BluetoothA2dpInterface()
|
||||
{ }
|
||||
|
||||
bt_status_t
|
||||
BluetoothA2dpInterface::Init(btav_callbacks_t* aCallbacks)
|
||||
void
|
||||
BluetoothA2dpInterface::Init(btav_callbacks_t* aCallbacks,
|
||||
BluetoothA2dpResultHandler* aRes)
|
||||
{
|
||||
return mInterface->init(aCallbacks);
|
||||
bt_status_t status = mInterface->init(aCallbacks);
|
||||
|
||||
if (aRes) {
|
||||
DispatchBluetoothA2dpResult(aRes, &BluetoothA2dpResultHandler::Init,
|
||||
status);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothA2dpInterface::Cleanup()
|
||||
BluetoothA2dpInterface::Cleanup(BluetoothA2dpResultHandler* aRes)
|
||||
{
|
||||
mInterface->cleanup();
|
||||
|
||||
if (aRes) {
|
||||
DispatchBluetoothA2dpResult(aRes, &BluetoothA2dpResultHandler::Cleanup,
|
||||
BT_STATUS_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
bt_status_t
|
||||
|
@ -969,16 +980,27 @@ BluetoothAvrcpInterface::BluetoothAvrcpInterface(
|
|||
BluetoothAvrcpInterface::~BluetoothAvrcpInterface()
|
||||
{ }
|
||||
|
||||
bt_status_t
|
||||
BluetoothAvrcpInterface::Init(btrc_callbacks_t* aCallbacks)
|
||||
void
|
||||
BluetoothAvrcpInterface::Init(btrc_callbacks_t* aCallbacks,
|
||||
BluetoothAvrcpResultHandler* aRes)
|
||||
{
|
||||
return mInterface->init(aCallbacks);
|
||||
bt_status_t status = mInterface->init(aCallbacks);
|
||||
|
||||
if (aRes) {
|
||||
DispatchBluetoothAvrcpResult(aRes, &BluetoothAvrcpResultHandler::Init,
|
||||
status);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothAvrcpInterface::Cleanup()
|
||||
BluetoothAvrcpInterface::Cleanup(BluetoothAvrcpResultHandler* aRes)
|
||||
{
|
||||
mInterface->cleanup();
|
||||
|
||||
if (aRes) {
|
||||
DispatchBluetoothAvrcpResult(aRes, &BluetoothAvrcpResultHandler::Cleanup,
|
||||
BT_STATUS_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
bt_status_t
|
||||
|
|
|
@ -204,8 +204,9 @@ class BluetoothA2dpInterface
|
|||
public:
|
||||
friend class BluetoothInterface;
|
||||
|
||||
bt_status_t Init(btav_callbacks_t *aCallbacks);
|
||||
void Cleanup();
|
||||
void Init(btav_callbacks_t *aCallbacks,
|
||||
BluetoothA2dpResultHandler* aRes);
|
||||
void Cleanup(BluetoothA2dpResultHandler* aRes);
|
||||
|
||||
bt_status_t Connect(bt_bdaddr_t *aBdAddr);
|
||||
bt_status_t Disconnect(bt_bdaddr_t *aBdAddr);
|
||||
|
@ -261,8 +262,9 @@ class BluetoothAvrcpInterface
|
|||
public:
|
||||
friend class BluetoothInterface;
|
||||
|
||||
bt_status_t Init(btrc_callbacks_t* aCallbacks);
|
||||
void Cleanup();
|
||||
void Init(btrc_callbacks_t* aCallbacks,
|
||||
BluetoothAvrcpResultHandler* aRes);
|
||||
void Cleanup(BluetoothAvrcpResultHandler* aRes);
|
||||
|
||||
bt_status_t GetPlayStatusRsp(btrc_play_status_t aPlayStatus,
|
||||
uint32_t aSongLen, uint32_t aSongPos);
|
||||
|
|
Загрузка…
Ссылка в новой задаче