From 080b61ba17014b8c93914f642ccbe05c76dc611d Mon Sep 17 00:00:00 2001 From: Joshua Bartel Date: Mon, 5 Oct 2009 12:44:46 -0400 Subject: LocationManagerService: Fix race when removing LocationListener In LocationManagerService if a LocationListener is removed while it has a pending broadcast the wake lock held while pending broadcasts are outstanding do not get cleared properly. There are 2 cases of this race that are fixed: 1. locationCallbackFinished was changed to check the mReceivers HashMap directly instead of calling getReceiver. getReceiver would add the ILocationListener as a new Receiver if it did not exist which caused a receiver that was removed when it still had a broadcast pending to be added back in a bad state when the pending broadcast completed. 2. removeUpdatesLocked was changed to decrement the pending broadcasts when a Receiver is removed that has pending broadcasts. Fixes bug b/2163871 Change-Id: I50a321c9b3359bf69845236dc4a4b9e38e847335 Signed-off-by: Mike Lockwood --- .../java/com/android/server/LocationManagerService.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java index f6a1be73328f..c8fa4c39ad03 100644 --- a/services/java/com/android/server/LocationManagerService.java +++ b/services/java/com/android/server/LocationManagerService.java @@ -382,7 +382,12 @@ public class LocationManagerService extends ILocationManager.Stub implements Run } public void locationCallbackFinished(ILocationListener listener) { - Receiver receiver = getReceiver(listener); + //Do not use getReceiver here as that will add the ILocationListener to + //the receiver list if it is not found. If it is not found then the + //LocationListener was removed when it had a pending broadcast and should + //not be added back. + IBinder binder = listener.asBinder(); + Receiver receiver = mReceivers.get(binder); if (receiver != null) { synchronized (receiver) { // so wakelock calls will succeed @@ -921,6 +926,12 @@ public class LocationManagerService extends ILocationManager.Stub implements Run try { if (mReceivers.remove(receiver.mKey) != null && receiver.isListener()) { receiver.getListener().asBinder().unlinkToDeath(receiver, 0); + synchronized(receiver) { + if(receiver.mPendingBroadcasts > 0) { + decrementPendingBroadcasts(); + receiver.mPendingBroadcasts = 0; + } + } } // Record which providers were associated with this listener -- cgit v1.2.3-59-g8ed1b