Bug 1141616: Lookup service channel in Bluedroid's OPP manager, r=btian
authorThomas Zimmermann <tdz@users.sourceforge.net>
Wed, 09 Sep 2015 13:20:57 +0200
changeset 261572 ee015390f701973fdaa46f06f010c2a6ca2198d3
parent 261571 a08d93552eba364d3ea3e4ccc5bad56673ec044b
child 261573 64bab3289232d1e464cd058829fcdaa87f97349b
push id64771
push userkwierso@gmail.com
push dateWed, 09 Sep 2015 20:49:01 +0000
treeherdermozilla-inbound@dd2a1d737a64 [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: Lookup service channel in Bluedroid's OPP manager, r=btian Bluedroid's |BluetoothOppManager| now retrieves the OBEX service's channel from the remote device. Previously this was done by the Bluedroid driver internally, but having this functionality in the manager itself will allow for future code sharing with the BlueZ backend.
dom/bluetooth/bluedroid/BluetoothOppManager.cpp
dom/bluetooth/bluedroid/BluetoothOppManager.h
--- a/dom/bluetooth/bluedroid/BluetoothOppManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothOppManager.cpp
@@ -50,16 +50,20 @@ namespace {
 
   /*
    * The format of the appended header of an PUT request is
    * [headerId:1][header length:4]
    * P.S. Length of name header is 4 since unicode is 2 bytes per char.
    */
   static const uint32_t kPutRequestAppendHeaderSize = 5;
 
+  // The default timeout we permit to wait for SDP updating if we can't get
+  // service channel.
+  static const double kSdpUpdatingTimeoutMs = 3000.0;
+
   // UUID of OBEX Object Push
   static const BluetoothUuid kObexObjectPush = {
     {
       0x00, 0x00, 0x11, 0x05, 0x00, 0x00, 0x10, 0x00,
       0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
     }
   };
 
@@ -193,16 +197,17 @@ private:
 BluetoothOppManager::BluetoothOppManager() : mConnected(false)
                                            , mRemoteObexVersion(0)
                                            , mRemoteConnectionFlags(0)
                                            , mRemoteMaxPacketLength(0)
                                            , mLastCommand(0)
                                            , mPacketLength(0)
                                            , mPutPacketReceivedLength(0)
                                            , mBodySegmentLength(0)
+                                           , mNeedsUpdatingSdpRecords(false)
                                            , mAbortFlag(false)
                                            , mNewFileFlag(false)
                                            , mPutFinalFlag(false)
                                            , mSendTransferCompleteFlag(false)
                                            , mSuccessFlag(false)
                                            , mIsServer(true)
                                            , mWaitingForConfirmationFlag(false)
                                            , mFileLength(0)
@@ -289,20 +294,27 @@ BluetoothOppManager::ConnectInternal(con
   mIsServer = false;
 
   BluetoothService* bs = BluetoothService::Get();
   if (!bs || sInShutdown || mSocket) {
     OnSocketConnectError(mSocket);
     return;
   }
 
+  mNeedsUpdatingSdpRecords = true;
+
+  nsString uuid;
+  BluetoothUuidHelper::GetString(BluetoothServiceClass::OBJECT_PUSH, uuid);
+
+  if (NS_FAILED(bs->GetServiceChannel(aDeviceAddress, uuid, this))) {
+    OnSocketConnectError(mSocket);
+    return;
+  }
+
   mSocket = new BluetoothSocket(this);
-  mSocket->Connect(aDeviceAddress, kObexObjectPush,
-                   BluetoothSocketType::RFCOMM, -1,
-                   false, true);
 }
 
 void
 BluetoothOppManager::HandleShutdown()
 {
   MOZ_ASSERT(NS_IsMainThread());
   sInShutdown = true;
   Disconnect(nullptr);
@@ -1604,23 +1616,66 @@ BluetoothOppManager::AcquireSdcardMountL
   return true;
 }
 
 void
 BluetoothOppManager::OnGetServiceChannel(const nsAString& aDeviceAddress,
                                          const nsAString& aServiceUuid,
                                          int aChannel)
 {
-  MOZ_ASSERT(false);
+  BluetoothUuid serviceUuid;
+  StringToUuid(aServiceUuid, serviceUuid);
+
+  if (aChannel < 0) {
+    BluetoothService* bs = BluetoothService::Get();
+    if (!bs || sInShutdown) {
+      OnSocketConnectError(mSocket);
+      return;
+    }
+
+    if (mNeedsUpdatingSdpRecords) {
+      mNeedsUpdatingSdpRecords = false;
+      mLastServiceChannelCheck = TimeStamp::Now();
+    } else {
+      // Refresh SDP records until it gets valid service channel
+      // unless timeout is hit.
+      TimeDuration duration = TimeStamp::Now() - mLastServiceChannelCheck;
+      if (duration.ToMilliseconds() >= kSdpUpdatingTimeoutMs) {
+        OnSocketConnectError(mSocket);
+        return;
+      }
+    }
+
+    if (!bs->UpdateSdpRecords(aDeviceAddress, this)) {
+      OnSocketConnectError(mSocket);
+      return;
+    }
+  }
+
+  mSocket->Connect(aDeviceAddress, serviceUuid,
+                   BluetoothSocketType::RFCOMM, aChannel,
+                   false, true);
 }
 
 void
 BluetoothOppManager::OnUpdateSdpRecords(const nsAString& aDeviceAddress)
 {
-  MOZ_ASSERT(false);
+  BluetoothService* bs = BluetoothService::Get();
+  if (!bs || sInShutdown) {
+    OnSocketConnectError(mSocket);
+    return;
+  }
+
+  nsString uuid;
+  BluetoothUuidHelper::GetString(BluetoothServiceClass::OBJECT_PUSH, uuid);
+
+  if (NS_FAILED(bs->GetServiceChannel(aDeviceAddress, uuid, this))) {
+    OnSocketConnectError(mSocket);
+    return;
+  }
 }
 
 void
 BluetoothOppManager::Connect(const nsAString& aDeviceAddress,
                              BluetoothProfileController* aController)
 {
   MOZ_ASSERT(false);
 }
--- a/dom/bluetooth/bluedroid/BluetoothOppManager.h
+++ b/dom/bluetooth/bluedroid/BluetoothOppManager.h
@@ -141,16 +141,28 @@ private:
   int mLastCommand;
 
   int mPacketLength;
   int mPutPacketReceivedLength;
   int mBodySegmentLength;
   int mUpdateProgressCounter;
 
   /**
+   * When it is true and the target service on target device couldn't be found,
+   * refreshing SDP records is necessary.
+   */
+  bool mNeedsUpdatingSdpRecords;
+
+  /**
+   * This holds the time when OPP manager fail to get service channel and
+   * prepare to refresh SDP records.
+   */
+  mozilla::TimeStamp mLastServiceChannelCheck;
+
+  /**
    * Set when StopSendingFile() is called.
    */
   bool mAbortFlag;
 
   /**
    * Set when receiving the first PUT packet of a new file
    */
   bool mNewFileFlag;