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

Commit 06989725 authored by Wyatt Riley's avatar Wyatt Riley Committed by android-build-merger
Browse files

Merge "Fix RemoteListenerHelper vs. HAL deadlock" into oc-dr1-dev

am: ec996b38

Change-Id: I345871c43857d1d0e01377a50e9745ce3c598955
parents 93a1ab8b ec996b38
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -243,8 +243,9 @@ public class LocationManagerService extends ILocationManager.Stub {

    private GnssLocationProvider.GnssSystemInfoProvider mGnssSystemInfoProvider;

    private GnssLocationProvider.GnssBatchingProvider mGnssBatchingProvider;
    private GnssLocationProvider.GnssMetricsProvider mGnssMetricsProvider;

    private GnssLocationProvider.GnssBatchingProvider mGnssBatchingProvider;
    private IBatchedLocationCallback mGnssBatchingCallback;
    private LinkedCallback mGnssBatchingDeathCallback;
    private boolean mGnssBatchingInProgress = false;
+16 −4
Original line number Diff line number Diff line
@@ -1754,21 +1754,33 @@ public class GnssLocationProvider implements LocationProviderInterface {
    }

    /**
     * called from native code - Gps measurements callback
     * called from native code - GNSS measurements callback
     */
    private void reportMeasurementData(GnssMeasurementsEvent event) {
        if (!mItarSpeedLimitExceeded) {
            // send to handler to allow native to return quickly
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    mGnssMeasurementsProvider.onMeasurementsAvailable(event);
                }
            });
        }
    }

    /**
     * called from native code - GPS navigation message callback
     * called from native code - GNSS navigation message callback
     */
    private void reportNavigationMessage(GnssNavigationMessage event) {
        if (!mItarSpeedLimitExceeded) {
            // send to handler to allow native to return quickly
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    mGnssNavigationMessageProvider.onNavigationMessageAvailable(event);
                }
            });
        }
    }

    /**
+2 −3
Original line number Diff line number Diff line
@@ -54,10 +54,9 @@ public abstract class GnssMeasurementsProvider
    }

    public void onGpsEnabledChanged() {
        if (tryUpdateRegistrationWithService()) {
        tryUpdateRegistrationWithService();
        updateResult();
    }
    }

    @Override
    protected ListenerOperation<IGnssMeasurementsListener> getHandlerOperation(int result) {
+2 −3
Original line number Diff line number Diff line
@@ -55,10 +55,9 @@ public abstract class GnssNavigationMessageProvider
    }

    public void onGpsEnabledChanged() {
        if (tryUpdateRegistrationWithService()) {
        tryUpdateRegistrationWithService();
        updateResult();
    }
    }

    @Override
    protected ListenerOperation<IGnssNavigationMessageListener> getHandlerOperation(int result) {
+42 −26
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.os.IInterface;
import android.os.RemoteException;
import android.util.Log;

import java.lang.Runnable;
import java.util.HashMap;
import java.util.Map;

@@ -45,7 +46,7 @@ abstract class RemoteListenerHelper<TListener extends IInterface> {

    private final Map<IBinder, LinkedListener> mListenerMap = new HashMap<>();

    private boolean mIsRegistered;
    private boolean mIsRegistered;  // must access only on handler thread
    private boolean mHasIsSupported;
    private boolean mIsSupported;

@@ -83,12 +84,12 @@ abstract class RemoteListenerHelper<TListener extends IInterface> {
            } else if (mHasIsSupported && !mIsSupported) {
                result = RESULT_NOT_SUPPORTED;
            } else if (!isGpsEnabled()) {
                result = RESULT_GPS_LOCATION_DISABLED;
            } else if (!tryRegister()) {
                // only attempt to register if GPS is enabled, otherwise we will register once GPS
                // becomes available
                result = RESULT_INTERNAL_ERROR;
                result = RESULT_GPS_LOCATION_DISABLED;
            } else if (mHasIsSupported && mIsSupported) {
                tryRegister();
                // initially presume success, possible internal error could follow asynchornously
                result = RESULT_SUCCESS;
            } else {
                // at this point if the supported flag is not set, the notification will be sent
@@ -117,8 +118,8 @@ abstract class RemoteListenerHelper<TListener extends IInterface> {

    protected abstract boolean isAvailableInPlatform();
    protected abstract boolean isGpsEnabled();
    protected abstract boolean registerWithService();
    protected abstract void unregisterFromService();
    protected abstract boolean registerWithService(); // must access only on handler thread
    protected abstract void unregisterFromService(); // must access only on handler thread
    protected abstract ListenerOperation<TListener> getHandlerOperation(int result);

    protected interface ListenerOperation<TListener extends IInterface> {
@@ -138,22 +139,16 @@ abstract class RemoteListenerHelper<TListener extends IInterface> {
        }
    }

    protected boolean tryUpdateRegistrationWithService() {
    protected void tryUpdateRegistrationWithService() {
        synchronized (mListenerMap) {
            if (!isGpsEnabled()) {
                tryUnregister();
                return true;
                return;
            }
            if (mListenerMap.isEmpty()) {
                return true;
            }
            if (tryRegister()) {
                // registration was successful, there is no need to update the state
                return true;
                return;
            }
            ListenerOperation<TListener> operation = getHandlerOperation(RESULT_INTERNAL_ERROR);
            foreachUnsafe(operation);
            return false;
            tryRegister();
        }
    }

@@ -180,20 +175,41 @@ abstract class RemoteListenerHelper<TListener extends IInterface> {
        }
    }

    private boolean tryRegister() {
    private void tryRegister() {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if (!mIsRegistered) {
                    mIsRegistered = registerWithService();
                }
        return mIsRegistered;
                if (!mIsRegistered) {
                    // post back a failure
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            synchronized (mListenerMap) {
                                ListenerOperation<TListener> operation = getHandlerOperation(RESULT_INTERNAL_ERROR);
                                foreachUnsafe(operation);
                            }
                        }
                    });
                }
            }
        });
    }

    private void tryUnregister() {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if (!mIsRegistered) {
                    return;
                }
                unregisterFromService();
                mIsRegistered = false;
            }
        });
    }

    private int calculateCurrentResultUnsafe() {
        // update statuses we already know about, starting from the ones that will never change