Bug 1002391 - Get the latest SDP records of the target device, r=shuang
authorEric Chou <echou@mozilla.com>
Fri, 06 Jun 2014 18:14:22 +0800
changeset 206357 03e02a8a1677f90ad139a54aad79cf9485c8bd4a
parent 206356 b5f1ee4b5eefdcc84cf9badeef0cdb8026f55064
child 206358 1cd0fb0a175a6b5c792f7721de2b122d04d49a43
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersshuang
bugs1002391
milestone32.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1002391 - Get the latest SDP records of the target device, r=shuang Use BlueZ API 'CreateDevice' to update the SDP records of those unknown devices. On the other hand, still use 'DiscoverServices' to update SDP records of paired devices.
dom/bluetooth/bluez/BluetoothDBusService.cpp
--- a/dom/bluetooth/bluez/BluetoothDBusService.cpp
+++ b/dom/bluetooth/bluez/BluetoothDBusService.cpp
@@ -3431,36 +3431,41 @@ BluetoothDBusService::ToggleCalls(Blueto
 
   DispatchBluetoothReply(aRunnable, BluetoothValue(true), EmptyString());
 }
 #endif // MOZ_B2G_RIL
 
 class OnUpdateSdpRecordsRunnable : public nsRunnable
 {
 public:
-  OnUpdateSdpRecordsRunnable(const nsAString& aObjectPath,
+  OnUpdateSdpRecordsRunnable(const nsAString& aDeviceAddress,
                              BluetoothProfileManagerBase* aManager)
-    : mManager(aManager)
+    : mDeviceAddress(aDeviceAddress)
+    , mManager(aManager)
   {
-    MOZ_ASSERT(!aObjectPath.IsEmpty());
+    MOZ_ASSERT(!aDeviceAddress.IsEmpty());
     MOZ_ASSERT(aManager);
-
-    mDeviceAddress = GetAddressFromObjectPath(aObjectPath);
   }
 
   nsresult
   Run()
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     mManager->OnUpdateSdpRecords(mDeviceAddress);
 
     return NS_OK;
   }
 
+  void
+  GetDeviceAddress(nsAString& aRetDeviceAddress)
+  {
+    aRetDeviceAddress = mDeviceAddress;
+  }
+
 private:
   nsString mDeviceAddress;
   BluetoothProfileManagerBase* mManager;
 };
 
 class OnGetServiceChannelRunnable : public nsRunnable
 {
 public:
@@ -3636,57 +3641,99 @@ public:
   }
 
   void Run() MOZ_OVERRIDE
   {
     MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
     MOZ_ASSERT(sDBusConnection);
     MOZ_ASSERT(!sAdapterPath.IsEmpty());
 
-    const nsString objectPath =
-      GetObjectPathFromAddress(sAdapterPath, mDeviceAddress);
+    // We first guess that the device doesn't exist at all. So we use BlueZ
+    // API "CreateDevice" to create an object path for the BluetoothDevice
+    // object. "CreateDevice" will connect to the remote device and retrieve
+    // SDP records of the target.
+    NS_ConvertUTF16toUTF8 address(mDeviceAddress);
+    const char* cAddress = address.get();
 
     // I choose to use raw pointer here because this is going to be passed as an
     // argument into SendWithReply() at once.
     OnUpdateSdpRecordsRunnable* callbackRunnable =
-      new OnUpdateSdpRecordsRunnable(objectPath, mBluetoothProfileManager);
-
-    sDBusConnection->SendWithReply(DiscoverServicesCallback,
-                                   (void*)callbackRunnable, -1,
-                                   BLUEZ_DBUS_BASE_IFC,
-                                   NS_ConvertUTF16toUTF8(objectPath).get(),
-                                   DBUS_DEVICE_IFACE,
-                                   "DiscoverServices",
-                                   DBUS_TYPE_STRING, &EmptyCString(),
-                                   DBUS_TYPE_INVALID);
+      new OnUpdateSdpRecordsRunnable(mDeviceAddress, mBluetoothProfileManager);
+
+    sDBusConnection->SendWithReply(
+      CreateDeviceCallback, callbackRunnable, -1,
+      BLUEZ_DBUS_BASE_IFC,
+      NS_ConvertUTF16toUTF8(sAdapterPath).get(),
+      DBUS_ADAPTER_IFACE,
+      "CreateDevice",
+      DBUS_TYPE_STRING, &cAddress,
+      DBUS_TYPE_INVALID);
   }
 
 protected:
+  static void CreateDeviceCallback(DBusMessage* aMsg, void* aData)
+  {
+    MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
+
+    nsAutoString errorString;
+    OnUpdateSdpRecordsRunnable* r =
+      static_cast<OnUpdateSdpRecordsRunnable*>(aData);
+
+    if (IsDBusMessageError(aMsg, nullptr, errorString)) {
+      // If the device already exists it comes here. If we want to refresh its
+      // SDP records then we have to do "DiscoverServices"
+      BT_LOGR("%s", NS_ConvertUTF16toUTF8(errorString).get());
+
+      nsString deviceAddress;
+      r->GetDeviceAddress(deviceAddress);
+
+      const nsString objectPath =
+        GetObjectPathFromAddress(sAdapterPath, deviceAddress);
+
+      sDBusConnection->SendWithReply(DiscoverServicesCallback,
+                                     aData, -1,
+                                     BLUEZ_DBUS_BASE_IFC,
+                                     NS_ConvertUTF16toUTF8(objectPath).get(),
+                                     DBUS_DEVICE_IFACE,
+                                     "DiscoverServices",
+                                     DBUS_TYPE_STRING, &EmptyCString(),
+                                     DBUS_TYPE_INVALID);
+      return;
+    }
+
+    NS_DispatchToMainThread(r);
+  }
+
   static void DiscoverServicesCallback(DBusMessage* aMsg, void* aData)
   {
     MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
 
-    nsRefPtr<OnUpdateSdpRecordsRunnable> r(
-      static_cast<OnUpdateSdpRecordsRunnable*>(aData));
+    nsAutoString errorStr;
+
+    if (IsDBusMessageError(aMsg, nullptr, errorStr)) {
+      BT_LOGR("%s", NS_ConvertUTF16toUTF8(errorStr).get());
+    }
+
+    OnUpdateSdpRecordsRunnable* r =
+      static_cast<OnUpdateSdpRecordsRunnable*>(aData);
     NS_DispatchToMainThread(r);
   }
 
 private:
   const nsString mDeviceAddress;
   BluetoothProfileManagerBase* mBluetoothProfileManager;
 };
 
 bool
 BluetoothDBusService::UpdateSdpRecords(const nsAString& aDeviceAddress,
                                        BluetoothProfileManagerBase* aManager)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  Task* task = new UpdateSdpRecordsTask(aDeviceAddress, aManager);
-  DispatchToDBusThread(task);
+  DispatchToDBusThread(new UpdateSdpRecordsTask(aDeviceAddress, aManager));
 
   return true;
 }
 
 void
 BluetoothDBusService::SendFile(const nsAString& aDeviceAddress,
                                BlobParent* aBlobParent,
                                BlobChild* aBlobChild,