Bug 1096266 - Avoid to create Bluetooth profiles on content process since HFP manager need permission to create setting lock. r=shuang, f=btian
--- 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!");