From 55bbcf17527e3e6a55ef8c5590de3be4221b6f41 Mon Sep 17 00:00:00 2001 From: Jamin Liu Date: Tue, 12 Aug 2014 16:30:42 +0800 Subject: [PATCH] Bug 1036234 - Implement pairing event handlers of BluetoothAdapter. r=btian, r=mrbkap - EventHandler ondevicepaired; - EventHandler ondeviceunpaired; --- content/base/src/nsGkAtomList.h | 2 + dom/bluetooth2/BluetoothAdapter.cpp | 84 ++++++++++++++++++- dom/bluetooth2/BluetoothAdapter.h | 34 +++++++- dom/bluetooth2/BluetoothCommon.h | 7 +- .../bluedroid/BluetoothServiceBluedroid.cpp | 11 ++- dom/webidl/BluetoothAdapter2.webidl | 9 +- 6 files changed, 132 insertions(+), 15 deletions(-) diff --git a/content/base/src/nsGkAtomList.h b/content/base/src/nsGkAtomList.h index 0cea77e05bf4..d1642cd6192f 100644 --- a/content/base/src/nsGkAtomList.h +++ b/content/base/src/nsGkAtomList.h @@ -706,6 +706,8 @@ GK_ATOM(ondeleted, "ondeleted") GK_ATOM(ondeliverysuccess, "ondeliverysuccess") GK_ATOM(ondeliveryerror, "ondeliveryerror") GK_ATOM(ondevicefound, "ondevicefound") +GK_ATOM(ondevicepaired, "ondevicepaired") +GK_ATOM(ondeviceunpaired, "ondeviceunpaired") GK_ATOM(ondialing, "ondialing") GK_ATOM(ondisabled, "ondisabled") GK_ATOM(ondischargingtimechange, "ondischargingtimechange") diff --git a/dom/bluetooth2/BluetoothAdapter.cpp b/dom/bluetooth2/BluetoothAdapter.cpp index 88deb5bb90d0..142934e8c628 100644 --- a/dom/bluetooth2/BluetoothAdapter.cpp +++ b/dom/bluetooth2/BluetoothAdapter.cpp @@ -299,7 +299,7 @@ BluetoothAdapter::SetPropertyByValue(const BluetoothNamedValue& aValue) BT_APPEND_NAMED_VALUE(props, "Address", pairedDeviceAddresses[i]); BT_APPEND_NAMED_VALUE(props, "Paired", true); - // Create paired device with address and paired attributes + // Create paired device with 'address' and 'paired' attributes nsRefPtr pairedDevice = BluetoothDevice::Create(GetOwner(), BluetoothValue(props)); @@ -351,8 +351,11 @@ BluetoothAdapter::Notify(const BluetoothSignal& aData) } } else if (aData.name().EqualsLiteral("PairingRequest")) { HandlePairingRequest(v); - } else if (aData.name().EqualsLiteral(PAIRED_STATUS_CHANGED_ID) || - aData.name().EqualsLiteral(HFP_STATUS_CHANGED_ID) || + } else if (aData.name().EqualsLiteral(DEVICE_PAIRED_ID)) { + HandleDevicePaired(aData.value()); + } else if (aData.name().EqualsLiteral(DEVICE_UNPAIRED_ID)) { + HandleDeviceUnpaired(aData.value()); + } else if (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); @@ -698,7 +701,7 @@ BluetoothAdapter::EnableDisable(bool aEnable, ErrorResult& aRv) promise, methodName); - if(NS_FAILED(bs->EnableDisable(aEnable, result))) { + if (NS_FAILED(bs->EnableDisable(aEnable, result))) { // Restore mState and notify applications of adapter state change mState = aEnable ? BluetoothAdapterState::Disabled : BluetoothAdapterState::Enabled; @@ -892,6 +895,79 @@ BluetoothAdapter::DispatchAttributeEvent(const nsTArray& aTypes) DispatchTrustedEvent(event); } +void +BluetoothAdapter::HandleDevicePaired(const BluetoothValue& aValue) +{ + MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothNamedValue); + + if (mState != BluetoothAdapterState::Enabled) { + BT_WARNING("HandleDevicePaired() is called when adapter isn't enabled."); + return; + } + + // Create paired device with 'address' and 'paired' attributes + nsRefPtr pairedDevice = + BluetoothDevice::Create(GetOwner(), aValue); + + size_t index = mDevices.IndexOf(pairedDevice, + 0, /* aStart */ + BluetoothDeviceComparator()); + + if (index != mDevices.NoIndex) { + pairedDevice = mDevices[index]; + } else { + mDevices.AppendElement(pairedDevice); + } + + // Notify application of paired device + BluetoothDeviceEventInit init; + init.mDevice = pairedDevice. + DispatchDeviceEvent(NS_LITERAL_STRING("devicepaired"), init); +} + +void +BluetoothAdapter::HandleDeviceUnpaired(const BluetoothValue& aValue) +{ + MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothNamedValue); + + if (mState != BluetoothAdapterState::Enabled) { + BT_WARNING("HandleDeviceUnpaired() is called when adapter isn't enabled."); + return; + } + + // Create unpaired device with 'address' and 'paired' attributes + nsRefPtr unpairedDevice = + BluetoothDevice::Create(GetOwner(), aValue); + + size_t index = mDevices.IndexOf(unpairedDevice, + 0, /* aStart */ + BluetoothDeviceComparator()); + + nsString deviceAddress; + if (index != mDevices.NoIndex) { + mDevices[index]->GetAddress(deviceAddress); + mDevices.RemoveElementAt(index); + } else { + unpairedDevice->GetAddress(deviceAddress); + } + + // Notify application of unpaired device + BluetoothDeviceEventInit init; + init.mAddress = deviceAddress; + DispatchDeviceEvent(NS_LITERAL_STRING("deviceunpaired"), init); +} + +void +BluetoothAdapter::DispatchDeviceEvent(const nsAString& aType, + const BluetoothDeviceEventInit& aInit) +{ + BT_API2_LOGR("aType (%s)", NS_ConvertUTF16toUTF8(aType).get()); + + nsRefPtr event = + BluetoothDeviceEvent::Constructor(this, aType, aInit); + DispatchTrustedEvent(event); +} + already_AddRefed BluetoothAdapter::Connect(BluetoothDevice& aDevice, const Optional& aServiceUuid, diff --git a/dom/bluetooth2/BluetoothAdapter.h b/dom/bluetooth2/BluetoothAdapter.h index b02f05c27792..57458aa3f699 100644 --- a/dom/bluetooth2/BluetoothAdapter.h +++ b/dom/bluetooth2/BluetoothAdapter.h @@ -10,6 +10,7 @@ #include "mozilla/Attributes.h" #include "mozilla/DOMEventTargetHelper.h" #include "mozilla/dom/BluetoothAdapter2Binding.h" +#include "mozilla/dom/BluetoothDeviceEvent.h" #include "mozilla/dom/Promise.h" #include "BluetoothCommon.h" #include "nsCOMPtr.h" @@ -149,10 +150,11 @@ public: IMPL_EVENT_HANDLER(a2dpstatuschanged); IMPL_EVENT_HANDLER(hfpstatuschanged); - IMPL_EVENT_HANDLER(pairedstatuschanged); IMPL_EVENT_HANDLER(requestmediaplaystatus); IMPL_EVENT_HANDLER(scostatuschanged); IMPL_EVENT_HANDLER(attributechanged); + IMPL_EVENT_HANDLER(devicepaired); + IMPL_EVENT_HANDLER(deviceunpaired); nsPIDOMWindow* GetParentObject() const { @@ -182,6 +184,36 @@ private: void HandleDeviceFound(const BluetoothValue& aValue); void HandlePairingRequest(const BluetoothValue& aValue); + /** + * Handle DEVICE_PAIRED_ID bluetooth signal. + * + * @param aValue [in] Properties array of the paired device. + * The array should contain two properties: + * - nsString 'Address' + * - bool 'Paired' + */ + void HandleDevicePaired(const BluetoothValue& aValue); + + /** + * Handle DEVICE_UNPAIRED_ID bluetooth signal. + * + * @param aValue [in] Properties array of the unpaired device. + * The array should contain two properties: + * - nsString 'Address' + * - bool 'Paired' + */ + void HandleDeviceUnpaired(const BluetoothValue& aValue); + + /** + * Fire BluetoothDeviceEvent to trigger + * ondeviceparied/ondeviceunpaired event handler. + * + * @param aType [in] Event type to fire + * @param aInit [in] Event initialization value + */ + void DispatchDeviceEvent(const nsAString& aType, + const BluetoothDeviceEventInit& aInit); + /** * mDevices holds references of all created device objects. * It is an empty array when the adapter state is disabled. diff --git a/dom/bluetooth2/BluetoothCommon.h b/dom/bluetooth2/BluetoothCommon.h index f4d56736255b..c2b7a3303763 100644 --- a/dom/bluetooth2/BluetoothCommon.h +++ b/dom/bluetooth2/BluetoothCommon.h @@ -158,10 +158,11 @@ extern bool gBluetoothDebugFlag; #define PAIRING_REQ_TYPE_CONSENT "pairingconsentreq" /** - * When the pair status of a Bluetooth device is changed, we'll dispatch an - * event. + * When a remote device gets paired / unpaired with local bluetooth adapter, + * we'll dispatch an event. */ -#define PAIRED_STATUS_CHANGED_ID "pairedstatuschanged" +#define DEVICE_PAIRED_ID "devicepaired" +#define DEVICE_UNPAIRED_ID "deviceunpaired" /** * When receiving a query about current play status from remote device, we'll diff --git a/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp b/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp index 697c927eb487..25e760fea0f4 100644 --- a/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp +++ b/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp @@ -762,11 +762,14 @@ BondStateChangedCallback(bt_status_t aStatus, bt_bdaddr_t* aRemoteBdAddress, props.Clear(); - // Update bonding status to BluetoothAdapter - BT_APPEND_NAMED_VALUE(props, "address", remoteBdAddress); - BT_APPEND_NAMED_VALUE(props, "status", bonded); + // Append signal properties and notify adapter. + BT_APPEND_NAMED_VALUE(props, "Address", remoteBdAddress); + BT_APPEND_NAMED_VALUE(props, "Paired", bonded); - BluetoothSignal adapterSignal(NS_LITERAL_STRING(PAIRED_STATUS_CHANGED_ID), + nsString signalName = bonded ? NS_LITERAL_STRING(DEVICE_PAIRED_ID) + : NS_LITERAL_STRING(DEVICE_UNPAIRED_ID); + + BluetoothSignal adapterSignal(signalName, NS_LITERAL_STRING(KEY_ADAPTER), BluetoothValue(props)); NS_DispatchToMainThread(new DistributeBluetoothSignalTask(adapterSignal)); diff --git a/dom/webidl/BluetoothAdapter2.webidl b/dom/webidl/BluetoothAdapter2.webidl index 686f61efd7f7..5ee421d699b3 100644 --- a/dom/webidl/BluetoothAdapter2.webidl +++ b/dom/webidl/BluetoothAdapter2.webidl @@ -61,9 +61,6 @@ interface BluetoothAdapter : EventTarget { [AvailableIn=CertifiedApps] readonly attribute BluetoothPairingListener pairingReqs; - // Fired when pairing process is completed - attribute EventHandler onpairedstatuschanged; - // Fired when a2dp connection status changed attribute EventHandler ona2dpstatuschanged; @@ -79,6 +76,12 @@ interface BluetoothAdapter : EventTarget { // Fired when attributes of BluetoothAdapter changed attribute EventHandler onattributechanged; + // Fired when a remote device gets paired with the adapter. + attribute EventHandler ondevicepaired; + + // Fired when a remote device gets unpaired from the adapter. + attribute EventHandler ondeviceunpaired; + /** * Enable/Disable a local bluetooth adapter by asynchronus methods and return * its result through a Promise.