Bug 803475 - Failed to transfer audio back to bluetooth headset while in a phone call, r=qdot
authorGina Yeh <gyeh@mozilla.com>
Fri, 26 Oct 2012 17:48:47 +0800
changeset 111653 1cd611b971784d7e837c6db234e7ce38fa983efa
parent 111652 3bd24121c80d304053e198eca45e6b88a7711f33
child 111654 4b2d566ad1ac77c285b3a0af352211b0e81b5718
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersqdot
bugs803475
milestone19.0a1
Bug 803475 - Failed to transfer audio back to bluetooth headset while in a phone call, r=qdot
dom/bluetooth/BluetoothScoManager.cpp
dom/bluetooth/BluetoothScoManager.h
dom/bluetooth/linux/BluetoothDBusService.cpp
--- a/dom/bluetooth/BluetoothScoManager.cpp
+++ b/dom/bluetooth/BluetoothScoManager.cpp
@@ -119,16 +119,18 @@ BluetoothScoManagerObserver::Observe(nsI
 
 BluetoothScoManager::BluetoothScoManager()
 {
 }
 
 bool
 BluetoothScoManager::Init()
 {
+  mSocketStatus = GetConnectionStatus();
+
   sScoObserver = new BluetoothScoManagerObserver();
   if (sScoObserver->Init()) {
     NS_WARNING("Cannot set up SCO observers!");
   }
   return true;
 }
 
 BluetoothScoManager::~BluetoothScoManager()
@@ -200,52 +202,91 @@ BluetoothScoManager::Connect(const nsASt
     return false;
   }
 
   if (GetConnectionStatus() == SocketConnectionStatus::SOCKET_CONNECTED) {
     NS_WARNING("Sco socket has been connected");
     return false;
   }
 
+  CloseSocket();
+
   BluetoothService* bs = BluetoothService::Get();
   if (!bs) {
     NS_WARNING("BluetoothService not available!");
     return false;
   }
 
   nsresult rv = bs->GetScoSocket(aDeviceAddress,
                                  true,
                                  false,
                                  this);
 
   return NS_FAILED(rv) ? false : true;
 }
 
+bool
+BluetoothScoManager::Listen()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  if (gInShutdown) {
+    MOZ_ASSERT(false, "Listen called while in shutdown!");
+    return false;
+  }
+
+  CloseSocket();
+
+  BluetoothService* bs = BluetoothService::Get();
+  if (!bs) {
+    NS_WARNING("BluetoothService not available!");
+    return false;
+  }
+
+  nsresult rv = bs->ListenSocketViaService(-1,
+                                           BluetoothSocketType::SCO,
+                                           true,
+                                           false,
+                                           this);
+
+  mSocketStatus = GetConnectionStatus();
+
+  return NS_FAILED(rv) ? false : true;
+}
+
 void
 BluetoothScoManager::Disconnect()
 {
   if (GetConnectionStatus() == SocketConnectionStatus::SOCKET_DISCONNECTED) {
     return;
   }
 
   CloseSocket();
 }
 
 void
 BluetoothScoManager::OnConnectSuccess()
 {
   nsString address;
   GetSocketAddr(address);
   NotifyAudioManager(address);
+
+  mSocketStatus = GetConnectionStatus();
 }
 
 void
 BluetoothScoManager::OnConnectError()
 {
   CloseSocket();
+  mSocketStatus = GetConnectionStatus();
+  Listen();
 }
 
 void
 BluetoothScoManager::OnDisconnect()
 {
-  nsString address = NS_LITERAL_STRING("");
-  NotifyAudioManager(address);
+  if (mSocketStatus == SocketConnectionStatus::SOCKET_CONNECTED) {
+    Listen();
+
+    nsString address = NS_LITERAL_STRING("");
+    NotifyAudioManager(address);
+  }
 }
--- a/dom/bluetooth/BluetoothScoManager.h
+++ b/dom/bluetooth/BluetoothScoManager.h
@@ -22,24 +22,27 @@ public:
   ~BluetoothScoManager();
 
   static BluetoothScoManager* Get();
   void ReceiveSocketData(mozilla::ipc::UnixSocketRawData* aMessage)
     MOZ_OVERRIDE;
 
   bool Connect(const nsAString& aDeviceObjectPath);
   void Disconnect();
+  bool Listen();
 
 private:
   friend class BluetoothScoManagerObserver;
   BluetoothScoManager();
   bool Init();
   void Cleanup();
   nsresult HandleShutdown();
   void NotifyAudioManager(const nsAString& aAddress);
   virtual void OnConnectSuccess() MOZ_OVERRIDE;
   virtual void OnConnectError() MOZ_OVERRIDE;
   virtual void OnDisconnect() MOZ_OVERRIDE;
+
+  int mSocketStatus;
 };
 
 END_BLUETOOTH_NAMESPACE
 
 #endif
--- a/dom/bluetooth/linux/BluetoothDBusService.cpp
+++ b/dom/bluetooth/linux/BluetoothDBusService.cpp
@@ -716,24 +716,32 @@ BluetoothDBusService::AddReservedService
 }
 
 class PrepareProfileManagersRunnable : public nsRunnable
 {
 public:
   NS_IMETHOD
   Run()
   {
-    BluetoothHfpManager* h = BluetoothHfpManager::Get();
-    if (h) {
-      h->Listen();
+    BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
+    if (!hfp || !hfp->Listen()) {
+      NS_WARNING("Failed to start listening for BluetoothHfpManager!");
+      return NS_ERROR_FAILURE;
+    }
+
+    BluetoothScoManager* sco = BluetoothScoManager::Get();
+    if (!sco || !sco->Listen()) {
+      NS_WARNING("Failed to start listening for BluetoothScoManager!");
+      return NS_ERROR_FAILURE;
     }
 
     BluetoothOppManager* opp = BluetoothOppManager::Get();
-    if (opp) {
-      opp->Listen();
+    if (!opp || !opp->Listen()) {
+      NS_WARNING("Failed to start listening for BluetoothOppManager!");
+      return NS_ERROR_FAILURE;
     }
 
     return NS_OK;
   }
 };
 
 class ShutdownProfileManagersRunnable : public nsRunnable
 {