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

Commit 39d614aa authored by Soonil Nagarkar's avatar Soonil Nagarkar
Browse files

Allow listener garbage collection

Currently listeners that expire (either because of expireAt or
numUpdates) will never be removed from the client listener list. Fix
this by adding a new ILocationListener callback.

Also remove old status callback that isn't being used anymore.

Test: atest CtsLocationFineTestCases
Change-Id: I3f8a5058988c8257f25fe63a0c62e9d26ed2cf00
parent 8beb64d0
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -31,8 +31,6 @@ oneway interface ILocationListener
    void onProviderEnabled(String provider);
    @UnsupportedAppUsage
    void onProviderDisabled(String provider);

    // --- deprecated ---
    @UnsupportedAppUsage
    void onStatusChanged(String provider, int status, in Bundle extras);
    // called when the listener is removed from the server side; no further callbacks are expected
    void onRemoved();
}
+13 −34
Original line number Diff line number Diff line
@@ -2480,9 +2480,6 @@ public class LocationManager {
            deliverResult(location);
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {}

        @Override
        public void onProviderEnabled(String provider) {}

@@ -2493,6 +2490,11 @@ public class LocationManager {
            deliverResult(null);
        }

        @Override
        public void onRemoved() {
            deliverResult(null);
        }

        private synchronized void deliverResult(@Nullable Location location) {
            if (mExecutor == null) {
                return;
@@ -2567,37 +2569,6 @@ public class LocationManager {
            }
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            Executor currentExecutor = mExecutor;
            if (currentExecutor == null) {
                return;
            }

            try {
                currentExecutor.execute(() -> {
                    try {
                        if (currentExecutor != mExecutor) {
                            return;
                        }

                        // we may be under the binder identity if a direct executor is used
                        long identity = Binder.clearCallingIdentity();
                        try {
                            mListener.onStatusChanged(provider, status, extras);
                        } finally {
                            Binder.restoreCallingIdentity(identity);
                        }
                    } finally {
                        locationCallbackFinished();
                    }
                });
            } catch (RejectedExecutionException e) {
                locationCallbackFinished();
                throw e;
            }
        }

        @Override
        public void onProviderEnabled(String provider) {
            Executor currentExecutor = mExecutor;
@@ -2660,6 +2631,14 @@ public class LocationManager {
            }
        }

        @Override
        public void onRemoved() {
            unregister();
            synchronized (mListeners) {
                mListeners.remove(mListener, this);
            }
        }

        private void locationCallbackFinished() {
            try {
                mService.locationCallbackFinished(this);
+12 −0
Original line number Diff line number Diff line
@@ -1453,6 +1453,16 @@ public class LocationManagerService extends ILocationManager.Stub {
            return true;
        }

        public void callRemovedLocked() {
            if (mListener != null) {
                try {
                    mListener.onRemoved();
                } catch (RemoteException e) {
                    // doesn't matter
                }
            }
        }

        @Override
        public void binderDied() {
            if (D) Log.d(TAG, "Remote " + mListenerName + " died.");
@@ -3066,6 +3076,8 @@ public class LocationManagerService extends ILocationManager.Stub {

            // track expired records
            if (r.mRealRequest.getNumUpdates() <= 0 || r.mRealRequest.getExpireAt() < now) {
                // notify the client it can remove this listener
                r.mReceiver.callRemovedLocked();
                if (deadUpdateRecords == null) {
                    deadUpdateRecords = new ArrayList<>();
                }