Bug 1029387: Convert Bluedroid Socket's Connect method to asynchronous design, r=shuang
authorThomas Zimmermann <tdz@users.sourceforge.net>
Thu, 10 Jul 2014 15:10:26 +0200
changeset 193327 786aa9a4e62deb86f72bad84897191428a0b606f
parent 193326 ed832ef4e12f1dd608f0f08dedbb7f48c709c498
child 193328 b56d8177948c5227d12781017dd655ff77c6b0ea
push id27116
push userryanvm@gmail.com
push dateThu, 10 Jul 2014 22:09:47 +0000
treeherdermozilla-central@0a0348d3f0c8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersshuang
bugs1029387
milestone33.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 1029387: Convert Bluedroid Socket's Connect method to asynchronous design, r=shuang
dom/bluetooth/bluedroid/BluetoothInterface.cpp
dom/bluetooth/bluedroid/BluetoothInterface.h
dom/bluetooth/bluedroid/BluetoothSocket.cpp
--- a/dom/bluetooth/bluedroid/BluetoothInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothInterface.cpp
@@ -126,23 +126,31 @@ BluetoothSocketInterface::Listen(btsock_
   bt_status_t status = mInterface->listen(aType, aServiceName, aServiceUuid,
                                           aChannel, &fd, aFlags);
   if (aRes) {
     DispatchBluetoothSocketResult(aRes, &BluetoothSocketResultHandler::Listen,
                                   fd, status);
   }
 }
 
-bt_status_t
+void
 BluetoothSocketInterface::Connect(const bt_bdaddr_t* aBdAddr,
                                   btsock_type_t aType, const uint8_t* aUuid,
-                                  int aChannel, int& aSockFd, int aFlags)
+                                  int aChannel, int aFlags,
+                                  BluetoothSocketResultHandler* aRes)
 {
-  return mInterface->connect(aBdAddr, aType, aUuid, aChannel, &aSockFd,
-                             aFlags);
+  int fd;
+
+  bt_status_t status = mInterface->connect(aBdAddr, aType, aUuid, aChannel,
+                                           &fd, aFlags);
+  if (aRes) {
+    DispatchBluetoothSocketResult(aRes,
+                                  &BluetoothSocketResultHandler::Connect,
+                                  fd, status);
+  }
 }
 
 BluetoothSocketInterface::BluetoothSocketInterface(
   const btsock_interface_t* aInterface)
 : mInterface(aInterface)
 {
   MOZ_ASSERT(mInterface);
 }
--- a/dom/bluetooth/bluedroid/BluetoothInterface.h
+++ b/dom/bluetooth/bluedroid/BluetoothInterface.h
@@ -46,19 +46,19 @@ public:
   friend class BluetoothInterface;
 
   // Init and Cleanup is handled by BluetoothInterface
 
   void Listen(btsock_type_t aType,
               const char* aServiceName, const uint8_t* aServiceUuid,
               int aChannel, int aFlags, BluetoothSocketResultHandler* aRes);
 
-  bt_status_t Connect(const bt_bdaddr_t* aBdAddr, btsock_type_t aType,
-                      const uint8_t* aUuid, int aChannel, int& aSockFd,
-                      int aFlags);
+  void Connect(const bt_bdaddr_t* aBdAddr, btsock_type_t aType,
+               const uint8_t* aUuid, int aChannel, int aFlags,
+               BluetoothSocketResultHandler* aRes);
 
 protected:
   BluetoothSocketInterface(const btsock_interface_t* aInterface);
   ~BluetoothSocketInterface();
 
 private:
   const btsock_interface_t* mInterface;
 };
--- a/dom/bluetooth/bluedroid/BluetoothSocket.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothSocket.cpp
@@ -154,17 +154,17 @@ public:
     MOZ_ASSERT(!NS_IsMainThread());
     MOZ_ASSERT(!mShuttingDownOnIOThread);
 
     RemoveWatchers(READ_WATCHER | WRITE_WATCHER);
 
     mShuttingDownOnIOThread = true;
   }
 
-  void Connect();
+  void Connect(int aFd);
   void Listen(int aFd);
 
   void SetUpIO(bool aWrite)
   {
     AddWatchers(READ_WATCHER, true);
     if (aWrite) {
         AddWatchers(WRITE_WATCHER, false);
     }
@@ -387,26 +387,30 @@ protected:
   }
 private:
   DroidSocketImpl* mDroidSocketImpl;
 };
 
 class SocketConnectTask : public DroidSocketImplTask
 {
 public:
-  SocketConnectTask(DroidSocketImpl* aDroidSocketImpl)
+  SocketConnectTask(DroidSocketImpl* aDroidSocketImpl, int aFd)
   : DroidSocketImplTask(aDroidSocketImpl)
+  , mFd(aFd)
   { }
 
   void Run() MOZ_OVERRIDE
   {
     MOZ_ASSERT(!NS_IsMainThread());
     MOZ_ASSERT(!IsCanceled());
-    GetDroidSocketImpl()->Connect();
+    GetDroidSocketImpl()->Connect(mFd);
   }
+
+private:
+  int mFd;
 };
 
 class SocketListenTask : public DroidSocketImplTask
 {
 public:
   SocketListenTask(DroidSocketImpl* aDroidSocketImpl, int aFd)
   : DroidSocketImplTask(aDroidSocketImpl)
   , mFd(aFd)
@@ -433,48 +437,31 @@ class SocketConnectClientFdTask : public
   }
 
   DroidSocketImpl* mImpl;
 public:
   SocketConnectClientFdTask(DroidSocketImpl* aImpl) : mImpl(aImpl) { }
 };
 
 void
-DroidSocketImpl::Connect()
+DroidSocketImpl::Connect(int aFd)
 {
-  MOZ_ASSERT(sBluetoothSocketInterface);
-
-  bt_bdaddr_t remoteBdAddress;
-  StringToBdAddressType(mDeviceAddress, &remoteBdAddress);
+  MOZ_ASSERT(aFd >= 0);
 
-  // TODO: uuid as argument
-  int fd = -1;
-  bt_status_t status =
-    sBluetoothSocketInterface->Connect(&remoteBdAddress,
-                                       BTSOCK_RFCOMM,
-                                       UUID_OBEX_OBJECT_PUSH,
-                                       mChannel,
-                                       fd,
-                                       (BTSOCK_FLAG_ENCRYPT * mEncrypt) |
-                                       (BTSOCK_FLAG_AUTH * mAuth));
-  NS_ENSURE_TRUE_VOID(status == BT_STATUS_SUCCESS);
-  NS_ENSURE_TRUE_VOID(fd >= 0);
-
-  int flags = TEMP_FAILURE_RETRY(fcntl(fd, F_GETFL));
+  int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL));
   NS_ENSURE_TRUE_VOID(flags >= 0);
 
   if (!(flags & O_NONBLOCK)) {
-    int res = TEMP_FAILURE_RETRY(fcntl(fd, F_SETFL, flags | O_NONBLOCK));
+    int res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags | O_NONBLOCK));
     NS_ENSURE_TRUE_VOID(!res);
   }
 
-  SetFd(fd);
+  SetFd(aFd);
 
   AddWatchers(READ_WATCHER, true);
-  AddWatchers(WRITE_WATCHER, false);
 }
 
 void
 DroidSocketImpl::Listen(int aFd)
 {
   MOZ_ASSERT(aFd >= 0);
 
   int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL));
@@ -669,28 +656,63 @@ BluetoothSocket::CloseDroidSocket()
   mImpl->ShutdownOnMainThread();
   XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
                                    new ShutdownSocketTask(mImpl));
   mImpl = nullptr;
 
   OnDisconnect();
 }
 
+class ConnectResultHandler MOZ_FINAL : public BluetoothSocketResultHandler
+{
+public:
+  ConnectResultHandler(DroidSocketImpl* aImpl)
+  : mImpl(aImpl)
+  {
+    MOZ_ASSERT(mImpl);
+  }
+
+  void Connect(int aFd) MOZ_OVERRIDE
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
+                                     new SocketConnectTask(mImpl, aFd));
+  }
+
+  void OnError(bt_status_t aStatus) MOZ_OVERRIDE
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+    BT_WARNING("Connect failed: %d", (int)aStatus);
+  }
+
+private:
+  DroidSocketImpl* mImpl;
+};
+
 bool
 BluetoothSocket::Connect(const nsAString& aDeviceAddress, int aChannel)
 {
   MOZ_ASSERT(NS_IsMainThread());
   NS_ENSURE_FALSE(mImpl, false);
 
   mIsServer = false;
   mImpl = new DroidSocketImpl(XRE_GetIOMessageLoop(), this, aDeviceAddress,
                               aChannel, mAuth, mEncrypt);
-  XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
-                                   new SocketConnectTask(mImpl));
+
+  bt_bdaddr_t remoteBdAddress;
+  StringToBdAddressType(aDeviceAddress, &remoteBdAddress);
 
+  // TODO: uuid as argument
+  sBluetoothSocketInterface->Connect(&remoteBdAddress,
+                                     BTSOCK_RFCOMM,
+                                     UUID_OBEX_OBJECT_PUSH,
+                                     aChannel,
+                                     (BTSOCK_FLAG_ENCRYPT * mEncrypt) |
+                                     (BTSOCK_FLAG_AUTH * mAuth),
+                                     new ConnectResultHandler(mImpl));
   return true;
 }
 
 class ListenResultHandler MOZ_FINAL : public BluetoothSocketResultHandler
 {
 public:
   ListenResultHandler(DroidSocketImpl* aImpl)
   : mImpl(aImpl)