From 619354ada2f49a491c3b129a82e3b38f54d097a4 Mon Sep 17 00:00:00 2001 From: Ben Tian Date: Fri, 6 Mar 2015 11:55:30 +0800 Subject: [PATCH] Bug 1128383 - [bluetooth2] Add adapter.onpairingaborted event handler, f=jocelyn, f=jaliu, r=shuang, r=bz --- dom/base/nsGkAtomList.h | 1 + dom/bluetooth2/BluetoothAdapter.cpp | 73 +++++++------- dom/bluetooth2/BluetoothAdapter.h | 22 +++-- dom/bluetooth2/BluetoothCommon.h | 5 +- .../bluedroid/BluetoothServiceBluedroid.cpp | 98 ++++++++++--------- dom/webidl/BluetoothAdapter2.webidl | 7 +- 6 files changed, 114 insertions(+), 92 deletions(-) diff --git a/dom/base/nsGkAtomList.h b/dom/base/nsGkAtomList.h index 6eca907de9d8..d5b2bce35a34 100644 --- a/dom/base/nsGkAtomList.h +++ b/dom/base/nsGkAtomList.h @@ -826,6 +826,7 @@ 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") GK_ATOM(onpaste, "onpaste") diff --git a/dom/bluetooth2/BluetoothAdapter.cpp b/dom/bluetooth2/BluetoothAdapter.cpp index dbd9511d1274..ca192e212179 100644 --- a/dom/bluetooth2/BluetoothAdapter.cpp +++ b/dom/bluetooth2/BluetoothAdapter.cpp @@ -364,15 +364,9 @@ BluetoothAdapter::Notify(const BluetoothSignal& aData) nsRefPtr event = BluetoothStatusChangedEvent::Constructor(this, aData.name(), init); DispatchTrustedEvent(event); - } else if (aData.name().EqualsLiteral(REQUEST_MEDIA_PLAYSTATUS_ID)) { - nsCOMPtr 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 if (aData.name().EqualsLiteral(PAIRING_ABORTED_ID) || + aData.name().EqualsLiteral(REQUEST_MEDIA_PLAYSTATUS_ID)) { + DispatchEmptyEvent(aData.name()); } else { BT_WARNING("Not handling adapter signal: %s", NS_ConvertUTF16toUTF8(aData.name()).get()); @@ -856,30 +850,6 @@ BluetoothAdapter::HandleDeviceFound(const BluetoothValue& aValue) mDiscoveryHandleInUse->DispatchDeviceEvent(discoveredDevice); } -void -BluetoothAdapter::DispatchAttributeEvent(const nsTArray& aTypes) -{ - NS_ENSURE_TRUE_VOID(aTypes.Length()); - - AutoJSAPI jsapi; - NS_ENSURE_TRUE_VOID(jsapi.Init(GetOwner())); - JSContext* cx = jsapi.cx(); - JS::Rooted value(cx); - - if (!ToJSValue(cx, aTypes, &value)) { - JS_ClearPendingException(cx); - return; - } - - RootedDictionary init(cx); - init.mAttrs = value; - nsRefPtr event = - BluetoothAttributeEvent::Constructor(this, - NS_LITERAL_STRING("attributechanged"), - init); - DispatchTrustedEvent(event); -} - void BluetoothAdapter::HandleDevicePaired(const BluetoothValue& aValue) { @@ -951,6 +921,30 @@ BluetoothAdapter::HandleDeviceUnpaired(const BluetoothValue& aValue) DispatchDeviceEvent(NS_LITERAL_STRING("deviceunpaired"), init); } +void +BluetoothAdapter::DispatchAttributeEvent(const nsTArray& aTypes) +{ + NS_ENSURE_TRUE_VOID(aTypes.Length()); + + AutoJSAPI jsapi; + NS_ENSURE_TRUE_VOID(jsapi.Init(GetOwner())); + JSContext* cx = jsapi.cx(); + JS::Rooted value(cx); + + if (!ToJSValue(cx, aTypes, &value)) { + JS_ClearPendingException(cx); + return; + } + + RootedDictionary init(cx); + init.mAttrs = value; + nsRefPtr event = + BluetoothAttributeEvent::Constructor(this, + NS_LITERAL_STRING("attributechanged"), + init); + DispatchTrustedEvent(event); +} + void BluetoothAdapter::DispatchDeviceEvent(const nsAString& aType, const BluetoothDeviceEventInit& aInit) @@ -962,6 +956,19 @@ BluetoothAdapter::DispatchDeviceEvent(const nsAString& aType, DispatchTrustedEvent(event); } +void +BluetoothAdapter::DispatchEmptyEvent(const nsAString& aType) +{ + nsCOMPtr event; + nsresult rv = NS_NewDOMEvent(getter_AddRefs(event), this, nullptr, nullptr); + NS_ENSURE_SUCCESS_VOID(rv); + + rv = event->InitEvent(aType, false, false); + NS_ENSURE_SUCCESS_VOID(rv); + + DispatchTrustedEvent(event); +} + already_AddRefed BluetoothAdapter::Connect(BluetoothDevice& aDevice, const Optional& aServiceUuid, diff --git a/dom/bluetooth2/BluetoothAdapter.h b/dom/bluetooth2/BluetoothAdapter.h index 5c65ede7702a..a06555a98581 100644 --- a/dom/bluetooth2/BluetoothAdapter.h +++ b/dom/bluetooth2/BluetoothAdapter.h @@ -83,6 +83,7 @@ public: IMPL_EVENT_HANDLER(attributechanged); IMPL_EVENT_HANDLER(devicepaired); IMPL_EVENT_HANDLER(deviceunpaired); + IMPL_EVENT_HANDLER(pairingaborted); IMPL_EVENT_HANDLER(a2dpstatuschanged); IMPL_EVENT_HANDLER(hfpstatuschanged); IMPL_EVENT_HANDLER(requestmediaplaystatus); @@ -221,6 +222,13 @@ private: */ void HandlePropertyChanged(const BluetoothValue& aValue); + /** + * Handle "DeviceFound" bluetooth signal. + * + * @param aValue [in] Properties array of the discovered device. + */ + void HandleDeviceFound(const BluetoothValue& aValue); + /** * Handle DEVICE_PAIRED_ID bluetooth signal. * @@ -241,13 +249,6 @@ private: */ void HandleDeviceUnpaired(const BluetoothValue& aValue); - /** - * Handle "DeviceFound" bluetooth signal. - * - * @param aValue [in] Properties array of the discovered device. - */ - void HandleDeviceFound(const BluetoothValue& aValue); - /** * Fire BluetoothAttributeEvent to trigger onattributechanged event handler. */ @@ -263,6 +264,13 @@ private: void DispatchDeviceEvent(const nsAString& aType, const BluetoothDeviceEventInit& aInit); + /** + * Fire event with no argument + * + * @param aType [in] Event type to fire + */ + void DispatchEmptyEvent(const nsAString& aType); + /** * Convert string to BluetoothAdapterAttribute. * diff --git a/dom/bluetooth2/BluetoothCommon.h b/dom/bluetooth2/BluetoothCommon.h index d2945b3579e7..816e4f5a4cc6 100644 --- a/dom/bluetooth2/BluetoothCommon.h +++ b/dom/bluetooth2/BluetoothCommon.h @@ -192,11 +192,12 @@ extern bool gBluetoothDebugFlag; #define BLUETOOTH_APP_ORIGIN "app://bluetooth.gaiamobile.org" /** - * When a remote device gets paired / unpaired with local bluetooth adapter, - * we'll dispatch an event. + * When a remote device gets paired / unpaired with local bluetooth adapter or + * pairing process is aborted, we'll dispatch an event. */ #define DEVICE_PAIRED_ID "devicepaired" #define DEVICE_UNPAIRED_ID "deviceunpaired" +#define PAIRING_ABORTED_ID "pairingaborted" /** * 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 8e1c1494e564..b536a77d2807 100644 --- a/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp +++ b/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp @@ -1593,74 +1593,76 @@ BluetoothServiceBluedroid::BondStateChangedNotification( return; } - bool bonded = (aState == BOND_STATE_BONDED); + BT_LOGR("Bond state: %d status: %d", aState, aStatus); - // Update bonded address array - nsString remoteBdAddr = nsString(aRemoteBdAddr); - if (bonded) { - if (!sAdapterBondedAddressArray.Contains(remoteBdAddr)) { - sAdapterBondedAddressArray.AppendElement(remoteBdAddr); + bool bonded = (aState == BOND_STATE_BONDED); + if (aStatus != STATUS_SUCCESS) { + if (!bonded) { // Active/passive pair failed + BT_LOGR("Pair failed! Abort pairing."); + + // Notify adapter of pairing aborted + DistributeSignal(NS_LITERAL_STRING(PAIRING_ABORTED_ID), + NS_LITERAL_STRING(KEY_ADAPTER)); + + // Reject pair promise + if (!sBondingRunnableArray.IsEmpty()) { + DispatchReplyError(sBondingRunnableArray[0], aStatus); + sBondingRunnableArray.RemoveElementAt(0); + } + } else if (!sUnbondingRunnableArray.IsEmpty()) { // Active unpair failed + // Reject unpair promise + DispatchReplyError(sUnbondingRunnableArray[0], aStatus); + sUnbondingRunnableArray.RemoveElementAt(0); } - } else { - sAdapterBondedAddressArray.RemoveElement(remoteBdAddr); + + return; } - // Update attribute BluetoothDevice.paired - InfallibleTArray propertiesArray; - BT_APPEND_NAMED_VALUE(propertiesArray, "Paired", bonded); - - // Retrieve device name from hash table of pairing device name. - nsString deviceName = EmptyString(); + // Retrieve and remove pairing device name from hash table + nsString deviceName; bool nameExists = sPairingNameTable.Get(aRemoteBdAddr, &deviceName); if (nameExists) { sPairingNameTable.Remove(aRemoteBdAddr); } - // Update attribute BluetoothDevice.name if the device is paired. - if (bonded && aStatus == STATUS_SUCCESS) { - MOZ_ASSERT(nameExists); + // Update bonded address array and append pairing device name + InfallibleTArray propertiesArray; + nsString remoteBdAddr = nsString(aRemoteBdAddr); + if (!bonded) { + sAdapterBondedAddressArray.RemoveElement(remoteBdAddr); + } else { + if (!sAdapterBondedAddressArray.Contains(remoteBdAddr)) { + sAdapterBondedAddressArray.AppendElement(remoteBdAddr); + } - // We don't assert |!deviceName.IsEmpty()| here since empty string is also - // a valid name. - // According to Bluetooth Core Spec. v3.0 - Sec. 6.22, a valid Bluetooth - // name is a UTF-8 encoding string which is up to 248 bytes in length. + // We don't assert |!deviceName.IsEmpty()| here since empty string is + // also a valid name. According to Bluetooth Core Spec. v3.0 - Sec. 6.22, + // "a valid Bluetooth name is a UTF-8 encoding string which is up to 248 + // bytes in length." + MOZ_ASSERT(nameExists); BT_APPEND_NAMED_VALUE(propertiesArray, "Name", deviceName); } + // Notify device of attribute changed + BT_APPEND_NAMED_VALUE(propertiesArray, "Paired", bonded); DistributeSignal(NS_LITERAL_STRING("PropertyChanged"), aRemoteBdAddr, BluetoothValue(propertiesArray)); - // Insert address to signal properties and notify adapter. - BT_INSERT_NAMED_VALUE(propertiesArray, 0, "Address", nsString(aRemoteBdAddr)); - - nsString signalName = bonded ? NS_LITERAL_STRING(DEVICE_PAIRED_ID) - : NS_LITERAL_STRING(DEVICE_UNPAIRED_ID); - - DistributeSignal(signalName, + // Notify adapter of device paired/unpaired + BT_INSERT_NAMED_VALUE(propertiesArray, 0, "Address", remoteBdAddr); + DistributeSignal(bonded ? NS_LITERAL_STRING(DEVICE_PAIRED_ID) + : NS_LITERAL_STRING(DEVICE_UNPAIRED_ID), NS_LITERAL_STRING(KEY_ADAPTER), BluetoothValue(propertiesArray)); - if (aStatus == STATUS_SUCCESS) { - // Resolve existing pair/unpair promise when pair/unpair succeeded - if (bonded && !sBondingRunnableArray.IsEmpty()) { - DispatchReplySuccess(sBondingRunnableArray[0]); - sBondingRunnableArray.RemoveElementAt(0); - } else if (!bonded && !sUnbondingRunnableArray.IsEmpty()) { - DispatchReplySuccess(sUnbondingRunnableArray[0]); - sUnbondingRunnableArray.RemoveElementAt(0); - } - } else { - // Reject existing pair/unpair promise when pair/unpair failed - if (!bonded && !sBondingRunnableArray.IsEmpty()) { - DispatchReplyError(sBondingRunnableArray[0], - NS_LITERAL_STRING("Pair failed")); - sBondingRunnableArray.RemoveElementAt(0); - } else if (bonded && !sUnbondingRunnableArray.IsEmpty()) { - DispatchReplyError(sUnbondingRunnableArray[0], - NS_LITERAL_STRING("Unpair failed")); - sUnbondingRunnableArray.RemoveElementAt(0); - } + // Resolve existing pair/unpair promise + if (bonded && !sBondingRunnableArray.IsEmpty()) { + DispatchReplySuccess(sBondingRunnableArray[0]); + sBondingRunnableArray.RemoveElementAt(0); + } else if (!bonded && !sUnbondingRunnableArray.IsEmpty()) { + DispatchReplySuccess(sUnbondingRunnableArray[0]); + sUnbondingRunnableArray.RemoveElementAt(0); } } diff --git a/dom/webidl/BluetoothAdapter2.webidl b/dom/webidl/BluetoothAdapter2.webidl index f5e9e3491d9b..96d67fe53896 100644 --- a/dom/webidl/BluetoothAdapter2.webidl +++ b/dom/webidl/BluetoothAdapter2.webidl @@ -53,6 +53,9 @@ interface BluetoothAdapter : EventTarget { // Fired when a remote device gets unpaired from the adapter attribute EventHandler ondeviceunpaired; + // Fired when the pairing process aborted + attribute EventHandler onpairingaborted; + // Fired when a2dp connection status changed attribute EventHandler ona2dpstatuschanged; @@ -78,9 +81,9 @@ interface BluetoothAdapter : EventTarget { Promise disable(); [NewObject, AvailableIn=CertifiedApps] - Promise setName(DOMString aName); + Promise setName(DOMString name); [NewObject] - Promise setDiscoverable(boolean aDiscoverable); + Promise setDiscoverable(boolean discoverable); [NewObject] Promise startDiscovery();