Merge B2g-inbound to Mozilla-Central

This commit is contained in:
Carsten "Tomcat" Book 2013-10-28 11:34:11 +01:00
commit d5ef9329d1
14 changed files with 376 additions and 198 deletions

View File

@ -1,4 +1,4 @@
{
"revision": "c09f78f6bdd9c8c3cea3943f8a6fe96c760d7de7",
"revision": "d2632e2be46de3f4fa9106ada595e33e317aaaa2",
"repo_path": "/integration/gaia-central"
}

View File

@ -207,8 +207,8 @@ BluetoothA2dpManager::OnConnect(const nsAString& aErrorStr)
*/
NS_ENSURE_TRUE_VOID(mController);
mController->OnConnect(aErrorStr);
mController = nullptr;
nsRefPtr<BluetoothProfileController> controller = mController.forget();
controller->OnConnect(aErrorStr);
}
void
@ -222,8 +222,8 @@ BluetoothA2dpManager::OnDisconnect(const nsAString& aErrorStr)
*/
NS_ENSURE_TRUE_VOID(mController);
mController->OnDisconnect(aErrorStr);
mController = nullptr;
nsRefPtr<BluetoothProfileController> controller = mController.forget();
controller->OnDisconnect(aErrorStr);
}
/* HandleSinkPropertyChanged update sink state in A2dp

View File

@ -323,7 +323,7 @@ Call::IsActive()
/**
* BluetoothHfpManager
*/
BluetoothHfpManager::BluetoothHfpManager()
BluetoothHfpManager::BluetoothHfpManager() : mController(nullptr)
{
Reset();
}
@ -367,8 +367,6 @@ BluetoothHfpManager::Reset()
// Please see Bug 878728 for more information.
mBSIR = false;
mController = nullptr;
ResetCallArray();
}
@ -1096,7 +1094,6 @@ BluetoothHfpManager::Disconnect(BluetoothProfileController* aController)
mController = aController;
mSocket->Disconnect();
mSocket = nullptr;
}
void
@ -1653,6 +1650,8 @@ BluetoothHfpManager::OnGetServiceChannel(const nsAString& aDeviceAddress,
return;
}
MOZ_ASSERT(mSocket);
if (!mSocket->Connect(NS_ConvertUTF16toUTF8(aDeviceAddress), aChannel)) {
OnConnect(NS_LITERAL_STRING("SocketConnectionError"));
}
@ -1815,8 +1814,8 @@ BluetoothHfpManager::OnConnect(const nsAString& aErrorStr)
*/
NS_ENSURE_TRUE_VOID(mController);
mController->OnConnect(aErrorStr);
mController = nullptr;
nsRefPtr<BluetoothProfileController> controller = mController.forget();
controller->OnConnect(aErrorStr);
}
void
@ -1834,8 +1833,8 @@ BluetoothHfpManager::OnDisconnect(const nsAString& aErrorStr)
*/
NS_ENSURE_TRUE_VOID(mController);
mController->OnDisconnect(aErrorStr);
mController = nullptr;
nsRefPtr<BluetoothProfileController> controller = mController.forget();
controller->OnDisconnect(aErrorStr);
}
NS_IMPL_ISUPPORTS1(BluetoothHfpManager, nsIObserver)

View File

@ -181,7 +181,6 @@ private:
nsTArray<Call> mCurrentCallArray;
nsAutoPtr<BluetoothRilListener> mListener;
nsRefPtr<BluetoothReplyRunnable> mRunnable;
nsRefPtr<BluetoothProfileController> mController;
nsRefPtr<BluetoothReplyRunnable> mScoRunnable;

View File

@ -167,8 +167,8 @@ BluetoothHidManager::OnConnect(const nsAString& aErrorStr)
*/
NS_ENSURE_TRUE_VOID(mController);
mController->OnConnect(aErrorStr);
mController = nullptr;
nsRefPtr<BluetoothProfileController> controller = mController.forget();
controller->OnConnect(aErrorStr);
}
void
@ -182,8 +182,8 @@ BluetoothHidManager::OnDisconnect(const nsAString& aErrorStr)
*/
NS_ENSURE_TRUE_VOID(mController);
mController->OnDisconnect(aErrorStr);
mController = nullptr;
nsRefPtr<BluetoothProfileController> controller = mController.forget();
controller->OnDisconnect(aErrorStr);
}
bool

View File

@ -291,7 +291,6 @@ BluetoothOppManager::Disconnect(BluetoothProfileController* aController)
mController = aController;
mSocket->Disconnect();
mSocket = nullptr;
}
void
@ -1483,8 +1482,8 @@ BluetoothOppManager::OnConnect(const nsAString& aErrorStr)
*/
NS_ENSURE_TRUE_VOID(mController);
mController->OnConnect(aErrorStr);
mController = nullptr;
nsRefPtr<BluetoothProfileController> controller = mController.forget();
controller->OnConnect(aErrorStr);
}
void
@ -1501,6 +1500,6 @@ BluetoothOppManager::OnDisconnect(const nsAString& aErrorStr)
*/
NS_ENSURE_TRUE_VOID(mController);
mController->OnDisconnect(aErrorStr);
mController = nullptr;
nsRefPtr<BluetoothProfileController> controller = mController.forget();
controller->OnDisconnect(aErrorStr);
}

View File

@ -21,7 +21,6 @@ class nsIVolumeMountLock;
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothReplyRunnable;
class BluetoothSocket;
class ObexHeaderSet;
@ -218,7 +217,6 @@ private:
nsCOMPtr<nsIOutputStream> mOutputStream;
nsCOMPtr<nsIInputStream> mInputStream;
nsCOMPtr<nsIVolumeMountLock> mMountLock;
nsRefPtr<BluetoothReplyRunnable> mRunnable;
nsRefPtr<BluetoothProfileController> mController;
nsRefPtr<DeviceStorageFile> mDsFile;

View File

@ -26,20 +26,38 @@ USING_BLUETOOTH_NAMESPACE
} while(0)
BluetoothProfileController::BluetoothProfileController(
bool aConnect,
const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable,
BluetoothProfileControllerCallback aCallback)
: mCallback(aCallback)
BluetoothProfileControllerCallback aCallback,
uint16_t aServiceUuid,
uint32_t aCod)
: mConnect(aConnect)
, mDeviceAddress(aDeviceAddress)
, mRunnable(aRunnable)
, mCallback(aCallback)
, mSuccess(false)
, mProfilesIndex(-1)
{
MOZ_ASSERT(!aDeviceAddress.IsEmpty());
MOZ_ASSERT(aRunnable);
MOZ_ASSERT(aCallback);
mProfilesIndex = -1;
mProfiles.Clear();
/**
* If the service uuid is not specified, either connect multiple profiles
* based on Cod, or disconnect all connected profiles.
*/
if (!aServiceUuid) {
mTarget.cod = aCod;
SetupProfiles(false);
} else {
BluetoothServiceClass serviceClass =
BluetoothUuidHelper::GetBluetoothServiceClass(aServiceUuid);
mTarget.service = serviceClass;
SetupProfiles(true);
}
}
BluetoothProfileController::~BluetoothProfileController()
@ -49,7 +67,7 @@ BluetoothProfileController::~BluetoothProfileController()
mCallback = nullptr;
}
bool
void
BluetoothProfileController::AddProfileWithServiceClass(
BluetoothServiceClass aClass)
{
@ -72,13 +90,13 @@ BluetoothProfileController::AddProfileWithServiceClass(
DispatchBluetoothReply(mRunnable, BluetoothValue(),
NS_LITERAL_STRING(ERR_UNKNOWN_PROFILE));
mCallback();
return false;
return;
}
return AddProfile(profile);
AddProfile(profile);
}
bool
void
BluetoothProfileController::AddProfile(BluetoothProfileManagerBase* aProfile,
bool aCheckConnected)
{
@ -86,43 +104,52 @@ BluetoothProfileController::AddProfile(BluetoothProfileManagerBase* aProfile,
DispatchBluetoothReply(mRunnable, BluetoothValue(),
NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
mCallback();
return false;
return;
}
if (aCheckConnected && !aProfile->IsConnected()) {
return false;
BT_WARNING("The profile is not connected.");
return;
}
mProfiles.AppendElement(aProfile);
return true;
}
void
BluetoothProfileController::Connect(BluetoothServiceClass aClass)
BluetoothProfileController::SetupProfiles(bool aAssignServiceClass)
{
MOZ_ASSERT(NS_IsMainThread());
NS_ENSURE_TRUE_VOID(AddProfileWithServiceClass(aClass));
/**
* When a service class is assigned, only its corresponding profile is put
* into array.
*/
if (aAssignServiceClass) {
AddProfileWithServiceClass(mTarget.service);
return;
}
ConnectNext();
}
// For a disconnect request, all connected profiles are put into array.
if (!mConnect) {
AddProfile(BluetoothHidManager::Get(), true);
AddProfile(BluetoothOppManager::Get(), true);
AddProfile(BluetoothA2dpManager::Get(), true);
AddProfile(BluetoothHfpManager::Get(), true);
return;
}
void
BluetoothProfileController::Connect(uint32_t aCod)
{
MOZ_ASSERT(NS_IsMainThread());
// Put multiple profiles into array and connect to all of them sequencely
bool hasAudio = HAS_AUDIO(aCod);
bool hasObjectTransfer = HAS_OBJECT_TRANSFER(aCod);
bool hasRendering = HAS_RENDERING(aCod);
bool isPeripheral = IS_PERIPHERAL(aCod);
/**
* For a connect request, put multiple profiles into array and connect to
* all of them sequencely.
*/
bool hasAudio = HAS_AUDIO(mTarget.cod);
bool hasObjectTransfer = HAS_OBJECT_TRANSFER(mTarget.cod);
bool hasRendering = HAS_RENDERING(mTarget.cod);
bool isPeripheral = IS_PERIPHERAL(mTarget.cod);
NS_ENSURE_TRUE_VOID(hasAudio || hasObjectTransfer ||
hasRendering || isPeripheral);
mCod = aCod;
/**
* Connect to HFP/HSP first. Then, connect A2DP if Rendering bit is set.
* It's almost impossible to send file to a remote device which is an Audio
@ -140,20 +167,40 @@ BluetoothProfileController::Connect(uint32_t aCod)
if (isPeripheral) {
AddProfile(BluetoothHidManager::Get());
}
ConnectNext();
}
void
BluetoothProfileController::ConnectNext()
BluetoothProfileController::Start()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mDeviceAddress.IsEmpty());
MOZ_ASSERT(mProfilesIndex == -1);
++mProfilesIndex;
BT_LOGR_PROFILE(mProfiles[mProfilesIndex], "");
if (mConnect) {
mProfiles[mProfilesIndex]->Connect(mDeviceAddress, this);
} else {
mProfiles[mProfilesIndex]->Disconnect(this);
}
}
void
BluetoothProfileController::Next()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mDeviceAddress.IsEmpty());
MOZ_ASSERT(mProfilesIndex < mProfiles.Length());
if (++mProfilesIndex < mProfiles.Length()) {
MOZ_ASSERT(!mDeviceAddress.IsEmpty());
BT_LOGR_PROFILE(mProfiles[mProfilesIndex], "");
mProfiles[mProfilesIndex]->Connect(mDeviceAddress, this);
if (mConnect) {
mProfiles[mProfilesIndex]->Connect(mDeviceAddress, this);
} else {
mProfiles[mProfilesIndex]->Disconnect(this);
}
return;
}
@ -183,53 +230,7 @@ BluetoothProfileController::OnConnect(const nsAString& aErrorStr)
mSuccess = true;
}
ConnectNext();
}
void
BluetoothProfileController::Disconnect(BluetoothServiceClass aClass)
{
MOZ_ASSERT(NS_IsMainThread());
if (aClass != BluetoothServiceClass::UNKNOWN) {
NS_ENSURE_TRUE_VOID(AddProfileWithServiceClass(aClass));
DisconnectNext();
return;
}
// Put all connected profiles into array and disconnect all of them
AddProfile(BluetoothHidManager::Get(), true);
AddProfile(BluetoothOppManager::Get(), true);
AddProfile(BluetoothA2dpManager::Get(), true);
AddProfile(BluetoothHfpManager::Get(), true);
DisconnectNext();
}
void
BluetoothProfileController::DisconnectNext()
{
MOZ_ASSERT(NS_IsMainThread());
if (++mProfilesIndex < mProfiles.Length()) {
BT_LOGR_PROFILE(mProfiles[mProfilesIndex], "");
mProfiles[mProfilesIndex]->Disconnect(this);
return;
}
MOZ_ASSERT(mRunnable && mCallback);
// The action has been completed, so the dom request is replied and then
// the callback is invoked
if (mSuccess) {
DispatchBluetoothReply(mRunnable, BluetoothValue(true), EmptyString());
} else {
DispatchBluetoothReply(mRunnable, BluetoothValue(),
NS_LITERAL_STRING(ERR_DISCONNECTION_FAILED));
}
mCallback();
Next();
}
void
@ -245,5 +246,5 @@ BluetoothProfileController::OnDisconnect(const nsAString& aErrorStr)
mSuccess = true;
}
DisconnectNext();
Next();
}

View File

@ -53,47 +53,76 @@ typedef void (*BluetoothProfileControllerCallback)();
class BluetoothProfileController : public RefCounted<BluetoothProfileController>
{
public:
BluetoothProfileController(const nsAString& aDeviceAddress,
/**
* @param aConnect: If it's a connect request, the value should be set
* to true. For disconnect request, set it to false.
* @param aDeviceAddress: The address of remote device.
* @param aRunnable: Once the controller has done, the runnable will be
* replied. When all connection/disconnection attemps
* have failed, an error is fired. In other words,
* reply a success if any attemp successes.
* @param aCallback: The callback will be invoked after the runnable is
* replied.
* @param aServiceUuid: Connect/Disconnect to the specified profile. Please
* see enum BluetoothServiceClass for valid value.
* @param aCod: If aServiceUuid is not assigned, i.e. the value is
* 0, the controller connect multiple profiles based on
* aCod or disconnect all connected profiles.
*/
BluetoothProfileController(bool aConnect,
const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable,
BluetoothProfileControllerCallback aCallback);
BluetoothProfileControllerCallback aCallback,
uint16_t aServiceUuid,
uint32_t aCod = 0);
~BluetoothProfileController();
// Connect to a specific service UUID.
void Connect(BluetoothServiceClass aClass);
// Based on the CoD, connect to multiple profiles sequencely.
void Connect(uint32_t aCod);
/**
* The controller starts connecting/disconnecting profiles one by one
* according to the order in array mProfiles.
*/
void Start();
/**
* If aClass is assigned with specific service class, disconnect its
* corresponding profile. Otherwise, disconnect all profiles connected to the
* remote device.
* It is invoked after a profile has tried to establish the connection.
* An error string is returned when it fails.
*/
void Disconnect(BluetoothServiceClass aClass = BluetoothServiceClass::UNKNOWN);
void OnConnect(const nsAString& aErrorStr);
/**
* It is invoked after a profile has tried to drop the connection.
* An error string is returned when it fails.
*/
void OnDisconnect(const nsAString& aErrorStr);
uint32_t GetCod() const
{
return mCod;
}
private:
void ConnectNext();
void DisconnectNext();
bool AddProfile(BluetoothProfileManagerBase* aProfile,
bool aCheckConnected = false);
bool AddProfileWithServiceClass(BluetoothServiceClass aClass);
// Setup data member mProfiles
void SetupProfiles(bool aAssignServiceClass);
// Add profiles into array with/without checking connection status
void AddProfile(BluetoothProfileManagerBase* aProfile,
bool aCheckConnected = false);
// Add specified profile into array
void AddProfileWithServiceClass(BluetoothServiceClass aClass);
// Connect/Disconnect next profile in the array
void Next();
const bool mConnect;
nsString mDeviceAddress;
nsRefPtr<BluetoothReplyRunnable> mRunnable;
BluetoothProfileControllerCallback mCallback;
bool mSuccess;
int8_t mProfilesIndex;
nsTArray<BluetoothProfileManagerBase*> mProfiles;
BluetoothProfileControllerCallback mCallback;
uint32_t mCod;
nsString mDeviceAddress;
nsRefPtr<BluetoothReplyRunnable> mRunnable;
bool mSuccess;
// Either CoD or BluetoothServiceClass is assigned.
union {
uint32_t cod;
BluetoothServiceClass service;
} mTarget;
};
END_BLUETOOTH_NAMESPACE

View File

@ -17,6 +17,10 @@
*/
#include "BluetoothServiceBluedroid.h"
#include <hardware/bluetooth.h>
#include <hardware/hardware.h>
#include "BluetoothReplyRunnable.h"
#include "BluetoothUtils.h"
#include "BluetoothUuid.h"
@ -27,22 +31,160 @@ using namespace mozilla;
using namespace mozilla::ipc;
USING_BLUETOOTH_NAMESPACE
/**
* Classes only used in this file
*/
class DistributeBluetoothSignalTask : public nsRunnable {
public:
DistributeBluetoothSignalTask(const BluetoothSignal& aSignal) :
mSignal(aSignal)
{
}
NS_IMETHOD
Run()
{
MOZ_ASSERT(NS_IsMainThread());
BluetoothService* bs = BluetoothService::Get();
bs->DistributeSignal(mSignal);
return NS_OK;
}
private:
BluetoothSignal mSignal;
};
/**
* Static variables
*/
static bluetooth_device_t* sBtDevice;
static const bt_interface_t* sBtInterface;
static bool sIsBtEnabled = false;
/**
* Static callback functions
*/
static void
AdapterStateChangeCallback(bt_state_t aStatus)
{
MOZ_ASSERT(!NS_IsMainThread());
BT_LOGD("Enter: %s, BT_STATE:%d", __FUNCTION__, aStatus);
nsAutoString signalName;
if (aStatus == BT_STATE_ON) {
sIsBtEnabled = true;
signalName = NS_LITERAL_STRING("AdapterAdded");
} else {
sIsBtEnabled = false;
signalName = NS_LITERAL_STRING("Disabled");
}
BluetoothSignal signal(signalName, NS_LITERAL_STRING(KEY_MANAGER), BluetoothValue(true));
nsRefPtr<DistributeBluetoothSignalTask>
t = new DistributeBluetoothSignalTask(signal);
if (NS_FAILED(NS_DispatchToMainThread(t))) {
NS_WARNING("Failed to dispatch to main thread!");
}
}
bt_callbacks_t sBluetoothCallbacks = {
sizeof(sBluetoothCallbacks),
AdapterStateChangeCallback
};
/**
* Static functions
*/
static bool
EnsureBluetoothHalLoad()
{
hw_module_t* module;
hw_device_t* device;
int err = hw_get_module(BT_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
if (err != 0) {
BT_LOGR("Error: %s ", strerror(err));
return false;
}
module->methods->open(module, BT_HARDWARE_MODULE_ID, &device);
sBtDevice = (bluetooth_device_t *)device;
sBtInterface = sBtDevice->get_bluetooth_interface();
BT_LOGD("Bluetooth HAL loaded");
return true;
}
static nsresult
StartStopGonkBluetooth(bool aShouldEnable)
{
MOZ_ASSERT(!NS_IsMainThread());
static bool sIsBtInterfaceInitialized = false;
if (!EnsureBluetoothHalLoad()) {
BT_LOGR("Failed to load bluedroid library.\n");
return NS_ERROR_FAILURE;
}
if (sIsBtEnabled == aShouldEnable)
return NS_OK;
if (sBtInterface && !sIsBtInterfaceInitialized) {
int ret = sBtInterface->init(&sBluetoothCallbacks);
if (ret != BT_STATUS_SUCCESS) {
BT_LOGR("Error while setting the callbacks %s", __FUNCTION__);
sBtInterface = nullptr;
return NS_ERROR_FAILURE;
}
sIsBtInterfaceInitialized = true;
}
int ret = aShouldEnable ? sBtInterface->enable() : sBtInterface->disable();
return (ret == BT_STATUS_SUCCESS) ? NS_OK : NS_ERROR_FAILURE;
}
/**
* Member functions
*/
nsresult
BluetoothServiceBluedroid::StartInternal()
{
return NS_OK;
MOZ_ASSERT(!NS_IsMainThread());
nsresult ret = StartStopGonkBluetooth(true);
if (NS_FAILED(ret)) {
BT_LOGR("Error: %s", __FUNCTION__);
}
return ret;
}
nsresult
BluetoothServiceBluedroid::StopInternal()
{
return NS_OK;
MOZ_ASSERT(!NS_IsMainThread());
nsresult ret = StartStopGonkBluetooth(false);
if (NS_FAILED(ret)) {
BT_LOGR("Error: %s", __FUNCTION__);
}
return ret;
}
bool
BluetoothServiceBluedroid::IsEnabledInternal()
{
return true;
MOZ_ASSERT(!NS_IsMainThread());
if (!EnsureBluetoothHalLoad()) {
NS_ERROR("Failed to load bluedroid library.\n");
return false;
}
return sIsBtEnabled;
}
nsresult

View File

@ -1,4 +1,4 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*-
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,

View File

@ -177,7 +177,7 @@ static nsString sAdapterPath;
static Atomic<int32_t> sIsPairing(0);
static int sConnectedDeviceCount = 0;
static StaticAutoPtr<Monitor> sStopBluetoothMonitor;
StaticRefPtr<BluetoothProfileController> sController;
static nsTArray<nsRefPtr<BluetoothProfileController> > sControllerArray;
typedef void (*UnpackFunc)(DBusMessage*, DBusError*, BluetoothValue&, nsAString&);
typedef bool (*FilterFunc)(const BluetoothValue&);
@ -1752,6 +1752,7 @@ BluetoothDBusService::StopInternal()
sConnectedDeviceCount = 0;
sAuthorizedServiceClass.Clear();
sControllerArray.Clear();
StopDBus();
return NS_OK;
@ -2559,9 +2560,38 @@ BluetoothDBusService::SetPairingConfirmationInternal(
}
static void
DestroyBluetoothProfileController()
NextBluetoothProfileController()
{
sController = nullptr;
sControllerArray[0] = nullptr;
sControllerArray.RemoveElementAt(0);
if (!sControllerArray.IsEmpty()) {
sControllerArray[0]->Start();
}
}
static void
ConnectDisconnect(bool aConnect, const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable,
uint16_t aServiceUuid, uint32_t aCod = 0)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aRunnable);
BluetoothProfileController* controller =
new BluetoothProfileController(aConnect, aDeviceAddress, aRunnable,
NextBluetoothProfileController,
aServiceUuid, aCod);
sControllerArray.AppendElement(controller);
/**
* If the request is the first element of the quene, start from here. Note
* that other request is pushed into the quene and is popped out after the
* first one is completed. See NextBluetoothProfileController() for details.
*/
if (sControllerArray.Length() == 1) {
sControllerArray[0]->Start();
}
}
void
@ -2570,26 +2600,7 @@ BluetoothDBusService::Connect(const nsAString& aDeviceAddress,
uint16_t aServiceUuid,
BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aRunnable);
BluetoothServiceClass serviceClass =
BluetoothUuidHelper::GetBluetoothServiceClass(aServiceUuid);
if (sController) {
DispatchBluetoothReply(aRunnable, BluetoothValue(),
NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
return;
}
sController =
new BluetoothProfileController(aDeviceAddress, aRunnable,
DestroyBluetoothProfileController);
if (aServiceUuid) {
sController->Connect(serviceClass);
} else {
sController->Connect(aCod);
}
ConnectDisconnect(true, aDeviceAddress, aRunnable, aServiceUuid, aCod);
}
void
@ -2597,26 +2608,7 @@ BluetoothDBusService::Disconnect(const nsAString& aDeviceAddress,
uint16_t aServiceUuid,
BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aRunnable);
BluetoothServiceClass serviceClass =
BluetoothUuidHelper::GetBluetoothServiceClass(aServiceUuid);
if (sController) {
DispatchBluetoothReply(aRunnable, BluetoothValue(),
NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
return;
}
sController =
new BluetoothProfileController(aDeviceAddress, aRunnable,
DestroyBluetoothProfileController);
if (aServiceUuid) {
sController->Disconnect(serviceClass);
} else {
sController->Disconnect();
}
ConnectDisconnect(false, aDeviceAddress, aRunnable, aServiceUuid);
}
bool

View File

@ -1763,12 +1763,13 @@ RadioInterface.prototype = {
});
},
// The following attributes/functions are used for acquiring the CPU wake
// lock when the RIL handles the received SMS. Note that we need a timer to
// bound the lock's life cycle to avoid exhausting the battery.
// The following attributes/functions are used for acquiring/releasing the
// CPU wake lock when the RIL handles the received SMS. Note that we need
// a timer to bound the lock's life cycle to avoid exhausting the battery.
_smsHandledWakeLock: null,
_smsHandledWakeLockTimer: null,
_cancelSmsHandledWakeLockTimer: function _cancelSmsHandledWakeLockTimer() {
_releaseSmsHandledWakeLock: function _releaseSmsHandledWakeLock() {
if (DEBUG) this.debug("Releasing the CPU wake lock for handling SMS.");
if (this._smsHandledWakeLockTimer) {
this._smsHandledWakeLockTimer.cancel();
@ -1796,7 +1797,7 @@ RadioInterface.prototype = {
}
if (DEBUG) this.debug("Setting the timer for releasing the CPU wake lock.");
this._smsHandledWakeLockTimer
.initWithCallback(this._cancelSmsHandledWakeLockTimer.bind(this),
.initWithCallback(this._releaseSmsHandledWakeLock.bind(this),
SMS_HANDLED_WAKELOCK_TIMEOUT,
Ci.nsITimer.TYPE_ONE_SHOT);
@ -2174,8 +2175,8 @@ RadioInterface.prototype = {
}
break;
case NS_XPCOM_SHUTDOWN_OBSERVER_ID:
// Cancel the timer of the CPU wake lock for handling the received SMS.
this._cancelSmsHandledWakeLockTimer();
// Release the CPU wake lock for handling the received SMS.
this._releaseSmsHandledWakeLock();
// Shutdown all RIL network interfaces
for each (let apnSetting in this.apnSettings.byAPN) {

View File

@ -107,9 +107,30 @@ TelephonyProvider.prototype = {
Ci.nsIGonkTelephonyProvider,
Ci.nsIObserver]),
// The following attributes/functions are used for acquiring/releasing the
// CPU wake lock when the RIL handles the incoming call. Note that we need
// a timer to bound the lock's life cycle to avoid exhausting the battery.
_callRingWakeLock: null,
_callRingWakeLockTimer: null,
_cancelCallRingWakeLockTimer: function _cancelCallRingWakeLockTimer() {
_acquireCallRingWakeLock: function _acquireCallRingWakeLock() {
if (!this._callRingWakeLock) {
if (DEBUG) debug("Acquiring a CPU wake lock for handling incoming call.");
this._callRingWakeLock = gPowerManagerService.newWakeLock("cpu");
}
if (!this._callRingWakeLockTimer) {
if (DEBUG) debug("Creating a timer for releasing the CPU wake lock.");
this._callRingWakeLockTimer =
Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
}
if (DEBUG) debug("Setting the timer for releasing the CPU wake lock.");
this._callRingWakeLockTimer
.initWithCallback(this._releaseCallRingWakeLock.bind(this),
CALL_WAKELOCK_TIMEOUT, Ci.nsITimer.TYPE_ONE_SHOT);
},
_releaseCallRingWakeLock: function _releaseCallRingWakeLock() {
if (DEBUG) debug("Releasing the CPU wake lock for handling incoming call.");
if (this._callRingWakeLockTimer) {
this._callRingWakeLockTimer.cancel();
}
@ -465,16 +486,9 @@ TelephonyProvider.prototype = {
* to start bringing up the Phone app already.
*/
notifyCallRing: function notifyCallRing() {
if (!this._callRingWakeLock) {
this._callRingWakeLock = gPowerManagerService.newWakeLock("cpu");
}
if (!this._callRingWakeLockTimer) {
this._callRingWakeLockTimer =
Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
}
this._callRingWakeLockTimer
.initWithCallback(this._cancelCallRingWakeLockTimer.bind(this),
CALL_WAKELOCK_TIMEOUT, Ci.nsITimer.TYPE_ONE_SHOT);
// We need to acquire a CPU wake lock to avoid the system falling into
// the sleep mode when the RIL handles the incoming call.
this._acquireCallRingWakeLock();
gSystemMessenger.broadcastMessage("telephony-new-call", {});
},
@ -503,6 +517,10 @@ TelephonyProvider.prototype = {
},
notifyCdmaCallWaiting: function notifyCdmaCallWaiting(aNumber) {
// We need to acquire a CPU wake lock to avoid the system falling into
// the sleep mode when the RIL handles the incoming call.
this._acquireCallRingWakeLock();
this._notifyAllListeners("notifyCdmaCallWaiting", [aNumber]);
},
@ -536,8 +554,8 @@ TelephonyProvider.prototype = {
break;
case NS_XPCOM_SHUTDOWN_OBSERVER_ID:
// Cancel the timer for the call-ring wake lock.
this._cancelCallRingWakeLockTimer();
// Release the CPU wake lock for handling the incoming call.
this._releaseCallRingWakeLock();
Services.obs.removeObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
break;