mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
671d1a817e
Backed out changeset 7d06b68c44d0 (bug 1079335) Backed out changeset 92030169528e (bug 1079301) Backed out changeset c09d7f95554a (bug 1047483) Backed out changeset c199f1057d7e (bug 1047483) Backed out changeset 18830d07884c (bug 1047483) Backed out changeset e087289ccfbb (bug 1047483) Backed out changeset 6238ff5d3ed0 (bug 1047483) CLOSED TREE --HG-- rename : content/base/public/File.h => content/base/public/nsDOMFile.h rename : content/base/src/MultipartFileImpl.cpp => content/base/src/nsDOMBlobBuilder.cpp rename : content/base/src/MultipartFileImpl.h => content/base/src/nsDOMBlobBuilder.h rename : content/base/src/File.cpp => content/base/src/nsDOMFile.cpp
1073 lines
29 KiB
C++
1073 lines
29 KiB
C++
/* -*- 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 "base/basictypes.h"
|
|
#include "nsDOMClassInfo.h"
|
|
#include "nsTArrayHelpers.h"
|
|
#include "DOMRequest.h"
|
|
#include "nsThreadUtils.h"
|
|
|
|
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
|
#include "mozilla/dom/BluetoothAdapterBinding.h"
|
|
#include "mozilla/dom/BluetoothDeviceEvent.h"
|
|
#include "mozilla/dom/BluetoothDiscoveryStateChangedEvent.h"
|
|
#include "mozilla/dom/BluetoothStatusChangedEvent.h"
|
|
#include "mozilla/dom/ContentChild.h"
|
|
#include "mozilla/dom/ScriptSettings.h"
|
|
#include "mozilla/LazyIdleThread.h"
|
|
|
|
#include "BluetoothAdapter.h"
|
|
#include "BluetoothDevice.h"
|
|
#include "BluetoothReplyRunnable.h"
|
|
#include "BluetoothService.h"
|
|
#include "BluetoothUtils.h"
|
|
|
|
using namespace mozilla;
|
|
using namespace mozilla::dom;
|
|
|
|
USING_BLUETOOTH_NAMESPACE
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_CLASS(BluetoothAdapter)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(BluetoothAdapter,
|
|
DOMEventTargetHelper)
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mJsUuids)
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mJsDeviceAddresses)
|
|
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BluetoothAdapter,
|
|
DOMEventTargetHelper)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BluetoothAdapter,
|
|
DOMEventTargetHelper)
|
|
tmp->Unroot();
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
|
|
|
// QueryInterface implementation for BluetoothAdapter
|
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BluetoothAdapter)
|
|
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
|
|
|
NS_IMPL_ADDREF_INHERITED(BluetoothAdapter, DOMEventTargetHelper)
|
|
NS_IMPL_RELEASE_INHERITED(BluetoothAdapter, DOMEventTargetHelper)
|
|
|
|
class GetDevicesTask : public BluetoothReplyRunnable
|
|
{
|
|
public:
|
|
GetDevicesTask(BluetoothAdapter* aAdapterPtr,
|
|
nsIDOMDOMRequest* aReq) :
|
|
BluetoothReplyRunnable(aReq),
|
|
mAdapterPtr(aAdapterPtr)
|
|
{
|
|
MOZ_ASSERT(aReq && aAdapterPtr);
|
|
}
|
|
|
|
virtual 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;
|
|
}
|
|
|
|
const InfallibleTArray<BluetoothNamedValue>& values =
|
|
v.get_ArrayOfBluetoothNamedValue();
|
|
|
|
nsTArray<nsRefPtr<BluetoothDevice> > devices;
|
|
for (uint32_t i = 0; i < values.Length(); i++) {
|
|
const BluetoothValue properties = values[i].value();
|
|
if (properties.type() != BluetoothValue::TArrayOfBluetoothNamedValue) {
|
|
BT_WARNING("Not a BluetoothNamedValue array!");
|
|
SetError(NS_LITERAL_STRING("BluetoothReplyTypeError"));
|
|
return false;
|
|
}
|
|
nsRefPtr<BluetoothDevice> d =
|
|
BluetoothDevice::Create(mAdapterPtr->GetOwner(),
|
|
mAdapterPtr->GetPath(),
|
|
properties);
|
|
devices.AppendElement(d);
|
|
}
|
|
|
|
AutoJSAPI jsapi;
|
|
if (!jsapi.Init(mAdapterPtr->GetOwner())) {
|
|
BT_WARNING("Failed to initialise AutoJSAPI!");
|
|
SetError(NS_LITERAL_STRING("BluetoothAutoJSAPIInitError"));
|
|
return false;
|
|
}
|
|
JSContext* cx = jsapi.cx();
|
|
JS::Rooted<JSObject*> JsDevices(cx);
|
|
if (NS_FAILED(nsTArrayToJSArray(cx, devices, &JsDevices))) {
|
|
BT_WARNING("Cannot create JS array!");
|
|
SetError(NS_LITERAL_STRING("BluetoothError"));
|
|
return false;
|
|
}
|
|
|
|
aValue.setObject(*JsDevices);
|
|
return true;
|
|
}
|
|
|
|
void
|
|
ReleaseMembers()
|
|
{
|
|
BluetoothReplyRunnable::ReleaseMembers();
|
|
mAdapterPtr = nullptr;
|
|
}
|
|
private:
|
|
nsRefPtr<BluetoothAdapter> mAdapterPtr;
|
|
};
|
|
|
|
class GetConnectionStatusTask : public BluetoothReplyRunnable
|
|
{
|
|
public:
|
|
GetConnectionStatusTask(nsIDOMDOMRequest* aReq) :
|
|
BluetoothReplyRunnable(aReq)
|
|
{
|
|
MOZ_ASSERT(aReq);
|
|
}
|
|
|
|
virtual bool ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue)
|
|
{
|
|
aValue.setUndefined();
|
|
|
|
const BluetoothValue& v = mReply->get_BluetoothReplySuccess().value();
|
|
if (v.type() != BluetoothValue::Tbool) {
|
|
BT_WARNING("Not a boolean!");
|
|
SetError(NS_LITERAL_STRING("BluetoothReplyTypeError"));
|
|
return false;
|
|
}
|
|
|
|
aValue.setBoolean(v.get_bool());
|
|
return true;
|
|
}
|
|
|
|
void
|
|
ReleaseMembers()
|
|
{
|
|
BluetoothReplyRunnable::ReleaseMembers();
|
|
}
|
|
};
|
|
|
|
static int kCreatePairedDeviceTimeout = 50000; // unit: msec
|
|
|
|
BluetoothAdapter::BluetoothAdapter(nsPIDOMWindow* aWindow,
|
|
const BluetoothValue& aValue)
|
|
: DOMEventTargetHelper(aWindow)
|
|
, BluetoothPropertyContainer(BluetoothObjectType::TYPE_ADAPTER)
|
|
, mJsUuids(nullptr)
|
|
, mJsDeviceAddresses(nullptr)
|
|
, mDiscoverable(false)
|
|
, mDiscovering(false)
|
|
, mPairable(false)
|
|
, mPowered(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(NS_LITERAL_STRING(KEY_ADAPTER), this);
|
|
}
|
|
|
|
BluetoothAdapter::~BluetoothAdapter()
|
|
{
|
|
Unroot();
|
|
BluetoothService* bs = BluetoothService::Get();
|
|
// We can be null on shutdown, where this might happen
|
|
NS_ENSURE_TRUE_VOID(bs);
|
|
bs->UnregisterBluetoothSignalHandler(NS_LITERAL_STRING(KEY_ADAPTER), this);
|
|
}
|
|
|
|
void
|
|
BluetoothAdapter::DisconnectFromOwner()
|
|
{
|
|
DOMEventTargetHelper::DisconnectFromOwner();
|
|
|
|
BluetoothService* bs = BluetoothService::Get();
|
|
NS_ENSURE_TRUE_VOID(bs);
|
|
bs->UnregisterBluetoothSignalHandler(NS_LITERAL_STRING(KEY_ADAPTER), this);
|
|
}
|
|
|
|
void
|
|
BluetoothAdapter::Unroot()
|
|
{
|
|
if (!mIsRooted) {
|
|
return;
|
|
}
|
|
mJsUuids = nullptr;
|
|
mJsDeviceAddresses = nullptr;
|
|
mozilla::DropJSObjects(this);
|
|
mIsRooted = false;
|
|
}
|
|
|
|
void
|
|
BluetoothAdapter::Root()
|
|
{
|
|
if (mIsRooted) {
|
|
return;
|
|
}
|
|
mozilla::HoldJSObjects(this);
|
|
mIsRooted = true;
|
|
}
|
|
|
|
void
|
|
BluetoothAdapter::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("Address")) {
|
|
mAddress = value.get_nsString();
|
|
} else if (name.EqualsLiteral("Path")) {
|
|
mPath = value.get_nsString();
|
|
} else if (name.EqualsLiteral("Discoverable")) {
|
|
mDiscoverable = value.get_bool();
|
|
} else if (name.EqualsLiteral("Discovering")) {
|
|
mDiscovering = value.get_bool();
|
|
} else if (name.EqualsLiteral("Pairable")) {
|
|
mPairable = value.get_bool();
|
|
} else if (name.EqualsLiteral("Powered")) {
|
|
mPowered = value.get_bool();
|
|
} else if (name.EqualsLiteral("PairableTimeout")) {
|
|
mPairableTimeout = value.get_uint32_t();
|
|
} else if (name.EqualsLiteral("DiscoverableTimeout")) {
|
|
mDiscoverableTimeout = value.get_uint32_t();
|
|
} else if (name.EqualsLiteral("Class")) {
|
|
mClass = value.get_uint32_t();
|
|
} 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("Devices")) {
|
|
mDeviceAddresses = value.get_ArrayOfnsString();
|
|
|
|
AutoJSAPI jsapi;
|
|
if (!jsapi.Init(GetOwner())) {
|
|
BT_WARNING("Failed to initialise AutoJSAPI!");
|
|
return;
|
|
}
|
|
JSContext* cx = jsapi.cx();
|
|
JS::Rooted<JSObject*> deviceAddresses(cx);
|
|
if (NS_FAILED(nsTArrayToJSArray(cx, mDeviceAddresses, &deviceAddresses))) {
|
|
BT_WARNING("Cannot set JS Devices object!");
|
|
return;
|
|
}
|
|
mJsDeviceAddresses = deviceAddresses;
|
|
Root();
|
|
} else {
|
|
#ifdef DEBUG
|
|
nsCString warningMsg;
|
|
warningMsg.AssignLiteral("Not handling adapter property: ");
|
|
warningMsg.Append(NS_ConvertUTF16toUTF8(name));
|
|
BT_WARNING(warningMsg.get());
|
|
#endif
|
|
}
|
|
}
|
|
|
|
// static
|
|
already_AddRefed<BluetoothAdapter>
|
|
BluetoothAdapter::Create(nsPIDOMWindow* aWindow, const BluetoothValue& aValue)
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
MOZ_ASSERT(aWindow);
|
|
|
|
nsRefPtr<BluetoothAdapter> adapter = new BluetoothAdapter(aWindow, aValue);
|
|
return adapter.forget();
|
|
}
|
|
|
|
void
|
|
BluetoothAdapter::Notify(const BluetoothSignal& aData)
|
|
{
|
|
InfallibleTArray<BluetoothNamedValue> arr;
|
|
|
|
BT_LOGD("[A] %s: %s", __FUNCTION__, NS_ConvertUTF16toUTF8(aData.name()).get());
|
|
|
|
BluetoothValue v = aData.value();
|
|
if (aData.name().EqualsLiteral("DeviceFound")) {
|
|
nsRefPtr<BluetoothDevice> device = BluetoothDevice::Create(GetOwner(), mPath, aData.value());
|
|
|
|
BluetoothDeviceEventInit init;
|
|
init.mBubbles = false;
|
|
init.mCancelable = false;
|
|
init.mDevice = device;
|
|
nsRefPtr<BluetoothDeviceEvent> event =
|
|
BluetoothDeviceEvent::Constructor(this, NS_LITERAL_STRING("devicefound"), init);
|
|
DispatchTrustedEvent(event);
|
|
} else 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 if (aData.name().EqualsLiteral(DISCOVERY_STATE_CHANGED_ID)) {
|
|
MOZ_ASSERT(v.type() == BluetoothValue::Tbool);
|
|
|
|
BluetoothDiscoveryStateChangedEventInit init;
|
|
init.mDiscovering = v.get_bool();
|
|
|
|
nsRefPtr<BluetoothDiscoveryStateChangedEvent> event =
|
|
BluetoothDiscoveryStateChangedEvent::Constructor(
|
|
this, NS_LITERAL_STRING(DISCOVERY_STATE_CHANGED_ID), init);
|
|
DispatchTrustedEvent(event);
|
|
} else if (aData.name().EqualsLiteral(PAIRED_STATUS_CHANGED_ID) ||
|
|
aData.name().EqualsLiteral(HFP_STATUS_CHANGED_ID) ||
|
|
aData.name().EqualsLiteral(SCO_STATUS_CHANGED_ID) ||
|
|
aData.name().EqualsLiteral(A2DP_STATUS_CHANGED_ID)) {
|
|
MOZ_ASSERT(v.type() == BluetoothValue::TArrayOfBluetoothNamedValue);
|
|
const InfallibleTArray<BluetoothNamedValue>& arr =
|
|
v.get_ArrayOfBluetoothNamedValue();
|
|
|
|
MOZ_ASSERT(arr.Length() == 2 &&
|
|
arr[0].value().type() == BluetoothValue::TnsString &&
|
|
arr[1].value().type() == BluetoothValue::Tbool);
|
|
nsString address = arr[0].value().get_nsString();
|
|
bool status = arr[1].value().get_bool();
|
|
|
|
BluetoothStatusChangedEventInit init;
|
|
init.mBubbles = false;
|
|
init.mCancelable = false;
|
|
init.mAddress = address;
|
|
init.mStatus = status;
|
|
nsRefPtr<BluetoothStatusChangedEvent> event =
|
|
BluetoothStatusChangedEvent::Constructor(this, aData.name(), init);
|
|
DispatchTrustedEvent(event);
|
|
} else if (aData.name().EqualsLiteral(REQUEST_MEDIA_PLAYSTATUS_ID)) {
|
|
nsCOMPtr<nsIDOMEvent> event;
|
|
nsresult rv = NS_NewDOMEvent(getter_AddRefs(event), this, nullptr, nullptr);
|
|
NS_ENSURE_SUCCESS_VOID(rv);
|
|
|
|
rv = event->InitEvent(aData.name(), false, false);
|
|
NS_ENSURE_SUCCESS_VOID(rv);
|
|
|
|
DispatchTrustedEvent(event);
|
|
} else {
|
|
#ifdef DEBUG
|
|
nsCString warningMsg;
|
|
warningMsg.AssignLiteral("Not handling adapter signal: ");
|
|
warningMsg.Append(NS_ConvertUTF16toUTF8(aData.name()));
|
|
BT_WARNING(warningMsg.get());
|
|
#endif
|
|
}
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::StartStopDiscovery(bool aStart, ErrorResult& aRv)
|
|
{
|
|
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
|
|
if (!win) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
nsRefPtr<DOMRequest> request = new DOMRequest(win);
|
|
nsRefPtr<BluetoothVoidReplyRunnable> results =
|
|
new BluetoothVoidReplyRunnable(request);
|
|
|
|
BluetoothService* bs = BluetoothService::Get();
|
|
if (!bs) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
nsresult rv;
|
|
if (aStart) {
|
|
rv = bs->StartDiscoveryInternal(results);
|
|
} else {
|
|
rv = bs->StopDiscoveryInternal(results);
|
|
}
|
|
if (NS_FAILED(rv)) {
|
|
BT_WARNING("Start/Stop Discovery failed!");
|
|
aRv.Throw(rv);
|
|
return nullptr;
|
|
}
|
|
|
|
// mDiscovering is not set here, we'll get a Property update from our external
|
|
// protocol to tell us that it's been set.
|
|
|
|
return request.forget();
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::StartDiscovery(ErrorResult& aRv)
|
|
{
|
|
return StartStopDiscovery(true, aRv);
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::StopDiscovery(ErrorResult& aRv)
|
|
{
|
|
return StartStopDiscovery(false, aRv);
|
|
}
|
|
|
|
void
|
|
BluetoothAdapter::GetDevices(JSContext* aContext,
|
|
JS::MutableHandle<JS::Value> aDevices,
|
|
ErrorResult& aRv)
|
|
{
|
|
if (!mJsDeviceAddresses) {
|
|
BT_WARNING("Devices not yet set!\n");
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return;
|
|
}
|
|
|
|
JS::ExposeObjectToActiveJS(mJsDeviceAddresses);
|
|
aDevices.setObject(*mJsDeviceAddresses);
|
|
}
|
|
|
|
void
|
|
BluetoothAdapter::GetUuids(JSContext* aContext,
|
|
JS::MutableHandle<JS::Value> aUuids,
|
|
ErrorResult& aRv)
|
|
{
|
|
if (!mJsUuids) {
|
|
BT_WARNING("UUIDs not yet set!\n");
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return;
|
|
}
|
|
|
|
JS::ExposeObjectToActiveJS(mJsUuids);
|
|
aUuids.setObject(*mJsUuids);
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::SetName(const nsAString& aName, ErrorResult& aRv)
|
|
{
|
|
if (mName.Equals(aName)) {
|
|
return FirePropertyAlreadySet(GetOwner(), aRv);
|
|
}
|
|
nsString name(aName);
|
|
BluetoothValue value(name);
|
|
BluetoothNamedValue property(NS_LITERAL_STRING("Name"), value);
|
|
return SetProperty(GetOwner(), property, aRv);
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::SetDiscoverable(bool aDiscoverable, ErrorResult& aRv)
|
|
{
|
|
if (aDiscoverable == mDiscoverable) {
|
|
return FirePropertyAlreadySet(GetOwner(), aRv);
|
|
}
|
|
BluetoothValue value(aDiscoverable);
|
|
BluetoothNamedValue property(NS_LITERAL_STRING("Discoverable"), value);
|
|
return SetProperty(GetOwner(), property, aRv);
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::SetDiscoverableTimeout(uint32_t aDiscoverableTimeout, ErrorResult& aRv)
|
|
{
|
|
if (aDiscoverableTimeout == mDiscoverableTimeout) {
|
|
return FirePropertyAlreadySet(GetOwner(), aRv);
|
|
}
|
|
BluetoothValue value(aDiscoverableTimeout);
|
|
BluetoothNamedValue property(NS_LITERAL_STRING("DiscoverableTimeout"), value);
|
|
return SetProperty(GetOwner(), property, aRv);
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::GetConnectedDevices(uint16_t aServiceUuid, ErrorResult& aRv)
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
|
|
if (!win) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
nsRefPtr<DOMRequest> request = new DOMRequest(win);
|
|
nsRefPtr<BluetoothReplyRunnable> results =
|
|
new GetDevicesTask(this, request);
|
|
|
|
BluetoothService* bs = BluetoothService::Get();
|
|
if (!bs) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
nsresult rv = bs->GetConnectedDevicePropertiesInternal(aServiceUuid, results);
|
|
if (NS_FAILED(rv)) {
|
|
aRv.Throw(rv);
|
|
return nullptr;
|
|
}
|
|
|
|
return request.forget();
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::GetPairedDevices(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 GetDevicesTask(this, request);
|
|
|
|
BluetoothService* bs = BluetoothService::Get();
|
|
if (!bs) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
nsresult rv = bs->GetPairedDevicePropertiesInternal(mDeviceAddresses, results);
|
|
if (NS_FAILED(rv)) {
|
|
aRv.Throw(rv);
|
|
return nullptr;
|
|
}
|
|
|
|
return request.forget();
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::PairUnpair(bool aPair, const nsAString& aDeviceAddress,
|
|
ErrorResult& aRv)
|
|
{
|
|
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
|
|
if (!win) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
nsRefPtr<DOMRequest> request = new DOMRequest(win);
|
|
nsRefPtr<BluetoothVoidReplyRunnable> results =
|
|
new BluetoothVoidReplyRunnable(request);
|
|
|
|
BluetoothService* bs = BluetoothService::Get();
|
|
if (!bs) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
nsresult rv;
|
|
if (aPair) {
|
|
rv = bs->CreatePairedDeviceInternal(aDeviceAddress,
|
|
kCreatePairedDeviceTimeout,
|
|
results);
|
|
} else {
|
|
rv = bs->RemoveDeviceInternal(aDeviceAddress, results);
|
|
}
|
|
if (NS_FAILED(rv)) {
|
|
BT_WARNING("Pair/Unpair failed!");
|
|
aRv.Throw(rv);
|
|
return nullptr;
|
|
}
|
|
|
|
return request.forget();
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::Pair(const nsAString& aDeviceAddress, ErrorResult& aRv)
|
|
{
|
|
return PairUnpair(true, aDeviceAddress, aRv);
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::Unpair(const nsAString& aDeviceAddress, ErrorResult& aRv)
|
|
{
|
|
return PairUnpair(false, aDeviceAddress, aRv);
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::SetPinCode(const nsAString& aDeviceAddress,
|
|
const nsAString& aPinCode, ErrorResult& aRv)
|
|
{
|
|
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
|
|
if (!win) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
nsRefPtr<DOMRequest> request = new DOMRequest(win);
|
|
nsRefPtr<BluetoothVoidReplyRunnable> results =
|
|
new BluetoothVoidReplyRunnable(request);
|
|
|
|
BluetoothService* bs = BluetoothService::Get();
|
|
if (!bs) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
if (!bs->SetPinCodeInternal(aDeviceAddress, aPinCode, results)) {
|
|
BT_WARNING("SetPinCode failed!");
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
return request.forget();
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::SetPasskey(const nsAString& aDeviceAddress, uint32_t aPasskey,
|
|
ErrorResult& aRv)
|
|
{
|
|
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
|
|
if (!win) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
nsRefPtr<DOMRequest> request = new DOMRequest(win);
|
|
nsRefPtr<BluetoothVoidReplyRunnable> results =
|
|
new BluetoothVoidReplyRunnable(request);
|
|
|
|
BluetoothService* bs = BluetoothService::Get();
|
|
if (!bs) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
if (bs->SetPasskeyInternal(aDeviceAddress, aPasskey, results)) {
|
|
BT_WARNING("SetPasskeyInternal failed!");
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
return request.forget();
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::SetPairingConfirmation(const nsAString& aDeviceAddress,
|
|
bool aConfirmation, ErrorResult& aRv)
|
|
{
|
|
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
|
|
if (!win) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
nsRefPtr<DOMRequest> request = new DOMRequest(win);
|
|
nsRefPtr<BluetoothVoidReplyRunnable> results =
|
|
new BluetoothVoidReplyRunnable(request);
|
|
|
|
BluetoothService* bs = BluetoothService::Get();
|
|
if (!bs) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
if (!bs->SetPairingConfirmationInternal(aDeviceAddress,
|
|
aConfirmation,
|
|
results)) {
|
|
BT_WARNING("SetPairingConfirmation failed!");
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
return request.forget();
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::Connect(BluetoothDevice& aDevice,
|
|
const Optional<uint16_t>& aServiceUuid,
|
|
ErrorResult& aRv)
|
|
{
|
|
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
|
|
if (!win) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
nsRefPtr<DOMRequest> request = new DOMRequest(win);
|
|
nsRefPtr<BluetoothVoidReplyRunnable> results =
|
|
new BluetoothVoidReplyRunnable(request);
|
|
|
|
nsAutoString address;
|
|
aDevice.GetAddress(address);
|
|
uint32_t deviceClass = aDevice.Class();
|
|
uint16_t serviceUuid = 0;
|
|
if (aServiceUuid.WasPassed()) {
|
|
serviceUuid = aServiceUuid.Value();
|
|
}
|
|
|
|
BluetoothService* bs = BluetoothService::Get();
|
|
if (!bs) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
bs->Connect(address, deviceClass, serviceUuid, results);
|
|
|
|
return request.forget();
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::Disconnect(BluetoothDevice& aDevice,
|
|
const Optional<uint16_t>& aServiceUuid,
|
|
ErrorResult& aRv)
|
|
{
|
|
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
|
|
if (!win) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
nsRefPtr<DOMRequest> request = new DOMRequest(win);
|
|
nsRefPtr<BluetoothVoidReplyRunnable> results =
|
|
new BluetoothVoidReplyRunnable(request);
|
|
|
|
nsAutoString address;
|
|
aDevice.GetAddress(address);
|
|
uint16_t serviceUuid = 0;
|
|
if (aServiceUuid.WasPassed()) {
|
|
serviceUuid = aServiceUuid.Value();
|
|
}
|
|
|
|
BluetoothService* bs = BluetoothService::Get();
|
|
if (!bs) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
bs->Disconnect(address, serviceUuid, results);
|
|
|
|
return request.forget();
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::IsConnected(const uint16_t aServiceUuid, 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 GetConnectionStatusTask(request);
|
|
|
|
BluetoothService* bs = BluetoothService::Get();
|
|
if (!bs) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
bs->IsConnected(aServiceUuid, results);
|
|
|
|
return request.forget();
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::SendFile(const nsAString& aDeviceAddress,
|
|
nsIDOMBlob* aBlob, ErrorResult& aRv)
|
|
{
|
|
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
|
|
if (!win) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
nsRefPtr<DOMRequest> request = new DOMRequest(win);
|
|
nsRefPtr<BluetoothVoidReplyRunnable> results =
|
|
new BluetoothVoidReplyRunnable(request);
|
|
|
|
BluetoothService* bs = BluetoothService::Get();
|
|
if (!bs) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
if (XRE_GetProcessType() == GeckoProcessType_Default) {
|
|
// In-process transfer
|
|
bs->SendFile(aDeviceAddress, aBlob, results);
|
|
} else {
|
|
ContentChild *cc = ContentChild::GetSingleton();
|
|
if (!cc) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
BlobChild* actor = cc->GetOrCreateActorForBlob(aBlob);
|
|
if (!actor) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
bs->SendFile(aDeviceAddress, nullptr, actor, results);
|
|
}
|
|
|
|
return request.forget();
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::StopSendingFile(const nsAString& aDeviceAddress, ErrorResult& aRv)
|
|
{
|
|
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
|
|
if (!win) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
nsRefPtr<DOMRequest> request = new DOMRequest(win);
|
|
nsRefPtr<BluetoothVoidReplyRunnable> results =
|
|
new BluetoothVoidReplyRunnable(request);
|
|
|
|
BluetoothService* bs = BluetoothService::Get();
|
|
if (!bs) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
bs->StopSendingFile(aDeviceAddress, results);
|
|
|
|
return request.forget();
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::ConfirmReceivingFile(const nsAString& aDeviceAddress,
|
|
bool aConfirmation, ErrorResult& aRv)
|
|
{
|
|
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
|
|
if (!win) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
nsRefPtr<DOMRequest> request = new DOMRequest(win);
|
|
nsRefPtr<BluetoothVoidReplyRunnable> results =
|
|
new BluetoothVoidReplyRunnable(request);
|
|
|
|
BluetoothService* bs = BluetoothService::Get();
|
|
if (!bs) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
bs->ConfirmReceivingFile(aDeviceAddress, aConfirmation, results);
|
|
|
|
return request.forget();
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::ConnectSco(ErrorResult& aRv)
|
|
{
|
|
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
|
|
if (!win) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
nsRefPtr<DOMRequest> request = new DOMRequest(win);
|
|
nsRefPtr<BluetoothVoidReplyRunnable> results =
|
|
new BluetoothVoidReplyRunnable(request);
|
|
|
|
BluetoothService* bs = BluetoothService::Get();
|
|
if (!bs) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
bs->ConnectSco(results);
|
|
|
|
return request.forget();
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::DisconnectSco(ErrorResult& aRv)
|
|
{
|
|
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
|
|
if (!win) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
nsRefPtr<DOMRequest> request = new DOMRequest(win);
|
|
nsRefPtr<BluetoothVoidReplyRunnable> results =
|
|
new BluetoothVoidReplyRunnable(request);
|
|
|
|
BluetoothService* bs = BluetoothService::Get();
|
|
if (!bs) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
bs->DisconnectSco(results);
|
|
|
|
return request.forget();
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::IsScoConnected(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 GetConnectionStatusTask(request);
|
|
|
|
BluetoothService* bs = BluetoothService::Get();
|
|
if (!bs) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
bs->IsScoConnected(results);
|
|
|
|
return request.forget();
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::AnswerWaitingCall(ErrorResult& aRv)
|
|
{
|
|
#ifdef MOZ_B2G_RIL
|
|
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
|
|
if (!win) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
nsRefPtr<DOMRequest> request = new DOMRequest(win);
|
|
nsRefPtr<BluetoothVoidReplyRunnable> results =
|
|
new BluetoothVoidReplyRunnable(request);
|
|
|
|
BluetoothService* bs = BluetoothService::Get();
|
|
if (!bs) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
bs->AnswerWaitingCall(results);
|
|
|
|
return request.forget();
|
|
#else
|
|
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
|
|
return nullptr;
|
|
#endif // MOZ_B2G_RIL
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::IgnoreWaitingCall(ErrorResult& aRv)
|
|
{
|
|
#ifdef MOZ_B2G_RIL
|
|
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
|
|
if (!win) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
nsRefPtr<DOMRequest> request = new DOMRequest(win);
|
|
nsRefPtr<BluetoothVoidReplyRunnable> results =
|
|
new BluetoothVoidReplyRunnable(request);
|
|
|
|
BluetoothService* bs = BluetoothService::Get();
|
|
if (!bs) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
bs->IgnoreWaitingCall(results);
|
|
|
|
return request.forget();
|
|
#else
|
|
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
|
|
return nullptr;
|
|
#endif // MOZ_B2G_RIL
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::ToggleCalls(ErrorResult& aRv)
|
|
{
|
|
#ifdef MOZ_B2G_RIL
|
|
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
|
|
if (!win) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
|
|
nsRefPtr<DOMRequest> request = new DOMRequest(win);
|
|
nsRefPtr<BluetoothVoidReplyRunnable> results =
|
|
new BluetoothVoidReplyRunnable(request);
|
|
|
|
BluetoothService* bs = BluetoothService::Get();
|
|
if (!bs) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
bs->ToggleCalls(results);
|
|
|
|
return request.forget();
|
|
#else
|
|
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
|
|
return nullptr;
|
|
#endif // MOZ_B2G_RIL
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::SendMediaMetaData(const MediaMetaData& aMediaMetaData, 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 BluetoothVoidReplyRunnable(request);
|
|
|
|
BluetoothService* bs = BluetoothService::Get();
|
|
if (!bs) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
bs->SendMetaData(aMediaMetaData.mTitle,
|
|
aMediaMetaData.mArtist,
|
|
aMediaMetaData.mAlbum,
|
|
aMediaMetaData.mMediaNumber,
|
|
aMediaMetaData.mTotalMediaCount,
|
|
aMediaMetaData.mDuration,
|
|
results);
|
|
|
|
return request.forget();
|
|
}
|
|
|
|
already_AddRefed<DOMRequest>
|
|
BluetoothAdapter::SendMediaPlayStatus(const MediaPlayStatus& aMediaPlayStatus, 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 BluetoothVoidReplyRunnable(request);
|
|
|
|
BluetoothService* bs = BluetoothService::Get();
|
|
if (!bs) {
|
|
aRv.Throw(NS_ERROR_FAILURE);
|
|
return nullptr;
|
|
}
|
|
bs->SendPlayStatus(aMediaPlayStatus.mDuration,
|
|
aMediaPlayStatus.mPosition,
|
|
aMediaPlayStatus.mPlayStatus,
|
|
results);
|
|
|
|
return request.forget();
|
|
}
|
|
|
|
JSObject*
|
|
BluetoothAdapter::WrapObject(JSContext* aCx)
|
|
{
|
|
return BluetoothAdapterBinding::Wrap(aCx, this);
|
|
}
|