static void BondStateChangedCallback(bt_status_t aStatus, bt_bdaddr_t* aRemoteBdAddress, bt_bond_state_t aState) { MOZ_ASSERT(!NS_IsMainThread()); nsAutoString remoteAddress; BdAddressTypeToString(aRemoteBdAddress, remoteAddress); // We don't need to handle bonding state NS_ENSURE_TRUE_VOID(aState != BT_BOND_STATE_BONDING); NS_ENSURE_FALSE_VOID(aState == BT_BOND_STATE_BONDED && sAdapterBondedAddressArray.Contains(remoteAddress)); bool bonded; if (aState == BT_BOND_STATE_NONE) { bonded = false; sAdapterBondedAddressArray.RemoveElement(remoteAddress); } else if (aState == BT_BOND_STATE_BONDED) { bonded = true; sAdapterBondedAddressArray.AppendElement(remoteAddress); } // Update bonded address list to BluetoothAdapter InfallibleTArray<BluetoothNamedValue> propertiesChangeArray; propertiesChangeArray.AppendElement( BluetoothNamedValue(NS_LITERAL_STRING("Devices"), sAdapterBondedAddressArray)); BluetoothValue value(propertiesChangeArray); BluetoothSignal signal(NS_LITERAL_STRING("PropertyChanged"), NS_LITERAL_STRING(KEY_ADAPTER), BluetoothValue(propertiesChangeArray)); NS_DispatchToMainThread(new DistributeBluetoothSignalTask(signal)); // Update bonding status to gaia InfallibleTArray<BluetoothNamedValue> propertiesArray; propertiesArray.AppendElement( BluetoothNamedValue(NS_LITERAL_STRING("address"), remoteAddress)); propertiesArray.AppendElement( BluetoothNamedValue(NS_LITERAL_STRING("status"), bonded)); BluetoothSignal newSignal(NS_LITERAL_STRING(PAIRED_STATUS_CHANGED_ID), NS_LITERAL_STRING(KEY_ADAPTER), BluetoothValue(propertiesArray)); NS_DispatchToMainThread(new DistributeBluetoothSignalTask(newSignal)); if (bonded && !sBondingRunnableArray.IsEmpty()) { DispatchBluetoothReply(sBondingRunnableArray[0], BluetoothValue(true), EmptyString()); sBondingRunnableArray.RemoveElementAt(0); } else if (!bonded && !sUnbondingRunnableArray.IsEmpty()) { DispatchBluetoothReply(sUnbondingRunnableArray[0], BluetoothValue(true), EmptyString()); sUnbondingRunnableArray.RemoveElementAt(0); } }
void BluetoothServiceBluedroid::BondStateChangedNotification( BluetoothStatus aStatus, const nsAString& aRemoteBdAddr, BluetoothBondState aState) { MOZ_ASSERT(NS_IsMainThread()); if (aState == BOND_STATE_BONDING) { // No need to handle bonding state 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."); // 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); } return; } // Retrieve and remove pairing device name from hash table nsString deviceName; bool nameExists = sPairingNameTable.Get(aRemoteBdAddr, &deviceName); if (nameExists) { sPairingNameTable.Remove(aRemoteBdAddr); } // 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." 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)); // 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)); // 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); } }