Bug 1192693 - [02] Remove bluetooth1 folder and rename webidl files, r=joliu, r=mrbkap

--HG--
rename : dom/webidl/BluetoothAdapter2.webidl => dom/webidl/BluetoothAdapter.webidl
rename : dom/webidl/BluetoothDevice2.webidl => dom/webidl/BluetoothDevice.webidl
rename : dom/webidl/BluetoothManager2.webidl => dom/webidl/BluetoothManager.webidl
This commit is contained in:
Ben Tian 2015-08-17 15:30:34 +08:00
parent 115d4a7516
commit a0a229d80d
51 changed files with 80 additions and 7392 deletions

View File

@ -405,6 +405,7 @@ FAIL_ON_WARNINGS = True
LOCAL_INCLUDES += [
'../battery',
'../bluetooth',
'../bluetooth/bluetooth2',
'../events',
'../media',
'../network',
@ -437,15 +438,6 @@ LOCAL_INCLUDES += [
'/xpcom/ds',
]
if CONFIG['MOZ_B2G_BT_API_V1']:
LOCAL_INCLUDES += [
'../bluetooth/bluetooth1',
]
else:
LOCAL_INCLUDES += [
'../bluetooth/bluetooth2',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
LOCAL_INCLUDES += [
'../fmradio',

View File

@ -740,7 +740,6 @@ GK_ATOM(ondischargingtimechange, "ondischargingtimechange")
GK_ATOM(ondisconnect, "ondisconnect")
GK_ATOM(ondisconnected, "ondisconnected")
GK_ATOM(ondisconnecting, "ondisconnecting")
GK_ATOM(ondiscoverystatechanged, "ondiscoverystatechanged")
GK_ATOM(ondisplaypasskeyreq, "ondisplaypasskeyreq")
GK_ATOM(ondownloading, "ondownloading")
GK_ATOM(onDOMActivate, "onDOMActivate")
@ -840,7 +839,6 @@ GK_ATOM(onoverflowchanged, "onoverflowchanged")
GK_ATOM(onpagehide, "onpagehide")
GK_ATOM(onpageshow, "onpageshow")
GK_ATOM(onpaint, "onpaint")
GK_ATOM(onpairedstatuschanged, "onpairedstatuschanged")
GK_ATOM(onpairingaborted, "onpairingaborted")
GK_ATOM(onpairingconfirmationreq, "onpairingconfirmationreq")
GK_ATOM(onpairingconsentreq, "onpairingconsentreq")

View File

@ -45,6 +45,7 @@ LOCAL_INCLUDES += [
'/dom/base',
'/dom/battery',
'/dom/bluetooth',
'/dom/bluetooth/bluetooth2',
'/dom/camera',
'/dom/canvas',
'/dom/geolocation',
@ -109,15 +110,6 @@ if CONFIG['MOZ_AUDIO_CHANNEL_MANAGER']:
'/dom/system/gonk',
]
if CONFIG['MOZ_B2G_BT_API_V1']:
LOCAL_INCLUDES += [
'/dom/bluetooth/bluetooth1',
]
else:
LOCAL_INCLUDES += [
'/dom/bluetooth/bluetooth2',
]
FINAL_LIBRARY = 'xul'
SPHINX_TREES['webidl'] = 'docs'

File diff suppressed because it is too large Load Diff

View File

@ -1,203 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_bluetooth_bluetoothadapter_h__
#define mozilla_dom_bluetooth_bluetoothadapter_h__
#include "mozilla/Attributes.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "BluetoothCommon.h"
#include "BluetoothPropertyContainer.h"
#include "nsCOMPtr.h"
namespace mozilla {
namespace dom {
class Blob;
class DOMRequest;
struct MediaMetaData;
struct MediaPlayStatus;
}
}
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothDevice;
class BluetoothSignal;
class BluetoothNamedValue;
class BluetoothValue;
class BluetoothAdapter : public DOMEventTargetHelper
, public BluetoothSignalObserver
, public BluetoothPropertyContainer
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(BluetoothAdapter,
DOMEventTargetHelper)
static already_AddRefed<BluetoothAdapter>
Create(nsPIDOMWindow* aOwner, const BluetoothValue& aValue);
void Notify(const BluetoothSignal& aParam);
void Unroot();
virtual void SetPropertyByValue(const BluetoothNamedValue& aValue) override;
virtual void DisconnectFromOwner() override;
void GetAddress(nsString& aAddress) const
{
aAddress = mAddress;
}
uint32_t
Class() const
{
return mClass;
}
void
GetName(nsString& aName) const
{
aName = mName;
}
bool
Discovering() const
{
return mDiscovering;
}
bool
Discoverable() const
{
return mDiscoverable;
}
uint32_t
DiscoverableTimeout() const
{
return mDiscoverableTimeout;
}
void GetDevices(JSContext* aContext, JS::MutableHandle<JS::Value> aDevices,
ErrorResult& aRv);
void GetUuids(JSContext* aContext, JS::MutableHandle<JS::Value> aUuids,
ErrorResult& aRv);
already_AddRefed<mozilla::dom::DOMRequest>
SetName(const nsAString& aName, ErrorResult& aRv);
already_AddRefed<DOMRequest>
SetDiscoverable(bool aDiscoverable, ErrorResult& aRv);
already_AddRefed<DOMRequest>
SetDiscoverableTimeout(uint32_t aTimeout, ErrorResult& aRv);
already_AddRefed<DOMRequest> StartDiscovery(ErrorResult& aRv);
already_AddRefed<DOMRequest> StopDiscovery(ErrorResult& aRv);
already_AddRefed<DOMRequest>
Pair(const nsAString& aDeviceAddress, ErrorResult& aRv);
already_AddRefed<DOMRequest>
Unpair(const nsAString& aDeviceAddress, ErrorResult& aRv);
already_AddRefed<DOMRequest>
GetPairedDevices(ErrorResult& aRv);
already_AddRefed<DOMRequest>
SetPinCode(const nsAString& aDeviceAddress, const nsAString& aPinCode,
ErrorResult& aRv);
already_AddRefed<DOMRequest>
SetPasskey(const nsAString& aDeviceAddress, uint32_t aPasskey,
ErrorResult& aRv);
already_AddRefed<DOMRequest>
SetPairingConfirmation(const nsAString& aDeviceAddress, bool aConfirmation,
ErrorResult& aRv);
already_AddRefed<DOMRequest>
SetAuthorization(const nsAString& aDeviceAddress, bool aAllow,
ErrorResult& aRv);
already_AddRefed<DOMRequest>
Connect(BluetoothDevice& aDevice,
const Optional<uint16_t>& aServiceUuid, ErrorResult& aRv);
already_AddRefed<DOMRequest>
Disconnect(BluetoothDevice& aDevice,
const Optional<uint16_t>& aServiceUuid,
ErrorResult& aRv);
already_AddRefed<DOMRequest>
IsConnected(const uint16_t aServiceUuid,
ErrorResult& aRv);
already_AddRefed<DOMRequest>
GetConnectedDevices(uint16_t aServiceUuid, ErrorResult& aRv);
already_AddRefed<DOMRequest>
SendFile(const nsAString& aDeviceAddress, Blob& aBlob,
ErrorResult& aRv);
already_AddRefed<DOMRequest>
StopSendingFile(const nsAString& aDeviceAddress, ErrorResult& aRv);
already_AddRefed<DOMRequest>
ConfirmReceivingFile(const nsAString& aDeviceAddress, bool aConfirmation,
ErrorResult& aRv);
already_AddRefed<DOMRequest> ConnectSco(ErrorResult& aRv);
already_AddRefed<DOMRequest> DisconnectSco(ErrorResult& aRv);
already_AddRefed<DOMRequest> IsScoConnected(ErrorResult& aRv);
already_AddRefed<DOMRequest> AnswerWaitingCall(ErrorResult& aRv);
already_AddRefed<DOMRequest> IgnoreWaitingCall(ErrorResult& aRv);
already_AddRefed<DOMRequest> ToggleCalls(ErrorResult& aRv);
already_AddRefed<DOMRequest>
SendMediaMetaData(const MediaMetaData& aMediaMetaData, ErrorResult& aRv);
already_AddRefed<DOMRequest>
SendMediaPlayStatus(const MediaPlayStatus& aMediaPlayStatus, ErrorResult& aRv);
IMPL_EVENT_HANDLER(devicefound);
IMPL_EVENT_HANDLER(discoverystatechanged);
IMPL_EVENT_HANDLER(a2dpstatuschanged);
IMPL_EVENT_HANDLER(hfpstatuschanged);
IMPL_EVENT_HANDLER(pairedstatuschanged);
IMPL_EVENT_HANDLER(requestmediaplaystatus);
IMPL_EVENT_HANDLER(scostatuschanged);
nsPIDOMWindow* GetParentObject() const
{
return GetOwner();
}
virtual JSObject*
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
private:
BluetoothAdapter(nsPIDOMWindow* aOwner, const BluetoothValue& aValue);
~BluetoothAdapter();
void Root();
already_AddRefed<mozilla::dom::DOMRequest>
StartStopDiscovery(bool aStart, ErrorResult& aRv);
already_AddRefed<mozilla::dom::DOMRequest>
PairUnpair(bool aPair, const nsAString& aDeviceAddress, ErrorResult& aRv);
JS::Heap<JSObject*> mJsUuids;
JS::Heap<JSObject*> mJsDeviceAddresses;
nsString mAddress;
nsString mName;
bool mDiscoverable;
bool mDiscovering;
bool mPairable;
bool mPowered;
uint32_t mPairableTimeout;
uint32_t mDiscoverableTimeout;
uint32_t mClass;
nsTArray<nsString> mDeviceAddresses;
nsTArray<nsString> mUuids;
bool mIsRooted;
};
END_BLUETOOTH_NAMESPACE
#endif

View File

@ -1,242 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "base/basictypes.h"
#include "BluetoothDevice.h"
#include "BluetoothReplyRunnable.h"
#include "BluetoothService.h"
#include "BluetoothUtils.h"
#include "nsTArrayHelpers.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/dom/BluetoothDeviceBinding.h"
#include "mozilla/dom/ScriptSettings.h"
USING_BLUETOOTH_NAMESPACE
NS_IMPL_CYCLE_COLLECTION_CLASS(BluetoothDevice)
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(BluetoothDevice,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mJsUuids)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mJsServices)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BluetoothDevice,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BluetoothDevice,
DOMEventTargetHelper)
tmp->Unroot();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BluetoothDevice)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(BluetoothDevice, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(BluetoothDevice, DOMEventTargetHelper)
BluetoothDevice::BluetoothDevice(nsPIDOMWindow* aWindow,
const nsAString& aAdapterPath,
const BluetoothValue& aValue)
: DOMEventTargetHelper(aWindow)
, BluetoothPropertyContainer(BluetoothObjectType::TYPE_DEVICE)
, mJsUuids(nullptr)
, mJsServices(nullptr)
, mAdapterPath(aAdapterPath)
, mConnected(false)
, mPaired(false)
, mIsRooted(false)
{
MOZ_ASSERT(aWindow);
const InfallibleTArray<BluetoothNamedValue>& values =
aValue.get_ArrayOfBluetoothNamedValue();
for (uint32_t i = 0; i < values.Length(); ++i) {
SetPropertyByValue(values[i]);
}
BluetoothService* bs = BluetoothService::Get();
NS_ENSURE_TRUE_VOID(bs);
bs->RegisterBluetoothSignalHandler(mAddress, this);
}
BluetoothDevice::~BluetoothDevice()
{
BluetoothService* bs = BluetoothService::Get();
// bs can be null on shutdown, where destruction might happen.
NS_ENSURE_TRUE_VOID(bs);
bs->UnregisterBluetoothSignalHandler(mAddress, this);
Unroot();
}
void
BluetoothDevice::DisconnectFromOwner()
{
DOMEventTargetHelper::DisconnectFromOwner();
BluetoothService* bs = BluetoothService::Get();
NS_ENSURE_TRUE_VOID(bs);
bs->UnregisterBluetoothSignalHandler(mAddress, this);
}
void
BluetoothDevice::Root()
{
if (!mIsRooted) {
mozilla::HoldJSObjects(this);
mIsRooted = true;
}
}
void
BluetoothDevice::Unroot()
{
if (mIsRooted) {
mJsUuids = nullptr;
mJsServices = nullptr;
mozilla::DropJSObjects(this);
mIsRooted = false;
}
}
void
BluetoothDevice::SetPropertyByValue(const BluetoothNamedValue& aValue)
{
const nsString& name = aValue.name();
const BluetoothValue& value = aValue.value();
if (name.EqualsLiteral("Name")) {
mName = value.get_nsString();
} else if (name.EqualsLiteral("Path")) {
MOZ_ASSERT(value.get_nsString().Length() > 0);
mPath = value.get_nsString();
} else if (name.EqualsLiteral("Address")) {
mAddress = value.get_nsString();
} else if (name.EqualsLiteral("Class")) {
mClass = value.get_uint32_t();
} else if (name.EqualsLiteral("Icon")) {
mIcon = value.get_nsString();
} else if (name.EqualsLiteral("Connected")) {
mConnected = value.get_bool();
} else if (name.EqualsLiteral("Paired")) {
mPaired = value.get_bool();
} else if (name.EqualsLiteral("UUIDs")) {
mUuids = value.get_ArrayOfnsString();
AutoJSAPI jsapi;
if (!jsapi.Init(GetOwner())) {
BT_WARNING("Failed to initialise AutoJSAPI!");
return;
}
JSContext* cx = jsapi.cx();
JS::Rooted<JSObject*> uuids(cx);
if (NS_FAILED(nsTArrayToJSArray(cx, mUuids, &uuids))) {
BT_WARNING("Cannot set JS UUIDs object!");
return;
}
mJsUuids = uuids;
Root();
} else if (name.EqualsLiteral("Services")) {
mServices = value.get_ArrayOfnsString();
AutoJSAPI jsapi;
if (!jsapi.Init(GetOwner())) {
BT_WARNING("Failed to initialise AutoJSAPI!");
return;
}
JSContext* cx = jsapi.cx();
JS::Rooted<JSObject*> services(cx);
if (NS_FAILED(nsTArrayToJSArray(cx, mServices, &services))) {
BT_WARNING("Cannot set JS Services object!");
return;
}
mJsServices = services;
Root();
} else {
nsCString warningMsg;
warningMsg.AssignLiteral("Not handling device property: ");
warningMsg.Append(NS_ConvertUTF16toUTF8(name));
BT_WARNING(warningMsg.get());
}
}
// static
already_AddRefed<BluetoothDevice>
BluetoothDevice::Create(nsPIDOMWindow* aWindow,
const nsAString& aAdapterPath,
const BluetoothValue& aValue)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aWindow);
nsRefPtr<BluetoothDevice> device =
new BluetoothDevice(aWindow, aAdapterPath, aValue);
return device.forget();
}
void
BluetoothDevice::Notify(const BluetoothSignal& aData)
{
BT_LOGD("[D] %s: %s", __FUNCTION__, NS_ConvertUTF16toUTF8(aData.name()).get());
BluetoothValue v = aData.value();
if (aData.name().EqualsLiteral("PropertyChanged")) {
MOZ_ASSERT(v.type() == BluetoothValue::TArrayOfBluetoothNamedValue);
const InfallibleTArray<BluetoothNamedValue>& arr =
v.get_ArrayOfBluetoothNamedValue();
for (uint32_t i = 0, propCount = arr.Length(); i < propCount; ++i) {
SetPropertyByValue(arr[i]);
}
} else {
#ifdef DEBUG
nsCString warningMsg;
warningMsg.AssignLiteral("Not handling device signal: ");
warningMsg.Append(NS_ConvertUTF16toUTF8(aData.name()));
BT_WARNING(warningMsg.get());
#endif
}
}
void
BluetoothDevice::GetUuids(JSContext* aContext,
JS::MutableHandle<JS::Value> aUuids,
ErrorResult& aRv)
{
if (!mJsUuids) {
BT_WARNING("UUIDs not yet set!");
aRv.Throw(NS_ERROR_FAILURE);
return;
}
JS::ExposeObjectToActiveJS(mJsUuids);
aUuids.setObject(*mJsUuids);
}
void
BluetoothDevice::GetServices(JSContext* aCx,
JS::MutableHandle<JS::Value> aServices,
ErrorResult& aRv)
{
if (!mJsServices) {
BT_WARNING("Services not yet set!");
aRv.Throw(NS_ERROR_FAILURE);
return;
}
JS::ExposeObjectToActiveJS(mJsServices);
aServices.setObject(*mJsServices);
}
JSObject*
BluetoothDevice::WrapObject(JSContext* aContext, JS::Handle<JSObject*> aGivenProto)
{
return BluetoothDeviceBinding::Wrap(aContext, this, aGivenProto);
}

View File

@ -1,117 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_bluetooth_bluetoothdevice_h__
#define mozilla_dom_bluetooth_bluetoothdevice_h__
#include "mozilla/Attributes.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "BluetoothCommon.h"
#include "BluetoothPropertyContainer.h"
#include "nsString.h"
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothNamedValue;
class BluetoothValue;
class BluetoothSignal;
class BluetoothDevice : public DOMEventTargetHelper
, public BluetoothSignalObserver
, public BluetoothPropertyContainer
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(BluetoothDevice,
DOMEventTargetHelper)
static already_AddRefed<BluetoothDevice>
Create(nsPIDOMWindow* aOwner, const nsAString& aAdapterPath,
const BluetoothValue& aValue);
void Notify(const BluetoothSignal& aParam);
void GetAddress(nsString& aAddress) const
{
aAddress = mAddress;
}
void GetName(nsString& aName) const
{
aName = mName;
}
void GetIcon(nsString& aIcon) const
{
aIcon = mIcon;
}
uint32_t Class() const
{
return mClass;
}
bool Paired() const
{
return mPaired;
}
bool Connected() const
{
return mConnected;
}
void GetUuids(JSContext* aContext, JS::MutableHandle<JS::Value> aUuids,
ErrorResult& aRv);
void GetServices(JSContext* aContext, JS::MutableHandle<JS::Value> aServices,
ErrorResult& aRv);
nsISupports*
ToISupports()
{
return static_cast<EventTarget*>(this);
}
void SetPropertyByValue(const BluetoothNamedValue& aValue) override;
void Unroot();
nsPIDOMWindow* GetParentObject() const
{
return GetOwner();
}
virtual JSObject*
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
virtual void DisconnectFromOwner() override;
private:
BluetoothDevice(nsPIDOMWindow* aOwner, const nsAString& aAdapterPath,
const BluetoothValue& aValue);
~BluetoothDevice();
void Root();
JS::Heap<JSObject*> mJsUuids;
JS::Heap<JSObject*> mJsServices;
nsString mAdapterPath;
nsString mAddress;
nsString mName;
nsString mIcon;
uint32_t mClass;
bool mConnected;
bool mPaired;
bool mIsRooted;
nsTArray<nsString> mUuids;
nsTArray<nsString> mServices;
};
END_BLUETOOTH_NAMESPACE
#endif

View File

@ -1,216 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "base/basictypes.h"
#include "BluetoothManager.h"
#include "BluetoothCommon.h"
#include "BluetoothAdapter.h"
#include "BluetoothService.h"
#include "BluetoothReplyRunnable.h"
#include "DOMRequest.h"
#include "nsContentUtils.h"
#include "nsDOMClassInfo.h"
#include "nsIPermissionManager.h"
#include "nsThreadUtils.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/dom/BluetoothManagerBinding.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/Services.h"
using namespace mozilla;
USING_BLUETOOTH_NAMESPACE
// QueryInterface implementation for BluetoothManager
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BluetoothManager)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(BluetoothManager, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(BluetoothManager, DOMEventTargetHelper)
class GetAdapterTask : public BluetoothReplyRunnable
{
public:
GetAdapterTask(BluetoothManager* aManager,
nsIDOMDOMRequest* aReq) :
BluetoothReplyRunnable(aReq),
mManagerPtr(aManager)
{
}
bool
ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue)
{
aValue.setUndefined();
const BluetoothValue& v = mReply->get_BluetoothReplySuccess().value();
if (v.type() != BluetoothValue::TArrayOfBluetoothNamedValue) {
BT_WARNING("Not a BluetoothNamedValue array!");
SetError(NS_LITERAL_STRING("BluetoothReplyTypeError"));
return false;
}
if (!mManagerPtr->GetOwner()) {
BT_WARNING("Bluetooth manager was disconnected from owner window.");
// Stop to create adapter since owner window of Bluetooth manager was
// gone. These is no need to create a DOMEvent target which has no owner
// to reply to.
return false;
}
const InfallibleTArray<BluetoothNamedValue>& values =
v.get_ArrayOfBluetoothNamedValue();
nsRefPtr<BluetoothAdapter> adapter =
BluetoothAdapter::Create(mManagerPtr->GetOwner(), values);
dom::AutoJSAPI jsapi;
if (!jsapi.Init(mManagerPtr->GetOwner())) {
BT_WARNING("Failed to initialise AutoJSAPI!");
SetError(NS_LITERAL_STRING("BluetoothAutoJSAPIInitError"));
return false;
}
JSContext* cx = jsapi.cx();
if (NS_FAILED(nsContentUtils::WrapNative(cx, adapter, aValue))) {
BT_WARNING("Cannot create native object!");
SetError(NS_LITERAL_STRING("BluetoothNativeObjectError"));
return false;
}
return true;
}
void
ReleaseMembers()
{
BluetoothReplyRunnable::ReleaseMembers();
mManagerPtr = nullptr;
}
private:
nsRefPtr<BluetoothManager> mManagerPtr;
};
BluetoothManager::BluetoothManager(nsPIDOMWindow *aWindow)
: DOMEventTargetHelper(aWindow)
, BluetoothPropertyContainer(BluetoothObjectType::TYPE_MANAGER)
{
MOZ_ASSERT(aWindow);
mPath.Assign('/');
BluetoothService* bs = BluetoothService::Get();
NS_ENSURE_TRUE_VOID(bs);
bs->RegisterBluetoothSignalHandler(NS_LITERAL_STRING(KEY_MANAGER), this);
}
BluetoothManager::~BluetoothManager()
{
BluetoothService* bs = BluetoothService::Get();
NS_ENSURE_TRUE_VOID(bs);
bs->UnregisterBluetoothSignalHandler(NS_LITERAL_STRING(KEY_MANAGER), this);
}
void
BluetoothManager::DisconnectFromOwner()
{
DOMEventTargetHelper::DisconnectFromOwner();
BluetoothService* bs = BluetoothService::Get();
NS_ENSURE_TRUE_VOID(bs);
bs->UnregisterBluetoothSignalHandler(NS_LITERAL_STRING(KEY_MANAGER), this);
}
void
BluetoothManager::SetPropertyByValue(const BluetoothNamedValue& aValue)
{
#ifdef DEBUG
const nsString& name = aValue.name();
nsCString warningMsg;
warningMsg.AssignLiteral("Not handling manager property: ");
warningMsg.Append(NS_ConvertUTF16toUTF8(name));
BT_WARNING(warningMsg.get());
#endif
}
bool
BluetoothManager::GetEnabled(ErrorResult& aRv)
{
BluetoothService* bs = BluetoothService::Get();
if (!bs) {
aRv.Throw(NS_ERROR_FAILURE);
return false;
}
return bs->IsEnabled();
}
already_AddRefed<dom::DOMRequest>
BluetoothManager::GetDefaultAdapter(ErrorResult& aRv)
{
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
if (!win) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<DOMRequest> request = new DOMRequest(win);
nsRefPtr<BluetoothReplyRunnable> results =
new GetAdapterTask(this, request);
BluetoothService* bs = BluetoothService::Get();
if (!bs) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsresult rv = bs->GetDefaultAdapterPathInternal(results);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return nullptr;
}
return request.forget();
}
// static
already_AddRefed<BluetoothManager>
BluetoothManager::Create(nsPIDOMWindow* aWindow)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aWindow);
nsRefPtr<BluetoothManager> manager = new BluetoothManager(aWindow);
return manager.forget();
}
void
BluetoothManager::Notify(const BluetoothSignal& aData)
{
BT_LOGD("[M] %s: %s", __FUNCTION__, NS_ConvertUTF16toUTF8(aData.name()).get());
if (aData.name().EqualsLiteral("AdapterAdded")) {
DispatchTrustedEvent(NS_LITERAL_STRING("adapteradded"));
} else if (aData.name().EqualsLiteral("Enabled")) {
DispatchTrustedEvent(NS_LITERAL_STRING("enabled"));
} else if (aData.name().EqualsLiteral("Disabled")) {
DispatchTrustedEvent(NS_LITERAL_STRING("disabled"));
} else {
#ifdef DEBUG
nsCString warningMsg;
warningMsg.AssignLiteral("Not handling manager signal: ");
warningMsg.Append(NS_ConvertUTF16toUTF8(aData.name()));
BT_WARNING(warningMsg.get());
#endif
}
}
JSObject*
BluetoothManager::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return BluetoothManagerBinding::Wrap(aCx, this, aGivenProto);
}

View File

@ -1,66 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_bluetooth_bluetoothmanager_h__
#define mozilla_dom_bluetooth_bluetoothmanager_h__
#include "mozilla/Attributes.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/Observer.h"
#include "BluetoothCommon.h"
#include "BluetoothPropertyContainer.h"
#include "nsISupportsImpl.h"
namespace mozilla {
namespace dom {
class DOMRequest;
}
}
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothNamedValue;
class BluetoothManager : public DOMEventTargetHelper
, public BluetoothSignalObserver
, public BluetoothPropertyContainer
{
public:
NS_DECL_ISUPPORTS_INHERITED
// Never returns null
static already_AddRefed<BluetoothManager>
Create(nsPIDOMWindow* aWindow);
static bool CheckPermission(nsPIDOMWindow* aWindow);
void Notify(const BluetoothSignal& aData);
virtual void SetPropertyByValue(const BluetoothNamedValue& aValue) override;
bool GetEnabled(ErrorResult& aRv);
already_AddRefed<DOMRequest> GetDefaultAdapter(ErrorResult& aRv);
IMPL_EVENT_HANDLER(enabled);
IMPL_EVENT_HANDLER(disabled);
IMPL_EVENT_HANDLER(adapteradded);
nsPIDOMWindow* GetParentObject() const
{
return GetOwner();
}
virtual JSObject*
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
virtual void DisconnectFromOwner() override;
private:
BluetoothManager(nsPIDOMWindow* aWindow);
~BluetoothManager();
};
END_BLUETOOTH_NAMESPACE
#endif

View File

@ -1,350 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BluetoothProfileController.h"
#include "BluetoothA2dpManager.h"
#include "BluetoothHfpManager.h"
#include "BluetoothHidManager.h"
#include "BluetoothReplyRunnable.h"
#include "BluetoothService.h"
#include "BluetoothUtils.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "nsComponentManagerUtils.h"
USING_BLUETOOTH_NAMESPACE
#define BT_LOGR_PROFILE(mgr, msg, ...) \
do { \
nsCString name; \
mgr->GetName(name); \
BT_LOGR("[%s] " msg, name.get(), ##__VA_ARGS__); \
} while(0)
#define CONNECTION_TIMEOUT_MS 15000
class CheckProfileStatusCallback : public nsITimerCallback
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSITIMERCALLBACK
CheckProfileStatusCallback(BluetoothProfileController* aController)
: mController(aController)
{
MOZ_ASSERT(aController);
}
protected:
virtual ~CheckProfileStatusCallback()
{
mController = nullptr;
}
private:
nsRefPtr<BluetoothProfileController> mController;
};
BluetoothProfileController::BluetoothProfileController(
bool aConnect,
const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable,
BluetoothProfileControllerCallback aCallback,
uint16_t aServiceUuid,
uint32_t aCod)
: mConnect(aConnect)
, mDeviceAddress(aDeviceAddress)
, mRunnable(aRunnable)
, mCallback(aCallback)
, mCurrentProfileFinished(false)
, mSuccess(false)
, mProfilesIndex(-1)
{
MOZ_ASSERT(!aDeviceAddress.IsEmpty());
MOZ_ASSERT(aRunnable);
MOZ_ASSERT(aCallback);
mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
MOZ_ASSERT(mTimer);
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()
{
mProfiles.Clear();
mRunnable = nullptr;
mCallback = nullptr;
if (mTimer) {
mTimer->Cancel();
}
}
void
BluetoothProfileController::AddProfileWithServiceClass(
BluetoothServiceClass aClass)
{
BluetoothProfileManagerBase* profile;
switch (aClass) {
case BluetoothServiceClass::HANDSFREE:
case BluetoothServiceClass::HEADSET:
profile = BluetoothHfpManager::Get();
break;
case BluetoothServiceClass::A2DP:
profile = BluetoothA2dpManager::Get();
break;
case BluetoothServiceClass::HID:
profile = BluetoothHidManager::Get();
break;
default:
DispatchReplyError(mRunnable, NS_LITERAL_STRING(ERR_UNKNOWN_PROFILE));
mCallback();
return;
}
AddProfile(profile);
}
void
BluetoothProfileController::AddProfile(BluetoothProfileManagerBase* aProfile,
bool aCheckConnected)
{
if (!aProfile) {
DispatchReplyError(mRunnable,
NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
mCallback();
return;
}
if (aCheckConnected && !aProfile->IsConnected()) {
BT_WARNING("The profile is not connected.");
return;
}
mProfiles.AppendElement(aProfile);
}
void
BluetoothProfileController::SetupProfiles(bool aAssignServiceClass)
{
MOZ_ASSERT(NS_IsMainThread());
/**
* When a service class is assigned, only its corresponding profile is put
* into array.
*/
if (aAssignServiceClass) {
AddProfileWithServiceClass(mTarget.service);
return;
}
// For a disconnect request, all connected profiles are put into array.
if (!mConnect) {
AddProfile(BluetoothHidManager::Get(), true);
AddProfile(BluetoothA2dpManager::Get(), true);
AddProfile(BluetoothHfpManager::Get(), true);
return;
}
/**
* For a connect request, put multiple profiles into array and connect to
* all of them sequencely.
*/
bool hasAudio = HAS_AUDIO(mTarget.cod);
bool hasRendering = HAS_RENDERING(mTarget.cod);
bool isPeripheral = IS_PERIPHERAL(mTarget.cod);
bool isRemoteControl = IS_REMOTE_CONTROL(mTarget.cod);
bool isKeyboard = IS_KEYBOARD(mTarget.cod);
bool isPointingDevice = IS_POINTING_DEVICE(mTarget.cod);
bool isInvalid = IS_INVALID_COD(mTarget.cod);
// The value of CoD is invalid. Since the device didn't declare its class of
// device properly, we assume the device may support all of these profiles.
if (isInvalid) {
AddProfile(BluetoothHfpManager::Get());
AddProfile(BluetoothA2dpManager::Get());
AddProfile(BluetoothHidManager::Get());
return;
}
NS_ENSURE_TRUE_VOID(hasAudio || hasRendering || isPeripheral);
// Audio bit should be set if remote device supports HFP/HSP.
if (hasAudio) {
AddProfile(BluetoothHfpManager::Get());
}
// Rendering bit should be set if remote device supports A2DP.
// A device which supports AVRCP should claim that it's a peripheral and it's
// a remote control.
if (hasRendering || (isPeripheral && isRemoteControl)) {
AddProfile(BluetoothA2dpManager::Get());
}
// A device which supports HID should claim that it's a peripheral and it's
// either a keyboard, a pointing device, or both.
if (isPeripheral && (isKeyboard || isPointingDevice)) {
AddProfile(BluetoothHidManager::Get());
}
}
NS_IMPL_ISUPPORTS(CheckProfileStatusCallback, nsITimerCallback)
NS_IMETHODIMP
CheckProfileStatusCallback::Notify(nsITimer* aTimer)
{
MOZ_ASSERT(mController);
// Continue on the next profile since we haven't got the callback after
// timeout.
mController->GiveupAndContinue();
return NS_OK;
}
void
BluetoothProfileController::StartSession()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mDeviceAddress.IsEmpty());
MOZ_ASSERT(mProfilesIndex == -1);
MOZ_ASSERT(mTimer);
if (!IsBtServiceAvailable()) {
EndSession();
return;
}
if (mProfiles.Length() < 1) {
BT_LOGR("No queued profile.");
EndSession();
return;
}
if (mTimer) {
mTimer->InitWithCallback(new CheckProfileStatusCallback(this),
CONNECTION_TIMEOUT_MS, nsITimer::TYPE_ONE_SHOT);
}
BT_LOGR("%s", mConnect ? "connecting" : "disconnecting");
Next();
}
void
BluetoothProfileController::EndSession()
{
MOZ_ASSERT(mRunnable && mCallback);
BT_LOGR("mSuccess %d", mSuccess);
// Don't have to check profile status and retrigger session after connection
// timeout, since session is end.
if (mTimer) {
mTimer->Cancel();
}
// The action has completed, so the DOM request should be replied then invoke
// the callback.
if (mSuccess) {
DispatchReplySuccess(mRunnable);
} else if (mConnect) {
DispatchReplyError(mRunnable, NS_LITERAL_STRING(ERR_CONNECTION_FAILED));
} else {
DispatchReplyError(mRunnable, NS_LITERAL_STRING(ERR_DISCONNECTION_FAILED));
}
mCallback();
}
void
BluetoothProfileController::Next()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mDeviceAddress.IsEmpty());
MOZ_ASSERT(mProfilesIndex < (int)mProfiles.Length());
MOZ_ASSERT(mTimer);
mCurrentProfileFinished = false;
if (!IsBtServiceAvailable()) {
EndSession();
return;
}
if (++mProfilesIndex >= (int)mProfiles.Length()) {
EndSession();
return;
}
BT_LOGR_PROFILE(mProfiles[mProfilesIndex], "");
if (mConnect) {
mProfiles[mProfilesIndex]->Connect(mDeviceAddress, this);
} else {
mProfiles[mProfilesIndex]->Disconnect(this);
}
}
bool
BluetoothProfileController::IsBtServiceAvailable() const
{
BluetoothService* bs = BluetoothService::Get();
return (bs && bs->IsEnabled() && !bs->IsToggling());
}
void
BluetoothProfileController::NotifyCompletion(const nsAString& aErrorStr)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mTimer);
MOZ_ASSERT(mProfiles.Length() > 0);
BT_LOGR_PROFILE(mProfiles[mProfilesIndex], "<%s>",
NS_ConvertUTF16toUTF8(aErrorStr).get());
mCurrentProfileFinished = true;
if (mTimer) {
mTimer->Cancel();
}
mSuccess |= aErrorStr.IsEmpty();
Next();
}
void
BluetoothProfileController::GiveupAndContinue()
{
MOZ_ASSERT(!mCurrentProfileFinished);
MOZ_ASSERT(mProfilesIndex < (int)mProfiles.Length());
BT_LOGR_PROFILE(mProfiles[mProfilesIndex], ERR_OPERATION_TIMEOUT);
mProfiles[mProfilesIndex]->Reset();
if (IsBtServiceAvailable()) {
Next();
} else {
EndSession();
}
}

View File

@ -1,160 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_bluetooth_bluetoothprofilecontroller_h__
#define mozilla_dom_bluetooth_bluetoothprofilecontroller_h__
#include "BluetoothUuid.h"
#include "nsISupportsImpl.h"
#include "nsAutoPtr.h"
#include "nsITimer.h"
BEGIN_BLUETOOTH_NAMESPACE
/*
* Class of Device(CoD): 32-bit unsigned integer
*
* 31 24 23 13 12 8 7 2 1 0
* | | Major | Major | Minor | |
* | | service | device | device | |
* | | class | class | class | |
* | |<- 11 ->|<- 5 ->|<- 6 ->| |
*
* https://www.bluetooth.org/en-us/specification/assigned-numbers/baseband
*/
// Bit 23 ~ Bit 13: Major service class
#define GET_MAJOR_SERVICE_CLASS(cod) ((cod & 0xffe000) >> 13)
// Bit 12 ~ Bit 8: Major device class
#define GET_MAJOR_DEVICE_CLASS(cod) ((cod & 0x1f00) >> 8)
// Bit 7 ~ Bit 2: Minor device class
#define GET_MINOR_DEVICE_CLASS(cod) ((cod & 0xfc) >> 2)
// Audio: Major service class = 0x100 (Bit 21 is set)
#define HAS_AUDIO(cod) (cod & 0x200000)
// Rendering: Major service class = 0x20 (Bit 18 is set)
#define HAS_RENDERING(cod) (cod & 0x40000)
// Peripheral: Major device class = 0x5
#define IS_PERIPHERAL(cod) (GET_MAJOR_DEVICE_CLASS(cod) == 0x5)
// Remote Control: sub-field of minor device class, Bit 5 ~ Bit 2 = 0x3
#define IS_REMOTE_CONTROL(cod) ((GET_MINOR_DEVICE_CLASS(cod) & 0xf) == 0x3)
// Keyboard: sub-field of minor device class (Bit 6)
#define IS_KEYBOARD(cod) ((GET_MINOR_DEVICE_CLASS(cod) & 0x10) >> 4)
// Pointing device: sub-field of minor device class (Bit 7)
#define IS_POINTING_DEVICE(cod) ((GET_MINOR_DEVICE_CLASS(cod) & 0x20) >> 5)
/**
* Check whether the value of CoD is invalid. (i.e. Bit 31 ~ Bit 24 != 0x0)
*
* According to Bluetooth core spec v4.1. Vol 2, Sec. 7.3, the data length of
* CoD (class of device) is 3 bytes. The two least significant bits are used to
* indicate 'format type'. The following 22 bits are used to indicate category
* of service class and device type. The remaining 8 bits (Bit 31 ~ Bit 24)
* should be unassigned bits, since BlueDroid uses uint32_t to store CoD.
*/
#define IS_INVALID_COD(cod) (cod >> 24)
class BluetoothProfileManagerBase;
class BluetoothReplyRunnable;
typedef void (*BluetoothProfileControllerCallback)();
class BluetoothProfileController final
{
~BluetoothProfileController();
public:
NS_INLINE_DECL_REFCOUNTING(BluetoothProfileController)
/**
* @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,
uint16_t aServiceUuid,
uint32_t aCod = 0);
/**
* The controller starts connecting/disconnecting profiles one by one
* according to the order in array mProfiles.
*/
void StartSession();
/**
* The original DOM request would be fired in this function.
*/
void EndSession();
/**
* It would be invoked after connect/disconnect operation is completed.
* An error string would be returned when it fails.
*/
void NotifyCompletion(const nsAString& aErrorStr);
/**
* It is invoked after a profile has reached timeout, reset mProfiles.
*/
void GiveupAndContinue();
private:
// 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();
// Is Bluetooth service available for profile connection/disconnection ?
bool IsBtServiceAvailable() const;
const bool mConnect;
nsString mDeviceAddress;
nsRefPtr<BluetoothReplyRunnable> mRunnable;
BluetoothProfileControllerCallback mCallback;
bool mCurrentProfileFinished;
bool mSuccess;
int8_t mProfilesIndex;
nsTArray<BluetoothProfileManagerBase*> mProfiles;
// Either CoD or BluetoothServiceClass is assigned.
union {
uint32_t cod;
BluetoothServiceClass service;
} mTarget;
nsCOMPtr<nsITimer> mTimer;
};
END_BLUETOOTH_NAMESPACE
#endif

View File

@ -1,59 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "base/basictypes.h"
#include "BluetoothPropertyContainer.h"
#include "BluetoothService.h"
#include "DOMRequest.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "nsServiceManagerUtils.h"
#include "js/Value.h"
USING_BLUETOOTH_NAMESPACE
already_AddRefed<mozilla::dom::DOMRequest>
BluetoothPropertyContainer::FirePropertyAlreadySet(nsPIDOMWindow* aOwner,
ErrorResult& aRv)
{
nsCOMPtr<nsIDOMRequestService> rs =
do_GetService(DOMREQUEST_SERVICE_CONTRACTID);
if (!rs) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<mozilla::dom::DOMRequest> request = new DOMRequest(aOwner);
rs->FireSuccess(request, JS::UndefinedHandleValue);
return request.forget();
}
already_AddRefed<mozilla::dom::DOMRequest>
BluetoothPropertyContainer::SetProperty(nsPIDOMWindow* aOwner,
const BluetoothNamedValue& aProperty,
ErrorResult& aRv)
{
nsRefPtr<mozilla::dom::DOMRequest> request = new DOMRequest(aOwner);
nsRefPtr<BluetoothReplyRunnable> task =
new BluetoothVoidReplyRunnable(request);
BluetoothService* bs = BluetoothService::Get();
if (!bs) {
BT_WARNING("Bluetooth service not available!");
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsresult rv = bs->SetProperty(mObjectType, aProperty, task);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return nullptr;
}
return request.forget();
}

View File

@ -1,59 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_bluetooth_bluetoothpropertyobject_h__
#define mozilla_dom_bluetooth_bluetoothpropertyobject_h__
#include "BluetoothCommon.h"
#include "BluetoothReplyRunnable.h"
class nsPIDOMWindow;
namespace mozilla {
class ErrorResult;
namespace dom {
class DOMRequest;
}
}
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothNamedValue;
class BluetoothPropertyContainer
{
public:
already_AddRefed<mozilla::dom::DOMRequest>
FirePropertyAlreadySet(nsPIDOMWindow* aOwner, ErrorResult& aRv);
already_AddRefed<mozilla::dom::DOMRequest>
SetProperty(nsPIDOMWindow* aOwner, const BluetoothNamedValue& aProperty,
ErrorResult& aRv);
virtual void SetPropertyByValue(const BluetoothNamedValue& aValue) = 0;
nsString GetPath()
{
return mPath;
}
// Compatibility with nsRefPtr to make sure we don't hold a weakptr to
// ourselves
virtual nsrefcnt AddRef() = 0;
virtual nsrefcnt Release() = 0;
protected:
BluetoothPropertyContainer(BluetoothObjectType aType) :
mObjectType(aType)
{}
~BluetoothPropertyContainer()
{}
nsString mPath;
BluetoothObjectType mObjectType;
};
END_BLUETOOTH_NAMESPACE
#endif

View File

@ -1,97 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "base/basictypes.h"
#include "BluetoothReplyRunnable.h"
#include "DOMRequest.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "nsServiceManagerUtils.h"
USING_BLUETOOTH_NAMESPACE
BluetoothReplyRunnable::BluetoothReplyRunnable(nsIDOMDOMRequest* aReq)
: mDOMRequest(aReq)
{}
void
BluetoothReplyRunnable::SetReply(BluetoothReply* aReply)
{
mReply = aReply;
}
void
BluetoothReplyRunnable::ReleaseMembers()
{
mDOMRequest = nullptr;
}
BluetoothReplyRunnable::~BluetoothReplyRunnable()
{}
nsresult
BluetoothReplyRunnable::FireReply(JS::Handle<JS::Value> aVal)
{
nsCOMPtr<nsIDOMRequestService> rs =
do_GetService(DOMREQUEST_SERVICE_CONTRACTID);
NS_ENSURE_TRUE(rs, NS_ERROR_FAILURE);
return mReply->type() == BluetoothReply::TBluetoothReplySuccess ?
rs->FireSuccessAsync(mDOMRequest, aVal) :
rs->FireErrorAsync(mDOMRequest, mReply->get_BluetoothReplyError().error());
}
nsresult
BluetoothReplyRunnable::FireErrorString()
{
nsCOMPtr<nsIDOMRequestService> rs =
do_GetService("@mozilla.org/dom/dom-request-service;1");
NS_ENSURE_TRUE(rs, NS_ERROR_FAILURE);
return rs->FireErrorAsync(mDOMRequest, mErrorString);
}
NS_IMETHODIMP
BluetoothReplyRunnable::Run()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mDOMRequest);
MOZ_ASSERT(mReply);
nsresult rv;
AutoSafeJSContext cx;
JS::Rooted<JS::Value> v(cx, JS::UndefinedValue());
if (mReply->type() != BluetoothReply::TBluetoothReplySuccess) {
rv = FireReply(v);
} else {
if (!ParseSuccessfulReply(&v)) {
rv = FireErrorString();
} else {
rv = FireReply(v);
}
}
if (NS_FAILED(rv)) {
BT_WARNING("Could not fire DOMRequest!");
}
ReleaseMembers();
MOZ_ASSERT(!mDOMRequest,
"mDOMRequest still alive! Deriving class should call "
"BluetoothReplyRunnable::ReleaseMembers()!");
return rv;
}
BluetoothVoidReplyRunnable::BluetoothVoidReplyRunnable(nsIDOMDOMRequest* aReq)
: BluetoothReplyRunnable(aReq)
{}
BluetoothVoidReplyRunnable::~BluetoothVoidReplyRunnable()
{}

View File

@ -1,71 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_bluetooth_bluetoothreplyrunnable_h__
#define mozilla_dom_bluetooth_bluetoothreplyrunnable_h__
#include "mozilla/Attributes.h"
#include "BluetoothCommon.h"
#include "nsThreadUtils.h"
#include "js/Value.h"
class nsIDOMDOMRequest;
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothReply;
class BluetoothReplyRunnable : public nsRunnable
{
public:
NS_DECL_NSIRUNNABLE
BluetoothReplyRunnable(nsIDOMDOMRequest* aReq);
void SetReply(BluetoothReply* aReply);
void SetError(const nsAString& aError)
{
mErrorString = aError;
}
virtual void ReleaseMembers();
protected:
virtual ~BluetoothReplyRunnable();
virtual bool ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue) = 0;
// This is an autoptr so we don't have to bring the ipdl include into the
// header. We assume we'll only be running this once and it should die on
// scope out of Run() anyways.
nsAutoPtr<BluetoothReply> mReply;
private:
nsresult FireReply(JS::Handle<JS::Value> aVal);
nsresult FireErrorString();
nsCOMPtr<nsIDOMDOMRequest> mDOMRequest;
nsString mErrorString;
};
class BluetoothVoidReplyRunnable : public BluetoothReplyRunnable
{
public:
BluetoothVoidReplyRunnable(nsIDOMDOMRequest* aReq);
~BluetoothVoidReplyRunnable();
protected:
virtual bool ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue) override
{
aValue.setUndefined();
return true;
}
};
END_BLUETOOTH_NAMESPACE
#endif

View File

@ -1,795 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "base/basictypes.h"
#include "BluetoothService.h"
#include "BluetoothCommon.h"
#include "BluetoothA2dpManager.h"
#include "BluetoothHfpManager.h"
#include "BluetoothHidManager.h"
#include "BluetoothManager.h"
#include "BluetoothOppManager.h"
#include "BluetoothParent.h"
#if defined(MOZ_B2G_BT_DAEMON)
#include "BluetoothPbapManager.h"
#endif
#include "BluetoothReplyRunnable.h"
#include "BluetoothServiceChildProcess.h"
#include "BluetoothUtils.h"
#include "jsapi.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/Services.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/unused.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/ipc/SocketBase.h"
#include "nsContentUtils.h"
#include "nsIObserverService.h"
#include "nsISettingsService.h"
#include "nsISystemMessagesInternal.h"
#include "nsITimer.h"
#include "nsServiceManagerUtils.h"
#include "nsXPCOM.h"
#include "mozilla/dom/SettingChangeNotificationBinding.h"
#if defined(MOZ_WIDGET_GONK)
#include "cutils/properties.h"
#endif
#if defined(MOZ_B2G_BT)
#if defined(MOZ_B2G_BT_BLUEZ)
/**
* B2G blueZ:
* MOZ_B2G_BT and MOZ_B2G_BT_BLUEZ are both defined.
*/
#include "BluetoothDBusService.h"
#elif defined(MOZ_B2G_BT_DAEMON)
/**
* B2G Bluetooth daemon:
* MOZ_B2G_BT and MOZ_B2G_BT_DAEMON are defined;
* MOZ_B2G_BLUEZ is not defined.
*/
#include "BluetoothServiceBluedroid.h"
#endif
#elif defined(MOZ_BLUETOOTH_DBUS)
/**
* Desktop bluetooth:
* MOZ_B2G_BT is not defined; MOZ_BLUETOOTH_DBUS is defined.
*/
#include "BluetoothDBusService.h"
#else
#error No backend
#endif
#define MOZSETTINGS_CHANGED_ID "mozsettings-changed"
#define BLUETOOTH_ENABLED_SETTING "bluetooth.enabled"
#define BLUETOOTH_DEBUGGING_SETTING "bluetooth.debugging.enabled"
#define PROP_BLUETOOTH_ENABLED "bluetooth.isEnabled"
#define DEFAULT_SHUTDOWN_TIMER_MS 5000
bool gBluetoothDebugFlag = false;
using namespace mozilla;
using namespace mozilla::dom;
USING_BLUETOOTH_NAMESPACE
namespace {
StaticRefPtr<BluetoothService> sBluetoothService;
bool sInShutdown = false;
bool sToggleInProgress = false;
void
ShutdownTimeExceeded(nsITimer* aTimer, void* aClosure)
{
MOZ_ASSERT(NS_IsMainThread());
*static_cast<bool*>(aClosure) = true;
}
void
GetAllBluetoothActors(InfallibleTArray<BluetoothParent*>& aActors)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aActors.IsEmpty());
nsAutoTArray<ContentParent*, 20> contentActors;
ContentParent::GetAll(contentActors);
for (uint32_t contentIndex = 0;
contentIndex < contentActors.Length();
contentIndex++) {
MOZ_ASSERT(contentActors[contentIndex]);
AutoInfallibleTArray<PBluetoothParent*, 5> bluetoothActors;
contentActors[contentIndex]->ManagedPBluetoothParent(bluetoothActors);
for (uint32_t bluetoothIndex = 0;
bluetoothIndex < bluetoothActors.Length();
bluetoothIndex++) {
MOZ_ASSERT(bluetoothActors[bluetoothIndex]);
BluetoothParent* actor =
static_cast<BluetoothParent*>(bluetoothActors[bluetoothIndex]);
aActors.AppendElement(actor);
}
}
}
} // namespace
BluetoothService::ToggleBtAck::ToggleBtAck(bool aEnabled)
: mEnabled(aEnabled)
{ }
NS_METHOD
BluetoothService::ToggleBtAck::Run()
{
BluetoothService::AcknowledgeToggleBt(mEnabled);
return NS_OK;
}
class BluetoothService::StartupTask final : public nsISettingsServiceCallback
{
public:
NS_DECL_ISUPPORTS
NS_IMETHOD Handle(const nsAString& aName, JS::Handle<JS::Value> aResult)
{
MOZ_ASSERT(NS_IsMainThread());
if (!aResult.isBoolean()) {
BT_WARNING("Setting for '" BLUETOOTH_ENABLED_SETTING "' is not a boolean!");
return NS_OK;
}
// It is theoretically possible to shut down before the first settings check
// has completed (though extremely unlikely).
if (sBluetoothService) {
return sBluetoothService->HandleStartupSettingsCheck(aResult.toBoolean());
}
return NS_OK;
}
NS_IMETHOD HandleError(const nsAString& aName)
{
BT_WARNING("Unable to get value for '" BLUETOOTH_ENABLED_SETTING "'");
return NS_OK;
}
protected:
~StartupTask() { }
};
NS_IMPL_ISUPPORTS(BluetoothService::StartupTask, nsISettingsServiceCallback);
NS_IMPL_ISUPPORTS(BluetoothService, nsIObserver)
bool
BluetoothService::IsToggling() const
{
return sToggleInProgress;
}
BluetoothService::~BluetoothService()
{
Cleanup();
}
PLDHashOperator
RemoveObserversExceptBluetoothManager
(const nsAString& key,
nsAutoPtr<BluetoothSignalObserverList>& value,
void* arg)
{
if (!key.EqualsLiteral(KEY_MANAGER)) {
return PL_DHASH_REMOVE;
}
return PL_DHASH_NEXT;
}
// static
BluetoothService*
BluetoothService::Create()
{
#if defined(MOZ_B2G_BT)
if (!XRE_IsParentProcess()) {
return BluetoothServiceChildProcess::Create();
}
#if defined(MOZ_B2G_BT_BLUEZ)
return new BluetoothDBusService();
#elif defined(MOZ_B2G_BT_DAEMON)
return new BluetoothServiceBluedroid();
#endif
#elif defined(MOZ_BLUETOOTH_DBUS)
return new BluetoothDBusService();
#endif
BT_WARNING("No platform support for bluetooth!");
return nullptr;
}
bool
BluetoothService::Init()
{
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
NS_ENSURE_TRUE(obs, false);
if (NS_FAILED(obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
false))) {
BT_WARNING("Failed to add shutdown observer!");
return false;
}
// Only the main process should observe bluetooth settings changes.
if (XRE_IsParentProcess() &&
NS_FAILED(obs->AddObserver(this, MOZSETTINGS_CHANGED_ID, false))) {
BT_WARNING("Failed to add settings change observer!");
return false;
}
return true;
}
void
BluetoothService::Cleanup()
{
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (obs &&
(NS_FAILED(obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) ||
NS_FAILED(obs->RemoveObserver(this, MOZSETTINGS_CHANGED_ID)))) {
BT_WARNING("Can't unregister observers!");
}
}
void
BluetoothService::RegisterBluetoothSignalHandler(
const nsAString& aNodeName,
BluetoothSignalObserver* aHandler)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aHandler);
BT_LOGD("[S] %s: %s", __FUNCTION__, NS_ConvertUTF16toUTF8(aNodeName).get());
BluetoothSignalObserverList* ol;
if (!mBluetoothSignalObserverTable.Get(aNodeName, &ol)) {
ol = new BluetoothSignalObserverList();
mBluetoothSignalObserverTable.Put(aNodeName, ol);
}
ol->AddObserver(aHandler);
}
void
BluetoothService::UnregisterBluetoothSignalHandler(
const nsAString& aNodeName,
BluetoothSignalObserver* aHandler)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aHandler);
BT_LOGD("[S] %s: %s", __FUNCTION__, NS_ConvertUTF16toUTF8(aNodeName).get());
BluetoothSignalObserverList* ol;
if (mBluetoothSignalObserverTable.Get(aNodeName, &ol)) {
ol->RemoveObserver(aHandler);
// We shouldn't have duplicate instances in the ObserverList, but there's
// no appropriate way to do duplication check while registering, so
// assertions are added here.
MOZ_ASSERT(!ol->RemoveObserver(aHandler));
if (ol->Length() == 0) {
mBluetoothSignalObserverTable.Remove(aNodeName);
}
}
else {
BT_WARNING("Node was never registered!");
}
}
PLDHashOperator
RemoveAllSignalHandlers(const nsAString& aKey,
nsAutoPtr<BluetoothSignalObserverList>& aData,
void* aUserArg)
{
BluetoothSignalObserver* handler = static_cast<BluetoothSignalObserver*>(aUserArg);
aData->RemoveObserver(handler);
// We shouldn't have duplicate instances in the ObserverList, but there's
// no appropriate way to do duplication check while registering, so
// assertions are added here.
MOZ_ASSERT(!aData->RemoveObserver(handler));
return aData->Length() ? PL_DHASH_NEXT : PL_DHASH_REMOVE;
}
void
BluetoothService::UnregisterAllSignalHandlers(BluetoothSignalObserver* aHandler)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aHandler);
mBluetoothSignalObserverTable.Enumerate(RemoveAllSignalHandlers, aHandler);
}
void
BluetoothService::DistributeSignal(const BluetoothSignal& aSignal)
{
MOZ_ASSERT(NS_IsMainThread());
if (aSignal.path().EqualsLiteral(KEY_LOCAL_AGENT)) {
Notify(aSignal);
return;
} else if (aSignal.path().EqualsLiteral(KEY_REMOTE_AGENT)) {
Notify(aSignal);
return;
}
BluetoothSignalObserverList* ol;
if (!mBluetoothSignalObserverTable.Get(aSignal.path(), &ol)) {
#if DEBUG
nsAutoCString msg("No observer registered for path ");
msg.Append(NS_ConvertUTF16toUTF8(aSignal.path()));
BT_WARNING(msg.get());
#endif
return;
}
MOZ_ASSERT(ol->Length());
ol->Broadcast(aSignal);
}
nsresult
BluetoothService::StartBluetooth(bool aIsStartup)
{
MOZ_ASSERT(NS_IsMainThread());
if (sInShutdown) {
// Don't try to start if we're already shutting down.
MOZ_ASSERT(false, "Start called while in shutdown!");
return NS_ERROR_FAILURE;
}
mAdapterAddedReceived = false;
/* When IsEnabled() is true, we don't switch on 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 already enabled.
*
* Please see bug 892392 for more information.
*/
if (aIsStartup || !sBluetoothService->IsEnabled()) {
// Switch Bluetooth on
if (NS_FAILED(sBluetoothService->StartInternal())) {
BT_WARNING("Bluetooth service failed to start!");
}
} else {
BT_WARNING("Bluetooth has already been enabled before.");
nsRefPtr<nsRunnable> runnable = new BluetoothService::ToggleBtAck(true);
if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
BT_WARNING("Failed to dispatch to main thread!");
}
}
return NS_OK;
}
nsresult
BluetoothService::StopBluetooth(bool aIsStartup)
{
MOZ_ASSERT(NS_IsMainThread());
static BluetoothProfileManagerBase* sProfiles[] = {
BluetoothHfpManager::Get(),
BluetoothA2dpManager::Get(),
BluetoothOppManager::Get(),
#if defined(MOZ_B2G_BT_DAEMON)
BluetoothPbapManager::Get(),
#endif
BluetoothHidManager::Get()
};
// Disconnect all connected profiles
for (uint8_t i = 0; i < MOZ_ARRAY_LENGTH(sProfiles); i++) {
nsCString profileName;
sProfiles[i]->GetName(profileName);
if (NS_WARN_IF(!sProfiles[i])) {
BT_LOGR("Profile manager [%s] is null", profileName.get());
return NS_ERROR_FAILURE;
}
if (sProfiles[i]->IsConnected()) {
sProfiles[i]->Disconnect(nullptr);
} else if (!profileName.EqualsLiteral("OPP") &&
!profileName.EqualsLiteral("PBAP")) {
sProfiles[i]->Reset();
}
}
mAdapterAddedReceived = false;
/* 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 || sBluetoothService->IsEnabled()) {
// Switch Bluetooth off
if (NS_FAILED(sBluetoothService->StopInternal())) {
BT_WARNING("Bluetooth service failed to stop!");
}
} else {
BT_WARNING("Bluetooth has already been enabled/disabled before.");
nsRefPtr<nsRunnable> runnable = new BluetoothService::ToggleBtAck(false);
if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
BT_WARNING("Failed to dispatch to main thread!");
}
}
return NS_OK;
}
nsresult
BluetoothService::StartStopBluetooth(bool aStart, bool aIsStartup)
{
nsresult rv;
if (aStart) {
rv = StartBluetooth(aIsStartup);
} else {
rv = StopBluetooth(aIsStartup);
}
return rv;
}
void
BluetoothService::SetEnabled(bool aEnabled)
{
MOZ_ASSERT(NS_IsMainThread());
AutoInfallibleTArray<BluetoothParent*, 10> childActors;
GetAllBluetoothActors(childActors);
for (uint32_t index = 0; index < childActors.Length(); index++) {
unused << childActors[index]->SendEnabled(aEnabled);
}
if (!aEnabled) {
/**
* Remove all handlers except BluetoothManager when turning off bluetooth
* since it is possible that the event 'onAdapterAdded' would be fired after
* BluetoothManagers of child process are registered. Please see Bug 827759
* for more details.
*/
mBluetoothSignalObserverTable.Enumerate(
RemoveObserversExceptBluetoothManager, nullptr);
}
/**
* mEnabled: real status of bluetooth
* aEnabled: expected status of bluetooth
*/
if (mEnabled == aEnabled) {
BT_WARNING("Bluetooth has already been enabled/disabled before "
"or the toggling is failed.");
}
mEnabled = aEnabled;
}
nsresult
BluetoothService::HandleStartup()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!sToggleInProgress);
nsCOMPtr<nsISettingsService> settings =
do_GetService("@mozilla.org/settingsService;1");
NS_ENSURE_TRUE(settings, NS_ERROR_UNEXPECTED);
nsCOMPtr<nsISettingsServiceLock> settingsLock;
nsresult rv = settings->CreateLock(nullptr, getter_AddRefs(settingsLock));
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<StartupTask> callback = new StartupTask();
rv = settingsLock->Get(BLUETOOTH_ENABLED_SETTING, callback);
NS_ENSURE_SUCCESS(rv, rv);
sToggleInProgress = true;
return NS_OK;
}
nsresult
BluetoothService::HandleStartupSettingsCheck(bool aEnable)
{
MOZ_ASSERT(NS_IsMainThread());
return StartStopBluetooth(aEnable, true);
}
nsresult
BluetoothService::HandleSettingsChanged(nsISupports* aSubject)
{
MOZ_ASSERT(NS_IsMainThread());
// The string that we're interested in will be a JSON string that looks like:
// {"key":"bluetooth.enabled","value":true}
RootedDictionary<SettingChangeNotification> setting(nsContentUtils::RootingCx());
if (!WrappedJSToDictionary(aSubject, setting)) {
return NS_OK;
}
if (setting.mKey.EqualsASCII(BLUETOOTH_DEBUGGING_SETTING)) {
if (!setting.mValue.isBoolean()) {
MOZ_ASSERT(false, "Expecting a boolean for 'bluetooth.debugging.enabled'!");
return NS_ERROR_UNEXPECTED;
}
SWITCH_BT_DEBUG(setting.mValue.toBoolean());
return NS_OK;
}
// Second, check if the string is BLUETOOTH_ENABLED_SETTING
if (!setting.mKey.EqualsASCII(BLUETOOTH_ENABLED_SETTING)) {
return NS_OK;
}
if (!setting.mValue.isBoolean()) {
MOZ_ASSERT(false, "Expecting a boolean for 'bluetooth.enabled'!");
return NS_ERROR_UNEXPECTED;
}
// Ignore bluetooth toggling request since toggling is already in progress.
if (sToggleInProgress) {
BT_LOGR("Ignore bluetooth toggling request since toggling is already in progress");
return NS_OK;
}
sToggleInProgress = true;
nsresult rv = StartStopBluetooth(setting.mValue.toBoolean(), false);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
nsresult
BluetoothService::HandleShutdown()
{
MOZ_ASSERT(NS_IsMainThread());
// This is a two phase shutdown. First we notify all child processes that
// bluetooth is going away, and then we wait for them to acknowledge. Then we
// close down all the bluetooth machinery.
sInShutdown = true;
Cleanup();
AutoInfallibleTArray<BluetoothParent*, 10> childActors;
GetAllBluetoothActors(childActors);
if (!childActors.IsEmpty()) {
// Notify child processes that they should stop using bluetooth now.
for (uint32_t index = 0; index < childActors.Length(); index++) {
childActors[index]->BeginShutdown();
}
// Create a timer to ensure that we don't wait forever for a child process
// or the bluetooth threads to finish. If we don't get a timer or can't use
// it for some reason then we skip all the waiting entirely since we really
// can't afford to hang on shutdown.
nsCOMPtr<nsITimer> timer = do_CreateInstance(NS_TIMER_CONTRACTID);
MOZ_ASSERT(timer);
if (timer) {
bool timeExceeded = false;
if (NS_SUCCEEDED(timer->InitWithFuncCallback(ShutdownTimeExceeded,
&timeExceeded,
DEFAULT_SHUTDOWN_TIMER_MS,
nsITimer::TYPE_ONE_SHOT))) {
nsIThread* currentThread = NS_GetCurrentThread();
MOZ_ASSERT(currentThread);
// Wait for those child processes to acknowledge.
while (!timeExceeded && !childActors.IsEmpty()) {
if (!NS_ProcessNextEvent(currentThread)) {
MOZ_ASSERT(false, "Something horribly wrong here!");
break;
}
GetAllBluetoothActors(childActors);
}
if (NS_FAILED(timer->Cancel())) {
MOZ_CRASH("Failed to cancel shutdown timer, this will crash!");
}
}
else {
MOZ_ASSERT(false, "Failed to initialize shutdown timer!");
}
}
}
if (IsEnabled() && NS_FAILED(StopBluetooth(false))) {
MOZ_ASSERT(false, "Failed to deliver stop message!");
}
return NS_OK;
}
// static
BluetoothService*
BluetoothService::Get()
{
MOZ_ASSERT(NS_IsMainThread());
// If we already exist, exit early
if (sBluetoothService) {
return sBluetoothService;
}
// If we're in shutdown, don't create a new instance
if (sInShutdown) {
BT_WARNING("BluetoothService can't be created during shutdown");
return nullptr;
}
// Create new instance, register, return
sBluetoothService = BluetoothService::Create();
NS_ENSURE_TRUE(sBluetoothService, nullptr);
if (!sBluetoothService->Init()) {
sBluetoothService->Cleanup();
return nullptr;
}
ClearOnShutdown(&sBluetoothService);
return sBluetoothService;
}
nsresult
BluetoothService::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData)
{
MOZ_ASSERT(NS_IsMainThread());
if (!strcmp(aTopic, "profile-after-change")) {
return HandleStartup();
}
if (!strcmp(aTopic, MOZSETTINGS_CHANGED_ID)) {
return HandleSettingsChanged(aSubject);
}
if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
return HandleShutdown();
}
MOZ_ASSERT(false, "BluetoothService got unexpected topic!");
return NS_ERROR_UNEXPECTED;
}
void
BluetoothService::TryFiringAdapterAdded()
{
MOZ_ASSERT(NS_IsMainThread());
if (IsToggling() || !mAdapterAddedReceived) {
return;
}
BluetoothSignal signal(NS_LITERAL_STRING("AdapterAdded"),
NS_LITERAL_STRING(KEY_MANAGER), true);
DistributeSignal(signal);
}
void
BluetoothService::AdapterAddedReceived()
{
MOZ_ASSERT(NS_IsMainThread());
mAdapterAddedReceived = true;
}
void
BluetoothService::Notify(const BluetoothSignal& aData)
{
nsString type = NS_LITERAL_STRING("bluetooth-pairing-request");
BT_LOGD("[S] %s: %s", __FUNCTION__, NS_ConvertUTF16toUTF8(aData.name()).get());
if (aData.name().EqualsLiteral("RequestConfirmation")) {
MOZ_ASSERT(aData.value().get_ArrayOfBluetoothNamedValue().Length() == 4,
"RequestConfirmation: Wrong length of parameters");
} else if (aData.name().EqualsLiteral("RequestPinCode")) {
MOZ_ASSERT(aData.value().get_ArrayOfBluetoothNamedValue().Length() == 3,
"RequestPinCode: Wrong length of parameters");
} else if (aData.name().EqualsLiteral("RequestPasskey")) {
MOZ_ASSERT(aData.value().get_ArrayOfBluetoothNamedValue().Length() == 3,
"RequestPinCode: Wrong length of parameters");
} else if (aData.name().EqualsLiteral("Cancel")) {
MOZ_ASSERT(aData.value().get_ArrayOfBluetoothNamedValue().Length() == 0,
"Cancel: Wrong length of parameters");
type.AssignLiteral("bluetooth-cancel");
} else if (aData.name().EqualsLiteral(PAIRED_STATUS_CHANGED_ID)) {
MOZ_ASSERT(aData.value().get_ArrayOfBluetoothNamedValue().Length() == 1,
"pairedstatuschanged: Wrong length of parameters");
type.AssignLiteral("bluetooth-pairedstatuschanged");
} else {
nsCString warningMsg;
warningMsg.AssignLiteral("Not handling service signal: ");
warningMsg.Append(NS_ConvertUTF16toUTF8(aData.name()));
BT_WARNING(warningMsg.get());
return;
}
BroadcastSystemMessage(type, aData.value());
}
void
BluetoothService::AcknowledgeToggleBt(bool aEnabled)
{
MOZ_ASSERT(NS_IsMainThread());
#if defined(MOZ_WIDGET_GONK)
// This is requested in Bug 836516. With settings this property, WLAN
// firmware could be aware of Bluetooth has been turned on/off, so that
// the mechanism of handling coexistence of WIFI and Bluetooth could be
// started.
//
// In the future, we may have our own way instead of setting a system
// property to let firmware developers be able to sense that Bluetooth
// has been toggled.
if (property_set(PROP_BLUETOOTH_ENABLED, aEnabled ? "true" : "false") != 0) {
BT_WARNING("Failed to set bluetooth enabled property");
}
#endif
if (sInShutdown) {
sBluetoothService = nullptr;
return;
}
NS_ENSURE_TRUE_VOID(sBluetoothService);
sBluetoothService->CompleteToggleBt(aEnabled);
}
void
BluetoothService::CompleteToggleBt(bool aEnabled)
{
MOZ_ASSERT(NS_IsMainThread());
// Update |mEnabled| of |BluetoothService| object since
// |StartInternal| and |StopInternal| have been already
// done.
SetEnabled(aEnabled);
sToggleInProgress = false;
nsAutoString signalName;
signalName = aEnabled ? NS_LITERAL_STRING("Enabled")
: NS_LITERAL_STRING("Disabled");
BluetoothSignal signal(signalName, NS_LITERAL_STRING(KEY_MANAGER), true);
DistributeSignal(signal);
// Event 'AdapterAdded' has to be fired after firing 'Enabled'
TryFiringAdapterAdded();
}

View File

@ -1,408 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_bluetooth_bluetootheventservice_h__
#define mozilla_dom_bluetooth_bluetootheventservice_h__
#include "BluetoothCommon.h"
#include "BluetoothProfileManagerBase.h"
#include "nsAutoPtr.h"
#include "nsClassHashtable.h"
#include "nsIObserver.h"
#include "nsTObserverArray.h"
#include "nsThreadUtils.h"
namespace mozilla {
namespace dom {
class Blob;
class BlobChild;
class BlobParent;
}
}
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothNamedValue;
class BluetoothReplyRunnable;
class BluetoothSignal;
typedef mozilla::ObserverList<BluetoothSignal> BluetoothSignalObserverList;
class BluetoothService : public nsIObserver
, public BluetoothSignalObserver
{
class ToggleBtTask;
friend class ToggleBtTask;
class StartupTask;
friend class StartupTask;
public:
class ToggleBtAck : public nsRunnable
{
public:
ToggleBtAck(bool aEnabled);
NS_IMETHOD Run();
private:
bool mEnabled;
};
friend class ToggleBtAck;
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
/**
* Add a message handler object from message distribution observer.
* Must be called from the main thread.
*
* @param aNodeName Node name of the object
* @param aMsgHandler Weak pointer to the object
*/
virtual void
RegisterBluetoothSignalHandler(const nsAString& aNodeName,
BluetoothSignalObserver* aMsgHandler);
/**
* Remove a message handler object from message distribution observer.
* Must be called from the main thread.
*
* @param aNodeName Node name of the object
* @param aMsgHandler Weak pointer to the object
*/
virtual void
UnregisterBluetoothSignalHandler(const nsAString& aNodeName,
BluetoothSignalObserver* aMsgHandler);
/**
* Remove a message handlers for the given observer.
* Must be called from the main thread.
*
* @param aMsgHandler Weak pointer to the object
*/
void
UnregisterAllSignalHandlers(BluetoothSignalObserver* aMsgHandler);
/**
* Distribute a signal to the observer list
*
* @param aSignal Signal object to distribute
*
* @return NS_OK if signal distributed, NS_ERROR_FAILURE on error
*/
void
DistributeSignal(const BluetoothSignal& aEvent);
/**
* Called when get a Bluetooth Signal from BluetoothDBusService
*
*/
void
Notify(const BluetoothSignal& aParam);
/**
* Returns the BluetoothService singleton. Only to be called from main thread.
*
* @param aService Pointer to return singleton into.
*
* @return NS_OK on proper assignment, NS_ERROR_FAILURE otherwise (if service
* has not yet been started, for instance)
*/
static BluetoothService*
Get();
static already_AddRefed<BluetoothService>
FactoryCreate()
{
nsRefPtr<BluetoothService> service = Get();
return service.forget();
}
/**
* Returns the path of the default adapter, implemented via a platform
* specific method.
*
* @return NS_OK on success, NS_ERROR_FAILURE otherwise
*/
virtual nsresult
GetDefaultAdapterPathInternal(BluetoothReplyRunnable* aRunnable) = 0;
/**
* Returns the properties of paired devices, implemented via a platform
* specific method.
*
* @return NS_OK on success, NS_ERROR_FAILURE otherwise
*/
virtual nsresult
GetPairedDevicePropertiesInternal(const nsTArray<nsString>& aDeviceAddresses,
BluetoothReplyRunnable* aRunnable) = 0;
/**
* Returns the properties of connected devices regarding to specific profile,
* implemented via a platform specific methood.
*
* @return NS_OK on success, NS_ERROR_FAILURE otherwise
*/
virtual nsresult
GetConnectedDevicePropertiesInternal(uint16_t aServiceUuid,
BluetoothReplyRunnable* aRunnable) = 0;
/**
* Stop device discovery (platform specific implementation)
*
* @return NS_OK if discovery stopped correctly, false otherwise
*/
virtual void
StopDiscoveryInternal(BluetoothReplyRunnable* aRunnable) = 0;
/**
* Start device discovery (platform specific implementation)
*
* @return NS_OK if discovery stopped correctly, false otherwise
*/
virtual void
StartDiscoveryInternal(BluetoothReplyRunnable* aRunnable) = 0;
/**
* Set a property for the specified object
*
* @param aPropName Name of the property
* @param aValue Boolean value
* @param aRunnable Runnable to run on async reply
*
* @return NS_OK if property is set correctly, NS_ERROR_FAILURE otherwise
*/
virtual nsresult
SetProperty(BluetoothObjectType aType,
const BluetoothNamedValue& aValue,
BluetoothReplyRunnable* aRunnable) = 0;
virtual nsresult
CreatePairedDeviceInternal(const nsAString& aAddress,
int aTimeout,
BluetoothReplyRunnable* aRunnable) = 0;
virtual nsresult
RemoveDeviceInternal(const nsAString& aObjectPath,
BluetoothReplyRunnable* aRunnable) = 0;
/**
* Get corresponding service channel of specific service on remote device.
* It's usually the very first step of establishing an outbound connection.
*
* @param aObjectPath Object path of remote device
* @param aServiceUuid UUID of the target service
* @param aManager Instance which has callback function OnGetServiceChannel()
*
* @return NS_OK if the task begins, NS_ERROR_FAILURE otherwise
*/
virtual nsresult
GetServiceChannel(const nsAString& aDeviceAddress,
const nsAString& aServiceUuid,
BluetoothProfileManagerBase* aManager) = 0;
virtual bool
UpdateSdpRecords(const nsAString& aDeviceAddress,
BluetoothProfileManagerBase* aManager) = 0;
virtual bool
SetPinCodeInternal(const nsAString& aDeviceAddress, const nsAString& aPinCode,
BluetoothReplyRunnable* aRunnable) = 0;
virtual bool
SetPasskeyInternal(const nsAString& aDeviceAddress, uint32_t aPasskey,
BluetoothReplyRunnable* aRunnable) = 0;
virtual bool
SetPairingConfirmationInternal(const nsAString& aDeviceAddress, bool aConfirm,
BluetoothReplyRunnable* aRunnable) = 0;
virtual void
Connect(const nsAString& aDeviceAddress, uint32_t aCod, uint16_t aServiceUuid,
BluetoothReplyRunnable* aRunnable) = 0;
virtual void
Disconnect(const nsAString& aDeviceAddress, uint16_t aServiceUuid,
BluetoothReplyRunnable* aRunnable) = 0;
virtual void
IsConnected(const uint16_t aServiceUuid, BluetoothReplyRunnable* aRunnable) = 0;
virtual void
SendFile(const nsAString& aDeviceAddress,
BlobParent* aBlobParent,
BlobChild* aBlobChild,
BluetoothReplyRunnable* aRunnable) = 0;
virtual void
SendFile(const nsAString& aDeviceAddress,
Blob* aBlob,
BluetoothReplyRunnable* aRunnable) = 0;
virtual void
StopSendingFile(const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable) = 0;
virtual void
ConfirmReceivingFile(const nsAString& aDeviceAddress, bool aConfirm,
BluetoothReplyRunnable* aRunnable) = 0;
virtual void
ConnectSco(BluetoothReplyRunnable* aRunnable) = 0;
virtual void
DisconnectSco(BluetoothReplyRunnable* aRunnable) = 0;
virtual void
IsScoConnected(BluetoothReplyRunnable* aRunnable) = 0;
#ifdef MOZ_B2G_RIL
virtual void
AnswerWaitingCall(BluetoothReplyRunnable* aRunnable) = 0;
virtual void
IgnoreWaitingCall(BluetoothReplyRunnable* aRunnable) = 0;
virtual void
ToggleCalls(BluetoothReplyRunnable* aRunnable) = 0;
#endif
virtual void
SendMetaData(const nsAString& aTitle,
const nsAString& aArtist,
const nsAString& aAlbum,
int64_t aMediaNumber,
int64_t aTotalMediaCount,
int64_t aDuration,
BluetoothReplyRunnable* aRunnable) = 0;
virtual void
SendPlayStatus(int64_t aDuration,
int64_t aPosition,
const nsAString& aPlayStatus,
BluetoothReplyRunnable* aRunnable) = 0;
virtual void
UpdatePlayStatus(uint32_t aDuration,
uint32_t aPosition,
ControlPlayStatus aPlayStatus) = 0;
virtual nsresult
SendSinkMessage(const nsAString& aDeviceAddresses,
const nsAString& aMessage) = 0;
virtual nsresult
SendInputMessage(const nsAString& aDeviceAddresses,
const nsAString& aMessage) = 0;
bool
IsEnabled() const
{
return mEnabled;
}
bool
IsToggling() const;
static void AcknowledgeToggleBt(bool aEnabled);
/**
* Below 2 function/variable are used for ensuring event 'AdapterAdded' will
* be fired after event 'Enabled'.
*/
void TryFiringAdapterAdded();
void AdapterAddedReceived();
protected:
BluetoothService() : mEnabled(false)
, mAdapterAddedReceived(false)
{
}
virtual ~BluetoothService();
bool
Init();
void
Cleanup();
nsresult
StartBluetooth(bool aIsStartup);
nsresult
StopBluetooth(bool aIsStartup);
nsresult
StartStopBluetooth(bool aStart, bool aIsStartup);
/**
* Platform specific startup functions go here. Usually deals with member
* variables, so not static. Guaranteed to be called outside of main thread.
*
* @return NS_OK on correct startup, NS_ERROR_FAILURE otherwise
*/
virtual nsresult
StartInternal() = 0;
/**
* Platform specific startup functions go here. Usually deals with member
* variables, so not static. Guaranteed to be called outside of main thread.
*
* @return NS_OK on correct startup, NS_ERROR_FAILURE otherwise
*/
virtual nsresult
StopInternal() = 0;
/**
* Called when XPCOM first creates this service.
*/
virtual nsresult
HandleStartup();
virtual void
CompleteToggleBt(bool aEnabled);
/**
* Called when the startup settings check has completed.
*/
nsresult
HandleStartupSettingsCheck(bool aEnable);
/**
* Called when "mozsettings-changed" observer topic fires.
*/
nsresult
HandleSettingsChanged(nsISupports* aSubject);
/**
* Called when XPCOM is shutting down.
*/
virtual nsresult
HandleShutdown();
// Called by ToggleBtAck.
void
SetEnabled(bool aEnabled);
// Called by Get().
static BluetoothService*
Create();
typedef nsClassHashtable<nsStringHashKey, BluetoothSignalObserverList >
BluetoothSignalObserverTable;
BluetoothSignalObserverTable mBluetoothSignalObserverTable;
bool mEnabled;
private:
bool mAdapterAddedReceived;
};
END_BLUETOOTH_NAMESPACE
#endif

View File

@ -1,177 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "base/basictypes.h"
#include "BluetoothChild.h"
#include "mozilla/Assertions.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/StaticPtr.h"
#include "nsDebug.h"
#include "nsISupportsImpl.h"
#include "nsThreadUtils.h"
#include "BluetoothReplyRunnable.h"
#include "BluetoothService.h"
#include "BluetoothServiceChildProcess.h"
using namespace mozilla;
USING_BLUETOOTH_NAMESPACE
namespace {
StaticRefPtr<BluetoothServiceChildProcess> sBluetoothService;
} // namespace
/*******************************************************************************
* BluetoothChild
******************************************************************************/
BluetoothChild::BluetoothChild(BluetoothServiceChildProcess* aBluetoothService)
: mShutdownState(Running)
{
MOZ_COUNT_CTOR(BluetoothChild);
MOZ_ASSERT(!sBluetoothService);
MOZ_ASSERT(aBluetoothService);
sBluetoothService = aBluetoothService;
ClearOnShutdown(&sBluetoothService);
}
BluetoothChild::~BluetoothChild()
{
MOZ_COUNT_DTOR(BluetoothChild);
MOZ_ASSERT(sBluetoothService);
MOZ_ASSERT(mShutdownState == Dead);
sBluetoothService = nullptr;
}
void
BluetoothChild::BeginShutdown()
{
// Only do something here if we haven't yet begun the shutdown sequence.
if (mShutdownState == Running) {
SendStopNotifying();
mShutdownState = SentStopNotifying;
}
}
void
BluetoothChild::ActorDestroy(ActorDestroyReason aWhy)
{
MOZ_ASSERT(sBluetoothService);
sBluetoothService->NoteDeadActor();
#ifdef DEBUG
mShutdownState = Dead;
#endif
}
bool
BluetoothChild::RecvNotify(const BluetoothSignal& aSignal)
{
MOZ_ASSERT(sBluetoothService);
if (sBluetoothService) {
sBluetoothService->DistributeSignal(aSignal);
}
return true;
}
bool
BluetoothChild::RecvEnabled(const bool& aEnabled)
{
MOZ_ASSERT(sBluetoothService);
if (sBluetoothService) {
sBluetoothService->SetEnabled(aEnabled);
}
return true;
}
bool
BluetoothChild::RecvBeginShutdown()
{
if (mShutdownState != Running && mShutdownState != SentStopNotifying) {
MOZ_ASSERT(false, "Bad state!");
return false;
}
SendStopNotifying();
mShutdownState = SentStopNotifying;
return true;
}
bool
BluetoothChild::RecvNotificationsStopped()
{
if (mShutdownState != SentStopNotifying) {
MOZ_ASSERT(false, "Bad state!");
return false;
}
Send__delete__(this);
return true;
}
PBluetoothRequestChild*
BluetoothChild::AllocPBluetoothRequestChild(const Request& aRequest)
{
MOZ_CRASH("Caller is supposed to manually construct a request!");
}
bool
BluetoothChild::DeallocPBluetoothRequestChild(PBluetoothRequestChild* aActor)
{
delete aActor;
return true;
}
/*******************************************************************************
* BluetoothRequestChild
******************************************************************************/
BluetoothRequestChild::BluetoothRequestChild(
BluetoothReplyRunnable* aReplyRunnable)
: mReplyRunnable(aReplyRunnable)
{
MOZ_COUNT_CTOR(BluetoothRequestChild);
MOZ_ASSERT(aReplyRunnable);
}
BluetoothRequestChild::~BluetoothRequestChild()
{
MOZ_COUNT_DTOR(BluetoothRequestChild);
}
void
BluetoothRequestChild::ActorDestroy(ActorDestroyReason aWhy)
{
// Nothing needed here.
}
bool
BluetoothRequestChild::Recv__delete__(const BluetoothReply& aReply)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mReplyRunnable);
nsRefPtr<BluetoothReplyRunnable> replyRunnable;
mReplyRunnable.swap(replyRunnable);
if (replyRunnable) {
// XXXbent Need to fix this, it copies unnecessarily.
replyRunnable->SetReply(new BluetoothReply(aReply));
return NS_SUCCEEDED(NS_DispatchToCurrentThread(replyRunnable));
}
return true;
}

View File

@ -1,105 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_bluetooth_ipc_bluetoothchild_h__
#define mozilla_dom_bluetooth_ipc_bluetoothchild_h__
#include "mozilla/dom/bluetooth/BluetoothCommon.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/dom/bluetooth/PBluetoothChild.h"
#include "mozilla/dom/bluetooth/PBluetoothRequestChild.h"
#include "mozilla/Attributes.h"
#include "nsAutoPtr.h"
namespace mozilla {
namespace dom {
namespace bluetooth {
class BluetoothServiceChildProcess;
} // namespace bluetooth
} // namespace dom
} // namespace mozilla
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothReplyRunnable;
/*******************************************************************************
* BluetoothChild
******************************************************************************/
class BluetoothChild : public PBluetoothChild
{
friend class mozilla::dom::bluetooth::BluetoothServiceChildProcess;
enum ShutdownState
{
Running = 0,
SentStopNotifying,
ReceivedNotificationsStopped,
Dead
};
ShutdownState mShutdownState;
protected:
BluetoothChild(BluetoothServiceChildProcess* aBluetoothService);
virtual ~BluetoothChild();
void
BeginShutdown();
virtual void
ActorDestroy(ActorDestroyReason aWhy) override;
virtual bool
RecvNotify(const BluetoothSignal& aSignal);
virtual bool
RecvEnabled(const bool& aEnabled) override;
virtual bool
RecvBeginShutdown() override;
virtual bool
RecvNotificationsStopped() override;
virtual PBluetoothRequestChild*
AllocPBluetoothRequestChild(const Request& aRequest) override;
virtual bool
DeallocPBluetoothRequestChild(PBluetoothRequestChild* aActor) override;
};
/*******************************************************************************
* BluetoothRequestChild
******************************************************************************/
class BluetoothRequestChild : public PBluetoothRequestChild
{
friend class mozilla::dom::bluetooth::BluetoothChild;
nsRefPtr<BluetoothReplyRunnable> mReplyRunnable;
public:
BluetoothRequestChild(BluetoothReplyRunnable* aReplyRunnable);
protected:
virtual ~BluetoothRequestChild();
virtual void
ActorDestroy(ActorDestroyReason aWhy) override;
virtual bool
Recv__delete__(const BluetoothReply& aReply) override;
};
END_BLUETOOTH_NAMESPACE
#endif // mozilla_dom_bluetooth_ipc_bluetoothchild_h__

View File

@ -1,25 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_bluetooth_ipc_bluetoothmessageutils_h__
#define mozilla_dom_bluetooth_ipc_bluetoothmessageutils_h__
#include "mozilla/dom/bluetooth/BluetoothCommon.h"
#include "ipc/IPCMessageUtils.h"
namespace IPC {
template <>
struct ParamTraits<mozilla::dom::bluetooth::BluetoothObjectType>
: public ContiguousEnumSerializer<
mozilla::dom::bluetooth::BluetoothObjectType,
mozilla::dom::bluetooth::TYPE_MANAGER,
mozilla::dom::bluetooth::NUM_TYPE>
{ };
} // namespace IPC
#endif // mozilla_dom_bluetooth_ipc_bluetoothmessageutils_h__

View File

@ -1,664 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "base/basictypes.h"
#include "BluetoothParent.h"
#include "mozilla/Assertions.h"
#include "mozilla/unused.h"
#include "nsDebug.h"
#include "nsISupportsImpl.h"
#include "nsThreadUtils.h"
#include "BluetoothReplyRunnable.h"
#include "BluetoothService.h"
using mozilla::unused;
USING_BLUETOOTH_NAMESPACE
/*******************************************************************************
* BluetoothRequestParent::ReplyRunnable
******************************************************************************/
class BluetoothRequestParent::ReplyRunnable final : public BluetoothReplyRunnable
{
BluetoothRequestParent* mRequest;
public:
ReplyRunnable(BluetoothRequestParent* aRequest)
: BluetoothReplyRunnable(nullptr), mRequest(aRequest)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aRequest);
}
NS_IMETHOD
Run() override
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mReply);
if (mRequest) {
// Must do this first because Send__delete__ will delete mRequest.
mRequest->RequestComplete();
if (!mRequest->Send__delete__(mRequest, *mReply)) {
BT_WARNING("Failed to send response to child process!");
return NS_ERROR_FAILURE;
}
}
ReleaseMembers();
return NS_OK;
}
void
Revoke()
{
ReleaseMembers();
}
virtual bool
ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue) override
{
MOZ_CRASH("This should never be called!");
}
virtual void
ReleaseMembers() override
{
MOZ_ASSERT(NS_IsMainThread());
mRequest = nullptr;
BluetoothReplyRunnable::ReleaseMembers();
}
};
/*******************************************************************************
* BluetoothParent
******************************************************************************/
BluetoothParent::BluetoothParent()
: mShutdownState(Running)
{
MOZ_COUNT_CTOR(BluetoothParent);
}
BluetoothParent::~BluetoothParent()
{
MOZ_COUNT_DTOR(BluetoothParent);
MOZ_ASSERT(!mService);
MOZ_ASSERT(mShutdownState == Dead);
}
void
BluetoothParent::BeginShutdown()
{
// Only do something here if we haven't yet begun the shutdown sequence.
if (mShutdownState == Running) {
unused << SendBeginShutdown();
mShutdownState = SentBeginShutdown;
}
}
bool
BluetoothParent::InitWithService(BluetoothService* aService)
{
MOZ_ASSERT(aService);
MOZ_ASSERT(!mService);
if (!SendEnabled(aService->IsEnabled())) {
return false;
}
mService = aService;
return true;
}
void
BluetoothParent::UnregisterAllSignalHandlers()
{
MOZ_ASSERT(mService);
mService->UnregisterAllSignalHandlers(this);
}
void
BluetoothParent::ActorDestroy(ActorDestroyReason aWhy)
{
if (mService) {
UnregisterAllSignalHandlers();
#ifdef DEBUG
mService = nullptr;
#endif
}
#ifdef DEBUG
mShutdownState = Dead;
#endif
}
bool
BluetoothParent::RecvRegisterSignalHandler(const nsString& aNode)
{
MOZ_ASSERT(mService);
mService->RegisterBluetoothSignalHandler(aNode, this);
return true;
}
bool
BluetoothParent::RecvUnregisterSignalHandler(const nsString& aNode)
{
MOZ_ASSERT(mService);
mService->UnregisterBluetoothSignalHandler(aNode, this);
return true;
}
bool
BluetoothParent::RecvStopNotifying()
{
MOZ_ASSERT(mService);
if (mShutdownState != Running && mShutdownState != SentBeginShutdown) {
MOZ_ASSERT(false, "Bad state!");
return false;
}
mShutdownState = ReceivedStopNotifying;
UnregisterAllSignalHandlers();
if (SendNotificationsStopped()) {
mShutdownState = SentNotificationsStopped;
return true;
}
return false;
}
bool
BluetoothParent::RecvPBluetoothRequestConstructor(
PBluetoothRequestParent* aActor,
const Request& aRequest)
{
BluetoothRequestParent* actor = static_cast<BluetoothRequestParent*>(aActor);
#ifdef DEBUG
actor->mRequestType = aRequest.type();
#endif
switch (aRequest.type()) {
case Request::TDefaultAdapterPathRequest:
return actor->DoRequest(aRequest.get_DefaultAdapterPathRequest());
case Request::TSetPropertyRequest:
return actor->DoRequest(aRequest.get_SetPropertyRequest());
case Request::TStartDiscoveryRequest:
return actor->DoRequest(aRequest.get_StartDiscoveryRequest());
case Request::TStopDiscoveryRequest:
return actor->DoRequest(aRequest.get_StopDiscoveryRequest());
case Request::TPairRequest:
return actor->DoRequest(aRequest.get_PairRequest());
case Request::TUnpairRequest:
return actor->DoRequest(aRequest.get_UnpairRequest());
case Request::TPairedDevicePropertiesRequest:
return actor->DoRequest(aRequest.get_PairedDevicePropertiesRequest());
case Request::TConnectedDevicePropertiesRequest:
return actor->DoRequest(aRequest.get_ConnectedDevicePropertiesRequest());
case Request::TSetPinCodeRequest:
return actor->DoRequest(aRequest.get_SetPinCodeRequest());
case Request::TSetPasskeyRequest:
return actor->DoRequest(aRequest.get_SetPasskeyRequest());
case Request::TConfirmPairingConfirmationRequest:
return actor->DoRequest(aRequest.get_ConfirmPairingConfirmationRequest());
case Request::TDenyPairingConfirmationRequest:
return actor->DoRequest(aRequest.get_DenyPairingConfirmationRequest());
case Request::TConnectRequest:
return actor->DoRequest(aRequest.get_ConnectRequest());
case Request::TDisconnectRequest:
return actor->DoRequest(aRequest.get_DisconnectRequest());
case Request::TIsConnectedRequest:
return actor->DoRequest(aRequest.get_IsConnectedRequest());
case Request::TSendFileRequest:
return actor->DoRequest(aRequest.get_SendFileRequest());
case Request::TStopSendingFileRequest:
return actor->DoRequest(aRequest.get_StopSendingFileRequest());
case Request::TConfirmReceivingFileRequest:
return actor->DoRequest(aRequest.get_ConfirmReceivingFileRequest());
case Request::TDenyReceivingFileRequest:
return actor->DoRequest(aRequest.get_DenyReceivingFileRequest());
case Request::TConnectScoRequest:
return actor->DoRequest(aRequest.get_ConnectScoRequest());
case Request::TDisconnectScoRequest:
return actor->DoRequest(aRequest.get_DisconnectScoRequest());
case Request::TIsScoConnectedRequest:
return actor->DoRequest(aRequest.get_IsScoConnectedRequest());
#ifdef MOZ_B2G_RIL
case Request::TAnswerWaitingCallRequest:
return actor->DoRequest(aRequest.get_AnswerWaitingCallRequest());
case Request::TIgnoreWaitingCallRequest:
return actor->DoRequest(aRequest.get_IgnoreWaitingCallRequest());
case Request::TToggleCallsRequest:
return actor->DoRequest(aRequest.get_ToggleCallsRequest());
#endif
case Request::TSendMetaDataRequest:
return actor->DoRequest(aRequest.get_SendMetaDataRequest());
case Request::TSendPlayStatusRequest:
return actor->DoRequest(aRequest.get_SendPlayStatusRequest());
default:
MOZ_CRASH("Unknown type!");
}
MOZ_CRASH("Should never get here!");
}
PBluetoothRequestParent*
BluetoothParent::AllocPBluetoothRequestParent(const Request& aRequest)
{
MOZ_ASSERT(mService);
return new BluetoothRequestParent(mService);
}
bool
BluetoothParent::DeallocPBluetoothRequestParent(PBluetoothRequestParent* aActor)
{
delete aActor;
return true;
}
void
BluetoothParent::Notify(const BluetoothSignal& aSignal)
{
unused << SendNotify(aSignal);
}
/*******************************************************************************
* BluetoothRequestParent
******************************************************************************/
BluetoothRequestParent::BluetoothRequestParent(BluetoothService* aService)
: mService(aService)
#ifdef DEBUG
, mRequestType(Request::T__None)
#endif
{
MOZ_COUNT_CTOR(BluetoothRequestParent);
MOZ_ASSERT(aService);
mReplyRunnable = new ReplyRunnable(this);
}
BluetoothRequestParent::~BluetoothRequestParent()
{
MOZ_COUNT_DTOR(BluetoothRequestParent);
// mReplyRunnable will be automatically revoked.
}
void
BluetoothRequestParent::ActorDestroy(ActorDestroyReason aWhy)
{
mReplyRunnable.Revoke();
}
void
BluetoothRequestParent::RequestComplete()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mReplyRunnable.IsPending());
mReplyRunnable.Forget();
}
bool
BluetoothRequestParent::DoRequest(const DefaultAdapterPathRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TDefaultAdapterPathRequest);
nsresult rv = mService->GetDefaultAdapterPathInternal(mReplyRunnable.get());
NS_ENSURE_SUCCESS(rv, false);
return true;
}
bool
BluetoothRequestParent::DoRequest(const SetPropertyRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TSetPropertyRequest);
nsresult rv =
mService->SetProperty(aRequest.type(), aRequest.value(),
mReplyRunnable.get());
NS_ENSURE_SUCCESS(rv, false);
return true;
}
bool
BluetoothRequestParent::DoRequest(const StartDiscoveryRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TStartDiscoveryRequest);
mService->StartDiscoveryInternal(mReplyRunnable.get());
return true;
}
bool
BluetoothRequestParent::DoRequest(const StopDiscoveryRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TStopDiscoveryRequest);
mService->StopDiscoveryInternal(mReplyRunnable.get());
return true;
}
bool
BluetoothRequestParent::DoRequest(const PairRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TPairRequest);
nsresult rv =
mService->CreatePairedDeviceInternal(aRequest.address(),
aRequest.timeoutMS(),
mReplyRunnable.get());
NS_ENSURE_SUCCESS(rv, false);
return true;
}
bool
BluetoothRequestParent::DoRequest(const UnpairRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TUnpairRequest);
nsresult rv =
mService->RemoveDeviceInternal(aRequest.address(),
mReplyRunnable.get());
NS_ENSURE_SUCCESS(rv, false);
return true;
}
bool
BluetoothRequestParent::DoRequest(const PairedDevicePropertiesRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TPairedDevicePropertiesRequest);
nsresult rv =
mService->GetPairedDevicePropertiesInternal(aRequest.addresses(),
mReplyRunnable.get());
NS_ENSURE_SUCCESS(rv, false);
return true;
}
bool
BluetoothRequestParent::DoRequest(const ConnectedDevicePropertiesRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TConnectedDevicePropertiesRequest);
nsresult rv =
mService->GetConnectedDevicePropertiesInternal(aRequest.serviceUuid(),
mReplyRunnable.get());
NS_ENSURE_SUCCESS(rv, false);
return true;
}
bool
BluetoothRequestParent::DoRequest(const SetPinCodeRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TSetPinCodeRequest);
bool result =
mService->SetPinCodeInternal(aRequest.path(),
aRequest.pincode(),
mReplyRunnable.get());
NS_ENSURE_TRUE(result, false);
return true;
}
bool
BluetoothRequestParent::DoRequest(const SetPasskeyRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TSetPasskeyRequest);
bool result =
mService->SetPasskeyInternal(aRequest.path(),
aRequest.passkey(),
mReplyRunnable.get());
NS_ENSURE_TRUE(result, false);
return true;
}
bool
BluetoothRequestParent::DoRequest(const ConfirmPairingConfirmationRequest&
aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TConfirmPairingConfirmationRequest);
bool result =
mService->SetPairingConfirmationInternal(aRequest.path(),
true,
mReplyRunnable.get());
NS_ENSURE_TRUE(result, false);
return true;
}
bool
BluetoothRequestParent::DoRequest(const DenyPairingConfirmationRequest&
aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TDenyPairingConfirmationRequest);
bool result =
mService->SetPairingConfirmationInternal(aRequest.path(),
false,
mReplyRunnable.get());
NS_ENSURE_TRUE(result, false);
return true;
}
bool
BluetoothRequestParent::DoRequest(const ConnectRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TConnectRequest);
mService->Connect(aRequest.address(),
aRequest.cod(),
aRequest.serviceUuid(),
mReplyRunnable.get());
return true;
}
bool
BluetoothRequestParent::DoRequest(const DisconnectRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TDisconnectRequest);
mService->Disconnect(aRequest.address(),
aRequest.serviceUuid(),
mReplyRunnable.get());
return true;
}
bool
BluetoothRequestParent::DoRequest(const IsConnectedRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TIsConnectedRequest);
mService->IsConnected(aRequest.serviceUuid(),
mReplyRunnable.get());
return true;
}
bool
BluetoothRequestParent::DoRequest(const SendFileRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TSendFileRequest);
mService->SendFile(aRequest.devicePath(),
(BlobParent*)aRequest.blobParent(),
(BlobChild*)aRequest.blobChild(),
mReplyRunnable.get());
return true;
}
bool
BluetoothRequestParent::DoRequest(const StopSendingFileRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TStopSendingFileRequest);
mService->StopSendingFile(aRequest.devicePath(),
mReplyRunnable.get());
return true;
}
bool
BluetoothRequestParent::DoRequest(const ConfirmReceivingFileRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TConfirmReceivingFileRequest);
mService->ConfirmReceivingFile(aRequest.devicePath(),
true,
mReplyRunnable.get());
return true;
}
bool
BluetoothRequestParent::DoRequest(const DenyReceivingFileRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TDenyReceivingFileRequest);
mService->ConfirmReceivingFile(aRequest.devicePath(),
false,
mReplyRunnable.get());
return true;
}
bool
BluetoothRequestParent::DoRequest(const ConnectScoRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TConnectScoRequest);
mService->ConnectSco(mReplyRunnable.get());
return true;
}
bool
BluetoothRequestParent::DoRequest(const DisconnectScoRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TDisconnectScoRequest);
mService->DisconnectSco(mReplyRunnable.get());
return true;
}
bool
BluetoothRequestParent::DoRequest(const IsScoConnectedRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TIsScoConnectedRequest);
mService->IsScoConnected(mReplyRunnable.get());
return true;
}
#ifdef MOZ_B2G_RIL
bool
BluetoothRequestParent::DoRequest(const AnswerWaitingCallRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TAnswerWaitingCallRequest);
mService->AnswerWaitingCall(mReplyRunnable.get());
return true;
}
bool
BluetoothRequestParent::DoRequest(const IgnoreWaitingCallRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TAnswerWaitingCallRequest);
mService->IgnoreWaitingCall(mReplyRunnable.get());
return true;
}
bool
BluetoothRequestParent::DoRequest(const ToggleCallsRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TAnswerWaitingCallRequest);
mService->ToggleCalls(mReplyRunnable.get());
return true;
}
#endif // MOZ_B2G_RIL
bool
BluetoothRequestParent::DoRequest(const SendMetaDataRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TSendMetaDataRequest);
mService->SendMetaData(aRequest.title(),
aRequest.artist(),
aRequest.album(),
aRequest.mediaNumber(),
aRequest.totalMediaCount(),
aRequest.duration(),
mReplyRunnable.get());
return true;
}
bool
BluetoothRequestParent::DoRequest(const SendPlayStatusRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TSendPlayStatusRequest);
mService->SendPlayStatus(aRequest.duration(),
aRequest.position(),
aRequest.playStatus(),
mReplyRunnable.get());
return true;
}

View File

@ -1,216 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_bluetooth_ipc_bluetoothparent_h__
#define mozilla_dom_bluetooth_ipc_bluetoothparent_h__
#include "mozilla/dom/bluetooth/BluetoothCommon.h"
#include "mozilla/dom/bluetooth/PBluetoothParent.h"
#include "mozilla/dom/bluetooth/PBluetoothRequestParent.h"
#include "mozilla/Attributes.h"
#include "mozilla/Observer.h"
#include "nsAutoPtr.h"
#include "nsTArray.h"
#include "nsThreadUtils.h"
template <class T>
class nsRevocableEventPtr;
namespace mozilla {
namespace dom {
class ContentParent;
} // namespace dom
} // namespace mozilla
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothService;
/*******************************************************************************
* BluetoothParent
******************************************************************************/
class BluetoothParent : public PBluetoothParent
, public BluetoothSignalObserver
{
friend class mozilla::dom::ContentParent;
enum ShutdownState
{
Running = 0,
SentBeginShutdown,
ReceivedStopNotifying,
SentNotificationsStopped,
Dead
};
nsRefPtr<BluetoothService> mService;
ShutdownState mShutdownState;
bool mReceivedStopNotifying;
bool mSentBeginShutdown;
public:
void
BeginShutdown();
protected:
BluetoothParent();
virtual ~BluetoothParent();
bool
InitWithService(BluetoothService* aService);
virtual void
ActorDestroy(ActorDestroyReason aWhy) override;
virtual bool
RecvRegisterSignalHandler(const nsString& aNode) override;
virtual bool
RecvUnregisterSignalHandler(const nsString& aNode) override;
virtual bool
RecvStopNotifying() override;
virtual bool
RecvPBluetoothRequestConstructor(PBluetoothRequestParent* aActor,
const Request& aRequest) override;
virtual PBluetoothRequestParent*
AllocPBluetoothRequestParent(const Request& aRequest) override;
virtual bool
DeallocPBluetoothRequestParent(PBluetoothRequestParent* aActor) override;
virtual void
Notify(const BluetoothSignal& aSignal) override;
private:
void
UnregisterAllSignalHandlers();
};
/*******************************************************************************
* BluetoothAdapterRequestParent
******************************************************************************/
class BluetoothRequestParent : public PBluetoothRequestParent
{
class ReplyRunnable;
friend class BluetoothParent;
friend class ReplyRunnable;
nsRefPtr<BluetoothService> mService;
nsRevocableEventPtr<ReplyRunnable> mReplyRunnable;
#ifdef DEBUG
Request::Type mRequestType;
#endif
protected:
BluetoothRequestParent(BluetoothService* aService);
virtual ~BluetoothRequestParent();
virtual void
ActorDestroy(ActorDestroyReason aWhy) override;
void
RequestComplete();
bool
DoRequest(const DefaultAdapterPathRequest& aRequest);
bool
DoRequest(const SetPropertyRequest& aRequest);
bool
DoRequest(const GetPropertyRequest& aRequest);
bool
DoRequest(const StartDiscoveryRequest& aRequest);
bool
DoRequest(const StopDiscoveryRequest& aRequest);
bool
DoRequest(const PairRequest& aRequest);
bool
DoRequest(const UnpairRequest& aRequest);
bool
DoRequest(const PairedDevicePropertiesRequest& aRequest);
bool
DoRequest(const ConnectedDevicePropertiesRequest& aRequest);
bool
DoRequest(const SetPinCodeRequest& aRequest);
bool
DoRequest(const SetPasskeyRequest& aRequest);
bool
DoRequest(const ConfirmPairingConfirmationRequest& aRequest);
bool
DoRequest(const DenyPairingConfirmationRequest& aRequest);
bool
DoRequest(const ConnectRequest& aRequest);
bool
DoRequest(const DisconnectRequest& aRequest);
bool
DoRequest(const IsConnectedRequest& aRequest);
bool
DoRequest(const SendFileRequest& aRequest);
bool
DoRequest(const StopSendingFileRequest& aRequest);
bool
DoRequest(const ConfirmReceivingFileRequest& aRequest);
bool
DoRequest(const DenyReceivingFileRequest& aRequest);
bool
DoRequest(const ConnectScoRequest& aRequest);
bool
DoRequest(const DisconnectScoRequest& aRequest);
bool
DoRequest(const IsScoConnectedRequest& aRequest);
#ifdef MOZ_B2G_RIL
bool
DoRequest(const AnswerWaitingCallRequest& aRequest);
bool
DoRequest(const IgnoreWaitingCallRequest& aRequest);
bool
DoRequest(const ToggleCallsRequest& aRequest);
#endif
bool
DoRequest(const SendMetaDataRequest& aRequest);
bool
DoRequest(const SendPlayStatusRequest& aRequest);
};
END_BLUETOOTH_NAMESPACE
#endif // mozilla_dom_bluetooth_ipc_bluetoothparent_h__

View File

@ -1,420 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "base/basictypes.h"
#include "BluetoothServiceChildProcess.h"
#include "mozilla/Assertions.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "BluetoothChild.h"
#include "MainThreadUtils.h"
USING_BLUETOOTH_NAMESPACE
namespace {
BluetoothChild* sBluetoothChild;
inline
void
SendRequest(BluetoothReplyRunnable* aRunnable, const Request& aRequest)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aRunnable);
NS_WARN_IF_FALSE(sBluetoothChild,
"Calling methods on BluetoothServiceChildProcess during "
"shutdown!");
if (sBluetoothChild) {
BluetoothRequestChild* actor = new BluetoothRequestChild(aRunnable);
sBluetoothChild->SendPBluetoothRequestConstructor(actor, aRequest);
}
}
} // namespace
// static
BluetoothServiceChildProcess*
BluetoothServiceChildProcess::Create()
{
MOZ_ASSERT(!sBluetoothChild);
mozilla::dom::ContentChild* contentChild =
mozilla::dom::ContentChild::GetSingleton();
MOZ_ASSERT(contentChild);
BluetoothServiceChildProcess* btService = new BluetoothServiceChildProcess();
sBluetoothChild = new BluetoothChild(btService);
contentChild->SendPBluetoothConstructor(sBluetoothChild);
return btService;
}
BluetoothServiceChildProcess::BluetoothServiceChildProcess()
{
}
BluetoothServiceChildProcess::~BluetoothServiceChildProcess()
{
sBluetoothChild = nullptr;
}
void
BluetoothServiceChildProcess::NoteDeadActor()
{
MOZ_ASSERT(sBluetoothChild);
sBluetoothChild = nullptr;
}
void
BluetoothServiceChildProcess::RegisterBluetoothSignalHandler(
const nsAString& aNodeName,
BluetoothSignalObserver* aHandler)
{
if (sBluetoothChild && !IsSignalRegistered(aNodeName)) {
sBluetoothChild->SendRegisterSignalHandler(nsString(aNodeName));
}
BluetoothService::RegisterBluetoothSignalHandler(aNodeName, aHandler);
}
void
BluetoothServiceChildProcess::UnregisterBluetoothSignalHandler(
const nsAString& aNodeName,
BluetoothSignalObserver* aHandler)
{
BluetoothService::UnregisterBluetoothSignalHandler(aNodeName, aHandler);
if (sBluetoothChild && !IsSignalRegistered(aNodeName)) {
sBluetoothChild->SendUnregisterSignalHandler(nsString(aNodeName));
}
}
nsresult
BluetoothServiceChildProcess::GetDefaultAdapterPathInternal(
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable, DefaultAdapterPathRequest());
return NS_OK;
}
nsresult
BluetoothServiceChildProcess::GetConnectedDevicePropertiesInternal(
uint16_t aServiceUuid,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable, ConnectedDevicePropertiesRequest(aServiceUuid));
return NS_OK;
}
nsresult
BluetoothServiceChildProcess::GetPairedDevicePropertiesInternal(
const nsTArray<nsString>& aDeviceAddresses,
BluetoothReplyRunnable* aRunnable)
{
PairedDevicePropertiesRequest request;
request.addresses().AppendElements(aDeviceAddresses);
SendRequest(aRunnable, request);
return NS_OK;
}
void
BluetoothServiceChildProcess::StopDiscoveryInternal(
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable, StopDiscoveryRequest());
}
void
BluetoothServiceChildProcess::StartDiscoveryInternal(
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable, StartDiscoveryRequest());
}
nsresult
BluetoothServiceChildProcess::SetProperty(BluetoothObjectType aType,
const BluetoothNamedValue& aValue,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable, SetPropertyRequest(aType, aValue));
return NS_OK;
}
nsresult
BluetoothServiceChildProcess::CreatePairedDeviceInternal(
const nsAString& aAddress,
int aTimeout,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable,
PairRequest(nsString(aAddress), aTimeout));
return NS_OK;
}
nsresult
BluetoothServiceChildProcess::RemoveDeviceInternal(
const nsAString& aObjectPath,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable,
UnpairRequest(nsString(aObjectPath)));
return NS_OK;
}
nsresult
BluetoothServiceChildProcess::GetServiceChannel(const nsAString& aDeviceAddress,
const nsAString& aServiceUuid,
BluetoothProfileManagerBase* aManager)
{
MOZ_CRASH("This should never be called!");
}
bool
BluetoothServiceChildProcess::UpdateSdpRecords(const nsAString& aDeviceAddress,
BluetoothProfileManagerBase* aManager)
{
MOZ_CRASH("This should never be called!");
}
bool
BluetoothServiceChildProcess::SetPinCodeInternal(
const nsAString& aDeviceAddress,
const nsAString& aPinCode,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable,
SetPinCodeRequest(nsString(aDeviceAddress), nsString(aPinCode)));
return true;
}
bool
BluetoothServiceChildProcess::SetPasskeyInternal(
const nsAString& aDeviceAddress,
uint32_t aPasskey,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable,
SetPasskeyRequest(nsString(aDeviceAddress), aPasskey));
return true;
}
bool
BluetoothServiceChildProcess::SetPairingConfirmationInternal(
const nsAString& aDeviceAddress,
bool aConfirm,
BluetoothReplyRunnable* aRunnable)
{
if(aConfirm) {
SendRequest(aRunnable,
ConfirmPairingConfirmationRequest(nsString(aDeviceAddress)));
} else {
SendRequest(aRunnable,
DenyPairingConfirmationRequest(nsString(aDeviceAddress)));
}
return true;
}
void
BluetoothServiceChildProcess::Connect(
const nsAString& aDeviceAddress,
uint32_t aCod,
uint16_t aServiceUuid,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable,
ConnectRequest(nsString(aDeviceAddress),
aCod,
aServiceUuid));
}
void
BluetoothServiceChildProcess::Disconnect(
const nsAString& aDeviceAddress,
uint16_t aServiceUuid,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable,
DisconnectRequest(nsString(aDeviceAddress), aServiceUuid));
}
void
BluetoothServiceChildProcess::IsConnected(
const uint16_t aServiceUuid,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable, IsConnectedRequest(aServiceUuid));
}
void
BluetoothServiceChildProcess::SendFile(
const nsAString& aDeviceAddress,
BlobParent* aBlobParent,
BlobChild* aBlobChild,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable,
SendFileRequest(nsString(aDeviceAddress), nullptr, aBlobChild));
}
void
BluetoothServiceChildProcess::SendFile(
const nsAString& aDeviceAddress,
Blob* aBlobChild,
BluetoothReplyRunnable* aRunnable)
{
// Parent-process-only method
MOZ_CRASH("This should never be called!");
}
void
BluetoothServiceChildProcess::StopSendingFile(
const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable,
StopSendingFileRequest(nsString(aDeviceAddress)));
}
void
BluetoothServiceChildProcess::ConfirmReceivingFile(
const nsAString& aDeviceAddress,
bool aConfirm,
BluetoothReplyRunnable* aRunnable)
{
if(aConfirm) {
SendRequest(aRunnable,
ConfirmReceivingFileRequest(nsString(aDeviceAddress)));
return;
}
SendRequest(aRunnable,
DenyReceivingFileRequest(nsString(aDeviceAddress)));
}
void
BluetoothServiceChildProcess::ConnectSco(BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable, ConnectScoRequest());
}
void
BluetoothServiceChildProcess::DisconnectSco(BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable, DisconnectScoRequest());
}
void
BluetoothServiceChildProcess::IsScoConnected(BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable, IsScoConnectedRequest());
}
#ifdef MOZ_B2G_RIL
void
BluetoothServiceChildProcess::AnswerWaitingCall(
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable, AnswerWaitingCallRequest());
}
void
BluetoothServiceChildProcess::IgnoreWaitingCall(
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable, IgnoreWaitingCallRequest());
}
void
BluetoothServiceChildProcess::ToggleCalls(
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable, ToggleCallsRequest());
}
#endif // MOZ_B2G_RIL
void
BluetoothServiceChildProcess::SendMetaData(const nsAString& aTitle,
const nsAString& aArtist,
const nsAString& aAlbum,
int64_t aMediaNumber,
int64_t aTotalMediaCount,
int64_t aDuration,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable,
SendMetaDataRequest(nsString(aTitle), nsString(aArtist),
nsString(aAlbum), aMediaNumber,
aTotalMediaCount, aDuration));
}
void
BluetoothServiceChildProcess::SendPlayStatus(int64_t aDuration,
int64_t aPosition,
const nsAString& aPlayStatus,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable,
SendPlayStatusRequest(aDuration, aPosition,
nsString(aPlayStatus)));
}
nsresult
BluetoothServiceChildProcess::HandleStartup()
{
// Don't need to do anything here for startup since our Create function takes
// care of the actor machinery.
return NS_OK;
}
nsresult
BluetoothServiceChildProcess::HandleShutdown()
{
// If this process is shutting down then we need to disconnect ourselves from
// the parent.
if (sBluetoothChild) {
sBluetoothChild->BeginShutdown();
}
return NS_OK;
}
nsresult
BluetoothServiceChildProcess::StartInternal()
{
MOZ_CRASH("This should never be called!");
}
nsresult
BluetoothServiceChildProcess::StopInternal()
{
MOZ_CRASH("This should never be called!");
}
nsresult
BluetoothServiceChildProcess::SendSinkMessage(const nsAString& aDeviceAddresses,
const nsAString& aMessage)
{
MOZ_CRASH("This should never be called!");
}
nsresult
BluetoothServiceChildProcess::SendInputMessage(const nsAString& aDeviceAddresses,
const nsAString& aMessage)
{
MOZ_CRASH("This should never be called!");
}
void
BluetoothServiceChildProcess::UpdatePlayStatus(uint32_t aDuration,
uint32_t aPosition,
ControlPlayStatus aPlayStatus)
{
MOZ_CRASH("This should never be called!");
}

View File

@ -1,207 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_bluetooth_ipc_bluetoothservicechildprocess_h__
#define mozilla_dom_bluetooth_ipc_bluetoothservicechildprocess_h__
#include "BluetoothService.h"
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothChild;
class BluetoothServiceChildProcess : public BluetoothService
{
friend class mozilla::dom::bluetooth::BluetoothChild;
public:
static BluetoothServiceChildProcess*
Create();
virtual void
RegisterBluetoothSignalHandler(const nsAString& aNodeName,
BluetoothSignalObserver* aMsgHandler)
override;
virtual void
UnregisterBluetoothSignalHandler(const nsAString& aNodeName,
BluetoothSignalObserver* aMsgHandler)
override;
virtual nsresult
GetDefaultAdapterPathInternal(BluetoothReplyRunnable* aRunnable) override;
virtual nsresult
GetPairedDevicePropertiesInternal(const nsTArray<nsString>& aDeviceAddresses,
BluetoothReplyRunnable* aRunnable)
override;
virtual nsresult
GetConnectedDevicePropertiesInternal(uint16_t aServiceUuid,
BluetoothReplyRunnable* aRunnable)
override;
virtual void
StopDiscoveryInternal(BluetoothReplyRunnable* aRunnable) override;
virtual void
StartDiscoveryInternal(BluetoothReplyRunnable* aRunnable) override;
virtual nsresult
SetProperty(BluetoothObjectType aType,
const BluetoothNamedValue& aValue,
BluetoothReplyRunnable* aRunnable) override;
virtual nsresult
CreatePairedDeviceInternal(const nsAString& aAddress,
int aTimeout,
BluetoothReplyRunnable* aRunnable) override;
virtual nsresult
RemoveDeviceInternal(const nsAString& aObjectPath,
BluetoothReplyRunnable* aRunnable) override;
virtual nsresult
GetServiceChannel(const nsAString& aDeviceAddress,
const nsAString& aServiceUuid,
BluetoothProfileManagerBase* aManager) override;
virtual bool
UpdateSdpRecords(const nsAString& aDeviceAddress,
BluetoothProfileManagerBase* aManager) override;
virtual bool
SetPinCodeInternal(const nsAString& aDeviceAddress,
const nsAString& aPinCode,
BluetoothReplyRunnable* aRunnable) override;
virtual bool
SetPasskeyInternal(const nsAString& aDeviceAddress,
uint32_t aPasskey,
BluetoothReplyRunnable* aRunnable) override;
virtual bool
SetPairingConfirmationInternal(const nsAString& aDeviceAddress,
bool aConfirm,
BluetoothReplyRunnable* aRunnable)
override;
virtual void
Connect(const nsAString& aDeviceAddress,
uint32_t aCod,
uint16_t aServiceUuid,
BluetoothReplyRunnable* aRunnable) override;
virtual void
Disconnect(const nsAString& aDeviceAddress,
uint16_t aServiceUuid,
BluetoothReplyRunnable* aRunnable) override;
virtual void
IsConnected(const uint16_t aServiceUuid,
BluetoothReplyRunnable* aRunnable) override;
virtual void
SendFile(const nsAString& aDeviceAddress,
BlobParent* aBlobParent,
BlobChild* aBlobChild,
BluetoothReplyRunnable* aRunnable) override;
virtual void
SendFile(const nsAString& aDeviceAddress,
Blob* aBlob,
BluetoothReplyRunnable* aRunnable) override;
virtual void
StopSendingFile(const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable) override;
virtual void
ConfirmReceivingFile(const nsAString& aDeviceAddress,
bool aConfirm,
BluetoothReplyRunnable* aRunnable) override;
virtual void
ConnectSco(BluetoothReplyRunnable* aRunnable) override;
virtual void
DisconnectSco(BluetoothReplyRunnable* aRunnable) override;
virtual void
IsScoConnected(BluetoothReplyRunnable* aRunnable) override;
#ifdef MOZ_B2G_RIL
virtual void
AnswerWaitingCall(BluetoothReplyRunnable* aRunnable) override;
virtual void
IgnoreWaitingCall(BluetoothReplyRunnable* aRunnable) override;
virtual void
ToggleCalls(BluetoothReplyRunnable* aRunnable) override;
#endif
virtual void
SendMetaData(const nsAString& aTitle,
const nsAString& aArtist,
const nsAString& aAlbum,
int64_t aMediaNumber,
int64_t aTotalMediaCount,
int64_t aDuration,
BluetoothReplyRunnable* aRunnable) override;
virtual void
SendPlayStatus(int64_t aDuration,
int64_t aPosition,
const nsAString& aPlayStatus,
BluetoothReplyRunnable* aRunnable) override;
virtual void
UpdatePlayStatus(uint32_t aDuration,
uint32_t aPosition,
ControlPlayStatus aPlayStatus) override;
virtual nsresult
SendSinkMessage(const nsAString& aDeviceAddresses,
const nsAString& aMessage) override;
virtual nsresult
SendInputMessage(const nsAString& aDeviceAddresses,
const nsAString& aMessage) override;
protected:
BluetoothServiceChildProcess();
virtual ~BluetoothServiceChildProcess();
void
NoteDeadActor();
void
NoteShutdownInitiated();
virtual nsresult
HandleStartup() override;
virtual nsresult
HandleShutdown() override;
private:
// This method should never be called.
virtual nsresult
StartInternal() override;
// This method should never be called.
virtual nsresult
StopInternal() override;
bool
IsSignalRegistered(const nsAString& aNodeName) {
return !!mBluetoothSignalObserverTable.Get(aNodeName);
}
};
END_BLUETOOTH_NAMESPACE
#endif // mozilla_dom_bluetooth_ipc_bluetoothservicechildprocess_h__

View File

@ -1,63 +0,0 @@
/* -*- 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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
namespace mozilla {
namespace dom {
namespace bluetooth {
/**
* Value structure for returns from bluetooth. Currently modeled after dbus
* returns, which can be a 32-bit int, an UTF16 string, a bool, or an array of
* UTF16 strings. Can also hold key-value pairs for dictionary-ish access.
*
*/
union BluetoothValue
{
uint32_t;
nsString;
bool;
nsString[];
uint8_t[];
BluetoothNamedValue[];
};
/**
* Key-value pair for dicts returned by the bluetooth backend. Used for things
* like property updates, where the property will have a name and a type.
*
*/
struct BluetoothNamedValue
{
nsString name;
BluetoothValue value;
};
struct BluetoothSignal
{
nsString name;
nsString path;
BluetoothValue value;
};
struct BluetoothReplySuccess
{
BluetoothValue value;
};
struct BluetoothReplyError
{
nsString error;
};
union BluetoothReply
{
BluetoothReplySuccess;
BluetoothReplyError;
};
}
}
}

View File

@ -1,301 +0,0 @@
/* -*- 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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PBlob;
include protocol PBluetoothRequest;
include protocol PContent;
include BluetoothTypes;
include "mozilla/dom/bluetooth/ipc/BluetoothMessageUtils.h";
using mozilla::dom::bluetooth::BluetoothObjectType from "mozilla/dom/bluetooth/BluetoothCommon.h";
namespace mozilla {
namespace dom {
namespace bluetooth {
/**
* Bluetooth request types.
*/
struct DefaultAdapterPathRequest
{ };
struct SetPropertyRequest
{
BluetoothObjectType type;
BluetoothNamedValue value;
};
struct GetPropertyRequest
{
BluetoothObjectType type;
nsString path;
};
struct StartDiscoveryRequest
{
};
struct StopDiscoveryRequest
{
};
struct PairRequest
{
nsString address;
uint32_t timeoutMS;
};
struct UnpairRequest
{
nsString address;
};
struct SetPinCodeRequest
{
nsString path;
nsString pincode;
};
struct SetPasskeyRequest
{
nsString path;
uint32_t passkey;
};
struct ConfirmPairingConfirmationRequest
{
nsString path;
};
struct DenyPairingConfirmationRequest
{
nsString path;
};
struct PairedDevicePropertiesRequest
{
nsString[] addresses;
};
struct ConnectedDevicePropertiesRequest
{
uint16_t serviceUuid;
};
struct ConnectRequest
{
nsString address;
uint32_t cod;
uint16_t serviceUuid;
};
struct DisconnectRequest
{
nsString address;
uint16_t serviceUuid;
};
struct IsConnectedRequest
{
uint16_t serviceUuid;
};
struct SendFileRequest
{
nsString devicePath;
PBlob blob;
};
struct StopSendingFileRequest
{
nsString devicePath;
};
struct ConfirmReceivingFileRequest
{
nsString devicePath;
};
struct DenyReceivingFileRequest
{
nsString devicePath;
};
struct ConnectScoRequest
{
};
struct DisconnectScoRequest
{
};
struct IsScoConnectedRequest
{
};
struct AnswerWaitingCallRequest
{
};
struct IgnoreWaitingCallRequest
{
};
struct ToggleCallsRequest
{
};
struct SendMetaDataRequest
{
nsString title;
nsString artist;
nsString album;
int64_t mediaNumber;
int64_t totalMediaCount;
int64_t duration;
};
struct SendPlayStatusRequest
{
int64_t duration;
int64_t position;
nsString playStatus;
};
union Request
{
DefaultAdapterPathRequest;
SetPropertyRequest;
GetPropertyRequest;
StartDiscoveryRequest;
StopDiscoveryRequest;
PairRequest;
UnpairRequest;
SetPinCodeRequest;
SetPasskeyRequest;
ConfirmPairingConfirmationRequest;
DenyPairingConfirmationRequest;
ConnectedDevicePropertiesRequest;
PairedDevicePropertiesRequest;
ConnectRequest;
DisconnectRequest;
IsConnectedRequest;
SendFileRequest;
StopSendingFileRequest;
ConfirmReceivingFileRequest;
DenyReceivingFileRequest;
ConnectScoRequest;
DisconnectScoRequest;
IsScoConnectedRequest;
AnswerWaitingCallRequest;
IgnoreWaitingCallRequest;
ToggleCallsRequest;
SendMetaDataRequest;
SendPlayStatusRequest;
};
protocol PBluetooth
{
manager PContent;
manages PBluetoothRequest;
/**
* The potential exists for a racy shutdown so the following sequence of
* messages is used to shutdown safely:
*
* 1. [BeginShutdown] (Parent -> Child [Optional])
* 2. StopNotifying (Child -> Parent)
* 3. NotificationsStopped (Parent -> Child)
* 4. __delete__() (Child -> Parent)
*/
child:
/**
* Sent when a settings change has enabled or disabled the bluetooth firmware.
*/
Enabled(bool enabled);
/**
* Sent when a bluetooth signal is broadcasted to child processes.
*/
Notify(BluetoothSignal signal);
/**
* Sent when the parent process is about to be shut down. See shutdown note
* above.
*/
BeginShutdown();
/**
* Sent to inform the child process that it will no longer receive any
* messages from the parent. See shutdown note above.
*/
NotificationsStopped();
parent:
/**
* Sent when the child no longer needs to use bluetooth. See shutdown note
* above.
*/
__delete__();
/**
* Sent when the child needs to receive signals related to the given node.
*/
RegisterSignalHandler(nsString node);
/**
* Sent when the child no longer needs to receive signals related to the given
* node.
*/
UnregisterSignalHandler(nsString node);
/**
* Sent when the child no longer needs to receive any messages from the
* parent. See shutdown note above.
*/
StopNotifying();
/**
* Sent when the child makes an asynchronous request to the parent.
*/
PBluetoothRequest(Request request);
/**
* FIXME: Bug 547703.
*
* This is the state machine we want:
*
* start state NOTIFYING:
* send Enabled goto NOTIFYING;
* send Notify goto NOTIFYING;
* recv RegisterSignalHandler goto NOTIFYING;
* recv UnregisterSignalHandler goto NOTIFYING;
* send BeginShutdown goto PARENT_DONE;
* recv StopNotifying goto CHILD_DONE;
*
* state PARENT_DONE:
* recv RegisterSignalHandler goto PARENT_DONE;
* recv UnregisterSignalHandler goto PARENT_DONE;
* recv StopNotifying goto CHILD_DONE;
*
* state CHILD_DONE:
* send Enabled goto CHILD_DONE;
* send Notify goto CHILD_DONE;
* send BeginShutdown goto CHILD_DONE;
* send NotificationsStopped goto DONE;
*
* state DONE:
* recv __delete__;
*/
};
} // namespace bluetooth
} // namespace dom
} // namespace mozilla

View File

@ -1,28 +0,0 @@
/* -*- 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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PBluetooth;
include BluetoothTypes;
namespace mozilla {
namespace dom {
namespace bluetooth {
protocol PBluetoothRequest
{
manager PBluetooth;
child:
/**
* Sent when the asynchronous request has completed.
*/
__delete__(BluetoothReply response);
};
} // namespace bluetooth
} // namespace dom
} // namespace mozilla

View File

@ -1,741 +0,0 @@
/* 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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://github.com/mozilla-b2g/platform_external_qemu/blob/master/vl-android.c#L765
// static int bt_hci_parse(const char *str) {
// ...
// bdaddr.b[0] = 0x52;
// bdaddr.b[1] = 0x54;
// bdaddr.b[2] = 0x00;
// bdaddr.b[3] = 0x12;
// bdaddr.b[4] = 0x34;
// bdaddr.b[5] = 0x56 + nb_hcis;
const EMULATOR_ADDRESS = "56:34:12:00:54:52";
// $ adb shell hciconfig /dev/ttyS2 name
// hci0: Type: BR/EDR Bus: UART
// BD Address: 56:34:12:00:54:52 ACL MTU: 512:1 SCO MTU: 0:0
// Name: 'Full Android on Emulator'
const EMULATOR_NAME = "Full Android on Emulator";
// $ adb shell hciconfig /dev/ttyS2 class
// hci0: Type: BR/EDR Bus: UART
// BD Address: 56:34:12:00:54:52 ACL MTU: 512:1 SCO MTU: 0:0
// Class: 0x58020c
// Service Classes: Capturing, Object Transfer, Telephony
// Device Class: Phone, Smart phone
const EMULATOR_CLASS = 0x58020c;
// Use same definition in QEMU for special bluetooth address,
// which were defined at external/qemu/hw/bt.h:
const BDADDR_ANY = "00:00:00:00:00:00";
const BDADDR_ALL = "ff:ff:ff:ff:ff:ff";
const BDADDR_LOCAL = "ff:ff:ff:00:00:00";
// A user friendly name for remote BT device.
const REMOTE_DEVICE_NAME = "Remote_BT_Device";
// A system message signature of pairing request event
const BT_PAIRING_REQ = "bluetooth-pairing-request";
// Passkey and pincode used to reply pairing requst
const BT_PAIRING_PASSKEY = 123456;
const BT_PAIRING_PINCODE = "ABCDEFG";
// Emulate Promise.jsm semantics.
Promise.defer = function() { return new Deferred(); }
function Deferred() {
this.promise = new Promise(function(resolve, reject) {
this.resolve = resolve;
this.reject = reject;
}.bind(this));
Object.freeze(this);
}
let bluetoothManager;
let pendingEmulatorCmdCount = 0;
/**
* Send emulator command with safe guard.
*
* We should only call |finish()| after all emulator command transactions
* end, so here comes with the pending counter. Resolve when the emulator
* gives positive response, and reject otherwise.
*
* Fulfill params:
* result -- an array of emulator response lines.
*
* Reject params:
* result -- an array of emulator response lines.
*
* @return A deferred promise.
*/
function runEmulatorCmdSafe(aCommand) {
let deferred = Promise.defer();
++pendingEmulatorCmdCount;
runEmulatorCmd(aCommand, function(aResult) {
--pendingEmulatorCmdCount;
ok(true, "Emulator response: " + JSON.stringify(aResult));
if (Array.isArray(aResult) && aResult[aResult.length - 1] === "OK") {
deferred.resolve(aResult);
} else {
ok(false, "Got an abnormal response from emulator.");
log("Fail to execute emulator command: [" + aCommand + "]");
deferred.reject(aResult);
}
});
return deferred.promise;
}
/**
* Add a Bluetooth remote device to scatternet and set its properties.
*
* Use QEMU command 'bt remote add' to add a virtual Bluetooth remote
* and set its properties by setEmulatorDeviceProperty().
*
* Fulfill params:
* result -- bluetooth address of the remote device.
* Reject params: (none)
*
* @param aProperies
* A javascript object with zero or several properties for initializing
* the remote device. By now, the properies could be 'name' or
* 'discoverable'. It valid to put a null object or a javascript object
* which don't have any properies.
*
* @return A promise object.
*/
function addEmulatorRemoteDevice(aProperties) {
let address;
let promise = runEmulatorCmdSafe("bt remote add")
.then(function(aResults) {
address = aResults[0].toUpperCase();
});
for (let key in aProperties) {
let value = aProperties[key];
let propertyName = key;
promise = promise.then(function() {
return setEmulatorDeviceProperty(address, propertyName, value);
});
}
return promise.then(function() {
return address;
});
}
/**
* Remove Bluetooth remote devices in scatternet.
*
* Use QEMU command 'bt remote remove <addr>' to remove a specific virtual
* Bluetooth remote device in scatternet or remove them all by QEMU command
* 'bt remote remove BDADDR_ALL'.
*
* @param aAddress
* The string of Bluetooth address with format xx:xx:xx:xx:xx:xx.
*
* Fulfill params:
* result -- an array of emulator response lines.
* Reject params: (none)
*
* @return A promise object.
*/
function removeEmulatorRemoteDevice(aAddress) {
let cmd = "bt remote remove " + aAddress;
return runEmulatorCmdSafe(cmd)
.then(function(aResults) {
// 'bt remote remove <bd_addr>' returns a list of removed device one at a line.
// The last item is "OK".
return aResults.slice(0, -1);
});
}
/**
* Set a property for a Bluetooth device.
*
* Use QEMU command 'bt property <bd_addr> <prop_name> <value>' to set property.
*
* Fulfill params:
* result -- an array of emulator response lines.
* Reject params:
* result -- an array of emulator response lines.
*
* @param aAddress
* The string of Bluetooth address with format xx:xx:xx:xx:xx:xx.
* @param aPropertyName
* The property name of Bluetooth device.
* @param aValue
* The new value of the specifc property.
*
* @return A deferred promise.
*/
function setEmulatorDeviceProperty(aAddress, aPropertyName, aValue) {
let cmd = "bt property " + aAddress + " " + aPropertyName + " " + aValue;
return runEmulatorCmdSafe(cmd);
}
/**
* Get a property from a Bluetooth device.
*
* Use QEMU command 'bt property <bd_addr> <prop_name>' to get properties.
*
* Fulfill params:
* result -- a string with format <prop_name>: <value_of_prop>
* Reject params:
* result -- an array of emulator response lines.
*
* @param aAddress
* The string of Bluetooth address with format xx:xx:xx:xx:xx:xx.
* @param aPropertyName
* The property name of Bluetooth device.
*
* @return A deferred promise.
*/
function getEmulatorDeviceProperty(aAddress, aPropertyName) {
let cmd = "bt property " + aAddress + " " + aPropertyName;
return runEmulatorCmdSafe(cmd)
.then(aResults => aResults[0]);
}
/**
* Start discovering Bluetooth devices.
*
* Allows the device's adapter to start seeking for remote devices.
*
* Fulfill params: (none)
* Reject params: a DOMError
*
* @param aAdapter
* A BluetoothAdapter which is used to interact with local BT device.
*
* @return A deferred promise.
*/
function startDiscovery(aAdapter) {
let request = aAdapter.startDiscovery();
return request.then(function resolve() {
// TODO (bug 892207): Make Bluetooth APIs available for 3rd party apps.
// Currently, discovering state wouldn't change immediately here.
// We would turn on this check when the redesigned API are landed.
// is(aAdapter.discovering, false, "BluetoothAdapter.discovering");
log(" Start discovery - Success");
}, function reject(aError) {
ok(false, "Start discovery - Fail");
throw aError;
});
}
/**
* Stop discovering Bluetooth devices.
*
* Allows the device's adapter to stop seeking for remote devices.
*
* Fulfill params: (none)
* Reject params: a DOMError
*
* @param aAdapter
* A BluetoothAdapter which is used to interact with local BT device.
*
* @return A deferred promise.
*/
function stopDiscovery(aAdapter) {
let request = aAdapter.stopDiscovery();
return request.then(function resolve() {
// TODO (bug 892207): Make Bluetooth APIs available for 3rd party apps.
// Currently, discovering state wouldn't change immediately here.
// We would turn on this check when the redesigned API are landed.
// is(aAdapter.discovering, false, "BluetoothAdapter.discovering");
log(" Stop discovery - Success");
}, function reject(aError) {
ok(false, "Stop discovery - Fail");
throw aError;
});
}
/**
* Wait for 'devicefound' event of specified devices.
*
* Resolve if that every specified devices has been found. Never reject.
*
* Fulfill params: an array which contains addresses of remote devices.
*
* @param aAdapter
* A BluetoothAdapter which is used to interact with local BT device.
* @param aRemoteAddresses
* An array which contains addresses of remote devices.
*
* @return A deferred promise.
*/
function waitForDevicesFound(aAdapter, aRemoteAddresses) {
let deferred = Promise.defer();
var addrArray = [];
aAdapter.addEventListener("devicefound", function onevent(aEvent) {
if(aRemoteAddresses.indexOf(aEvent.device.address) != -1) {
addrArray.push(aEvent.device.address);
}
if(addrArray.length == aRemoteAddresses.length) {
aAdapter.removeEventListener("devicefound", onevent);
ok(true, "BluetoothAdapter has found all remote devices.");
deferred.resolve(addrArray);
}
});
return deferred.promise;
}
/**
* Start discovering Bluetooth devices and wait for 'devicefound' events.
*
* Allows the device's adapter to start seeking for remote devices and wait for
* the 'devicefound' events of specified devices.
*
* Fulfill params: an array of addresses of found devices.
*
* @param aAdapter
* A BluetoothAdapter which is used to interact with local BT device.
* @param aRemoteAddresses
* An array which contains addresses of remote devices.
*
* @return A deferred promise.
*/
function startDiscoveryAndWaitDevicesFound(aAdapter, aRemoteAddresses) {
let promises = [];
promises.push(waitForDevicesFound(aAdapter, aRemoteAddresses));
promises.push(startDiscovery(aAdapter));
return Promise.all(promises)
.then(aResults => aResults[0]);
}
/**
* Start pairing a remote device.
*
* Start pairing a remote device with the device's adapter.
*
* Fulfill params: (none)
* Reject params: a DOMError
*
* @param aAdapter
* A BluetoothAdapter which is used to interact with local BT device.
* @param aDeviceAddress
* The string of remote Bluetooth address with format xx:xx:xx:xx:xx:xx.
*
* @return A deferred promise.
*/
function pair(aAdapter, aDeviceAddress) {
let request = aAdapter.pair(aDeviceAddress);
return request.then(function resolve() {
log(" Pair - Success");
}, function reject(aError) {
ok(false, "Pair - Fail");
throw aError;
});
}
/**
* Remove the paired device from the paired device list.
*
* Remove the paired device from the paired device list of the device's adapter.
*
* Fulfill params: (none)
* Reject params: a DOMError
*
* @param aAdapter
* A BluetoothAdapter which is used to interact with local BT device.
* @param aDeviceAddress
* The string of remote Bluetooth address with format xx:xx:xx:xx:xx:xx.
*
* @return A deferred promise.
*/
function unpair(aAdapter, aDeviceAddress) {
let request = aAdapter.unpair(aDeviceAddress);
return request.then(function resolve() {
log(" Unpair - Success");
}, function reject(aError) {
ok(false, "Unpair - Fail");
throw aError;
});
}
/**
* Start pairing a remote device and wait for "pairedstatuschanged" event.
*
* Start pairing a remote device with the device's adapter and wait for
* "pairedstatuschanged" event.
*
* Fulfill params: an array of promise results contains the fulfilled params of
* 'waitForAdapterEvent' and 'pair'.
*
* @param aAdapter
* A BluetoothAdapter which is used to interact with local BT device.
* @param aDeviceAddress
* The string of remote Bluetooth address with format xx:xx:xx:xx:xx:xx.
*
* @return A deferred promise.
*/
function pairDeviceAndWait(aAdapter, aDeviceAddress) {
let promises = [];
promises.push(waitForAdapterEvent(aAdapter, "pairedstatuschanged"));
promises.push(pair(aAdapter, aDeviceAddress));
return Promise.all(promises);
}
/**
* Get paried Bluetooth devices.
*
* The getPairedDevices method is used to retrieve the full list of all devices
* paired with the device's adapter.
*
* Fulfill params: a shallow copy of the Array of paired BluetoothDevice
* objects.
* Reject params: a DOMError
*
* @param aAdapter
* A BluetoothAdapter which is used to interact with local BT device.
*
* @return A deferred promise.
*/
function getPairedDevices(aAdapter) {
let request = aAdapter.getPairedDevices();
return request.then(function resolve() {
log(" getPairedDevices - Success");
let pairedDevices = request.result.slice();
return pairedDevices;
}, function reject(aError) {
ok(false, "getPairedDevices - Fail");
throw aError;
});
}
/**
* Get mozSettings value specified by @aKey.
*
* Resolve if that mozSettings value is retrieved successfully, reject
* otherwise.
*
* Fulfill params:
* The corresponding mozSettings value of the key.
* Reject params: (none)
*
* @param aKey
* A string.
*
* @return A deferred promise.
*/
function getSettings(aKey) {
let request = navigator.mozSettings.createLock().get(aKey);
return request.then(function resolve(aValue) {
ok(true, "getSettings(" + aKey + ")");
return aValue[aKey];
}, function reject(aError) {
ok(false, "getSettings(" + aKey + ")");
throw aError;
});
}
/**
* Set mozSettings values.
*
* Resolve if that mozSettings value is set successfully, reject otherwise.
*
* Fulfill params: (none)
* Reject params: (none)
*
* @param aSettings
* An object of format |{key1: value1, key2: value2, ...}|.
*
* @return A deferred promise.
*/
function setSettings(aSettings) {
let lock = window.navigator.mozSettings.createLock();
let request = lock.set(aSettings);
let deferred = Promise.defer();
lock.onsettingstransactionsuccess = function () {
ok(true, "setSettings(" + JSON.stringify(aSettings) + ")");
deferred.resolve();
};
lock.onsettingstransactionfailure = function (aEvent) {
ok(false, "setSettings(" + JSON.stringify(aSettings) + ")");
deferred.reject();
};
return deferred.promise;
}
/**
* Get mozSettings value of 'bluetooth.enabled'.
*
* Resolve if that mozSettings value is retrieved successfully, reject
* otherwise.
*
* Fulfill params:
* A boolean value.
* Reject params: (none)
*
* @return A deferred promise.
*/
function getBluetoothEnabled() {
return getSettings("bluetooth.enabled");
}
/**
* Set mozSettings value of 'bluetooth.enabled'.
*
* Resolve if that mozSettings value is set successfully, reject otherwise.
*
* Fulfill params: (none)
* Reject params: (none)
*
* @param aEnabled
* A boolean value.
*
* @return A deferred promise.
*/
function setBluetoothEnabled(aEnabled) {
let obj = {};
obj["bluetooth.enabled"] = aEnabled;
return setSettings(obj);
}
/**
* Push required permissions and test if |navigator.mozBluetooth| exists.
* Resolve if it does, reject otherwise.
*
* Fulfill params:
* bluetoothManager -- an reference to navigator.mozBluetooth.
* Reject params: (none)
*
* @param aPermissions
* Additional permissions to push before any test cases. Could be either
* a string or an array of strings.
*
* @return A deferred promise.
*/
function ensureBluetoothManager(aPermissions) {
let deferred = Promise.defer();
let permissions = ["bluetooth"];
if (aPermissions) {
if (Array.isArray(aPermissions)) {
permissions = permissions.concat(aPermissions);
} else if (typeof aPermissions == "string") {
permissions.push(aPermissions);
}
}
let obj = [];
for (let perm of permissions) {
obj.push({
"type": perm,
"allow": 1,
"context": document,
});
}
SpecialPowers.pushPermissions(obj, function() {
ok(true, "permissions pushed: " + JSON.stringify(permissions));
bluetoothManager = window.navigator.mozBluetooth;
log("navigator.mozBluetooth is " +
(bluetoothManager ? "available" : "unavailable"));
if (bluetoothManager instanceof BluetoothManager) {
deferred.resolve(bluetoothManager);
} else {
deferred.reject();
}
});
return deferred.promise;
}
/**
* Wait for one named BluetoothManager event.
*
* Resolve if that named event occurs. Never reject.
*
* Fulfill params: the DOMEvent passed.
*
* @param aEventName
* The name of the EventHandler.
*
* @return A deferred promise.
*/
function waitForManagerEvent(aEventName) {
let deferred = Promise.defer();
bluetoothManager.addEventListener(aEventName, function onevent(aEvent) {
bluetoothManager.removeEventListener(aEventName, onevent);
ok(true, "BluetoothManager event '" + aEventName + "' got.");
deferred.resolve(aEvent);
});
return deferred.promise;
}
/**
* Wait for one named BluetoothAdapter event.
*
* Resolve if that named event occurs. Never reject.
*
* Fulfill params: the DOMEvent passed.
*
* @param aAdapter
* A BluetoothAdapter which is used to interact with local BT device.
* @param aEventName
* The name of the EventHandler.
*
* @return A deferred promise.
*/
function waitForAdapterEvent(aAdapter, aEventName) {
let deferred = Promise.defer();
aAdapter.addEventListener(aEventName, function onevent(aEvent) {
aAdapter.removeEventListener(aEventName, onevent);
ok(true, "BluetoothAdapter event '" + aEventName + "' got.");
deferred.resolve(aEvent);
});
return deferred.promise;
}
/**
* Convenient function for setBluetoothEnabled and waitForManagerEvent
* combined.
*
* Resolve if that named event occurs. Reject if we can't set settings.
*
* Fulfill params: an array of promise results contains the fulfill params of
* 'waitForManagerEvent' and 'setBluetoothEnabled'.
* Reject params: (none)
*
* @return A deferred promise.
*/
function setBluetoothEnabledAndWait(aEnabled) {
let promises = [];
// Bug 969109 - Intermittent test_dom_BluetoothManager_adapteradded.js
//
// Here we want to wait for two events coming up -- Bluetooth "settings-set"
// event and one of "enabled"/"disabled" events. Special care is taken here
// to ensure that we can always receive that "enabled"/"disabled" event by
// installing the event handler *before* we ever enable/disable Bluetooth. Or
// we might just miss those events and get a timeout error.
promises.push(waitForManagerEvent(aEnabled ? "enabled" : "disabled"));
promises.push(setBluetoothEnabled(aEnabled));
return Promise.all(promises);
}
/**
* Get default adapter.
*
* Resolve if that default adapter is got, reject otherwise.
*
* Fulfill params: a BluetoothAdapter instance.
* Reject params: a DOMError, or null if if there is no adapter ready yet.
*
* @return A deferred promise.
*/
function getDefaultAdapter() {
let deferred = Promise.defer();
let request = bluetoothManager.getDefaultAdapter();
request.onsuccess = function(aEvent) {
let adapter = aEvent.target.result;
if (!(adapter instanceof BluetoothAdapter)) {
ok(false, "no BluetoothAdapter ready yet.");
deferred.reject(null);
return;
}
ok(true, "BluetoothAdapter got.");
// TODO: We have an adapter instance now, but some of its attributes may
// still remain unassigned/out-dated. Here we waste a few seconds to
// wait for the property changed events.
//
// See https://bugzilla.mozilla.org/show_bug.cgi?id=932914
window.setTimeout(function() {
deferred.resolve(adapter);
}, 3000);
};
request.onerror = function(aEvent) {
ok(false, "Failed to get default adapter.");
deferred.reject(aEvent.target.error);
};
return deferred.promise;
}
/**
* Wait for pending emulator transactions and call |finish()|.
*/
function cleanUp() {
// Use ok here so that we have at least one test run.
ok(true, ":: CLEANING UP ::");
waitFor(finish, function() {
return pendingEmulatorCmdCount === 0;
});
}
function startBluetoothTestBase(aPermissions, aTestCaseMain) {
ensureBluetoothManager(aPermissions)
.then(aTestCaseMain)
.then(cleanUp, function() {
ok(false, "Unhandled rejected promise.");
cleanUp();
});
}
function startBluetoothTest(aReenable, aTestCaseMain) {
startBluetoothTestBase(["settings-read", "settings-write", "settings-api-read", "settings-api-write"], function() {
let origEnabled, needEnable;
return getBluetoothEnabled()
.then(function(aEnabled) {
origEnabled = aEnabled;
needEnable = !aEnabled;
log("Original 'bluetooth.enabled' is " + origEnabled);
if (aEnabled && aReenable) {
log(" Disable 'bluetooth.enabled' ...");
needEnable = true;
return setBluetoothEnabledAndWait(false);
}
})
.then(function() {
if (needEnable) {
log(" Enable 'bluetooth.enabled' ...");
// See setBluetoothEnabledAndWait(). We must install all event
// handlers *before* enabling Bluetooth.
let promises = [];
promises.push(waitForManagerEvent("adapteradded"));
promises.push(setBluetoothEnabledAndWait(true));
return Promise.all(promises);
}
})
.then(getDefaultAdapter)
.then(aTestCaseMain)
.then(function() {
if (!origEnabled) {
return setBluetoothEnabledAndWait(false);
}
});
});
}

View File

@ -1,11 +0,0 @@
[DEFAULT]
b2g = true
browser = false
qemu = true
[test_dom_BluetoothManager_enabled.js]
[test_dom_BluetoothManager_adapteradded.js]
[test_dom_BluetoothAdapter_setters.js]
[test_dom_BluetoothAdapter_getters.js]
[test_dom_BluetoothAdapter_discovery.js]
[test_dom_BluetoothAdapter_pair.js]

View File

@ -1,39 +0,0 @@
/* 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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
///////////////////////////////////////////////////////////////////////////////
// Test Purpose:
// To verify that discovery process of BluetoothAdapter is correct.
// Use B2G emulator commands to add/remove remote devices to simulate
// discovering behavior.
//
// Test Coverage:
// - BluetoothAdapter.startDiscovery()
// - BluetoothAdapter.stopDiscovery()
// - BluetoothAdapter.ondevicefound()
// - BluetoothAdapter.discovering [Temporarily turned off until BT API update]
//
///////////////////////////////////////////////////////////////////////////////
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = 'head.js';
startBluetoothTest(true, function testCaseMain(aAdapter) {
log("Testing the discovery process of BluetoothAdapter ...");
return Promise.resolve()
.then(() => removeEmulatorRemoteDevice(BDADDR_ALL))
.then(() => addEmulatorRemoteDevice(null))
.then(function(aRemoteAddress) {
let promises = [];
promises.push(waitForAdapterEvent(aAdapter, "devicefound"));
promises.push(startDiscovery(aAdapter));
return Promise.all(promises)
.then(function(aResults) {
is(aResults[0].device.address, aRemoteAddress, "BluetoothDevice.address");
});
})
.then(() => stopDiscovery(aAdapter))
.then(() => removeEmulatorRemoteDevice(BDADDR_ALL));
});

View File

@ -1,43 +0,0 @@
/* 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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
///////////////////////////////////////////////////////////////////////////////
// Test Purpose:
// To verify that the properties of BluetoothAdapter can be updated and
// retrieved correctly. Use B2G emulator commands to set properties for this
// test case.
//
// Test Coverage:
// - BluetoothAdapter.name
// - BluetoothAdapter.address
// - BluetoothAdapter.class
// - BluetoothAdapter.discoverable
// - BluetoothAdapter.discovering
// ( P.S. Don't include [BluetoothAdapter.uuids], [BluetoothAdapter.devices] )
//
///////////////////////////////////////////////////////////////////////////////
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = 'head.js';
function testAdapterGetter(aAdapter, aPropertyName, aParamName, aExpected) {
let cmd = "bt property " + BDADDR_LOCAL + " " + aParamName;
return runEmulatorCmdSafe(cmd)
.then(function(aResults) {
is(aResults[1], "OK", "The status report from emulator command.");
log(" Got adapter " + aResults[0]);
is(aResults[0], aParamName + ": " + aExpected, "BluetoothAdapter." + aPropertyName);
});
}
startBluetoothTest(true, function testCaseMain(aAdapter) {
log("Checking the correctness of BluetoothAdapter properties ...");
return Promise.resolve()
.then(() => testAdapterGetter(aAdapter, "name", "name", aAdapter.name))
.then(() => testAdapterGetter(aAdapter, "address", "address", aAdapter.address))
.then(() => testAdapterGetter(aAdapter, "class", "cod", "0x" + aAdapter.class.toString(16)))
.then(() => testAdapterGetter(aAdapter, "discoverable", "discoverable", aAdapter.discoverable.toString()))
.then(() => testAdapterGetter(aAdapter, "discovering", "discovering", aAdapter.discovering.toString()));
});

View File

@ -1,66 +0,0 @@
/* 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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
///////////////////////////////////////////////////////////////////////////////
// Test Purpose:
// To verify that pairing process of BluetoothAdapter is correct.
// Use B2G emulator commands to add/remove remote devices to simulate
// discovering behavior. With current emulator implemation, the pair method
// between adapter and remote device would be 'confirmation'.
//
// Test Coverage:
// - BluetoothAdapter.startDiscovery()
// - BluetoothAdapter.stopDiscovery()
// - BluetoothAdapter.pair()
// - BluetoothAdapter.unpair()
// - BluetoothAdapter.onpairedstatuschanged()
// - BluetoothAdapter.setPairingConfirmation()
//
///////////////////////////////////////////////////////////////////////////////
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = 'head.js';
function replyPairingReq(aAdapter, aPairingEvent) {
switch (aPairingEvent.method) {
case 'confirmation':
log("The pairing passkey is " + aPairingEvent.passkey);
aAdapter.setPairingConfirmation(aPairingEvent.address, true);
break;
case 'pincode':
let pincode = BT_PAIRING_PINCODE;
aAdapter.setPinCode(aPairingEvent.address, pincode);
break;
case 'passkey':
let passkey = BT_PAIRING_PASSKEY;
aAdapter.setPasskey(aPairingEvent.address, passkey);
break;
default:
ok(false, "Unsupported pairing method. [" + aPairingEvent.method + "]");
}
}
startBluetoothTest(true, function testCaseMain(aAdapter) {
log("Testing the pairing process of BluetoothAdapter ...");
// listens to the system message BT_PAIRING_REQ
navigator.mozSetMessageHandler(BT_PAIRING_REQ,
(evt) => replyPairingReq(aAdapter, evt));
return Promise.resolve()
.then(() => removeEmulatorRemoteDevice(BDADDR_ALL))
.then(() => addEmulatorRemoteDevice())
.then((aRemoteAddress) =>
startDiscoveryAndWaitDevicesFound(aAdapter, [aRemoteAddress]))
.then((aRemoteAddresses) =>
stopDiscovery(aAdapter).then(() => aRemoteAddresses))
// 'aRemoteAddresses' is an arrary which contains addresses of discovered
// remote devices.
// Pairs with the first device in 'aRemoteAddresses' to test the functionality
// of BluetoothAdapter.pair and BluetoothAdapter.onpairedstatuschanged.
.then((aRemoteAddresses) => pairDeviceAndWait(aAdapter, aRemoteAddresses.pop()))
.then(() => getPairedDevices(aAdapter))
.then((aPairedDevices) => unpair(aAdapter, aPairedDevices.pop().address))
.then(() => removeEmulatorRemoteDevice(BDADDR_ALL));
});

View File

@ -1,83 +0,0 @@
/* 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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
///////////////////////////////////////////////////////////////////////////////
// Test Purpose:
// To verify that all setters of BluetoothAdapter (except for pairing related
// APIs) can change properties correctly.
//
// Test Coverage:
// - BluetoothAdapter.setName()
// - BluetoothAdapter.setDiscoverable()
// - BluetoothAdapter.setDiscoverableTimeout()
//
///////////////////////////////////////////////////////////////////////////////
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = 'head.js';
const BT_DEVICE_NAME = "User friendly name of local BT device";
function setName(aAdapter, aName) {
let deferred = Promise.defer();
let request = aAdapter.setName(aName);
request.onsuccess = function () {
log(" setName succeed: " + aName);
is(aAdapter.name, aName, "aAdapter.name");
deferred.resolve();
}
request.onerror = function () {
ok(false, "setName failed")
deferred.reject();
}
return deferred.promise;
}
function setDiscoverable(aAdapter, aIsDiscoverable) {
let deferred = Promise.defer();
let request = aAdapter.setDiscoverable(aIsDiscoverable);
request.onsuccess = function () {
log(" setDiscoverable succeed: " + aIsDiscoverable);
is(aAdapter.discoverable, aIsDiscoverable, "aAdapter.discoverable");
deferred.resolve();
}
request.onerror = function () {
ok(false, "setDiscoverable failed")
deferred.reject();
}
return deferred.promise;
}
function setDiscoverableTimeout(aAdapter, aTimeout) {
let deferred = Promise.defer();
let request = aAdapter.setDiscoverableTimeout(aTimeout);
request.onsuccess = function () {
log(" setDiscoverableTimeout succeed: " + aTimeout);
is(aAdapter.discoverableTimeout, aTimeout, "aAdapter.discoverableTimeout");
deferred.resolve();
}
request.onerror = function () {
ok(false, "setDiscoverableTimeout failed")
deferred.reject();
}
return deferred.promise;
}
startBluetoothTest(true, function testCaseMain(aAdapter) {
log("Testing BluetoothAdapter setters ...");
return Promise.resolve()
.then( () => setName(aAdapter, BT_DEVICE_NAME) )
.then( () => setDiscoverableTimeout(aAdapter, 180) )
.then( () => setDiscoverable(aAdapter, true) )
.then( () => setName(aAdapter, EMULATOR_NAME) )
.then( () => setDiscoverable(aAdapter, false) )
.then( () => setDiscoverableTimeout(aAdapter, 120) );
});

View File

@ -1,17 +0,0 @@
/* 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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = 'head.js';
startBluetoothTest(true, function testCaseMain(aAdapter) {
log("Checking adapter attributes ...");
is(aAdapter.name, EMULATOR_NAME, "adapter.name");
is(aAdapter.class, EMULATOR_CLASS, "adapter.class");
is(aAdapter.address, EMULATOR_ADDRESS, "adapter.address");
is(aAdapter.discovering, false, "adapter.discovering");
is(aAdapter.discoverable, false, "adapter.discoverable");
is(aAdapter.discoverableTimeout, 120, "adapter.discoverableTimeout");
});

View File

@ -1,69 +0,0 @@
/* 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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = 'head.js';
function waitEitherEnabledOrDisabled() {
let deferred = Promise.defer();
function onEnabledDisabled(aEvent) {
bluetoothManager.removeEventListener("adapteradded", onEnabledDisabled);
bluetoothManager.removeEventListener("disabled", onEnabledDisabled);
ok(true, "Got event " + aEvent.type);
deferred.resolve(aEvent.type === "adapteradded");
}
// Listen 'adapteradded' rather than 'enabled' since the current API can't
// disable BT before the BT adapter is initialized.
// We should listen to 'enabled' when gecko can handle the case I mentioned
// above, please refer to the follow-up bug 973482.
bluetoothManager.addEventListener("adapteradded", onEnabledDisabled);
bluetoothManager.addEventListener("disabled", onEnabledDisabled);
return deferred.promise;
}
function test(aEnabled) {
log("Testing 'bluetooth.enabled' => " + aEnabled);
let deferred = Promise.defer();
// Ensures that we can always receive that "enabled"/"disabled" event by
// installing the event handler *before* we ever enable/disable Bluetooth. Or
// we might just miss those events and get a timeout error.
let promises = [];
promises.push(waitEitherEnabledOrDisabled());
promises.push(setBluetoothEnabled(aEnabled));
Promise.all(promises)
.then(function(aResults) {
/* aResults is an array of two elements:
* [ <result of waitEitherEnabledOrDisabled>,
* <result of setBluetoothEnabled>]
*/
log(" Examine results " + JSON.stringify(aResults));
is(bluetoothManager.enabled, aEnabled, "bluetoothManager.enabled");
is(aResults[0], aEnabled, "'adapteradded' event received");
if (bluetoothManager.enabled === aEnabled && aResults[0] === aEnabled) {
deferred.resolve();
} else {
deferred.reject();
}
});
return deferred.promise;
}
startBluetoothTestBase(["settings-read", "settings-write", "settings-api-read", "settings-api-write"],
function testCaseMain() {
return getBluetoothEnabled()
.then(function(aEnabled) {
log("Original 'bluetooth.enabled' is " + aEnabled);
// Set to !aEnabled and reset back to aEnabled.
return test(!aEnabled).then(test.bind(null, aEnabled));
});
});

View File

@ -14,7 +14,7 @@
#include "nsIPrincipal.h"
#include "nsTArrayHelpers.h"
#include "mozilla/dom/BluetoothAdapter2Binding.h"
#include "mozilla/dom/BluetoothAdapterBinding.h"
#include "mozilla/dom/BluetoothAttributeEvent.h"
#include "mozilla/dom/BluetoothStatusChangedEvent.h"
#include "mozilla/dom/ContentChild.h"

View File

@ -10,7 +10,7 @@
#include "BluetoothCommon.h"
#include "mozilla/Attributes.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/dom/BluetoothAdapter2Binding.h"
#include "mozilla/dom/BluetoothAdapterBinding.h"
#include "mozilla/dom/BluetoothDeviceEvent.h"
#include "mozilla/dom/Promise.h"
#include "nsCOMPtr.h"

View File

@ -9,7 +9,7 @@
#include "BluetoothUtils.h"
#include "mozilla/dom/BluetoothAttributeEvent.h"
#include "mozilla/dom/BluetoothDevice2Binding.h"
#include "mozilla/dom/BluetoothDeviceBinding.h"
#include "mozilla/dom/bluetooth/BluetoothClassOfDevice.h"
#include "mozilla/dom/bluetooth/BluetoothDevice.h"
#include "mozilla/dom/bluetooth/BluetoothGatt.h"

View File

@ -9,7 +9,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/dom/BluetoothDevice2Binding.h"
#include "mozilla/dom/BluetoothDeviceBinding.h"
#include "mozilla/dom/bluetooth/BluetoothCommon.h"
#include "nsString.h"
#include "nsCOMPtr.h"

View File

@ -12,7 +12,7 @@
#include "mozilla/dom/bluetooth/BluetoothAdapter.h"
#include "mozilla/dom/bluetooth/BluetoothManager.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/dom/BluetoothManager2Binding.h"
#include "mozilla/dom/BluetoothManagerBinding.h"
#include "mozilla/Services.h"
#include "nsContentUtils.h"
#include "nsDOMClassInfo.h"

View File

@ -23,25 +23,6 @@ if CONFIG['MOZ_B2G_BT']:
'BluetoothRilListener.cpp'
]
if CONFIG['MOZ_B2G_BT_API_V1']:
SOURCES += [
'bluetooth1/BluetoothAdapter.cpp',
'bluetooth1/BluetoothDevice.cpp',
'bluetooth1/BluetoothManager.cpp',
'bluetooth1/BluetoothProfileController.cpp',
'bluetooth1/BluetoothPropertyContainer.cpp',
'bluetooth1/BluetoothReplyRunnable.cpp',
'bluetooth1/BluetoothService.cpp',
'bluetooth1/ipc/BluetoothChild.cpp',
'bluetooth1/ipc/BluetoothParent.cpp',
'bluetooth1/ipc/BluetoothServiceChildProcess.cpp',
]
LOCAL_INCLUDES += [
'bluetooth1',
'bluetooth1/ipc',
]
DEFINES['MOZ_B2G_BT_API_V1'] = True
else:
SOURCES += [
'bluetooth2/BluetoothAdapter.cpp',
'bluetooth2/BluetoothClassOfDevice.cpp',
@ -98,6 +79,7 @@ if CONFIG['MOZ_B2G_BT']:
'bluedroid/BluetoothDaemonInterface.cpp',
'bluedroid/BluetoothDaemonSetupInterface.cpp',
'bluedroid/BluetoothDaemonSocketInterface.cpp',
'bluedroid/BluetoothGattManager.cpp',
'bluedroid/BluetoothOppManager.cpp',
'bluedroid/BluetoothPbapManager.cpp',
'bluedroid/BluetoothServiceBluedroid.cpp',
@ -122,10 +104,6 @@ if CONFIG['MOZ_B2G_BT']:
LOCAL_INCLUDES += [
'bluedroid/hfp-fallback',
]
if not CONFIG['MOZ_B2G_BT_API_V1']:
SOURCES += [
'bluedroid/BluetoothGattManager.cpp',
]
DEFINES['MOZ_B2G_BT_DAEMON'] = True
elif CONFIG['MOZ_ENABLE_DBUS']:
@ -149,25 +127,6 @@ if CONFIG['MOZ_B2G_BT']:
# Exported interfaces
#
EXPORTS.mozilla.dom.bluetooth += [
'BluetoothCommon.h'
]
if CONFIG['MOZ_B2G_BT_API_V1']:
EXPORTS.mozilla.dom.bluetooth.ipc += [
'bluetooth1/ipc/BluetoothMessageUtils.h',
]
EXPORTS.mozilla.dom.bluetooth += [
'bluetooth1/BluetoothAdapter.h',
'bluetooth1/BluetoothDevice.h',
'bluetooth1/BluetoothManager.h',
]
IPDL_SOURCES += [
'bluetooth1/ipc/BluetoothTypes.ipdlh',
'bluetooth1/ipc/PBluetooth.ipdl',
'bluetooth1/ipc/PBluetoothRequest.ipdl',
]
else:
EXPORTS.mozilla.dom.bluetooth.ipc += [
'bluetooth2/ipc/BluetoothMessageUtils.h',
]
@ -185,6 +144,7 @@ else:
'bluetooth2/BluetoothManager.h',
'bluetooth2/BluetoothPairingHandle.h',
'bluetooth2/BluetoothPairingListener.h',
'BluetoothCommon.h'
]
IPDL_SOURCES += [
'bluetooth2/ipc/BluetoothTypes.ipdlh',

View File

@ -64,10 +64,6 @@ const kEventConstructors = {
return new BluetoothDeviceEvent(aName, aProps);
},
},
BluetoothDiscoveryStateChangedEvent: { create: function (aName, aProps) {
return new BluetoothDiscoveryStateChangedEvent(aName, aProps);
},
},
BluetoothGattCharacteristicEvent: { create: function (aName, aProps) {
return new BluetoothGattCharacteristicEvent(aName, aProps);
},

View File

@ -129,6 +129,8 @@ LOCAL_INCLUDES += [
'/docshell/base',
'/dom/base',
'/dom/bluetooth',
'/dom/bluetooth/bluetooth2',
'/dom/bluetooth/bluetooth2/ipc',
'/dom/devicestorage',
'/dom/filesystem',
'/dom/fmradio/ipc',
@ -167,17 +169,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gtk2', 'gonk', 'qt'):
if CONFIG['MOZ_TOOLKIT_SEARCH']:
DEFINES['MOZ_TOOLKIT_SEARCH'] = True
if CONFIG['MOZ_B2G_BT_API_V1']:
LOCAL_INCLUDES += [
'/dom/bluetooth/bluetooth1',
'/dom/bluetooth/bluetooth1/ipc',
]
else:
LOCAL_INCLUDES += [
'/dom/bluetooth/bluetooth2',
'/dom/bluetooth/bluetooth2/ipc',
]
JAR_MANIFESTS += ['jar.mn']
BROWSER_CHROME_MANIFESTS += ['tests/browser.ini']

View File

@ -120,17 +120,9 @@ include('/ipc/chromium/chromium-config.mozbuild')
LOCAL_INCLUDES += [
'/dom/base',
'/dom/bluetooth',
'/dom/bluetooth/bluetooth2',
'/dom/geolocation',
'/dom/wifi',
]
if CONFIG['MOZ_B2G_BT_API_V1']:
LOCAL_INCLUDES += [
'/dom/bluetooth/bluetooth1',
]
else:
LOCAL_INCLUDES += [
'/dom/bluetooth/bluetooth2',
]
FINAL_LIBRARY = 'xul'

View File

@ -1,19 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
[Constructor(DOMString type,
optional BluetoothDiscoveryStateChangedEventInit eventInitDict),
CheckAnyPermissions="bluetooth"]
interface BluetoothDiscoveryStateChangedEvent : Event
{
readonly attribute boolean discovering;
};
dictionary BluetoothDiscoveryStateChangedEventInit : EventInit
{
boolean discovering = false;
};

View File

@ -665,17 +665,10 @@ if CONFIG['MOZ_DEBUG']:
'TestInterfaceJSMaplikeSetlike.webidl']
if CONFIG['MOZ_B2G_BT']:
if CONFIG['MOZ_B2G_BT_API_V1']:
WEBIDL_FILES += [
'BluetoothAdapter.webidl',
'BluetoothDevice.webidl',
'BluetoothManager.webidl',
]
else:
WEBIDL_FILES += [
'BluetoothAdapter2.webidl',
'BluetoothClassOfDevice.webidl',
'BluetoothDevice2.webidl',
'BluetoothDevice.webidl',
'BluetoothDiscoveryHandle.webidl',
'BluetoothGatt.webidl',
'BluetoothGattCharacteristic.webidl',
@ -683,7 +676,7 @@ if CONFIG['MOZ_B2G_BT']:
'BluetoothGattServer.webidl',
'BluetoothGattService.webidl',
'BluetoothLeDeviceEvent.webidl',
'BluetoothManager2.webidl',
'BluetoothManager.webidl',
'BluetoothPairingHandle.webidl',
'BluetoothPairingListener.webidl',
]
@ -826,20 +819,12 @@ if CONFIG['MOZ_GAMEPAD']:
]
if CONFIG['MOZ_B2G_BT']:
if CONFIG['MOZ_B2G_BT_API_V1']:
GENERATED_EVENTS_WEBIDL_FILES += [
'BluetoothDiscoveryStateChangedEvent.webidl',
]
else:
GENERATED_EVENTS_WEBIDL_FILES += [
'BluetoothAdapterEvent.webidl',
'BluetoothAttributeEvent.webidl',
'BluetoothDeviceEvent.webidl',
'BluetoothGattCharacteristicEvent.webidl',
'BluetoothPairingEvent.webidl',
]
GENERATED_EVENTS_WEBIDL_FILES += [
'BluetoothDeviceEvent.webidl',
'BluetoothStatusChangedEvent.webidl',
]

View File

@ -73,12 +73,5 @@ LOCAL_INCLUDES += [
if CONFIG['MOZ_B2G_BT']:
LOCAL_INCLUDES += [
'/dom/bluetooth',
]
if CONFIG['MOZ_B2G_BT_API_V1']:
LOCAL_INCLUDES += [
'/dom/bluetooth/bluetooth1',
]
else:
LOCAL_INCLUDES += [
'/dom/bluetooth/bluetooth2',
]

View File

@ -107,13 +107,6 @@ if CONFIG['MOZ_B2G_FM']:
if CONFIG['MOZ_B2G_BT']:
LOCAL_INCLUDES += [
'/dom/bluetooth',
]
if CONFIG['MOZ_B2G_BT_API_V1']:
LOCAL_INCLUDES += [
'/dom/bluetooth/bluetooth1',
]
else:
LOCAL_INCLUDES += [
'/dom/bluetooth/bluetooth2',
]