mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Merge B2g-inbound to Mozilla-Central
This commit is contained in:
commit
d5ef9329d1
@ -1,4 +1,4 @@
|
||||
{
|
||||
"revision": "c09f78f6bdd9c8c3cea3943f8a6fe96c760d7de7",
|
||||
"revision": "d2632e2be46de3f4fa9106ada595e33e317aaaa2",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -181,7 +181,6 @@ private:
|
||||
|
||||
nsTArray<Call> mCurrentCallArray;
|
||||
nsAutoPtr<BluetoothRilListener> mListener;
|
||||
nsRefPtr<BluetoothReplyRunnable> mRunnable;
|
||||
nsRefPtr<BluetoothProfileController> mController;
|
||||
nsRefPtr<BluetoothReplyRunnable> mScoRunnable;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user