Bug 730992 - Patch 3: Hooking things up to BluetoothAdapter, r=qdot, sr=mrbkap
---
dom/bluetooth/BluetoothAdapter.cpp | 204 +++++++++++++++++++++++++++++-
dom/bluetooth/BluetoothAdapter.h | 8 ++
dom/bluetooth/nsIDOMBluetoothAdapter.idl | 16 +++-
3 files changed, 224 insertions(+), 4 deletions(-)
--- a/dom/bluetooth/BluetoothAdapter.cpp
+++ b/dom/bluetooth/BluetoothAdapter.cpp
@@ -4,16 +4,17 @@
* 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 "BluetoothAdapter.h"
#include "BluetoothDevice.h"
#include "BluetoothDeviceEvent.h"
#include "BluetoothPropertyEvent.h"
+#include "BluetoothPairingEvent.h"
#include "BluetoothService.h"
#include "BluetoothTypes.h"
#include "BluetoothReplyRunnable.h"
#include "BluetoothUtils.h"
#include "nsDOMClassInfo.h"
#include "nsDOMEvent.h"
#include "nsThreadUtils.h"
@@ -38,25 +39,35 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INH
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mJsDeviceAddresses)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BluetoothAdapter,
nsDOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(devicefound)
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(devicedisappeared)
- NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(propertychanged)
+ NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(propertychanged)
+ NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(requestconfirmation)
+ NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(requestpincode)
+ NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(requestpasskey)
+ NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(authorize)
+ NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(cancel)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BluetoothAdapter,
nsDOMEventTargetHelper)
tmp->Unroot();
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(devicefound)
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(devicedisappeared)
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(propertychanged)
+ NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(requestconfirmation)
+ NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(requestpincode)
+ NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(requestpasskey)
+ NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(authorize)
+ NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(cancel)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BluetoothAdapter)
NS_INTERFACE_MAP_ENTRY(nsIDOMBluetoothAdapter)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(BluetoothAdapter)
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(BluetoothAdapter, nsDOMEventTargetHelper)
@@ -122,16 +133,18 @@ public:
{
BluetoothReplyRunnable::ReleaseMembers();
mAdapterPtr = nullptr;
}
private:
nsRefPtr<BluetoothAdapter> mAdapterPtr;
};
+static int kCreatePairedDeviceTimeout = 50000; // unit: msec
+
BluetoothAdapter::BluetoothAdapter(nsPIDOMWindow* aOwner, const BluetoothValue& aValue)
: BluetoothPropertyContainer(BluetoothObjectType::TYPE_ADAPTER)
, mEnabled(false)
, mDiscoverable(false)
, mDiscovering(false)
, mPairable(false)
, mPowered(false)
, mJsUuids(nullptr)
@@ -257,38 +270,102 @@ BluetoothAdapter::Create(nsPIDOMWindow*
return nullptr;
}
nsRefPtr<BluetoothAdapter> adapter = new BluetoothAdapter(aOwner, aValue);
if (NS_FAILED(bs->RegisterBluetoothSignalHandler(adapter->GetPath(), adapter))) {
NS_WARNING("Failed to register object with observer!");
return nullptr;
}
+
+ if (NS_FAILED(bs->RegisterBluetoothSignalHandler(NS_LITERAL_STRING(LOCAL_AGENT_PATH), adapter))) {
+ NS_WARNING("Failed to register local agent object with observer!");
+ return nullptr;
+ }
+
+ if (NS_FAILED(bs->RegisterBluetoothSignalHandler(NS_LITERAL_STRING(REMOTE_AGENT_PATH), adapter))) {
+ NS_WARNING("Failed to register remote agent object with observer!");
+ return nullptr;
+ }
+
return adapter.forget();
}
void
BluetoothAdapter::Notify(const BluetoothSignal& aData)
{
+ InfallibleTArray<BluetoothNamedValue> arr;
+
if (aData.name().EqualsLiteral("DeviceFound")) {
nsRefPtr<BluetoothDevice> d = BluetoothDevice::Create(GetOwner(), mPath, aData.value());
nsRefPtr<BluetoothDeviceEvent> e = BluetoothDeviceEvent::Create(d);
e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("devicefound"));
} else if (aData.name().EqualsLiteral("PropertyChanged")) {
// Get BluetoothNamedValue, make sure array length is 1
- InfallibleTArray<BluetoothNamedValue> arr = aData.value().get_ArrayOfBluetoothNamedValue();
- if (arr.Length() != 1) {
+ arr = aData.value().get_ArrayOfBluetoothNamedValue();
+ if(arr.Length() != 1) {
// This really should not happen
NS_ERROR("Got more than one property in a change message!");
return;
}
BluetoothNamedValue v = arr[0];
SetPropertyByValue(v);
nsRefPtr<BluetoothPropertyEvent> e = BluetoothPropertyEvent::Create(v.name());
e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("propertychanged"));
+ } else if (aData.name().EqualsLiteral("RequestConfirmation")) {
+ arr = aData.value().get_ArrayOfBluetoothNamedValue();
+ if(arr.Length() != 2) {
+ NS_ERROR("RequestConfirmation: Length of parameters is wrong");
+ return;
+ }
+
+ nsString deviceAddress = arr[0].value().get_nsString();
+ uint32_t passkey = arr[1].value().get_uint32_t();
+
+ nsRefPtr<BluetoothPairingEvent> e = BluetoothPairingEvent::Create(deviceAddress, passkey);
+ e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("requestconfirmation"));
+ } else if (aData.name().EqualsLiteral("RequestPinCode")) {
+ arr = aData.value().get_ArrayOfBluetoothNamedValue();
+ if(arr.Length() != 1) {
+ NS_ERROR("RequestPinCode: Length of parameters is wrong");
+ return;
+ }
+
+ nsString deviceAddress = arr[0].value().get_nsString();
+
+ nsRefPtr<BluetoothPairingEvent> e = BluetoothPairingEvent::Create(deviceAddress, 0);
+ e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("requestpincode"));
+ } else if (aData.name().EqualsLiteral("RequestPasskey")) {
+ arr = aData.value().get_ArrayOfBluetoothNamedValue();
+ if(arr.Length() != 1) {
+ NS_ERROR("RequestPasskey: Length of parameters is wrong");
+ return;
+ }
+
+ nsString deviceAddress = arr[0].value().get_nsString();
+
+ nsRefPtr<BluetoothPairingEvent> e = BluetoothPairingEvent::Create(deviceAddress, 0);
+ e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("requestpasskey"));
+ } else if (aData.name().EqualsLiteral("Authorize")) {
+ arr = aData.value().get_ArrayOfBluetoothNamedValue();
+ if(arr.Length() != 2) {
+ NS_ERROR("Authorize: Length of parameters is wrong");
+ return;
+ }
+
+ nsString deviceAddress = arr[0].value().get_nsString();
+ nsString serviceUuid = arr[1].value().get_nsString();
+
+ nsRefPtr<BluetoothPairingEvent> e = BluetoothPairingEvent::Create(deviceAddress, serviceUuid);
+ e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("authorize"));
+ } else if (aData.name().EqualsLiteral("Cancel")) {
+ // Just send a null nsString, won't be used
+ nsString deviceObjectPath = EmptyString();
+ nsRefPtr<BluetoothPairingEvent> e = BluetoothPairingEvent::Create(deviceObjectPath, 0);
+ e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("cancel"));
} else {
#ifdef DEBUG
nsCString warningMsg;
warningMsg.AssignLiteral("Not handling manager signal: ");
warningMsg.Append(NS_ConvertUTF16toUTF8(aData.name()));
NS_WARNING(warningMsg.get());
#endif
}
@@ -485,11 +562,132 @@ BluetoothAdapter::GetPairedDevices(nsIDO
nsRefPtr<BluetoothReplyRunnable> results = new GetPairedDevicesTask(this, request);
if (NS_FAILED(bs->GetPairedDevicePropertiesInternal(mDeviceAddresses, results))) {
return NS_ERROR_FAILURE;
}
request.forget(aRequest);
return NS_OK;
}
+nsresult
+BluetoothAdapter::PairUnpair(bool aPair,
+ nsIDOMBluetoothDevice* aDevice,
+ nsIDOMDOMRequest** aRequest)
+{
+ BluetoothService* bs = BluetoothService::Get();
+ if (!bs) {
+ NS_WARNING("BluetoothService not available!");
+ return NS_ERROR_FAILURE;
+ }
+
+ nsCOMPtr<nsIDOMRequestService> rs = do_GetService("@mozilla.org/dom/dom-request-service;1");
+ if (!rs) {
+ NS_WARNING("No DOMRequest Service!");
+ return NS_ERROR_FAILURE;
+ }
+
+ nsCOMPtr<nsIDOMDOMRequest> req;
+ nsresult rv = rs->CreateRequest(GetOwner(), getter_AddRefs(req));
+ if (NS_FAILED(rv)) {
+ NS_WARNING("Can't create DOMRequest!");
+ return NS_ERROR_FAILURE;
+ }
+
+ nsRefPtr<BluetoothVoidReplyRunnable> results = new BluetoothVoidReplyRunnable(req);
+
+ nsString addr;
+ aDevice->GetAddress(addr);
+
+ if (aPair) {
+ rv = bs->CreatePairedDeviceInternal(mPath,
+ addr,
+ kCreatePairedDeviceTimeout,
+ results);
+ } else {
+ rv = bs->RemoveDeviceInternal(mPath, addr, results);
+ }
+
+ if (NS_FAILED(rv)) {
+ NS_WARNING("Pair/Unpair failed!");
+ return NS_ERROR_FAILURE;
+ }
+
+ req.forget(aRequest);
+
+ return NS_OK;
+}
+
+nsresult
+BluetoothAdapter::Pair(nsIDOMBluetoothDevice* aDevice, nsIDOMDOMRequest** aRequest)
+{
+ return PairUnpair(true, aDevice, aRequest);
+}
+
+nsresult
+BluetoothAdapter::Unpair(nsIDOMBluetoothDevice* aDevice, nsIDOMDOMRequest** aRequest)
+{
+ return PairUnpair(false, aDevice, aRequest);
+}
+
+nsresult
+BluetoothAdapter::SetPinCode(const nsAString& aDeviceAddress, const nsAString& aPinCode)
+{
+ BluetoothService* bs = BluetoothService::Get();
+ if (!bs) {
+ NS_WARNING("BluetoothService not available!");
+ return NS_ERROR_FAILURE;
+ }
+
+ bool result = bs->SetPinCodeInternal(aDeviceAddress, aPinCode);
+
+ return result ? NS_OK : NS_ERROR_FAILURE;
+}
+
+nsresult
+BluetoothAdapter::SetPasskey(const nsAString& aDeviceAddress, PRUint32 aPasskey)
+{
+ BluetoothService* bs = BluetoothService::Get();
+ if (!bs) {
+ NS_WARNING("BluetoothService not available!");
+ return NS_ERROR_FAILURE;
+ }
+
+ bool result = bs->SetPasskeyInternal(aDeviceAddress, aPasskey);
+
+ return result ? NS_OK : NS_ERROR_FAILURE;
+}
+
+nsresult
+BluetoothAdapter::SetPairingConfirmation(const nsAString& aDeviceAddress, bool aConfirmation)
+{
+ BluetoothService* bs = BluetoothService::Get();
+ if (!bs) {
+ NS_WARNING("BluetoothService not available!");
+ return NS_ERROR_FAILURE;
+ }
+
+ bool result = bs->SetPairingConfirmationInternal(aDeviceAddress, aConfirmation);
+
+ return result ? NS_OK : NS_ERROR_FAILURE;
+}
+
+nsresult
+BluetoothAdapter::SetAuthorization(const nsAString& aDeviceAddress, bool aAllow)
+{
+ BluetoothService* bs = BluetoothService::Get();
+ if (!bs) {
+ NS_WARNING("BluetoothService not available!");
+ return NS_ERROR_FAILURE;
+ }
+
+ bool result = bs->SetAuthorizationInternal(aDeviceAddress, aAllow);
+
+ return result ? NS_OK : NS_ERROR_FAILURE;
+}
+
NS_IMPL_EVENT_HANDLER(BluetoothAdapter, propertychanged)
NS_IMPL_EVENT_HANDLER(BluetoothAdapter, devicefound)
NS_IMPL_EVENT_HANDLER(BluetoothAdapter, devicedisappeared)
+NS_IMPL_EVENT_HANDLER(BluetoothAdapter, requestconfirmation)
+NS_IMPL_EVENT_HANDLER(BluetoothAdapter, requestpincode)
+NS_IMPL_EVENT_HANDLER(BluetoothAdapter, requestpasskey)
+NS_IMPL_EVENT_HANDLER(BluetoothAdapter, authorize)
+NS_IMPL_EVENT_HANDLER(BluetoothAdapter, cancel)
--- a/dom/bluetooth/BluetoothAdapter.h
+++ b/dom/bluetooth/BluetoothAdapter.h
@@ -58,16 +58,19 @@ public:
virtual void SetPropertyByValue(const BluetoothNamedValue& aValue);
private:
BluetoothAdapter(nsPIDOMWindow* aOwner, const BluetoothValue& aValue);
~BluetoothAdapter();
void Root();
nsresult StartStopDiscovery(bool aStart, nsIDOMDOMRequest** aRequest);
+ nsresult PairUnpair(bool aPair,
+ nsIDOMBluetoothDevice* aDevice,
+ nsIDOMDOMRequest** aRequest);
nsString mAddress;
nsString mName;
bool mEnabled;
bool mDiscoverable;
bool mDiscovering;
bool mPairable;
bool mPowered;
@@ -78,13 +81,18 @@ private:
nsTArray<nsString> mUuids;
JSObject* mJsUuids;
JSObject* mJsDeviceAddresses;
bool mIsRooted;
NS_DECL_EVENT_HANDLER(propertychanged)
NS_DECL_EVENT_HANDLER(devicefound)
NS_DECL_EVENT_HANDLER(devicedisappeared)
+ NS_DECL_EVENT_HANDLER(requestconfirmation)
+ NS_DECL_EVENT_HANDLER(requestpincode)
+ NS_DECL_EVENT_HANDLER(requestpasskey)
+ NS_DECL_EVENT_HANDLER(authorize)
+ NS_DECL_EVENT_HANDLER(cancel)
};
END_BLUETOOTH_NAMESPACE
#endif
--- a/dom/bluetooth/nsIDOMBluetoothAdapter.idl
+++ b/dom/bluetooth/nsIDOMBluetoothAdapter.idl
@@ -4,17 +4,17 @@
* 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 "nsIDOMEventTarget.idl"
interface nsIDOMDOMRequest;
interface nsIDOMBluetoothDevice;
-[scriptable, builtinclass, uuid(86e9fe78-ce64-476e-a357-333f7d3c8980)]
+[scriptable, builtinclass, uuid(db6b4dd6-64f1-415d-ac51-ae0fa0fe05ed)]
interface nsIDOMBluetoothAdapter : nsIDOMEventTarget
{
readonly attribute DOMString address;
[binaryname(AdapterClass)] readonly attribute unsigned long class;
readonly attribute bool enabled;
readonly attribute bool discovering;
[implicit_jscontext]
@@ -28,16 +28,29 @@ interface nsIDOMBluetoothAdapter : nsIDO
// Unit: sec
readonly attribute unsigned long discoverableTimeout;
nsIDOMDOMRequest setName(in DOMString name);
nsIDOMDOMRequest setDiscoverable(in bool discoverable);
nsIDOMDOMRequest setDiscoverableTimeout(in unsigned long timeout);
nsIDOMDOMRequest startDiscovery();
nsIDOMDOMRequest stopDiscovery();
+ nsIDOMDOMRequest pair(in nsIDOMBluetoothDevice aDevice);
+ nsIDOMDOMRequest unpair(in nsIDOMBluetoothDevice aDevice);
nsIDOMDOMRequest getPairedDevices();
+ void setPinCode(in DOMString aDeviceAddress, in DOMString aPinCode);
+ void setPasskey(in DOMString aDeviceAddress, in unsigned long aPasskey);
+ void setPairingConfirmation(in DOMString aDeviceAddress, in bool aConfirmation);
+ void setAuthorization(in DOMString aDeviceAddress, in bool aAllow);
+
// Fired when discoverying and any device is discovered.
attribute nsIDOMEventListener ondevicefound;
// Fired when any device is out of discoverable range.
attribute nsIDOMEventListener ondevicedisappeared;
// Fired when a property of the adapter is changed
attribute nsIDOMEventListener onpropertychanged;
+ // Pairing related events
+ attribute nsIDOMEventListener onrequestconfirmation;
+ attribute nsIDOMEventListener onrequestpincode;
+ attribute nsIDOMEventListener onrequestpasskey;
+ attribute nsIDOMEventListener onauthorize;
+ attribute nsIDOMEventListener oncancel;
};