mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1038645: Asynchronous starting and stopping of profile managers (under bluetooth2/), r=btian
Profile managers use the new class |BluetoothProfileResultHandler| to signal the result of initializing of cleaning up operations to |BluetoothServiceBluedroid|. |BluetoothServiceBluedroid| proceeds once all profile handlers have finished. Future patches will build upon this patch to create completely asynchronous profile managers.
This commit is contained in:
parent
506b43c91f
commit
9b1bbedfbc
@ -28,6 +28,18 @@
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
class BluetoothProfileController;
|
||||
|
||||
class BluetoothProfileResultHandler
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BluetoothProfileResultHandler);
|
||||
|
||||
virtual ~BluetoothProfileResultHandler() { }
|
||||
|
||||
virtual void OnError(nsresult aResult) { }
|
||||
virtual void Init() { }
|
||||
virtual void Deinit() { }
|
||||
};
|
||||
|
||||
class BluetoothProfileManagerBase : public nsIObserver
|
||||
{
|
||||
public:
|
||||
|
@ -500,13 +500,25 @@ static btrc_callbacks_t sBtAvrcpCallbacks = {
|
||||
*/
|
||||
// static
|
||||
void
|
||||
BluetoothA2dpManager::InitA2dpInterface()
|
||||
BluetoothA2dpManager::InitA2dpInterface(BluetoothProfileResultHandler* aRes)
|
||||
{
|
||||
BluetoothInterface* btInf = BluetoothInterface::GetInstance();
|
||||
NS_ENSURE_TRUE_VOID(btInf);
|
||||
if (!btInf) {
|
||||
BT_LOGR("Error: Bluetooth interface not available");
|
||||
if (aRes) {
|
||||
aRes->OnError(NS_ERROR_FAILURE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
sBtA2dpInterface = btInf->GetBluetoothA2dpInterface();
|
||||
NS_ENSURE_TRUE_VOID(sBtA2dpInterface);
|
||||
if (!sBtA2dpInterface) {
|
||||
BT_LOGR("Error: Bluetooth A2DP interface not available");
|
||||
if (aRes) {
|
||||
aRes->OnError(NS_ERROR_FAILURE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int ret = sBtA2dpInterface->Init(&sBtA2dpCallbacks);
|
||||
if (ret != BT_STATUS_SUCCESS) {
|
||||
@ -515,13 +527,23 @@ BluetoothA2dpManager::InitA2dpInterface()
|
||||
|
||||
#if ANDROID_VERSION > 17
|
||||
sBtAvrcpInterface = btInf->GetBluetoothAvrcpInterface();
|
||||
NS_ENSURE_TRUE_VOID(sBtAvrcpInterface);
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
BluetoothA2dpManager::~BluetoothA2dpManager()
|
||||
@ -597,7 +619,7 @@ BluetoothA2dpManager::Get()
|
||||
|
||||
// static
|
||||
void
|
||||
BluetoothA2dpManager::DeinitA2dpInterface()
|
||||
BluetoothA2dpManager::DeinitA2dpInterface(BluetoothProfileResultHandler* aRes)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
@ -611,6 +633,9 @@ BluetoothA2dpManager::DeinitA2dpInterface()
|
||||
sBtAvrcpInterface = nullptr;
|
||||
}
|
||||
#endif
|
||||
if (aRes) {
|
||||
aRes->Deinit();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -30,8 +30,8 @@ public:
|
||||
};
|
||||
|
||||
static BluetoothA2dpManager* Get();
|
||||
static void InitA2dpInterface();
|
||||
static void DeinitA2dpInterface();
|
||||
static void InitA2dpInterface(BluetoothProfileResultHandler* aRes);
|
||||
static void DeinitA2dpInterface(BluetoothProfileResultHandler* aRes);
|
||||
virtual ~BluetoothA2dpManager();
|
||||
|
||||
// A2DP-specific functions
|
||||
|
@ -152,12 +152,54 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/* |ProfileDeinitResultHandler| collects the results of all profile
|
||||
* result handlers and calls |Proceed| after all results handlers
|
||||
* have been run.
|
||||
*/
|
||||
class ProfileDeinitResultHandler MOZ_FINAL
|
||||
: public BluetoothProfileResultHandler
|
||||
{
|
||||
public:
|
||||
ProfileDeinitResultHandler(unsigned char aNumProfiles)
|
||||
: mNumProfiles(aNumProfiles)
|
||||
{
|
||||
MOZ_ASSERT(mNumProfiles);
|
||||
}
|
||||
|
||||
void Deinit() MOZ_OVERRIDE
|
||||
{
|
||||
if (!(--mNumProfiles)) {
|
||||
Proceed();
|
||||
}
|
||||
}
|
||||
|
||||
void OnError(nsresult aResult) MOZ_OVERRIDE
|
||||
{
|
||||
if (!(--mNumProfiles)) {
|
||||
Proceed();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void Proceed() const
|
||||
{
|
||||
sBtInterface->Cleanup(nullptr);
|
||||
}
|
||||
|
||||
unsigned char mNumProfiles;
|
||||
};
|
||||
|
||||
class CleanupTask MOZ_FINAL : public nsRunnable
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD
|
||||
Run()
|
||||
{
|
||||
static void (* const sDeinitManager[])(BluetoothProfileResultHandler*) = {
|
||||
BluetoothHfpManager::DeinitHfpInterface,
|
||||
BluetoothA2dpManager::DeinitA2dpInterface
|
||||
};
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// Return error if BluetoothService is unavailable
|
||||
@ -185,9 +227,12 @@ public:
|
||||
bs->DistributeSignal(signal);
|
||||
|
||||
// Cleanup bluetooth interfaces after BT state becomes BT_STATE_OFF.
|
||||
BluetoothHfpManager::DeinitHfpInterface();
|
||||
BluetoothA2dpManager::DeinitA2dpInterface();
|
||||
sBtInterface->Cleanup(nullptr);
|
||||
nsRefPtr<ProfileDeinitResultHandler> res =
|
||||
new ProfileDeinitResultHandler(MOZ_ARRAY_LENGTH(sDeinitManager));
|
||||
|
||||
for (size_t i = 0; i < MOZ_ARRAY_LENGTH(sDeinitManager); ++i) {
|
||||
sDeinitManager[i](res);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -765,19 +810,64 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/* |ProfileInitResultHandler| collects the results of all profile
|
||||
* result handlers and calls |Proceed| after all results handlers
|
||||
* have been run.
|
||||
*/
|
||||
class ProfileInitResultHandler MOZ_FINAL
|
||||
: public BluetoothProfileResultHandler
|
||||
{
|
||||
public:
|
||||
ProfileInitResultHandler(unsigned char aNumProfiles)
|
||||
: mNumProfiles(aNumProfiles)
|
||||
{
|
||||
MOZ_ASSERT(mNumProfiles);
|
||||
}
|
||||
|
||||
void Init() MOZ_OVERRIDE
|
||||
{
|
||||
if (!(--mNumProfiles)) {
|
||||
Proceed();
|
||||
}
|
||||
}
|
||||
|
||||
void OnError(nsresult aResult) MOZ_OVERRIDE
|
||||
{
|
||||
if (!(--mNumProfiles)) {
|
||||
Proceed();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void Proceed() const
|
||||
{
|
||||
sBtInterface->Enable(new EnableResultHandler());
|
||||
}
|
||||
|
||||
unsigned char mNumProfiles;
|
||||
};
|
||||
|
||||
class InitResultHandler MOZ_FINAL : public BluetoothResultHandler
|
||||
{
|
||||
public:
|
||||
void Init() MOZ_OVERRIDE
|
||||
{
|
||||
static void (* const sInitManager[])(BluetoothProfileResultHandler*) = {
|
||||
BluetoothHfpManager::InitHfpInterface,
|
||||
BluetoothA2dpManager::InitA2dpInterface
|
||||
};
|
||||
|
||||
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());
|
||||
nsRefPtr<ProfileInitResultHandler> res =
|
||||
new ProfileInitResultHandler(MOZ_ARRAY_LENGTH(sInitManager));
|
||||
|
||||
for (size_t i = 0; i < MOZ_ARRAY_LENGTH(sInitManager); ++i) {
|
||||
sInitManager[i](res);
|
||||
}
|
||||
}
|
||||
|
||||
void OnError(int aStatus) MOZ_OVERRIDE
|
||||
|
@ -430,10 +430,16 @@ BluetoothHfpManager::Init()
|
||||
|
||||
// static
|
||||
void
|
||||
BluetoothHfpManager::InitHfpInterface()
|
||||
BluetoothHfpManager::InitHfpInterface(BluetoothProfileResultHandler* aRes)
|
||||
{
|
||||
BluetoothInterface* btInf = BluetoothInterface::GetInstance();
|
||||
NS_ENSURE_TRUE_VOID(btInf);
|
||||
if (!btInf) {
|
||||
BT_LOGR("Error: Bluetooth interface not available");
|
||||
if (aRes) {
|
||||
aRes->OnError(NS_ERROR_FAILURE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (sBluetoothHfpInterface) {
|
||||
sBluetoothHfpInterface->Cleanup();
|
||||
@ -442,11 +448,26 @@ BluetoothHfpManager::InitHfpInterface()
|
||||
|
||||
BluetoothHandsfreeInterface *interface =
|
||||
btInf->GetBluetoothHandsfreeInterface();
|
||||
NS_ENSURE_TRUE_VOID(interface);
|
||||
if (!interface) {
|
||||
BT_LOGR("Error: Bluetooth Handsfree interface not available");
|
||||
if (aRes) {
|
||||
aRes->OnError(NS_ERROR_FAILURE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (interface->Init(&sBluetoothHfpCallbacks) != BT_STATUS_SUCCESS) {
|
||||
if (aRes) {
|
||||
aRes->OnError(NS_ERROR_FAILURE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE_VOID(BT_STATUS_SUCCESS ==
|
||||
interface->Init(&sBluetoothHfpCallbacks));
|
||||
sBluetoothHfpInterface = interface;
|
||||
|
||||
if (aRes) {
|
||||
aRes->Init();
|
||||
}
|
||||
}
|
||||
|
||||
BluetoothHfpManager::~BluetoothHfpManager()
|
||||
@ -469,12 +490,15 @@ BluetoothHfpManager::~BluetoothHfpManager()
|
||||
|
||||
// static
|
||||
void
|
||||
BluetoothHfpManager::DeinitHfpInterface()
|
||||
BluetoothHfpManager::DeinitHfpInterface(BluetoothProfileResultHandler* aRes)
|
||||
{
|
||||
if (sBluetoothHfpInterface) {
|
||||
sBluetoothHfpInterface->Cleanup();
|
||||
sBluetoothHfpInterface = nullptr;
|
||||
}
|
||||
if (aRes) {
|
||||
aRes->Deinit();
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
|
@ -82,8 +82,8 @@ public:
|
||||
|
||||
static BluetoothHfpManager* Get();
|
||||
virtual ~BluetoothHfpManager();
|
||||
static void InitHfpInterface();
|
||||
static void DeinitHfpInterface();
|
||||
static void InitHfpInterface(BluetoothProfileResultHandler* aRes);
|
||||
static void DeinitHfpInterface(BluetoothProfileResultHandler* aRes);
|
||||
|
||||
bool ConnectSco();
|
||||
bool DisconnectSco();
|
||||
|
Loading…
Reference in New Issue
Block a user