Bug 1161956 - Fix crashes while using GATT client functions. r=jocelyn
authorBruce Sun <brsun@mozilla.com>
Wed, 03 Jun 2015 18:19:43 +0800
changeset 246927 ce7b42bbf7173dc2a81a73d9791ef754f6afa750
parent 246926 7ada5429c80deeedcefbd2925355d3f6c80e1bc6
child 246928 f21174a2552d96f6f96234094b5cd247d2950653
push id28846
push userryanvm@gmail.com
push dateWed, 03 Jun 2015 19:51:00 +0000
treeherdermozilla-central@e5ee2c56963c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjocelyn
bugs1161956
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1161956 - Fix crashes while using GATT client functions. r=jocelyn
dom/bluetooth/bluedroid/BluetoothGattManager.cpp
--- a/dom/bluetooth/bluedroid/BluetoothGattManager.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothGattManager.cpp
@@ -474,17 +474,20 @@ BluetoothGattManager::UnregisterClient(i
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aRunnable);
 
   ENSURE_GATT_CLIENT_INTF_IS_READY_VOID(aRunnable);
 
   size_t index = sClients->IndexOf(aClientIf, 0 /* Start */,
                                    ClientIfComparator());
-  MOZ_ASSERT(index != sClients->NoIndex);
+  if (NS_WARN_IF(index == sClients->NoIndex)) {
+    DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
+    return;
+  }
 
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
   client->mUnregisterClientRunnable = aRunnable;
 
   sBluetoothGattClientInterface->UnregisterClient(
     aClientIf,
     new UnregisterClientResultHandler(client));
 }
@@ -575,17 +578,17 @@ BluetoothGattManager::StartLeScan(const 
   ENSURE_GATT_CLIENT_INTF_IS_READY_VOID(aRunnable);
 
   nsString appUuidStr;
   GenerateUuid(appUuidStr);
 
   size_t index = sClients->IndexOf(appUuidStr, 0 /* Start */, UuidComparator());
 
   // Reject the startLeScan request if the clientIf is being used.
-  if (index != sClients->NoIndex) {
+  if (NS_WARN_IF(index != sClients->NoIndex)) {
     DispatchReplyError(aRunnable,
                        NS_LITERAL_STRING("start LE scan failed"));
     return;
   }
 
   index = sClients->Length();
   sClients->AppendElement(new BluetoothGattClient(appUuidStr, EmptyString()));
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
@@ -733,17 +736,20 @@ BluetoothGattManager::Disconnect(const n
                                  BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aRunnable);
 
   ENSURE_GATT_CLIENT_INTF_IS_READY_VOID(aRunnable);
 
   size_t index = sClients->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
-  MOZ_ASSERT(index != sClients->NoIndex);
+  if (NS_WARN_IF(index == sClients->NoIndex)) {
+    DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
+    return;
+  }
 
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
   client->mDisconnectRunnable = aRunnable;
 
   sBluetoothGattClientInterface->Disconnect(
     client->mClientIf,
     aDeviceAddr,
     client->mConnId,
@@ -777,17 +783,20 @@ BluetoothGattManager::Discover(const nsA
                                BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aRunnable);
 
   ENSURE_GATT_CLIENT_INTF_IS_READY_VOID(aRunnable);
 
   size_t index = sClients->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
-  MOZ_ASSERT(index != sClients->NoIndex);
+  if (NS_WARN_IF(index == sClients->NoIndex)) {
+    DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
+    return;
+  }
 
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
   MOZ_ASSERT(client->mConnId > 0);
   MOZ_ASSERT(!client->mDiscoverRunnable);
 
   client->mDiscoverRunnable = aRunnable;
 
   /**
@@ -846,17 +855,20 @@ BluetoothGattManager::ReadRemoteRssi(int
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aRunnable);
 
   ENSURE_GATT_CLIENT_INTF_IS_READY_VOID(aRunnable);
 
   size_t index = sClients->IndexOf(aClientIf, 0 /* Start */,
                                    ClientIfComparator());
-  MOZ_ASSERT(index != sClients->NoIndex);
+  if (NS_WARN_IF(index == sClients->NoIndex)) {
+    DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
+    return;
+  }
 
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
   client->mReadRemoteRssiRunnable = aRunnable;
 
   sBluetoothGattClientInterface->ReadRemoteRssi(
     aClientIf, aDeviceAddr,
     new ReadRemoteRssiResultHandler(client));
 }
@@ -910,17 +922,20 @@ BluetoothGattManager::RegisterNotificati
   const BluetoothGattId& aCharId, BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aRunnable);
 
   ENSURE_GATT_CLIENT_INTF_IS_READY_VOID(aRunnable);
 
   size_t index = sClients->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
-  MOZ_ASSERT(index != sClients->NoIndex);
+  if (NS_WARN_IF(index == sClients->NoIndex)) {
+    DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
+    return;
+  }
 
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
 
   // Reject the request if there is an ongoing request or client is already
   // disconnected
   if (client->mRegisterNotificationsRunnable || client->mConnId <= 0) {
     DispatchReplyError(aRunnable,
                        NS_LITERAL_STRING("RegisterNotifications failed"));
@@ -983,17 +998,20 @@ BluetoothGattManager::DeregisterNotifica
   const BluetoothGattId& aCharId, BluetoothReplyRunnable* aRunnable)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aRunnable);
 
   ENSURE_GATT_CLIENT_INTF_IS_READY_VOID(aRunnable);
 
   size_t index = sClients->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
-  MOZ_ASSERT(index != sClients->NoIndex);
+  if (NS_WARN_IF(index == sClients->NoIndex)) {
+    DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
+    return;
+  }
 
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
 
   // Reject the request if there is an ongoing request
   if (client->mDeregisterNotificationsRunnable) {
     DispatchReplyError(aRunnable,
                        NS_LITERAL_STRING("DeregisterNotifications failed"));
     return;
@@ -1044,19 +1062,17 @@ BluetoothGattManager::ReadCharacteristic
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aRunnable);
 
   ENSURE_GATT_CLIENT_INTF_IS_READY_VOID(aRunnable);
 
   size_t index = sClients->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
   if (NS_WARN_IF(index == sClients->NoIndex)) {
-    // Reject the read characteristic value request
-    DispatchReplyError(aRunnable,
-                       NS_LITERAL_STRING("ReadCharacteristicValue failed"));
+    DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
     return;
   }
 
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
 
   /**
    * Reject subsequent reading requests to follow ATT sequential protocol that
    * handles one request at a time. Otherwise underlying layers would drop the
@@ -1126,19 +1142,17 @@ BluetoothGattManager::WriteCharacteristi
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aRunnable);
 
   ENSURE_GATT_CLIENT_INTF_IS_READY_VOID(aRunnable);
 
   size_t index = sClients->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
   if (NS_WARN_IF(index == sClients->NoIndex)) {
-    // Reject the write characteristic value request
-    DispatchReplyError(aRunnable,
-                       NS_LITERAL_STRING("WriteCharacteristicValue failed"));
+    DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
     return;
   }
 
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
 
   /**
    * Reject subsequent writing requests to follow ATT sequential protocol that
    * handles one request at a time. Otherwise underlying layers would drop the
@@ -1209,19 +1223,17 @@ BluetoothGattManager::ReadDescriptorValu
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aRunnable);
 
   ENSURE_GATT_CLIENT_INTF_IS_READY_VOID(aRunnable);
 
   size_t index = sClients->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
   if (NS_WARN_IF(index == sClients->NoIndex)) {
-    // Reject the read descriptor value request
-    DispatchReplyError(aRunnable,
-                       NS_LITERAL_STRING("ReadDescriptorValue failed"));
+    DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
     return;
   }
 
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
 
   /**
    * Reject subsequent reading requests to follow ATT sequential protocol that
    * handles one request at a time. Otherwise underlying layers would drop the
@@ -1292,19 +1304,17 @@ BluetoothGattManager::WriteDescriptorVal
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aRunnable);
 
   ENSURE_GATT_CLIENT_INTF_IS_READY_VOID(aRunnable);
 
   size_t index = sClients->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
   if (NS_WARN_IF(index == sClients->NoIndex)) {
-    // Reject the write descriptor value request
-    DispatchReplyError(aRunnable,
-                       NS_LITERAL_STRING("WriteDescriptorValue failed"));
+    DispatchReplyError(aRunnable, STATUS_PARM_INVALID);
     return;
   }
 
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
 
   /**
    * Reject subsequent writing requests to follow ATT sequential protocol that
    * handles one request at a time. Otherwise underlying layers would drop the
@@ -1347,17 +1357,18 @@ BluetoothGattManager::RegisterClientNoti
 {
   BT_API2_LOGR("Client Registered, clientIf = %d", aClientIf);
   MOZ_ASSERT(NS_IsMainThread());
 
   nsString uuid;
   UuidToString(aAppUuid, uuid);
 
   size_t index = sClients->IndexOf(uuid, 0 /* Start */, UuidComparator());
-  MOZ_ASSERT(index != sClients->NoIndex);
+  NS_ENSURE_TRUE_VOID(index != sClients->NoIndex);
+
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
 
   BluetoothService* bs = BluetoothService::Get();
   NS_ENSURE_TRUE_VOID(bs);
 
   if (aStatus != GATT_STATUS_SUCCESS) {
     BT_API2_LOGR(
       "RegisterClient failed, clientIf = %d, status = %d, appUuid = %s",
@@ -1442,17 +1453,18 @@ BluetoothGattManager::ConnectNotificatio
   BT_API2_LOGR();
   MOZ_ASSERT(NS_IsMainThread());
 
   BluetoothService* bs = BluetoothService::Get();
   NS_ENSURE_TRUE_VOID(bs);
 
   size_t index = sClients->IndexOf(aClientIf, 0 /* Start */,
                                    ClientIfComparator());
-  MOZ_ASSERT(index != sClients->NoIndex);
+  NS_ENSURE_TRUE_VOID(index != sClients->NoIndex);
+
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
 
   if (aStatus != GATT_STATUS_SUCCESS) {
     BT_API2_LOGR("Connect failed, clientIf = %d, connId = %d, status = %d",
                  aClientIf, aConnId, aStatus);
 
     // Notify BluetoothGatt that the client remains disconnected
     bs->DistributeSignal(
@@ -1494,17 +1506,18 @@ BluetoothGattManager::DisconnectNotifica
   BT_API2_LOGR();
   MOZ_ASSERT(NS_IsMainThread());
 
   BluetoothService* bs = BluetoothService::Get();
   NS_ENSURE_TRUE_VOID(bs);
 
   size_t index = sClients->IndexOf(aClientIf, 0 /* Start */,
                                    ClientIfComparator());
-  MOZ_ASSERT(index != sClients->NoIndex);
+  NS_ENSURE_TRUE_VOID(index != sClients->NoIndex);
+
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
 
   if (aStatus != GATT_STATUS_SUCCESS) {
     // Notify BluetoothGatt that the client remains connected
     bs->DistributeSignal(
       NS_LITERAL_STRING(GATT_CONNECTION_STATE_CHANGED_ID),
       client->mAppUuid,
       BluetoothValue(true)); // Connected
@@ -1540,17 +1553,17 @@ BluetoothGattManager::SearchCompleteNoti
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   BluetoothService* bs = BluetoothService::Get();
   NS_ENSURE_TRUE_VOID(bs);
 
   size_t index = sClients->IndexOf(aConnId, 0 /* Start */,
                                    ConnIdComparator());
-  MOZ_ASSERT(index != sClients->NoIndex);
+  NS_ENSURE_TRUE_VOID(index != sClients->NoIndex);
 
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
   MOZ_ASSERT(client->mDiscoverRunnable);
 
   if (aStatus != GATT_STATUS_SUCCESS) {
     client->NotifyDiscoverCompleted(false);
     return;
   }
@@ -1577,17 +1590,17 @@ BluetoothGattManager::SearchCompleteNoti
 void
 BluetoothGattManager::SearchResultNotification(
   int aConnId, const BluetoothGattServiceId& aServiceId)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   size_t index = sClients->IndexOf(aConnId, 0 /* Start */,
                                    ConnIdComparator());
-  MOZ_ASSERT(index != sClients->NoIndex);
+  NS_ENSURE_TRUE_VOID(index != sClients->NoIndex);
 
   // Save to mServices for distributing to application and discovering
   // included services, characteristics of this service later
   sClients->ElementAt(index)->mServices.AppendElement(aServiceId);
 }
 
 void
 BluetoothGattManager::GetCharacteristicNotification(
@@ -1598,17 +1611,17 @@ BluetoothGattManager::GetCharacteristicN
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   BluetoothService* bs = BluetoothService::Get();
   NS_ENSURE_TRUE_VOID(bs);
 
   size_t index = sClients->IndexOf(aConnId, 0 /* Start */,
                                    ConnIdComparator());
-  MOZ_ASSERT(index != sClients->NoIndex);
+  NS_ENSURE_TRUE_VOID(index != sClients->NoIndex);
 
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
   MOZ_ASSERT(client->mDiscoverRunnable);
 
   if (aStatus == GATT_STATUS_SUCCESS) {
     BluetoothGattCharAttribute attribute;
     attribute.mId = aCharId;
     attribute.mProperties = aCharProperty;
@@ -1650,17 +1663,17 @@ BluetoothGattManager::GetDescriptorNotif
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   BluetoothService* bs = BluetoothService::Get();
   NS_ENSURE_TRUE_VOID(bs);
 
   size_t index = sClients->IndexOf(aConnId, 0 /* Start */,
                                    ConnIdComparator());
-  MOZ_ASSERT(index != sClients->NoIndex);
+  NS_ENSURE_TRUE_VOID(index != sClients->NoIndex);
 
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
   MOZ_ASSERT(client->mDiscoverRunnable);
 
   if (aStatus == GATT_STATUS_SUCCESS) {
     // Save to mDescriptors for distributing to applications
     client->mDescriptors.AppendElement(aDescriptorId);
 
@@ -1694,17 +1707,17 @@ BluetoothGattManager::GetIncludedService
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   BluetoothService* bs = BluetoothService::Get();
   NS_ENSURE_TRUE_VOID(bs);
 
   size_t index = sClients->IndexOf(aConnId, 0 /* Start */,
                                    ConnIdComparator());
-  MOZ_ASSERT(index != sClients->NoIndex);
+  NS_ENSURE_TRUE_VOID(index != sClients->NoIndex);
 
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
   MOZ_ASSERT(client->mDiscoverRunnable);
 
   if (aStatus == GATT_STATUS_SUCCESS) {
     // Save to mIncludedServices for distributing to applications
     client->mIncludedServices.AppendElement(aIncludedServId);
 
@@ -2013,16 +2026,17 @@ BluetoothGattManager::ReadRemoteRssiNoti
   MOZ_ASSERT(NS_IsMainThread());
 
   BluetoothService* bs = BluetoothService::Get();
   NS_ENSURE_TRUE_VOID(bs);
 
   size_t index = sClients->IndexOf(aClientIf, 0 /* Start */,
                                    ClientIfComparator());
   NS_ENSURE_TRUE_VOID(index != sClients->NoIndex);
+
   nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
 
   if (aStatus != GATT_STATUS_SUCCESS) { // operation failed
     BT_API2_LOGR("ReadRemoteRssi failed, clientIf = %d, bdAddr = %s, " \
                  "rssi = %d, status = %d", aClientIf,
                  NS_ConvertUTF16toUTF8(aBdAddr).get(), aRssi, (int)aStatus);
 
     // Reject the read remote rssi request