Bug 972253: Merge the content of DBusThread.cpp into Bluetooth code, r=echou
DBusThread.{cpp,h} maintains state for Bluetooth. This patch moves
the content of these files to Bluetooth's Bluez backend.
--- a/dom/bluetooth/bluez/linux/BluetoothDBusService.cpp
+++ b/dom/bluetooth/bluez/linux/BluetoothDBusService.cpp
@@ -35,17 +35,16 @@
#include "nsThreadUtils.h"
#include "nsDebug.h"
#include "nsDataHashtable.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/Atomics.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/Hal.h"
#include "mozilla/ipc/UnixSocket.h"
-#include "mozilla/ipc/DBusThread.h"
#include "mozilla/ipc/DBusUtils.h"
#include "mozilla/ipc/RawDBusConnection.h"
#include "mozilla/Mutex.h"
#include "mozilla/NullPtr.h"
#include "mozilla/StaticMutex.h"
#if defined(MOZ_WIDGET_GONK)
#include "cutils/properties.h"
@@ -270,16 +269,19 @@ static const char* sBluetoothDBusSignals
"type='signal',interface='org.bluez.Input'",
"type='signal',interface='org.bluez.Network'",
"type='signal',interface='org.bluez.NetworkServer'",
"type='signal',interface='org.bluez.HealthDevice'",
"type='signal',interface='org.bluez.AudioSink'",
"type='signal',interface='org.bluez.Control'"
};
+// The DBus connection to the BlueZ daemon
+static RawDBusConnection* sDBusConnection;
+
// Only A2DP and HID are authorized.
static nsTArray<BluetoothServiceClass> 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,
@@ -300,16 +302,29 @@ static StaticAutoPtr<Monitor> sGetProper
static StaticAutoPtr<Monitor> sStopBluetoothMonitor;
// A quene for connect/disconnect request. See Bug 913372 for details.
static nsTArray<nsRefPtr<BluetoothProfileController> > sControllerArray;
typedef void (*UnpackFunc)(DBusMessage*, DBusError*, BluetoothValue&, nsAString&);
typedef bool (*FilterFunc)(const BluetoothValue&);
+static void
+DispatchToDBusThread(Task* task)
+{
+ XRE_GetIOMessageLoop()->PostTask(FROM_HERE, task);
+}
+
+static RawDBusConnection*
+GetDBusConnection()
+{
+ NS_ENSURE_TRUE(sDBusConnection, nullptr);
+ return sDBusConnection;
+}
+
BluetoothDBusService::BluetoothDBusService()
{
sGetPropertyMonitor = new Monitor("BluetoothService.sGetPropertyMonitor");
sStopBluetoothMonitor = new Monitor("BluetoothService.sStopBluetoothMonitor");
}
BluetoothDBusService::~BluetoothDBusService()
{
@@ -1835,36 +1850,60 @@ BluetoothDBusService::IsReady()
{
if (!IsEnabled() || !GetDBusConnection() || IsToggling()) {
BT_WARNING("Bluetooth service is not ready yet!");
return false;
}
return true;
}
+class WatchDBusConnectionTask : public Task
+{
+public:
+ WatchDBusConnectionTask(RawDBusConnection* aConnection)
+ : mConnection(aConnection)
+ {
+ MOZ_ASSERT(mConnection);
+ }
+
+ void Run()
+ {
+ mConnection->Watch();
+ }
+
+private:
+ RawDBusConnection* mConnection;
+};
+
nsresult
BluetoothDBusService::StartInternal()
{
// This could block. It should never be run on the main thread.
MOZ_ASSERT(!NS_IsMainThread());
#ifdef MOZ_WIDGET_GONK
if (!sBluedroid.Enable()) {
BT_WARNING("Bluetooth not available.");
return NS_ERROR_FAILURE;
}
#endif
- if (!StartDBus()) {
- BT_WARNING("Cannot start DBus thread!");
+ NS_ENSURE_TRUE(!sDBusConnection, NS_OK);
+
+ RawDBusConnection* connection = new RawDBusConnection();
+ nsresult rv = connection->EstablishDBusConnection();
+ if (NS_FAILED(rv)) {
+ BT_WARNING("Failed to establish connection to BlueZ daemon");
return NS_ERROR_FAILURE;
}
- RawDBusConnection* connection = GetDBusConnection();
- MOZ_ASSERT(connection);
+ XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
+ new WatchDBusConnectionTask(connection));
+
+ sDBusConnection = connection;
DBusError err;
dbus_error_init(&err);
// Set which messages will be processed by this dbus connection.
// Since we are maintaining a single thread for all the DBus bluez
// signals we want, register all of them in this thread at startup.
// The event handler will sort the destinations out as needed.
@@ -1912,16 +1951,38 @@ BluetoothDBusService::StartInternal()
PLDHashOperator
UnrefDBusMessages(const nsAString& key, DBusMessage* value, void* arg)
{
dbus_message_unref(value);
return PL_DHASH_NEXT;
}
+class DeleteDBusConnectionTask : public Task
+{
+public:
+ DeleteDBusConnectionTask(RawDBusConnection* aConnection)
+ : mConnection(aConnection)
+ {
+ MOZ_ASSERT(mConnection);
+ }
+
+ void Run()
+ {
+ MOZ_ASSERT(!NS_IsMainThread());
+
+ // This command closes the DBus connection and all instances of
+ // DBusWatch will be removed and free'd.
+ delete mConnection;
+ }
+
+private:
+ RawDBusConnection* mConnection;
+};
+
nsresult
BluetoothDBusService::StopInternal()
{
// This could block. It should never be run on the main thread.
MOZ_ASSERT(!NS_IsMainThread());
{
MonitorAutoLock lock(*sStopBluetoothMonitor);
@@ -1967,17 +2028,20 @@ BluetoothDBusService::StopInternal()
sPairingReqTable->Clear();
sIsPairing = 0;
sConnectedDeviceCount = 0;
sAuthorizedServiceClass.Clear();
sControllerArray.Clear();
- StopDBus();
+ sDBusConnection = nullptr;
+
+ XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
+ new DeleteDBusConnectionTask(connection));
#ifdef MOZ_WIDGET_GONK
MOZ_ASSERT(sBluedroid.IsEnabled());
if (!sBluedroid.Disable()) {
return NS_ERROR_FAILURE;
}
#endif