From: Jakub Pawlowski Date: Sat, 12 Dec 2015 06:35:01 +0000 (-0800) Subject: Fix race condition when doing GATT discovery X-Git-Tag: android-7.1.2_r17~195^2~1^2~7^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=bac1f06eeded99fa43e00ac4114846a96c22e03c;p=android-x86%2Fpackages-apps-Bluetooth.git Fix race condition when doing GATT discovery Right now if discovery to multiple GATT clients is happening simultaneously, onSearchComplete will be run only for device that finishes discovery last, while it should be run for each device. mSearchQueue is one for all discovery sessions. Instead of checking if it's empty, we must check if there are no elements for given connId. Bug: 26038939 Change-Id: I9417cd7be8cab4b808ce7f045861e1adc2055629 --- diff --git a/src/com/android/bluetooth/gatt/GattService.java b/src/com/android/bluetooth/gatt/GattService.java index 4847c53c..376994c7 100644 --- a/src/com/android/bluetooth/gatt/GattService.java +++ b/src/com/android/bluetooth/gatt/GattService.java @@ -2138,7 +2138,20 @@ public class GattService extends ProfileService { } private void continueSearch(int connId, int status) throws RemoteException { - if (status == 0 && !mSearchQueue.isEmpty()) { + + // Search is complete when there was error, or nothing more to process + if (status != 0 || mSearchQueue.isEmptyFor(connId)) { + // In case we complete because of error, clean up + // any remaining operations for this connection. + mSearchQueue.removeConnId(connId); + + ClientMap.App app = mClientMap.getByConnId(connId); + if (app != null) { + app.callback.onSearchComplete(mClientMap.addressByConnId(connId), status); + } + } + + if (!mSearchQueue.isEmpty()) { SearchQueue.Entry svc = mSearchQueue.pop(); if (svc.charUuidLsb == 0) { @@ -2151,11 +2164,6 @@ public class GattService extends ProfileService { svc.srvcInstId, svc.srvcUuidLsb, svc.srvcUuidMsb, svc.charInstId, svc.charUuidLsb, svc.charUuidMsb, 0, 0, 0); } - } else { - ClientMap.App app = mClientMap.getByConnId(connId); - if (app != null) { - app.callback.onSearchComplete(mClientMap.addressByConnId(connId), status); - } } } diff --git a/src/com/android/bluetooth/gatt/SearchQueue.java b/src/com/android/bluetooth/gatt/SearchQueue.java index 3064a51e..c784415e 100644 --- a/src/com/android/bluetooth/gatt/SearchQueue.java +++ b/src/com/android/bluetooth/gatt/SearchQueue.java @@ -86,6 +86,16 @@ import java.util.List; return mEntries.isEmpty(); } + boolean isEmptyFor(int connId) { + for (Iterator it = mEntries.iterator(); it.hasNext();) { + Entry entry = it.next(); + if (entry.connId == connId) { + return false; + } + } + return true; + } + void clear() { mEntries.clear(); }