Bug 1096266 - Avoid to create Bluetooth profiles on content process since HFP manager need permission to create setting lock. r=shuang, f=btian
authorJamin Liu <jaliu@mozilla.com>
Thu, 25 Dec 2014 14:46:37 +0800
changeset 238073 054216fee88afc25d0072430848c392e58b400f9
parent 238072 3add7c91e032c871637fd904047ea1f768f9e5b8
child 238074 e2b1ece4af2f0a84770359727245288d1038be55
push id7472
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 20:36:27 +0000
treeherdermozilla-aurora@300ca104f8fb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersshuang
bugs1096266
milestone37.0a1
Bug 1096266 - Avoid to create Bluetooth profiles on content process since HFP manager need permission to create setting lock. r=shuang, f=btian
dom/bluetooth2/BluetoothService.cpp
dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp
dom/bluetooth2/bluedroid/BluetoothUtils.cpp
dom/bluetooth2/bluedroid/BluetoothUtils.h
dom/bluetooth2/bluedroid/hfp/BluetoothHfpManager.cpp
dom/bluetooth2/bluez/BluetoothDBusService.cpp
dom/bluetooth2/bluez/BluetoothHfpManager.cpp
--- a/dom/bluetooth2/BluetoothService.cpp
+++ b/dom/bluetooth2/BluetoothService.cpp
@@ -89,22 +89,16 @@ USING_BLUETOOTH_NAMESPACE
 
 namespace {
 
 StaticRefPtr<BluetoothService> sBluetoothService;
 
 bool sInShutdown = false;
 bool sToggleInProgress = false;
 
-bool
-IsMainProcess()
-{
-  return XRE_GetProcessType() == GeckoProcessType_Default;
-}
-
 void
 ShutdownTimeExceeded(nsITimer* aTimer, void* aClosure)
 {
   MOZ_ASSERT(NS_IsMainThread());
   *static_cast<bool*>(aClosure) = true;
 }
 
 void
@@ -400,56 +394,25 @@ BluetoothService::StartBluetooth(bool aI
 }
 
 nsresult
 BluetoothService::StopBluetooth(bool aIsStartup,
                                 BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  BluetoothProfileManagerBase* profile;
-  profile = BluetoothHfpManager::Get();
-  NS_ENSURE_TRUE(profile, NS_ERROR_FAILURE);
-  if (profile->IsConnected()) {
-    profile->Disconnect(nullptr);
-  } else {
-    profile->Reset();
-  }
-
-  profile = BluetoothOppManager::Get();
-  NS_ENSURE_TRUE(profile, NS_ERROR_FAILURE);
-  if (profile->IsConnected()) {
-    profile->Disconnect(nullptr);
-  }
-
-  profile = BluetoothA2dpManager::Get();
-  NS_ENSURE_TRUE(profile, NS_ERROR_FAILURE);
-  if (profile->IsConnected()) {
-    profile->Disconnect(nullptr);
-  } else {
-    profile->Reset();
-  }
-
-  profile = BluetoothHidManager::Get();
-  NS_ENSURE_TRUE(profile, NS_ERROR_FAILURE);
-  if (profile->IsConnected()) {
-    profile->Disconnect(nullptr);
-  } else {
-    profile->Reset();
-  }
-
   /* When IsEnabled() is false, we don't switch off Bluetooth but we still
    * send ToggleBtAck task. One special case happens at startup stage. At
    * startup, the initialization of BluetoothService still has to be done
    * even if Bluetooth is disabled.
    *
    * Please see bug 892392 for more information.
    */
   if (aIsStartup || IsEnabled()) {
-    // Switch Bluetooth off
+    // Any connected Bluetooth profile would be disconnected.
     nsresult rv = StopInternal(aRunnable);
     if (NS_FAILED(rv)) {
       BT_WARNING("Bluetooth service failed to stop!");
       return rv;
     }
   } else {
     BT_WARNING("Bluetooth has already been enabled/disabled before.");
     nsRefPtr<nsRunnable> runnable = new BluetoothService::ToggleBtAck(false);
--- a/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp
+++ b/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp
@@ -16,16 +16,17 @@
 ** limitations under the License.
 */
 
 #include "BluetoothServiceBluedroid.h"
 
 #include "BluetoothA2dpManager.h"
 #include "BluetoothGattManager.h"
 #include "BluetoothHfpManager.h"
+#include "BluetoothHidManager.h"
 #include "BluetoothOppManager.h"
 #include "BluetoothProfileController.h"
 #include "BluetoothReplyRunnable.h"
 #include "BluetoothUtils.h"
 #include "BluetoothUuid.h"
 #include "mozilla/dom/bluetooth/BluetoothTypes.h"
 #include "mozilla/ipc/UnixSocket.h"
 #include "mozilla/StaticMutex.h"
@@ -330,16 +331,47 @@ BluetoothServiceBluedroid::StartInternal
   return ret;
 }
 
 nsresult
 BluetoothServiceBluedroid::StopInternal(BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
+  BluetoothProfileManagerBase* profile;
+  profile = BluetoothHfpManager::Get();
+  NS_ENSURE_TRUE(profile, NS_ERROR_FAILURE);
+  if (profile->IsConnected()) {
+    profile->Disconnect(nullptr);
+  } else {
+    profile->Reset();
+  }
+
+  profile = BluetoothOppManager::Get();
+  NS_ENSURE_TRUE(profile, NS_ERROR_FAILURE);
+  if (profile->IsConnected()) {
+    profile->Disconnect(nullptr);
+  }
+
+  profile = BluetoothA2dpManager::Get();
+  NS_ENSURE_TRUE(profile, NS_ERROR_FAILURE);
+  if (profile->IsConnected()) {
+    profile->Disconnect(nullptr);
+  } else {
+    profile->Reset();
+  }
+
+  profile = BluetoothHidManager::Get();
+  NS_ENSURE_TRUE(profile, NS_ERROR_FAILURE);
+  if (profile->IsConnected()) {
+    profile->Disconnect(nullptr);
+  } else {
+    profile->Reset();
+  }
+
   // aRunnable will be a nullptr during starup and shutdown
   if(aRunnable) {
     sChangeAdapterStateRunnableArray.AppendElement(aRunnable);
   }
 
   nsresult ret = StopGonkBluetooth();
   if (NS_FAILED(ret)) {
     BluetoothService::AcknowledgeToggleBt(true);
--- a/dom/bluetooth2/bluedroid/BluetoothUtils.cpp
+++ b/dom/bluetooth2/bluedroid/BluetoothUtils.cpp
@@ -15,16 +15,17 @@
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/bluetooth/BluetoothTypes.h"
 #include "nsContentUtils.h"
 #include "nsIScriptContext.h"
 #include "nsISystemMessagesInternal.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "nsServiceManagerUtils.h"
+#include "nsXULAppAPI.h"
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 void
 UuidToString(const BluetoothUuid& aUuid, nsAString& aString)
 {
   char uuidStr[37];
   uint32_t uuid0, uuid4;
@@ -192,9 +193,15 @@ DispatchStatusChangedEvent(const nsAStri
 
   BluetoothSignal signal(nsString(aType), NS_LITERAL_STRING(KEY_ADAPTER), data);
 
   BluetoothService* bs = BluetoothService::Get();
   NS_ENSURE_TRUE_VOID(bs);
   bs->DistributeSignal(signal);
 }
 
+bool
+IsMainProcess()
+{
+  return XRE_GetProcessType() == GeckoProcessType_Default;
+}
+
 END_BLUETOOTH_NAMESPACE
--- a/dom/bluetooth2/bluedroid/BluetoothUtils.h
+++ b/dom/bluetooth2/bluedroid/BluetoothUtils.h
@@ -71,12 +71,19 @@ DispatchBluetoothReply(BluetoothReplyRun
                        const BluetoothValue& aValue,
                        const enum BluetoothStatus aStatusCode);
 
 void
 DispatchStatusChangedEvent(const nsAString& aType,
                            const nsAString& aDeviceAddress,
                            bool aStatus);
 
+/**
+ * Test whether this function is running at b2g process.
+ *
+ * @return true if the function is running at b2g process, false otherwise.
+ */
+bool
+IsMainProcess();
 
 END_BLUETOOTH_NAMESPACE
 
 #endif
--- a/dom/bluetooth2/bluedroid/hfp/BluetoothHfpManager.cpp
+++ b/dom/bluetooth2/bluedroid/hfp/BluetoothHfpManager.cpp
@@ -218,16 +218,18 @@ BluetoothHfpManager::Reset()
   mSignal = 0;
 
   mController = nullptr;
 }
 
 bool
 BluetoothHfpManager::Init()
 {
+  // The function must run at b2g process since it would access SettingsService.
+  MOZ_ASSERT(IsMainProcess());
   MOZ_ASSERT(NS_IsMainThread());
 
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   NS_ENSURE_TRUE(obs, false);
 
   if (NS_FAILED(obs->AddObserver(this, MOZSETTINGS_CHANGED_ID, false)) ||
       NS_FAILED(obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false))) {
     BT_WARNING("Failed to add observers!");
--- a/dom/bluetooth2/bluez/BluetoothDBusService.cpp
+++ b/dom/bluetooth2/bluez/BluetoothDBusService.cpp
@@ -136,16 +136,48 @@ public:
 
   bool Disable()
   {
     MOZ_ASSERT(!NS_IsMainThread()); // BT thread
 
     if (!IsEnabled()) {
       return true;
     }
+
+    BluetoothProfileManagerBase* profile;
+    profile = BluetoothHfpManager::Get();
+    NS_ENSURE_TRUE(profile, NS_ERROR_FAILURE);
+    if (profile->IsConnected()) {
+      profile->Disconnect(nullptr);
+    } else {
+      profile->Reset();
+    }
+
+    profile = BluetoothOppManager::Get();
+    NS_ENSURE_TRUE(profile, NS_ERROR_FAILURE);
+    if (profile->IsConnected()) {
+      profile->Disconnect(nullptr);
+    }
+
+    profile = BluetoothA2dpManager::Get();
+    NS_ENSURE_TRUE(profile, NS_ERROR_FAILURE);
+    if (profile->IsConnected()) {
+      profile->Disconnect(nullptr);
+    } else {
+      profile->Reset();
+    }
+
+    profile = BluetoothHidManager::Get();
+    NS_ENSURE_TRUE(profile, NS_ERROR_FAILURE);
+    if (profile->IsConnected()) {
+      profile->Disconnect(nullptr);
+    } else {
+      profile->Reset();
+    }
+
     // 0 == success, -1 == error
     return !m_bt_disable();
   }
 
   bool IsEnabled() const
   {
     MOZ_ASSERT(!NS_IsMainThread()); // BT thread
 
--- a/dom/bluetooth2/bluez/BluetoothHfpManager.cpp
+++ b/dom/bluetooth2/bluez/BluetoothHfpManager.cpp
@@ -411,16 +411,18 @@ BluetoothHfpManager::Reset()
   mIsHsp = false;
   mReceiveVgsFlag = false;
   mController = nullptr;
 }
 
 bool
 BluetoothHfpManager::Init()
 {
+  // The function must run at b2g process since it would access SettingsService.
+  MOZ_ASSERT(IsMainProcess());
   MOZ_ASSERT(NS_IsMainThread());
 
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   NS_ENSURE_TRUE(obs, false);
 
   if (NS_FAILED(obs->AddObserver(this, MOZSETTINGS_CHANGED_ID, false)) ||
       NS_FAILED(obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false))) {
     BT_WARNING("Failed to add observers!");