mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1006314 - Patch 3/3: Revise BluetoothAdapter, r=bz, r=echou
This commit is contained in:
parent
fd8dc9104d
commit
145f5d24aa
@ -21,6 +21,7 @@
|
||||
|
||||
#include "BluetoothAdapter.h"
|
||||
#include "BluetoothDevice.h"
|
||||
#include "BluetoothDiscoveryHandle.h"
|
||||
#include "BluetoothReplyRunnable.h"
|
||||
#include "BluetoothService.h"
|
||||
#include "BluetoothUtils.h"
|
||||
@ -55,6 +56,49 @@ NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
||||
NS_IMPL_ADDREF_INHERITED(BluetoothAdapter, DOMEventTargetHelper)
|
||||
NS_IMPL_RELEASE_INHERITED(BluetoothAdapter, DOMEventTargetHelper)
|
||||
|
||||
class StartDiscoveryTask : public BluetoothReplyRunnable
|
||||
{
|
||||
public:
|
||||
StartDiscoveryTask(BluetoothAdapter* aAdapter, Promise* aPromise)
|
||||
: BluetoothReplyRunnable(nullptr, aPromise,
|
||||
NS_LITERAL_STRING("StartDiscovery"))
|
||||
, mAdapter(aAdapter)
|
||||
{
|
||||
MOZ_ASSERT(aPromise && aAdapter);
|
||||
}
|
||||
|
||||
bool
|
||||
ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue)
|
||||
{
|
||||
BT_API2_LOGR();
|
||||
aValue.setUndefined();
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
NS_ENSURE_TRUE(jsapi.Init(mAdapter->GetParentObject()), false);
|
||||
|
||||
// Wrap BluetoothDiscoveryHandle to return
|
||||
JSContext* cx = jsapi.cx();
|
||||
nsRefPtr<BluetoothDiscoveryHandle> discoveryHandle =
|
||||
BluetoothDiscoveryHandle::Create(mAdapter->GetParentObject());
|
||||
if (!ToJSValue(cx, discoveryHandle, aValue)) {
|
||||
JS_ClearPendingException(cx);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void
|
||||
ReleaseMembers() MOZ_OVERRIDE
|
||||
{
|
||||
BluetoothReplyRunnable::ReleaseMembers();
|
||||
mAdapter = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<BluetoothAdapter> mAdapter;
|
||||
};
|
||||
|
||||
class GetDevicesTask : public BluetoothReplyRunnable
|
||||
{
|
||||
public:
|
||||
@ -304,24 +348,10 @@ BluetoothAdapter::Notify(const BluetoothSignal& aData)
|
||||
{
|
||||
InfallibleTArray<BluetoothNamedValue> arr;
|
||||
|
||||
BT_LOGD("[A] %s: %s", __FUNCTION__,
|
||||
NS_ConvertUTF16toUTF8(aData.name()).get());
|
||||
BT_LOGD("[A] %s", NS_ConvertUTF16toUTF8(aData.name()).get());
|
||||
|
||||
BluetoothValue v = aData.value();
|
||||
if (aData.name().EqualsLiteral("DeviceFound")) {
|
||||
nsRefPtr<BluetoothDevice> device =
|
||||
BluetoothDevice::Create(GetOwner(), 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")) {
|
||||
if (aData.name().EqualsLiteral("PropertyChanged")) {
|
||||
HandlePropertyChanged(v);
|
||||
} else if (aData.name().EqualsLiteral(PAIRED_STATUS_CHANGED_ID) ||
|
||||
aData.name().EqualsLiteral(HFP_STATUS_CHANGED_ID) ||
|
||||
@ -360,49 +390,55 @@ BluetoothAdapter::Notify(const BluetoothSignal& aData)
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<DOMRequest>
|
||||
already_AddRefed<Promise>
|
||||
BluetoothAdapter::StartStopDiscovery(bool aStart, ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
|
||||
if (!win) {
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
|
||||
if (!global) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
nsRefPtr<Promise> promise = new Promise(global);
|
||||
|
||||
nsRefPtr<DOMRequest> request = new DOMRequest(win);
|
||||
nsRefPtr<BluetoothVoidReplyRunnable> results =
|
||||
new BluetoothVoidReplyRunnable(request);
|
||||
|
||||
/**
|
||||
* Ensure
|
||||
* - adapter does not already start/stop discovering,
|
||||
* - adapter is already enabled, and
|
||||
* - BluetoothService is available
|
||||
*/
|
||||
BT_ENSURE_TRUE_RESOLVE(mDiscovering != aStart, JS::UndefinedHandleValue);
|
||||
BT_ENSURE_TRUE_REJECT(mState == BluetoothAdapterState::Enabled,
|
||||
NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
if (!bs) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
BT_ENSURE_TRUE_REJECT(bs, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
BT_API2_LOGR("aStart %d", aStart);
|
||||
nsresult rv;
|
||||
if (aStart) {
|
||||
rv = bs->StartDiscoveryInternal(results);
|
||||
// Start discovery: return BluetoothDiscoveryHandle in StartDiscoveryTask
|
||||
nsRefPtr<BluetoothReplyRunnable> result =
|
||||
new StartDiscoveryTask(this, promise);
|
||||
rv = bs->StartDiscoveryInternal(result);
|
||||
} else {
|
||||
rv = bs->StopDiscoveryInternal(results);
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
BT_WARNING("Start/Stop Discovery failed!");
|
||||
aRv.Throw(rv);
|
||||
return nullptr;
|
||||
// Stop discovery: void return
|
||||
nsRefPtr<BluetoothReplyRunnable> result =
|
||||
new BluetoothVoidReplyRunnable(nullptr /* DOMRequest */,
|
||||
promise,
|
||||
NS_LITERAL_STRING("StopDiscovery"));
|
||||
rv = bs->StopDiscoveryInternal(result);
|
||||
}
|
||||
BT_ENSURE_TRUE_REJECT(NS_SUCCEEDED(rv), NS_ERROR_DOM_OPERATION_ERR);
|
||||
|
||||
// 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();
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DOMRequest>
|
||||
already_AddRefed<Promise>
|
||||
BluetoothAdapter::StartDiscovery(ErrorResult& aRv)
|
||||
{
|
||||
return StartStopDiscovery(true, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<DOMRequest>
|
||||
already_AddRefed<Promise>
|
||||
BluetoothAdapter::StopDiscovery(ErrorResult& aRv)
|
||||
{
|
||||
return StartStopDiscovery(false, aRv);
|
||||
@ -446,38 +482,32 @@ BluetoothAdapter::SetName(const nsAString& aName, ErrorResult& aRv)
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = new Promise(global);
|
||||
|
||||
if (mState != BluetoothAdapterState::Enabled) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
if (mName.Equals(aName)) {
|
||||
// Need to resolved with "undefined" since this method is Promise<void>
|
||||
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
nsString name(aName);
|
||||
BluetoothValue value(name);
|
||||
BluetoothNamedValue property(NS_LITERAL_STRING("Name"), value);
|
||||
|
||||
/**
|
||||
* Ensure
|
||||
* - adapter's name does not equal to aName,
|
||||
* - adapter is already enabled, and
|
||||
* - BluetoothService is available
|
||||
*/
|
||||
BT_ENSURE_TRUE_RESOLVE(!mName.Equals(aName), JS::UndefinedHandleValue);
|
||||
BT_ENSURE_TRUE_REJECT(mState == BluetoothAdapterState::Enabled,
|
||||
NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
if (!bs) {
|
||||
promise->MaybeReject(NS_ERROR_NOT_AVAILABLE);
|
||||
return promise.forget();
|
||||
}
|
||||
BT_ENSURE_TRUE_REJECT(bs, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
// Wrap property to set and runnable to handle result
|
||||
nsString name(aName);
|
||||
BluetoothNamedValue property(NS_LITERAL_STRING("Name"),
|
||||
BluetoothValue(name));
|
||||
nsRefPtr<BluetoothReplyRunnable> result =
|
||||
new BluetoothVoidReplyRunnable(nullptr /* DOMRequest */,
|
||||
promise,
|
||||
NS_LITERAL_STRING("SetName"));
|
||||
if (NS_FAILED(bs->SetProperty(BluetoothObjectType::TYPE_ADAPTER,
|
||||
property, result))) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
|
||||
}
|
||||
BT_ENSURE_TRUE_REJECT(
|
||||
NS_SUCCEEDED(bs->SetProperty(BluetoothObjectType::TYPE_ADAPTER,
|
||||
property, result)),
|
||||
NS_ERROR_DOM_OPERATION_ERR);
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
@ -490,37 +520,32 @@ BluetoothAdapter::SetDiscoverable(bool aDiscoverable, ErrorResult& aRv)
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = new Promise(global);
|
||||
|
||||
if (mState != BluetoothAdapterState::Enabled) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
if (aDiscoverable == mDiscoverable) {
|
||||
// Need to resolved with "undefined" since this method is Promise<void>
|
||||
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
BluetoothValue value(aDiscoverable);
|
||||
BluetoothNamedValue property(NS_LITERAL_STRING("Discoverable"), value);
|
||||
|
||||
/**
|
||||
* Ensure
|
||||
* - mDiscoverable does not equal to aDiscoverable,
|
||||
* - adapter is already enabled, and
|
||||
* - BluetoothService is available
|
||||
*/
|
||||
BT_ENSURE_TRUE_RESOLVE(mDiscoverable != aDiscoverable,
|
||||
JS::UndefinedHandleValue);
|
||||
BT_ENSURE_TRUE_REJECT(mState == BluetoothAdapterState::Enabled,
|
||||
NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
if (!bs) {
|
||||
promise->MaybeReject(NS_ERROR_NOT_AVAILABLE);
|
||||
return promise.forget();
|
||||
}
|
||||
BT_ENSURE_TRUE_REJECT(bs, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
// Wrap property to set and runnable to handle result
|
||||
BluetoothNamedValue property(NS_LITERAL_STRING("Discoverable"),
|
||||
BluetoothValue(aDiscoverable));
|
||||
nsRefPtr<BluetoothReplyRunnable> result =
|
||||
new BluetoothVoidReplyRunnable(nullptr /* DOMRequest */,
|
||||
promise,
|
||||
NS_LITERAL_STRING("SetDiscoverable"));
|
||||
if (NS_FAILED(bs->SetProperty(BluetoothObjectType::TYPE_ADAPTER,
|
||||
property, result))) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
|
||||
}
|
||||
BT_ENSURE_TRUE_REJECT(
|
||||
NS_SUCCEEDED(bs->SetProperty(BluetoothObjectType::TYPE_ADAPTER,
|
||||
property, result)),
|
||||
NS_ERROR_DOM_OPERATION_ERR);
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
@ -723,42 +748,36 @@ BluetoothAdapter::EnableDisable(bool aEnable, ErrorResult& aRv)
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = new Promise(global);
|
||||
|
||||
// Ensure BluetoothService is available before modifying adapter state
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
if (!bs) {
|
||||
promise->MaybeReject(NS_ERROR_NOT_AVAILABLE);
|
||||
return promise.forget();
|
||||
}
|
||||
BT_ENSURE_TRUE_REJECT(bs, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
nsString methodName;
|
||||
// Modify adapter state to Enabling/Disabling if adapter is in a valid state
|
||||
nsAutoString methodName;
|
||||
if (aEnable) {
|
||||
// Enable local adapter
|
||||
if (mState != BluetoothAdapterState::Disabled) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
BT_ENSURE_TRUE_REJECT(mState == BluetoothAdapterState::Disabled,
|
||||
NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
methodName.AssignLiteral("Enable");
|
||||
mState = BluetoothAdapterState::Enabling;
|
||||
} else {
|
||||
// Disable local adapter
|
||||
if (mState != BluetoothAdapterState::Enabled) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
BT_ENSURE_TRUE_REJECT(mState == BluetoothAdapterState::Enabled,
|
||||
NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
methodName.AssignLiteral("Disable");
|
||||
mState = BluetoothAdapterState::Disabling;
|
||||
}
|
||||
|
||||
// Notify applications of adapter state change to Enabling/Disabling
|
||||
nsTArray<nsString> types;
|
||||
BT_APPEND_ENUM_STRING(types,
|
||||
BluetoothAdapterAttribute,
|
||||
BluetoothAdapterAttribute::State);
|
||||
|
||||
DispatchAttributeEvent(types);
|
||||
|
||||
// Wrap runnable to handle result
|
||||
nsRefPtr<BluetoothReplyRunnable> result =
|
||||
new BluetoothVoidReplyRunnable(nullptr, /* DOMRequest */
|
||||
promise,
|
||||
|
@ -96,8 +96,8 @@ public:
|
||||
already_AddRefed<Promise> SetName(const nsAString& aName, ErrorResult& aRv);
|
||||
already_AddRefed<Promise>
|
||||
SetDiscoverable(bool aDiscoverable, ErrorResult& aRv);
|
||||
already_AddRefed<DOMRequest> StartDiscovery(ErrorResult& aRv);
|
||||
already_AddRefed<DOMRequest> StopDiscovery(ErrorResult& aRv);
|
||||
already_AddRefed<Promise> StartDiscovery(ErrorResult& aRv);
|
||||
already_AddRefed<Promise> StopDiscovery(ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<DOMRequest>
|
||||
Pair(const nsAString& aDeviceAddress, ErrorResult& aRv);
|
||||
@ -176,8 +176,7 @@ private:
|
||||
|
||||
void Root();
|
||||
|
||||
already_AddRefed<mozilla::dom::DOMRequest>
|
||||
StartStopDiscovery(bool aStart, ErrorResult& aRv);
|
||||
already_AddRefed<Promise> StartStopDiscovery(bool aStart, ErrorResult& aRv);
|
||||
already_AddRefed<mozilla::dom::DOMRequest>
|
||||
PairUnpair(bool aPair, const nsAString& aDeviceAddress, ErrorResult& aRv);
|
||||
|
||||
|
@ -95,6 +95,30 @@ extern bool gBluetoothDebugFlag;
|
||||
array.AppendElement(name); \
|
||||
} while(0) \
|
||||
|
||||
/**
|
||||
* Resolve promise with |ret| if |x| is false.
|
||||
*/
|
||||
#define BT_ENSURE_TRUE_RESOLVE(x, ret) \
|
||||
do { \
|
||||
if (MOZ_UNLIKELY(!(x))) { \
|
||||
BT_API2_LOGR("BT_ENSURE_TRUE_RESOLVE(" #x ") failed"); \
|
||||
promise->MaybeResolve(ret); \
|
||||
return promise.forget(); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* Reject promise with |ret| if |x| is false.
|
||||
*/
|
||||
#define BT_ENSURE_TRUE_REJECT(x, ret) \
|
||||
do { \
|
||||
if (MOZ_UNLIKELY(!(x))) { \
|
||||
BT_API2_LOGR("BT_ENSURE_TRUE_REJECT(" #x ") failed"); \
|
||||
promise->MaybeReject(ret); \
|
||||
return promise.forget(); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define BEGIN_BLUETOOTH_NAMESPACE \
|
||||
namespace mozilla { namespace dom { namespace bluetooth {
|
||||
#define END_BLUETOOTH_NAMESPACE \
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "BluetoothManager.h"
|
||||
#include "BluetoothCommon.h"
|
||||
#include "BluetoothAdapter.h"
|
||||
#include "BluetoothService.h"
|
||||
#include "BluetoothReplyRunnable.h"
|
||||
@ -76,8 +75,8 @@ class GetAdaptersTask : public BluetoothReplyRunnable
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ReleaseMembers()
|
||||
virtual void
|
||||
ReleaseMembers() MOZ_OVERRIDE
|
||||
{
|
||||
BluetoothReplyRunnable::ReleaseMembers();
|
||||
mManager = nullptr;
|
||||
|
Loading…
Reference in New Issue
Block a user