Skip to content
This repository has been archived by the owner on Aug 4, 2022. It is now read-only.

Commit

Permalink
Bug 1121404 - Cache addresses of bonded devices and notify adapter pr…
Browse files Browse the repository at this point in the history
…operly. r=btian
  • Loading branch information
JaminLiu committed Jan 29, 2015
1 parent bfd62c6 commit f26e640
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 34 deletions.
56 changes: 37 additions & 19 deletions dom/bluetooth2/BluetoothAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,13 @@ BluetoothAdapter::SetPropertyByValue(const BluetoothNamedValue& aValue)
= value.get_ArrayOfnsString();

for (uint32_t i = 0; i < pairedDeviceAddresses.Length(); i++) {
// Check whether or not the address exists in mDevices.
if (mDevices.Contains(pairedDeviceAddresses[i])) {
// If the paired device exists in mDevices, it would handle
// 'PropertyChanged' signal in BluetoothDevice::Notify().
continue;
}

InfallibleTArray<BluetoothNamedValue> props;
BT_APPEND_NAMED_VALUE(props, "Address", pairedDeviceAddresses[i]);
BT_APPEND_NAMED_VALUE(props, "Paired", true);
Expand All @@ -288,10 +295,8 @@ BluetoothAdapter::SetPropertyByValue(const BluetoothNamedValue& aValue)
nsRefPtr<BluetoothDevice> pairedDevice =
BluetoothDevice::Create(GetOwner(), BluetoothValue(props));

// Append to adapter's device array if the device hasn't been created
if (!mDevices.Contains(pairedDevice)) {
mDevices.AppendElement(pairedDevice);
}
// Append to adapter's device array
mDevices.AppendElement(pairedDevice);
}

// Retrieve device properties, result will be handled by device objects.
Expand Down Expand Up @@ -885,14 +890,27 @@ BluetoothAdapter::HandleDevicePaired(const BluetoothValue& aValue)
return;
}

// Create paired device with 'address' and 'paired' attributes
nsRefPtr<BluetoothDevice> pairedDevice =
BluetoothDevice::Create(GetOwner(), aValue);
const InfallibleTArray<BluetoothNamedValue>& arr =
aValue.get_ArrayOfBluetoothNamedValue();

MOZ_ASSERT(arr.Length() == 2 &&
arr[0].value().type() == BluetoothValue::TnsString && // Address
arr[1].value().type() == BluetoothValue::Tbool); // Paired
MOZ_ASSERT(!arr[0].value().get_nsString().IsEmpty() &&
arr[1].value().get_bool());

nsString deviceAddress = arr[0].value().get_nsString();

size_t index = mDevices.IndexOf(pairedDevice);
nsRefPtr<BluetoothDevice> pairedDevice = nullptr;

// Check whether or not the address exists in mDevices.
size_t index = mDevices.IndexOf(deviceAddress);
if (index == mDevices.NoIndex) {
// Create a new device and append it to adapter's device array
pairedDevice = BluetoothDevice::Create(GetOwner(), aValue);
mDevices.AppendElement(pairedDevice);
} else {
// Use existing device
pairedDevice = mDevices[index];
}

Expand All @@ -912,19 +930,19 @@ BluetoothAdapter::HandleDeviceUnpaired(const BluetoothValue& aValue)
return;
}

// Create unpaired device with 'address' and 'paired' attributes
nsRefPtr<BluetoothDevice> unpairedDevice =
BluetoothDevice::Create(GetOwner(), aValue);
const InfallibleTArray<BluetoothNamedValue>& arr =
aValue.get_ArrayOfBluetoothNamedValue();

size_t index = mDevices.IndexOf(unpairedDevice);
MOZ_ASSERT(arr.Length() == 2 &&
arr[0].value().type() == BluetoothValue::TnsString && // Address
arr[1].value().type() == BluetoothValue::Tbool); // Paired
MOZ_ASSERT(!arr[0].value().get_nsString().IsEmpty() &&
!arr[1].value().get_bool());

nsString deviceAddress;
if (index == mDevices.NoIndex) {
unpairedDevice->GetAddress(deviceAddress);
} else {
mDevices[index]->GetAddress(deviceAddress);
mDevices.RemoveElementAt(index);
}
nsString deviceAddress = arr[0].value().get_nsString();

// Remove the device with the same address
mDevices.RemoveElement(deviceAddress);

// Notify application of unpaired device
BluetoothDeviceEventInit init;
Expand Down
57 changes: 47 additions & 10 deletions dom/bluetooth2/BluetoothDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,6 @@ class BluetoothDevice MOZ_FINAL : public DOMEventTargetHelper
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
virtual void DisconnectFromOwner() MOZ_OVERRIDE;

/**
* Override operator== for device comparison
*/
bool operator==(BluetoothDevice& aDevice) const
{
nsString address;
aDevice.GetAddress(address);
return mAddress.Equals(address);
}

private:
BluetoothDevice(nsPIDOMWindow* aOwner, const BluetoothValue& aValue);
~BluetoothDevice();
Expand Down Expand Up @@ -187,4 +177,51 @@ class BluetoothDevice MOZ_FINAL : public DOMEventTargetHelper

END_BLUETOOTH_NAMESPACE

/**
* Explicit Specialization of Function Templates
*
* Allows customizing the template code for a given set of template arguments.
* With this function template, nsTArray can handle comparison of
* 'nsRefPtr<BluetoothDevice>' properly, including IndexOf() and Contains();
*/
template <>
class nsDefaultComparator <nsRefPtr<mozilla::dom::bluetooth::BluetoothDevice>,
nsRefPtr<mozilla::dom::bluetooth::BluetoothDevice>> {
public:

bool Equals(
const nsRefPtr<mozilla::dom::bluetooth::BluetoothDevice>& aDeviceA,
const nsRefPtr<mozilla::dom::bluetooth::BluetoothDevice>& aDeviceB) const
{
nsString addressA, addressB;
aDeviceA->GetAddress(addressA);
aDeviceB->GetAddress(addressB);

return addressA.Equals(addressB);
}
};

/**
* Explicit Specialization of Function Templates
*
* Allows customizing the template code for a given set of template arguments.
* With this function template, nsTArray can handle comparison between
* 'nsRefPtr<BluetoothDevice>' and nsString properly, including IndexOf() and
* Contains();
*/
template <>
class nsDefaultComparator <nsRefPtr<mozilla::dom::bluetooth::BluetoothDevice>,
nsString> {
public:
bool Equals(
const nsRefPtr<mozilla::dom::bluetooth::BluetoothDevice>& aDevice,
const nsString& aAddress) const
{
nsString deviceAddress;
aDevice->GetAddress(deviceAddress);

return deviceAddress.Equals(aAddress);
}
};

#endif
29 changes: 24 additions & 5 deletions dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ static nsString sAdapterBdName;
static bool sAdapterDiscoverable(false);
static bool sAdapterDiscovering(false);
static bool sAdapterEnabled(false);
// InfallibleTArray is an alias for nsTArray.
static InfallibleTArray<nsString> sAdapterBondedAddressArray;

static BluetoothInterface* sBtInterface;
static nsTArray<nsRefPtr<BluetoothProfileController> > sControllerArray;
Expand Down Expand Up @@ -422,6 +424,8 @@ BluetoothServiceBluedroid::GetAdaptersInternal(
"Discoverable", sAdapterDiscoverable);
BT_APPEND_NAMED_VALUE(properties.get_ArrayOfBluetoothNamedValue(),
"Discovering", sAdapterDiscovering);
BT_APPEND_NAMED_VALUE(properties.get_ArrayOfBluetoothNamedValue(),
"PairedDevices", sAdapterBondedAddressArray);

BT_APPEND_NAMED_VALUE(adaptersProperties.get_ArrayOfBluetoothNamedValue(),
"Adapter", properties);
Expand Down Expand Up @@ -1190,6 +1194,10 @@ BluetoothServiceBluedroid::AdapterStateChangedNotification(bool aState)
sAdapterDiscovering = false;
BT_APPEND_NAMED_VALUE(props, "Discovering", false);
}
if (!sAdapterBondedAddressArray.IsEmpty()) {
BT_APPEND_NAMED_VALUE(props, "PairedDevices",
InfallibleTArray<nsString>());
}

BluetoothSignal signal(NS_LITERAL_STRING("PropertyChanged"),
NS_LITERAL_STRING(KEY_ADAPTER), props);
Expand Down Expand Up @@ -1279,13 +1287,15 @@ BluetoothServiceBluedroid::AdapterPropertiesNotification(
BT_LOGD("Adapter property: BONDED_DEVICES. Count: %d",
p.mStringArray.Length());

nsTArray<nsString> pairedDeviceAddresses;
// Whenever reloading paired devices, force refresh
sAdapterBondedAddressArray.Clear();

for (size_t index = 0; index < p.mStringArray.Length(); index++) {
pairedDeviceAddresses.AppendElement(p.mStringArray[index]);
sAdapterBondedAddressArray.AppendElement(p.mStringArray[index]);
}

BT_APPEND_NAMED_VALUE(propertiesArray, "PairedDevices", pairedDeviceAddresses);

BT_APPEND_NAMED_VALUE(propertiesArray, "PairedDevices",
sAdapterBondedAddressArray);
} else if (p.mType == PROPERTY_UNKNOWN) {
/* Bug 1065999: working around unknown properties */
} else {
Expand Down Expand Up @@ -1570,6 +1580,16 @@ BluetoothServiceBluedroid::BondStateChangedNotification(

bool bonded = (aState == BOND_STATE_BONDED);

// Update bonded address array
nsString remoteBdAddr = nsString(aRemoteBdAddr);
if (bonded) {
if (!sAdapterBondedAddressArray.Contains(remoteBdAddr)) {
sAdapterBondedAddressArray.AppendElement(remoteBdAddr);
}
} else {
sAdapterBondedAddressArray.RemoveElement(remoteBdAddr);
}

// Update attribute BluetoothDevice.paired
InfallibleTArray<BluetoothNamedValue> propertiesArray;
BT_APPEND_NAMED_VALUE(propertiesArray, "Paired", bonded);
Expand All @@ -1594,7 +1614,6 @@ BluetoothServiceBluedroid::BondStateChangedNotification(
DispatchBluetoothReply(sBondingRunnableArray[0],
BluetoothValue(true), EmptyString());
sBondingRunnableArray.RemoveElementAt(0);

} else if (!bonded && !sUnbondingRunnableArray.IsEmpty()) {
DispatchBluetoothReply(sUnbondingRunnableArray[0],
BluetoothValue(true), EmptyString());
Expand Down

0 comments on commit f26e640

Please sign in to comment.