Bug 1161945 - Fix empty characteristics and descriptors after searching services. f=elin, r=jocelyn

This commit is contained in:
Bruce Sun 2015-06-12 10:44:57 +08:00
Родитель c64976d18f
Коммит b47876dbca
7 изменённых файлов: 198 добавлений и 106 удалений

Просмотреть файл

@ -1642,13 +1642,15 @@ BluetoothGattManager::GetCharacteristicNotification(
aCharId,
new DiscoverResultHandler(client));
} else { // all characteristics of this service are discovered
// Notify BluetoothGattService to create characteristics then proceed
nsString path;
GeneratePathFromGattId(aServiceId.mId, path);
// Notify BluetoothGatt to make BluetoothGattService create characteristics
// then proceed
nsTArray<BluetoothNamedValue> values;
BT_APPEND_NAMED_VALUE(values, "serviceId", aServiceId);
BT_APPEND_NAMED_VALUE(values, "characteristics", client->mCharacteristics);
bs->DistributeSignal(NS_LITERAL_STRING("CharacteristicsDiscovered"),
path,
BluetoothValue(client->mCharacteristics));
client->mAppUuid,
BluetoothValue(values));
ProceedDiscoverProcess(client, aServiceId);
}
@ -1686,13 +1688,16 @@ BluetoothGattManager::GetDescriptorNotification(
aDescriptorId,
new DiscoverResultHandler(client));
} else { // all descriptors of this characteristic are discovered
// Notify BluetoothGattCharacteristic to create descriptors then proceed
nsString path;
GeneratePathFromGattId(aCharId, path);
// Notify BluetoothGatt to make BluetoothGattCharacteristic create
// descriptors then proceed
nsTArray<BluetoothNamedValue> values;
BT_APPEND_NAMED_VALUE(values, "serviceId", aServiceId);
BT_APPEND_NAMED_VALUE(values, "characteristicId", aCharId);
BT_APPEND_NAMED_VALUE(values, "descriptors", client->mDescriptors);
bs->DistributeSignal(NS_LITERAL_STRING("DescriptorsDiscovered"),
path,
BluetoothValue(client->mDescriptors));
client->mAppUuid,
BluetoothValue(values));
client->mDescriptors.Clear();
ProceedDiscoverProcess(client, aServiceId);
@ -1729,13 +1734,16 @@ BluetoothGattManager::GetIncludedServiceNotification(
aIncludedServId,
new DiscoverResultHandler(client));
} else { // all included services of this service are discovered
// Notify BluetoothGattService to create included services
nsString path;
GeneratePathFromGattId(aServiceId.mId, path);
// Notify BluetoothGatt to make BluetoothGattService create included
// services
nsTArray<BluetoothNamedValue> values;
BT_APPEND_NAMED_VALUE(values, "serviceId", aServiceId);
BT_APPEND_NAMED_VALUE(values, "includedServices",
client->mIncludedServices);
bs->DistributeSignal(NS_LITERAL_STRING("IncludedServicesDiscovered"),
path,
BluetoothValue(client->mIncludedServices));
client->mAppUuid,
BluetoothValue(values));
client->mIncludedServices.Clear();
// Start to discover characteristics of this service

Просмотреть файл

@ -281,6 +281,77 @@ BluetoothGatt::HandleServicesDiscovered(const BluetoothValue& aValue)
BluetoothGattBinding::ClearCachedServicesValue(this);
}
void
BluetoothGatt::HandleIncludedServicesDiscovered(const BluetoothValue& aValue)
{
MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothNamedValue);
const InfallibleTArray<BluetoothNamedValue>& values =
aValue.get_ArrayOfBluetoothNamedValue();
MOZ_ASSERT(values.Length() == 2); // ServiceId, IncludedServices
MOZ_ASSERT(values[0].name().EqualsLiteral("serviceId"));
MOZ_ASSERT(values[0].value().type() ==
BluetoothValue::TBluetoothGattServiceId);
MOZ_ASSERT(values[1].name().EqualsLiteral("includedServices"));
MOZ_ASSERT(values[1].value().type() ==
BluetoothValue::TArrayOfBluetoothGattServiceId);
size_t index = mServices.IndexOf(
values[0].value().get_BluetoothGattServiceId());
NS_ENSURE_TRUE_VOID(index != mServices.NoIndex);
nsRefPtr<BluetoothGattService> service = mServices.ElementAt(index);
service->AssignIncludedServices(
values[1].value().get_ArrayOfBluetoothGattServiceId());
}
void
BluetoothGatt::HandleCharacteristicsDiscovered(const BluetoothValue& aValue)
{
MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothNamedValue);
const InfallibleTArray<BluetoothNamedValue>& values =
aValue.get_ArrayOfBluetoothNamedValue();
MOZ_ASSERT(values.Length() == 2); // ServiceId, Characteristics
MOZ_ASSERT(values[0].name().EqualsLiteral("serviceId"));
MOZ_ASSERT(values[0].value().type() == BluetoothValue::TBluetoothGattServiceId);
MOZ_ASSERT(values[1].name().EqualsLiteral("characteristics"));
MOZ_ASSERT(values[1].value().type() ==
BluetoothValue::TArrayOfBluetoothGattCharAttribute);
size_t index = mServices.IndexOf(
values[0].value().get_BluetoothGattServiceId());
NS_ENSURE_TRUE_VOID(index != mServices.NoIndex);
nsRefPtr<BluetoothGattService> service = mServices.ElementAt(index);
service->AssignCharacteristics(
values[1].value().get_ArrayOfBluetoothGattCharAttribute());
}
void
BluetoothGatt::HandleDescriptorsDiscovered(const BluetoothValue& aValue)
{
MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothNamedValue);
const InfallibleTArray<BluetoothNamedValue>& values =
aValue.get_ArrayOfBluetoothNamedValue();
MOZ_ASSERT(values.Length() == 3); // ServiceId, CharacteristicId, Descriptors
MOZ_ASSERT(values[0].name().EqualsLiteral("serviceId"));
MOZ_ASSERT(values[0].value().type() == BluetoothValue::TBluetoothGattServiceId);
MOZ_ASSERT(values[1].name().EqualsLiteral("characteristicId"));
MOZ_ASSERT(values[1].value().type() == BluetoothValue::TBluetoothGattId);
MOZ_ASSERT(values[2].name().EqualsLiteral("descriptors"));
MOZ_ASSERT(values[2].value().type() == BluetoothValue::TArrayOfBluetoothGattId);
size_t index = mServices.IndexOf(
values[0].value().get_BluetoothGattServiceId());
NS_ENSURE_TRUE_VOID(index != mServices.NoIndex);
nsRefPtr<BluetoothGattService> service = mServices.ElementAt(index);
service->AssignDescriptors(values[1].value().get_BluetoothGattId(),
values[2].value().get_ArrayOfBluetoothGattId());
}
void
BluetoothGatt::HandleCharacteristicChanged(const BluetoothValue& aValue)
{
@ -348,6 +419,12 @@ BluetoothGatt::Notify(const BluetoothSignal& aData)
}
mDiscoveringServices = false;
} else if (aData.name().EqualsLiteral("IncludedServicesDiscovered")) {
HandleIncludedServicesDiscovered(v);
} else if (aData.name().EqualsLiteral("CharacteristicsDiscovered")) {
HandleCharacteristicsDiscovered(v);
} else if (aData.name().EqualsLiteral("DescriptorsDiscovered")) {
HandleDescriptorsDiscovered(v);
} else if (aData.name().EqualsLiteral(GATT_CHARACTERISTIC_CHANGED_ID)) {
HandleCharacteristicChanged(v);
} else {

Просмотреть файл

@ -96,6 +96,50 @@ private:
*/
void HandleServicesDiscovered(const BluetoothValue& aValue);
/**
* Add newly discovered GATT included services into mIncludedServices of
* BluetoothGattService and update the cache value of mIncludedServices.
*
* @param aValue [in] BluetoothValue which contains an array of
* BluetoothNamedValue. There are exact two elements in
* the array. The first element uses 'serviceId' as the
* name and uses BluetoothGattServiceId as the value. The
* second element uses 'includedServices' as the name and
* uses an array of BluetoothGattServiceId of all
* discovered included services as the value.
*/
void HandleIncludedServicesDiscovered(const BluetoothValue& aValue);
/**
* Add newly discovered GATT characteristics into mCharacteristics of
* BluetoothGattService and update the cache value of mCharacteristics.
*
* @param aValue [in] BluetoothValue which contains an array of
* BluetoothNamedValue. There are exact two elements in
* the array. The first element uses 'serviceId' as the
* name and uses BluetoothGattServiceId as the value. The
* second element uses 'characteristics' as the name and
* uses an array of BluetoothGattCharAttribute of all
* discovered characteristics as the value.
*/
void HandleCharacteristicsDiscovered(const BluetoothValue& aValue);
/**
* Add newly discovered GATT descriptors into mDescriptors of
* BluetoothGattCharacteristic and update the cache value of mDescriptors.
*
* @param aValue [in] BluetoothValue which contains an array of
* BluetoothNamedValue. There are exact three elements in
* the array. The first element uses 'serviceId' as the
* name and uses BluetoothGattServiceId as the value. The
* second element uses 'characteristicId' as the name and
* uses BluetoothGattId as the value. The third element
* uses 'descriptors' as the name and uses an array of
* BluetoothGattId of all discovered descriptors as the
* value.
*/
void HandleDescriptorsDiscovered(const BluetoothValue& aValue);
/**
* The value of a GATT characteristic has changed. In the mean time, the
* cached value of this GATT characteristic has already been updated. An

Просмотреть файл

@ -142,18 +142,13 @@ BluetoothGattCharacteristic::StopNotifications(ErrorResult& aRv)
}
void
BluetoothGattCharacteristic::HandleDescriptorsDiscovered(
const BluetoothValue& aValue)
BluetoothGattCharacteristic::AssignDescriptors(
const nsTArray<BluetoothGattId>& aDescriptorIds)
{
MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothGattId);
const InfallibleTArray<BluetoothGattId>& descriptorIds =
aValue.get_ArrayOfBluetoothGattId();
mDescriptors.Clear();
for (uint32_t i = 0; i < descriptorIds.Length(); i++) {
for (uint32_t i = 0; i < aDescriptorIds.Length(); i++) {
mDescriptors.AppendElement(new BluetoothGattDescriptor(
GetParentObject(), this, descriptorIds[i]));
GetParentObject(), this, aDescriptorIds[i]));
}
BluetoothGattCharacteristicBinding::ClearCachedDescriptorsValue(this);
@ -175,9 +170,7 @@ BluetoothGattCharacteristic::Notify(const BluetoothSignal& aData)
NS_ENSURE_TRUE_VOID(mSignalRegistered);
BluetoothValue v = aData.value();
if (aData.name().EqualsLiteral("DescriptorsDiscovered")) {
HandleDescriptorsDiscovered(v);
} else if (aData.name().EqualsLiteral("CharacteristicValueUpdated")) {
if (aData.name().EqualsLiteral("CharacteristicValueUpdated")) {
HandleCharacteristicValueUpdated(v);
} else {
BT_WARNING("Not handling GATT Characteristic signal: %s",

Просмотреть файл

@ -32,6 +32,7 @@ class BluetoothGattCharacteristic final : public nsISupports
, public nsWrapperCache
, public BluetoothSignalObserver
{
friend class BluetoothGattService;
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(BluetoothGattCharacteristic)
@ -106,10 +107,10 @@ private:
* Add newly discovered GATT descriptors into mDescriptors and update the
* cache value of mDescriptors.
*
* @param aValue [in] BluetoothValue which contains an array of
* BluetoothGattId of all discovered descriptors.
* @param aDescriptorIds [in] An array of BluetoothGattId for each descriptor
* that belongs to this characteristic.
*/
void HandleDescriptorsDiscovered(const BluetoothValue& aValue);
void AssignDescriptors(const nsTArray<BluetoothGattId>& aDescriptorIds);
/**
* Update the value of this characteristic.

Просмотреть файл

@ -17,33 +17,10 @@ using namespace mozilla::dom;
USING_BLUETOOTH_NAMESPACE
NS_IMPL_CYCLE_COLLECTION_CLASS(BluetoothGattService)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(BluetoothGattService)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mIncludedServices)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCharacteristics)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
/**
* Unregister the bluetooth signal handler after unlinked.
*
* This is needed to avoid ending up with exposing a deleted object to JS or
* accessing deleted objects while receiving signals from parent process
* after unlinked. Please see Bug 1138267 for detail informations.
*/
nsString path;
GeneratePathFromGattId(tmp->mServiceId.mId, path);
UnregisterBluetoothSignalHandler(path, tmp);
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(BluetoothGattService)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIncludedServices)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCharacteristics)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(BluetoothGattService)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(BluetoothGattService,
mOwner,
mIncludedServices,
mCharacteristics)
NS_IMPL_CYCLE_COLLECTING_ADDREF(BluetoothGattService)
NS_IMPL_CYCLE_COLLECTING_RELEASE(BluetoothGattService)
@ -63,72 +40,49 @@ BluetoothGattService::BluetoothGattService(
MOZ_ASSERT(!mAppUuid.IsEmpty());
UuidToString(mServiceId.mId.mUuid, mUuidStr);
// Generate bluetooth signal path of this service to applications
nsString path;
GeneratePathFromGattId(mServiceId.mId, path);
RegisterBluetoothSignalHandler(path, this);
}
BluetoothGattService::~BluetoothGattService()
{
nsString path;
GeneratePathFromGattId(mServiceId.mId, path);
UnregisterBluetoothSignalHandler(path, this);
}
void
BluetoothGattService::HandleIncludedServicesDiscovered(
const BluetoothValue& aValue)
BluetoothGattService::AssignIncludedServices(
const nsTArray<BluetoothGattServiceId>& aServiceIds)
{
MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothGattServiceId);
const InfallibleTArray<BluetoothGattServiceId>& includedServIds =
aValue.get_ArrayOfBluetoothGattServiceId();
mIncludedServices.Clear();
for (uint32_t i = 0; i < includedServIds.Length(); i++) {
for (uint32_t i = 0; i < aServiceIds.Length(); i++) {
mIncludedServices.AppendElement(new BluetoothGattService(
GetParentObject(), mAppUuid, includedServIds[i]));
GetParentObject(), mAppUuid, aServiceIds[i]));
}
BluetoothGattServiceBinding::ClearCachedIncludedServicesValue(this);
}
void
BluetoothGattService::HandleCharacteristicsDiscovered(
const BluetoothValue& aValue)
BluetoothGattService::AssignCharacteristics(
const nsTArray<BluetoothGattCharAttribute>& aCharacteristics)
{
MOZ_ASSERT(aValue.type() ==
BluetoothValue::TArrayOfBluetoothGattCharAttribute);
const InfallibleTArray<BluetoothGattCharAttribute>& characteristics =
aValue.get_ArrayOfBluetoothGattCharAttribute();
mCharacteristics.Clear();
for (uint32_t i = 0; i < characteristics.Length(); i++) {
for (uint32_t i = 0; i < aCharacteristics.Length(); i++) {
mCharacteristics.AppendElement(new BluetoothGattCharacteristic(
GetParentObject(), this, characteristics[i]));
GetParentObject(), this, aCharacteristics[i]));
}
BluetoothGattServiceBinding::ClearCachedCharacteristicsValue(this);
}
void
BluetoothGattService::Notify(const BluetoothSignal& aData)
BluetoothGattService::AssignDescriptors(
const BluetoothGattId& aCharacteristicId,
const nsTArray<BluetoothGattId>& aDescriptorIds)
{
BT_LOGD("[D] %s", NS_ConvertUTF16toUTF8(aData.name()).get());
NS_ENSURE_TRUE_VOID(mSignalRegistered);
size_t index = mCharacteristics.IndexOf(aCharacteristicId);
NS_ENSURE_TRUE_VOID(index != mCharacteristics.NoIndex);
BluetoothValue v = aData.value();
if (aData.name().EqualsLiteral("IncludedServicesDiscovered")) {
HandleIncludedServicesDiscovered(v);
} else if (aData.name().EqualsLiteral("CharacteristicsDiscovered")) {
HandleCharacteristicsDiscovered(v);
} else {
BT_WARNING("Not handling GATT Service signal: %s",
NS_ConvertUTF16toUTF8(aData.name()).get());
}
nsRefPtr<BluetoothGattCharacteristic> characteristic =
mCharacteristics.ElementAt(index);
characteristic->AssignDescriptors(aDescriptorIds);
}
JSObject*

Просмотреть файл

@ -17,13 +17,14 @@
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothGatt;
class BluetoothSignal;
class BluetoothValue;
class BluetoothGattService final : public nsISupports
, public nsWrapperCache
, public BluetoothSignalObserver
{
friend class BluetoothGatt;
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(BluetoothGattService)
@ -71,8 +72,6 @@ public:
return mServiceId;
}
void Notify(const BluetoothSignal& aData); // BluetoothSignalObserver
nsPIDOMWindow* GetParentObject() const
{
return mOwner;
@ -92,20 +91,36 @@ private:
* Add newly discovered GATT included services into mIncludedServices and
* update the cache value of mIncludedServices.
*
* @param aValue [in] BluetoothValue which contains an array of
* BluetoothGattServiceId of all discovered included
* services.
* @param aServiceIds [in] An array of BluetoothGattServiceId for each
* included service that belongs to this service.
*/
void HandleIncludedServicesDiscovered(const BluetoothValue& aValue);
void AssignIncludedServices(
const nsTArray<BluetoothGattServiceId>& aServiceIds);
/**
* Add newly discovered GATT characteristics into mCharacteristics and
* update the cache value of mCharacteristics.
*
* @param aValue [in] BluetoothValue which contains an array of
* BluetoothGattId of all discovered characteristics.
* @param aCharacteristics [in] An array of BluetoothGattCharAttribute for
* each characteristic that belongs to this
* service.
*/
void HandleCharacteristicsDiscovered(const BluetoothValue& aValue);
void AssignCharacteristics(
const nsTArray<BluetoothGattCharAttribute>& aCharacteristics);
/**
* Add newly discovered GATT descriptors into mDescriptors of
* BluetoothGattCharacteristic and update the cache value of mDescriptors.
*
* @param aCharacteristicId [in] BluetoothGattId of a characteristic that
* belongs to this service.
* @param aDescriptorIds [in] An array of BluetoothGattId for each descriptor
* that belongs to the characteristic referred by
* aCharacteristicId.
*/
void AssignDescriptors(
const BluetoothGattId& aCharacteristicId,
const nsTArray<BluetoothGattId>& aDescriptorIds);
/****************************************************************************
* Variables