Bug 1029390: Asynchronous A2DP connect/disconnect, r=shuang
authorThomas Zimmermann <tdz@users.sourceforge.net>
Wed, 23 Jul 2014 07:56:23 +0200
changeset 195575 2ca67af54fa1ac5e59dbb524f99662d17cf159a1
parent 195574 332edac38e3cab15c3858137188090f09390eb28
child 195576 1a8d196dfcc1d08b13ed3d723e5653235093ba15
push id27187
push usercbook@mozilla.com
push dateWed, 23 Jul 2014 10:59:56 +0000
treeherdermozilla-central@d0f6259e8446 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersshuang
bugs1029390
milestone34.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 1029390: Asynchronous A2DP connect/disconnect, r=shuang
dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp
dom/bluetooth/bluedroid/BluetoothA2dpManager.h
dom/bluetooth/bluedroid/BluetoothInterface.cpp
dom/bluetooth/bluedroid/BluetoothInterface.h
--- a/dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothA2dpManager.cpp
@@ -767,16 +767,39 @@ BluetoothA2dpManager::HandleShutdown()
 {
   MOZ_ASSERT(NS_IsMainThread());
   sInShutdown = true;
   Disconnect(nullptr);
   sBluetoothA2dpManager = nullptr;
 }
 
 void
+BluetoothA2dpManager::OnConnectError()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  mController->NotifyCompletion(NS_LITERAL_STRING(ERR_CONNECTION_FAILED));
+
+  mController = nullptr;
+  mDeviceAddress.Truncate();
+}
+
+class ConnectResultHandler MOZ_FINAL : public BluetoothA2dpResultHandler
+{
+public:
+  void OnError(bt_status_t aStatus) MOZ_OVERRIDE
+  {
+    BT_LOGR("BluetoothA2dpInterface::Connect failed: %d", (int)aStatus);
+
+    NS_ENSURE_TRUE_VOID(sBluetoothA2dpManager);
+    sBluetoothA2dpManager->OnConnectError();
+  }
+};
+
+void
 BluetoothA2dpManager::Connect(const nsAString& aDeviceAddress,
                               BluetoothProfileController* aController)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!aDeviceAddress.IsEmpty());
   MOZ_ASSERT(aController);
 
   BluetoothService* bs = BluetoothService::Get();
@@ -797,23 +820,38 @@ BluetoothA2dpManager::Connect(const nsAS
     BT_LOGR("sBluetoothA2dpInterface is null");
     aController->NotifyCompletion(NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
     return;
   }
 
   bt_bdaddr_t remoteAddress;
   StringToBdAddressType(aDeviceAddress, &remoteAddress);
 
-  bt_status_t result = sBtA2dpInterface->Connect(&remoteAddress);
-  if (BT_STATUS_SUCCESS != result) {
-    BT_LOGR("Failed to connect: %x", result);
-    aController->NotifyCompletion(NS_LITERAL_STRING(ERR_CONNECTION_FAILED));
-    return;
+  sBtA2dpInterface->Connect(&remoteAddress, new ConnectResultHandler());
+}
+
+void
+BluetoothA2dpManager::OnDisconnectError()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  mController->NotifyCompletion(NS_LITERAL_STRING(ERR_DISCONNECTION_FAILED));
+}
+
+class DisconnectResultHandler MOZ_FINAL : public BluetoothA2dpResultHandler
+{
+public:
+  void OnError(bt_status_t aStatus) MOZ_OVERRIDE
+  {
+    BT_LOGR("BluetoothA2dpInterface::Disconnect failed: %d", (int)aStatus);
+
+    NS_ENSURE_TRUE_VOID(sBluetoothA2dpManager);
+    sBluetoothA2dpManager->OnDisconnectError();
   }
-}
+};
 
 void
 BluetoothA2dpManager::Disconnect(BluetoothProfileController* aController)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!mController);
 
   BluetoothService* bs = BluetoothService::Get();
@@ -839,22 +877,17 @@ BluetoothA2dpManager::Disconnect(Bluetoo
     BT_LOGR("sBluetoothA2dpInterface is null");
     aController->NotifyCompletion(NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
     return;
   }
 
   bt_bdaddr_t remoteAddress;
   StringToBdAddressType(mDeviceAddress, &remoteAddress);
 
-  bt_status_t result = sBtA2dpInterface->Disconnect(&remoteAddress);
-  if (BT_STATUS_SUCCESS != result) {
-    BT_LOGR("Failed to disconnect: %x", result);
-    aController->NotifyCompletion(NS_LITERAL_STRING(ERR_DISCONNECTION_FAILED));
-    return;
-  }
+  sBtA2dpInterface->Disconnect(&remoteAddress, new DisconnectResultHandler());
 }
 
 void
 BluetoothA2dpManager::OnConnect(const nsAString& aErrorStr)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   /**
--- a/dom/bluetooth/bluedroid/BluetoothA2dpManager.h
+++ b/dom/bluetooth/bluedroid/BluetoothA2dpManager.h
@@ -29,16 +29,19 @@ public:
     SINK_PLAYING,
   };
 
   static BluetoothA2dpManager* Get();
   static void InitA2dpInterface(BluetoothProfileResultHandler* aRes);
   static void DeinitA2dpInterface(BluetoothProfileResultHandler* aRes);
   virtual ~BluetoothA2dpManager();
 
+  void OnConnectError();
+  void OnDisconnectError();
+
   // A2DP-specific functions
   void HandleSinkPropertyChanged(const BluetoothSignal& aSignal);
 
   // AVRCP-specific functions
   void SetAvrcpConnected(bool aConnected);
   bool IsAvrcpConnected();
   void UpdateMetaData(const nsAString& aTitle,
                       const nsAString& aArtist,
--- a/dom/bluetooth/bluedroid/BluetoothInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothInterface.cpp
@@ -906,26 +906,38 @@ BluetoothA2dpInterface::Cleanup(Bluetoot
   mInterface->cleanup();
 
   if (aRes) {
     DispatchBluetoothA2dpResult(aRes, &BluetoothA2dpResultHandler::Cleanup,
                                 BT_STATUS_SUCCESS);
   }
 }
 
-bt_status_t
-BluetoothA2dpInterface::Connect(bt_bdaddr_t *aBdAddr)
+void
+BluetoothA2dpInterface::Connect(bt_bdaddr_t *aBdAddr,
+                                BluetoothA2dpResultHandler* aRes)
 {
-  return mInterface->connect(aBdAddr);
+  bt_status_t status = mInterface->connect(aBdAddr);
+
+  if (aRes) {
+    DispatchBluetoothA2dpResult(aRes, &BluetoothA2dpResultHandler::Connect,
+                                status);
+  }
 }
 
-bt_status_t
-BluetoothA2dpInterface::Disconnect(bt_bdaddr_t *aBdAddr)
+void
+BluetoothA2dpInterface::Disconnect(bt_bdaddr_t *aBdAddr,
+                                   BluetoothA2dpResultHandler* aRes)
 {
-  return mInterface->disconnect(aBdAddr);
+  bt_status_t status = mInterface->disconnect(aBdAddr);
+
+  if (aRes) {
+    DispatchBluetoothA2dpResult(aRes, &BluetoothA2dpResultHandler::Disconnect,
+                                status);
+  }
 }
 
 //
 // Bluetooth AVRCP Interface
 //
 
 #if ANDROID_VERSION >= 18
 template<>
--- a/dom/bluetooth/bluedroid/BluetoothInterface.h
+++ b/dom/bluetooth/bluedroid/BluetoothInterface.h
@@ -203,18 +203,20 @@ class BluetoothA2dpInterface
 {
 public:
   friend class BluetoothInterface;
 
   void Init(btav_callbacks_t *aCallbacks,
             BluetoothA2dpResultHandler* aRes);
   void Cleanup(BluetoothA2dpResultHandler* aRes);
 
-  bt_status_t Connect(bt_bdaddr_t *aBdAddr);
-  bt_status_t Disconnect(bt_bdaddr_t *aBdAddr);
+  void Connect(bt_bdaddr_t *aBdAddr,
+               BluetoothA2dpResultHandler* aRes);
+  void Disconnect(bt_bdaddr_t *aBdAddr,
+                  BluetoothA2dpResultHandler* aRes);
 
 protected:
   BluetoothA2dpInterface(const btav_interface_t* aInterface);
   ~BluetoothA2dpInterface();
 
 private:
   const btav_interface_t* mInterface;
 };