mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 11:55:49 +00:00
Bug 1128383 - [bluetooth2] Add adapter.onpairingaborted event handler, f=jocelyn, f=jaliu, r=shuang, r=bz
This commit is contained in:
parent
8506a11dd0
commit
619354ada2
@ -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")
|
||||
|
@ -364,15 +364,9 @@ BluetoothAdapter::Notify(const BluetoothSignal& aData)
|
||||
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 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<nsString>& aTypes)
|
||||
{
|
||||
NS_ENSURE_TRUE_VOID(aTypes.Length());
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
NS_ENSURE_TRUE_VOID(jsapi.Init(GetOwner()));
|
||||
JSContext* cx = jsapi.cx();
|
||||
JS::Rooted<JS::Value> value(cx);
|
||||
|
||||
if (!ToJSValue(cx, aTypes, &value)) {
|
||||
JS_ClearPendingException(cx);
|
||||
return;
|
||||
}
|
||||
|
||||
RootedDictionary<BluetoothAttributeEventInit> init(cx);
|
||||
init.mAttrs = value;
|
||||
nsRefPtr<BluetoothAttributeEvent> 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<nsString>& aTypes)
|
||||
{
|
||||
NS_ENSURE_TRUE_VOID(aTypes.Length());
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
NS_ENSURE_TRUE_VOID(jsapi.Init(GetOwner()));
|
||||
JSContext* cx = jsapi.cx();
|
||||
JS::Rooted<JS::Value> value(cx);
|
||||
|
||||
if (!ToJSValue(cx, aTypes, &value)) {
|
||||
JS_ClearPendingException(cx);
|
||||
return;
|
||||
}
|
||||
|
||||
RootedDictionary<BluetoothAttributeEventInit> init(cx);
|
||||
init.mAttrs = value;
|
||||
nsRefPtr<BluetoothAttributeEvent> 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<nsIDOMEvent> 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<DOMRequest>
|
||||
BluetoothAdapter::Connect(BluetoothDevice& aDevice,
|
||||
const Optional<short unsigned int>& aServiceUuid,
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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
|
||||
|
@ -1593,56 +1593,70 @@ BluetoothServiceBluedroid::BondStateChangedNotification(
|
||||
return;
|
||||
}
|
||||
|
||||
BT_LOGR("Bond state: %d status: %d", aState, aStatus);
|
||||
|
||||
bool bonded = (aState == BOND_STATE_BONDED);
|
||||
if (aStatus != STATUS_SUCCESS) {
|
||||
if (!bonded) { // Active/passive pair failed
|
||||
BT_LOGR("Pair failed! Abort pairing.");
|
||||
|
||||
// Update bonded address array
|
||||
nsString remoteBdAddr = nsString(aRemoteBdAddr);
|
||||
if (bonded) {
|
||||
if (!sAdapterBondedAddressArray.Contains(remoteBdAddr)) {
|
||||
sAdapterBondedAddressArray.AppendElement(remoteBdAddr);
|
||||
// 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 {
|
||||
sAdapterBondedAddressArray.RemoveElement(remoteBdAddr);
|
||||
} else if (!sUnbondingRunnableArray.IsEmpty()) { // Active unpair failed
|
||||
// Reject unpair promise
|
||||
DispatchReplyError(sUnbondingRunnableArray[0], aStatus);
|
||||
sUnbondingRunnableArray.RemoveElementAt(0);
|
||||
}
|
||||
|
||||
// Update attribute BluetoothDevice.paired
|
||||
InfallibleTArray<BluetoothNamedValue> propertiesArray;
|
||||
BT_APPEND_NAMED_VALUE(propertiesArray, "Paired", bonded);
|
||||
return;
|
||||
}
|
||||
|
||||
// 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<BluetoothNamedValue> 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
|
||||
// Resolve existing pair/unpair promise
|
||||
if (bonded && !sBondingRunnableArray.IsEmpty()) {
|
||||
DispatchReplySuccess(sBondingRunnableArray[0]);
|
||||
sBondingRunnableArray.RemoveElementAt(0);
|
||||
@ -1650,18 +1664,6 @@ BluetoothServiceBluedroid::BondStateChangedNotification(
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -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<void> disable();
|
||||
|
||||
[NewObject, AvailableIn=CertifiedApps]
|
||||
Promise<void> setName(DOMString aName);
|
||||
Promise<void> setName(DOMString name);
|
||||
[NewObject]
|
||||
Promise<void> setDiscoverable(boolean aDiscoverable);
|
||||
Promise<void> setDiscoverable(boolean discoverable);
|
||||
|
||||
[NewObject]
|
||||
Promise<BluetoothDiscoveryHandle> startDiscovery();
|
||||
|
Loading…
Reference in New Issue
Block a user