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 <lockwood@android.com>
This commit is contained in:
committed by
Mike Lockwood
parent
7c12540f09
commit
080b61ba17
@ -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
|
||||
|
Reference in New Issue
Block a user