Bug 1128383 - [bluetooth2] Add adapter.onpairingaborted event handler, f=jocelyn, f=jaliu, r=shuang, r=bz

This commit is contained in:
Ben Tian 2015-03-06 11:55:30 +08:00
parent 8506a11dd0
commit 619354ada2
6 changed files with 114 additions and 92 deletions

View File

@ -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")

View File

@ -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,

View File

@ -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.
*

View File

@ -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

View File

@ -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<BluetoothNamedValue> 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<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
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);
}
}

View File

@ -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();