Bug 1141616: Support SDP lookups in |BluetoothServiceBluedroid|, r=btian
authorThomas Zimmermann <tdz@users.sourceforge.net>
Wed, 09 Sep 2015 13:20:54 +0200
changeset 294100 a08d93552eba364d3ea3e4ccc5bad56673ec044b
parent 294099 21b1705ef65c7b7d7c53fc452cb3442d3edc98e2
child 294101 ee015390f701973fdaa46f06f010c2a6ca2198d3
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbtian
bugs1141616
milestone43.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 1141616: Support SDP lookups in |BluetoothServiceBluedroid|, r=btian This patch adds support for SDP lookups to Bluedroid's service manager |BluetoothServiceBluedroid|. The class now implements looking up a remote device's services.
dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp
dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h
--- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp
@@ -941,21 +941,107 @@ BluetoothServiceBluedroid::GetServiceCha
   } else {
     sBtInterface->GetRemoteServiceRecord(
       aDeviceAddress, uuid.mUuid, res);
   }
 
   return NS_OK;
 }
 
+struct BluetoothServiceBluedroid::GetRemoteServicesRequest final
+{
+  GetRemoteServicesRequest(const nsAString& aDeviceAddress,
+                           BluetoothProfileManagerBase* aManager)
+    : mDeviceAddress(aDeviceAddress)
+    , mManager(aManager)
+  {
+    MOZ_ASSERT(!mDeviceAddress.IsEmpty());
+    MOZ_ASSERT(mManager);
+  }
+
+  const nsString mDeviceAddress;
+  BluetoothProfileManagerBase* mManager;
+};
+
+class BluetoothServiceBluedroid::GetRemoteServicesResultHandler final
+  : public BluetoothResultHandler
+{
+public:
+  GetRemoteServicesResultHandler(
+    nsTArray<GetRemoteServicesRequest>& aGetRemoteServicesArray,
+    const nsAString& aDeviceAddress,
+    BluetoothProfileManagerBase* aManager)
+    : mGetRemoteServicesArray(aGetRemoteServicesArray)
+    , mDeviceAddress(aDeviceAddress)
+    , mManager(aManager)
+  { }
+
+  void OnError(BluetoothStatus aStatus) override
+  {
+    // Find call in array
+
+    ssize_t i = FindRequest();
+
+    if (i == -1) {
+      BT_WARNING("No GetRemoteServices request found");
+      return;
+    }
+
+    // Cleanup array
+    mGetRemoteServicesArray.RemoveElementAt(i);
+
+    // There's no error-signaling mechanism; just call manager
+    mManager->OnUpdateSdpRecords(mDeviceAddress);
+  }
+
+  void CancelDiscovery() override
+  {
+    // Disabled discovery mode, now perform SDP operation.
+    sBtInterface->GetRemoteServices(mDeviceAddress, this);
+  }
+
+private:
+  ssize_t FindRequest() const
+  {
+    for (size_t i = 0; i < mGetRemoteServicesArray.Length(); ++i) {
+      if ((mGetRemoteServicesArray[i].mDeviceAddress == mDeviceAddress) &&
+          (mGetRemoteServicesArray[i].mManager == mManager)) {
+        return i;
+      }
+    }
+
+    return -1;
+  }
+
+  nsTArray<GetRemoteServicesRequest>& mGetRemoteServicesArray;
+  const nsString mDeviceAddress;
+  BluetoothProfileManagerBase* mManager;
+};
+
 bool
 BluetoothServiceBluedroid::UpdateSdpRecords(
   const nsAString& aDeviceAddress,
   BluetoothProfileManagerBase* aManager)
 {
+  mGetRemoteServicesArray.AppendElement(
+    GetRemoteServicesRequest(aDeviceAddress, aManager));
+
+  nsRefPtr<BluetoothResultHandler> res =
+    new GetRemoteServicesResultHandler(mGetRemoteServicesArray,
+                                       aDeviceAddress, aManager);
+
+  /* Stop discovery of remote devices here, because SDP operations
+   * won't be performed while the adapter is in discovery mode.
+   */
+  if (mDiscovering) {
+    sBtInterface->CancelDiscovery(res);
+  } else {
+    sBtInterface->GetRemoteServices(aDeviceAddress, res);
+  }
+
   return true;
 }
 
 nsresult
 BluetoothServiceBluedroid::CreatePairedDeviceInternal(
   const nsAString& aDeviceAddress, int aTimeout,
   BluetoothReplyRunnable* aRunnable)
 {
@@ -1731,20 +1817,39 @@ BluetoothServiceBluedroid::RemoteDeviceP
       // Update <address, name> mapping
       mDeviceNameMap.Remove(bdAddr);
       mDeviceNameMap.Put(bdAddr, p.mString);
     } else if (p.mType == PROPERTY_CLASS_OF_DEVICE) {
       uint32_t cod = p.mUint32;
       AppendNamedValue(propertiesArray, "Cod", cod);
 
     } else if (p.mType == PROPERTY_UUIDS) {
+
+      size_t index;
+
+      // Handler for |UpdateSdpRecords|
+
+      for (index = 0; index < mGetRemoteServicesArray.Length(); ++index) {
+        if (mGetRemoteServicesArray[index].mDeviceAddress == aBdAddr) {
+          break;
+        }
+      }
+
+      if (index < mGetRemoteServicesArray.Length()) {
+        mGetRemoteServicesArray[index].mManager->OnUpdateSdpRecords(aBdAddr);
+        mGetRemoteServicesArray.RemoveElementAt(index);
+        continue; // continue with outer loop
+      }
+
+      // Handler for |FetchUuidsInternal|
+
       nsTArray<nsString> uuids;
 
       // Construct a sorted uuid set
-      for (uint32_t index = 0; index < p.mUuidArray.Length(); ++index) {
+      for (index = 0; index < p.mUuidArray.Length(); ++index) {
         nsAutoString uuid;
         UuidToString(p.mUuidArray[index], uuid);
 
         if (!uuids.Contains(uuid)) { // filter out duplicate uuids
           uuids.InsertElementSorted(uuid);
         }
       }
       AppendNamedValue(propertiesArray, "UUIDs", uuids);
--- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h
+++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h
@@ -18,25 +18,27 @@ class BluetoothServiceBluedroid : public
                                 , public BluetoothNotificationHandler
 {
   class CleanupResultHandler;
   class DisableResultHandler;
   class DispatchReplyErrorResultHandler;
   class EnableResultHandler;
   class GetRemoteDevicePropertiesResultHandler;
   class GetRemoteServiceRecordResultHandler;
+  class GetRemoteServicesResultHandler;
   class InitResultHandler;
   class PinReplyResultHandler;
   class ProfileDeinitResultHandler;
   class ProfileInitResultHandler;
   class SetAdapterPropertyDiscoverableResultHandler;
   class SspReplyResultHandler;
 
   class GetDeviceRequest;
   struct GetRemoteServiceRecordRequest;
+  struct GetRemoteServicesRequest;
 
 public:
   BluetoothServiceBluedroid();
   ~BluetoothServiceBluedroid();
 
   virtual nsresult StartInternal(BluetoothReplyRunnable* aRunnable);
   virtual nsresult StopInternal(BluetoothReplyRunnable* aRunnable);
 
@@ -394,13 +396,14 @@ protected:
   // 3) runnable to reply success/error
   nsTArray<GetDeviceRequest> mGetDeviceRequests;
 
   // <address, name> mapping table for remote devices
   nsDataHashtable<nsStringHashKey, nsString> mDeviceNameMap;
 
   // Arrays for SDP operations
   nsTArray<GetRemoteServiceRecordRequest> mGetRemoteServiceRecordArray;
+  nsTArray<GetRemoteServicesRequest> mGetRemoteServicesArray;
 };
 
 END_BLUETOOTH_NAMESPACE
 
 #endif // mozilla_dom_bluetooth_bluedroid_BluetoothServiceBluedroid_h