Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 080b61ba authored by Joshua Bartel's avatar Joshua Bartel Committed by Mike Lockwood
Browse files

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: default avatarMike Lockwood <lockwood@android.com>
parent 7c12540f
Loading
Loading
Loading
Loading
+12 −1
Original line number Original line Diff line number Diff line
@@ -382,7 +382,12 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
    }
    }


    public void locationCallbackFinished(ILocationListener listener) {
    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) {
        if (receiver != null) {
            synchronized (receiver) {
            synchronized (receiver) {
                // so wakelock calls will succeed
                // so wakelock calls will succeed
@@ -921,6 +926,12 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
        try {
        try {
            if (mReceivers.remove(receiver.mKey) != null && receiver.isListener()) {
            if (mReceivers.remove(receiver.mKey) != null && receiver.isListener()) {
                receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
                receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
                synchronized(receiver) {
                    if(receiver.mPendingBroadcasts > 0) {
                        decrementPendingBroadcasts();
                        receiver.mPendingBroadcasts = 0;
                    }
                }
            }
            }


            // Record which providers were associated with this listener
            // Record which providers were associated with this listener