diff --git a/dom/bluetooth/bluez/linux/BluetoothDBusService.cpp b/dom/bluetooth/bluez/linux/BluetoothDBusService.cpp index 37cefe3a6a0d..8a72c5369b6e 100644 --- a/dom/bluetooth/bluez/linux/BluetoothDBusService.cpp +++ b/dom/bluetooth/bluez/linux/BluetoothDBusService.cpp @@ -46,6 +46,7 @@ #include "mozilla/NullPtr.h" #include "mozilla/StaticMutex.h" #include "mozilla/Util.h" + #if defined(MOZ_WIDGET_GONK) #include "cutils/properties.h" #endif @@ -171,13 +172,32 @@ static const char* sBluetoothDBusSignals[] = * used by any other thread. */ static nsRefPtr gThreadConnection; -static nsDataHashtable* sPairingReqTable; + +// Only A2DP and HID are authorized. static nsTArray sAuthorizedServiceClass; + +// The object path of adpater which should be updated after switching Bluetooth. static nsString sAdapterPath; + +/** + * The adapter name may not be ready whenever event 'AdapterAdded' is received, + * so we'd like to wait for a bit. + */ static bool sAdapterNameIsReady = false; +static int sWaitingForAdapterNameInterval = 1000; //unit: ms + +// Keep the pairing requests. static Atomic sIsPairing(0); +static nsDataHashtable* sPairingReqTable; + +/** + * Disconnect all profiles before turning off Bluetooth. Please see Bug 891257 + * for more details. + */ static int sConnectedDeviceCount = 0; static StaticAutoPtr sStopBluetoothMonitor; + +// A quene for connect/disconnect request. See Bug 913372 for details. static nsTArray > sControllerArray; typedef void (*UnpackFunc)(DBusMessage*, DBusError*, BluetoothValue&, nsAString&); @@ -335,22 +355,46 @@ private: BluetoothSignal mSignal; }; -class TryFiringAdapterAddedTask : public nsRunnable +class TryFiringAdapterAddedTask : public Task { public: - NS_IMETHOD - Run() + void Run() MOZ_OVERRIDE { MOZ_ASSERT(NS_IsMainThread()); BluetoothService* bs = BluetoothService::Get(); - NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE); + NS_ENSURE_TRUE_VOID(bs); bs->AdapterAddedReceived(); bs->TryFiringAdapterAdded(); + } +}; + +class TryFiringAdapterAddedRunnable : public nsRunnable +{ +public: + TryFiringAdapterAddedRunnable(bool aDelay) + : mDelay(aDelay) + { } + + nsresult Run() + { + MOZ_ASSERT(NS_IsMainThread()); + + if (mDelay) { + MessageLoop::current()-> + PostDelayedTask(FROM_HERE, new TryFiringAdapterAddedTask(), + sWaitingForAdapterNameInterval); + } else { + MessageLoop::current()-> + PostTask(FROM_HERE, new TryFiringAdapterAddedTask()); + } return NS_OK; } + +private: + bool mDelay; }; static bool @@ -727,7 +771,7 @@ GetProperty(DBusMessageIter aIter, Properties* aPropertyTypes, // Notify BluetoothManager whenever adapter name is ready. if (!propertyValue.get_nsString().IsEmpty()) { sAdapterNameIsReady = true; - NS_DispatchToMainThread(new TryFiringAdapterAddedTask()); + NS_DispatchToMainThread(new TryFiringAdapterAddedRunnable(false)); } } @@ -1305,6 +1349,8 @@ public: NS_IMETHOD Run() { + MOZ_ASSERT(NS_IsMainThread()); + static const dbus_uint32_t sServices[] = { BluetoothServiceClass::HANDSFREE_AG, BluetoothServiceClass::HEADSET_AG, @@ -1576,6 +1622,7 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData) errorStr.AssignLiteral("Cannot parse manager path!"); } else { v = NS_ConvertUTF8toUTF16(str); + NS_DispatchToMainThread(new TryFiringAdapterAddedRunnable(true)); NS_DispatchToMainThread(new PrepareAdapterRunnable(v.get_nsString())); /**