Bug 796300 - Final version: Set audio device BLUETOOTH_SCO_HEADSET to unavailable when disconnect Sco socket, r=qdot
authorGina Yeh <gyeh@mozilla.com>
Wed, 03 Oct 2012 10:55:28 +0800
changeset 115291 a2756948142d25f95ae71e47a17f46a3629022cc
parent 115290 56e8259f189b772a7f1315e7f8f7c2f1e3500da6
child 115292 a742bf08f125941501a1097ba2a63a5be39cda52
push id1708
push userakeybl@mozilla.com
push dateMon, 19 Nov 2012 21:10:21 +0000
treeherdermozilla-beta@27b14fe50103 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersqdot
bugs796300
milestone18.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 796300 - Final version: Set audio device BLUETOOTH_SCO_HEADSET to unavailable when disconnect Sco socket, r=qdot
dom/bluetooth/BluetoothHfpManager.cpp
dom/bluetooth/linux/BluetoothDBusService.cpp
dom/system/gonk/AudioManager.cpp
hal/HalTypes.h
--- a/dom/bluetooth/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/BluetoothHfpManager.cpp
@@ -11,26 +11,28 @@
 #include "BluetoothReplyRunnable.h"
 #include "BluetoothScoManager.h"
 #include "BluetoothService.h"
 #include "BluetoothServiceUuid.h"
 
 #include "mozilla/dom/bluetooth/BluetoothTypes.h"
 #include "mozilla/Services.h"
 #include "nsContentUtils.h"
+#include "nsIAudioManager.h"
 #include "nsIObserverService.h"
 #include "nsIRadioInterfaceLayer.h"
 #include "nsISystemMessagesInternal.h"
 #include "BluetoothUtils.h"
 
 #include "nsVariant.h"
 
 #include <unistd.h> /* usleep() */
 
 #define MOZSETTINGS_CHANGED_ID "mozsettings-changed"
+#define BLUETOOTH_SCO_STATUS_CHANGED "bluetooth-sco-status-changed"
 #define AUDIO_VOLUME_MASTER "audio.volume.master"
 
 USING_BLUETOOTH_NAMESPACE
 using namespace mozilla::ipc;
 
 static nsRefPtr<BluetoothHfpManager> sInstance = nullptr;
 static nsCOMPtr<nsIThread> sHfpCommandThread;
 static bool sStopSendingRingFlag = true;
@@ -77,24 +79,39 @@ OpenScoSocket(const nsAString& aDevicePa
   }
 }
 
 void
 CloseScoSocket()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
+  nsCOMPtr<nsIAudioManager> am = do_GetService("@mozilla.org/telephony/audiomanager;1");
+  if (!am) {
+    NS_WARNING("Failed to get AudioManager Service!");
+    return;
+  }
+  am->SetForceForUse(am->USE_COMMUNICATION, am->FORCE_NONE);
+
   BluetoothScoManager* sco = BluetoothScoManager::Get();
   if (!sco) {
     NS_WARNING("BluetoothScoManager is not available!");
     return;
   }
 
-  if (sco->GetConnected())
+  if (sco->GetConnected()) {
+    nsCOMPtr<nsIObserverService> obs = do_GetService("@mozilla.org/observer-service;1");
+    if (obs) {
+      if (NS_FAILED(obs->NotifyObservers(nullptr, BLUETOOTH_SCO_STATUS_CHANGED, nullptr))) {
+        NS_WARNING("Failed to notify bluetooth-sco-status-changed observsers!");
+        return;
+      }
+    }
     sco->Disconnect();
+  }
 }
 
 BluetoothHfpManager::BluetoothHfpManager()
   : mCurrentVgs(-1)
   , mCurrentCallIndex(0)
   , mCurrentCallState(nsIRadioInterfaceLayer::CALL_STATE_DISCONNECTED)
 {
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
--- a/dom/bluetooth/linux/BluetoothDBusService.cpp
+++ b/dom/bluetooth/linux/BluetoothDBusService.cpp
@@ -185,16 +185,19 @@ public:
   }
 
   NS_IMETHOD
   Run()
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     nsCOMPtr<nsIAudioManager> am = do_GetService("@mozilla.org/telephony/audiomanager;1");
+    if (!am) {
+      NS_WARNING("Failed to get AudioManager service!");
+    }
     am->SetForceForUse(am->USE_COMMUNICATION, am->FORCE_BT_SCO);
 
     nsCOMPtr<nsIObserverService> obs = do_GetService("@mozilla.org/observer-service;1");
     if (obs) {
       if (NS_FAILED(obs->NotifyObservers(nullptr, BLUETOOTH_SCO_STATUS_CHANGED, mObjectPath.get()))) {
         NS_WARNING("Failed to notify bluetooth-sco-status-changed observsers!");
         return NS_ERROR_FAILURE;
       }
--- a/dom/system/gonk/AudioManager.cpp
+++ b/dom/system/gonk/AudioManager.cpp
@@ -31,17 +31,16 @@ using namespace mozilla;
 #define HEADPHONES_STATUS_CHANGED "headphones-status-changed"
 #define HEADPHONES_STATUS_ON      NS_LITERAL_STRING("on").get()
 #define HEADPHONES_STATUS_OFF     NS_LITERAL_STRING("off").get()
 #define HEADPHONES_STATUS_UNKNOWN NS_LITERAL_STRING("unknown").get()
 #define BLUETOOTH_SCO_STATUS_CHANGED "bluetooth-sco-status-changed"
 
 // A bitwise variable for recording what kind of headset is attached.
 static int sHeadsetState;
-static const char* sDeviceAddress;
 static int kBtSampleRate = 8000;
 
 static bool
 IsFmRadioAudioOn()
 {
   if (static_cast<
       audio_policy_dev_state_t (*) (audio_devices_t, const char *)
       >(AudioSystem::getDeviceConnectionState)) {
@@ -75,20 +74,16 @@ InternalSetAudioRoutesICS(SwitchState aS
   if (aState == SWITCH_STATE_HEADSET) {
     AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_OUT_WIRED_HEADSET,
                                           AUDIO_POLICY_DEVICE_STATE_AVAILABLE, "");
     sHeadsetState |= AUDIO_DEVICE_OUT_WIRED_HEADSET;
   } else if (aState == SWITCH_STATE_HEADPHONE) {
     AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_OUT_WIRED_HEADPHONE,
                                           AUDIO_POLICY_DEVICE_STATE_AVAILABLE, "");
     sHeadsetState |= AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
-  } else if (aState == SWITCH_STATE_BLUETOOTH_SCO) {
-    AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET,
-                                          AUDIO_POLICY_DEVICE_STATE_AVAILABLE, sDeviceAddress);
-    sHeadsetState |= AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
   } else if (aState == SWITCH_STATE_OFF) {
     AudioSystem::setDeviceConnectionState(static_cast<audio_devices_t>(sHeadsetState),
                                           AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, "");
     sHeadsetState = 0;
   }
 
   // The audio volume is not consistent when we plug and unplug the headset.
   // Set the fm volume again here.
@@ -130,22 +125,32 @@ InternalSetAudioRoutes(SwitchState aStat
 }
 
 nsresult
 AudioManager::Observe(nsISupports* aSubject,
                       const char* aTopic,
                       const PRUnichar* aData)
 {
   if (!strcmp(aTopic, BLUETOOTH_SCO_STATUS_CHANGED)) {
-    String8 cmd;
-    cmd.appendFormat("bt_samplerate=%d", kBtSampleRate);
-    AudioSystem::setParameters(0, cmd);
+    if (aData) {
+      String8 cmd;
+      cmd.appendFormat("bt_samplerate=%d", kBtSampleRate);
+      AudioSystem::setParameters(0, cmd);
+      const char* address = NS_ConvertUTF16toUTF8(nsDependentString(aData)).get();
+      AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET,
+                                            AUDIO_POLICY_DEVICE_STATE_AVAILABLE, address);
+      AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
+                                            AUDIO_POLICY_DEVICE_STATE_AVAILABLE, address);
+    } else {
+      AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET,
+                                            AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, "");
+      AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
+                                            AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, "");
+    }
 
-    sDeviceAddress = NS_ConvertUTF16toUTF8(nsDependentString(aData)).get();
-    InternalSetAudioRoutes(SwitchState::SWITCH_STATE_BLUETOOTH_SCO);
     return NS_OK;
   }
   return NS_ERROR_UNEXPECTED;
 }
 
 static void
 NotifyHeadphonesStatus(SwitchState aState)
 {
--- a/hal/HalTypes.h
+++ b/hal/HalTypes.h
@@ -57,17 +57,16 @@ enum SwitchDevice {
 };
 
 enum SwitchState {
   SWITCH_STATE_UNKNOWN = -1,
   SWITCH_STATE_ON,
   SWITCH_STATE_OFF,
   SWITCH_STATE_HEADSET,          // Headphone with microphone
   SWITCH_STATE_HEADPHONE,        // without microphone
-  SWITCH_STATE_BLUETOOTH_SCO,
   NUM_SWITCH_STATE
 };
 
 typedef Observer<SwitchEvent> SwitchObserver;
 
 enum ProcessPriority {
   PROCESS_PRIORITY_BACKGROUND,
   PROCESS_PRIORITY_FOREGROUND,