diff options
author | Joshua Bartel <joshua.bartel@gmail.com> | 2009-10-05 12:44:46 -0400 |
---|---|---|
committer | Joshua Bartel <joshua.bartel@gmail.com> | 2009-10-05 12:44:46 -0400 |
commit | 9ff67a5f9b0bca15ad6933eac90a65b11b29eb2e (patch) | |
tree | be6b8a4728f94454eee79e5601dec7887dd7e752 | |
parent | 5550ef48739a7bb16f80aa6b10e9c151b1438163 (diff) | |
download | base-9ff67a5f9b0bca15ad6933eac90a65b11b29eb2e.tar.gz |
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.
-rw-r--r-- | services/java/com/android/server/LocationManagerService.java | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java index 9866ccea8732..4a4d5abb3371 100644 --- a/services/java/com/android/server/LocationManagerService.java +++ b/services/java/com/android/server/LocationManagerService.java @@ -394,7 +394,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 @@ -1030,6 +1035,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 |