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

Commit b1c75082 authored by Victoria Lease's avatar Victoria Lease Committed by Android (Google) Code Review
Browse files

Merge "prevent concurrency issues during LocationManager init"

parents e06c046d 5cd731a2
Loading
Loading
Loading
Loading
+39 −37
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import android.location.LocationRequest;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
@@ -86,7 +87,7 @@ import java.util.Set;
 * The service class that manages LocationProviders and issues location
 * updates and alerts.
 */
public class LocationManagerService extends ILocationManager.Stub implements Runnable {
public class LocationManagerService extends ILocationManager.Stub {
    private static final String TAG = "LocationManagerService";
    public static final boolean D = false;

@@ -127,7 +128,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
    // used internally for synchronization
    private final Object mLock = new Object();

    // --- fields below are final after init() ---
    // --- fields below are final after systemReady() ---
    private LocationFudger mLocationFudger;
    private GeofenceManager mGeofenceManager;
    private PowerManager.WakeLock mWakeLock;
@@ -138,6 +139,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
    private LocationWorkerHandler mLocationHandler;
    private PassiveProvider mPassiveProvider;  // track passive provider for special cases
    private LocationBlacklist mBlacklist;
    private HandlerThread mHandlerThread;

    // --- fields below are protected by mWakeLock ---
    private int mPendingBroadcasts;
@@ -192,36 +194,33 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
    }

    public void systemReady() {
        Thread thread = new Thread(null, this, THREAD_NAME);
        thread.start();
    }

    @Override
    public void run() {
        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
        Looper.prepare();
        mLocationHandler = new LocationWorkerHandler();
        init();
        Looper.loop();
    }
        synchronized (mLock) {
            if (D) Log.d(TAG, "systemReady()");

    private void init() {
        if (D) Log.d(TAG, "init()");
            // fetch package manager
            mPackageManager = mContext.getPackageManager();

        PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
            // prepare wake lock
            PowerManager powerManager =
                    (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
            mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
        mPackageManager = mContext.getPackageManager();

            // prepare worker thread
            mHandlerThread = new HandlerThread(THREAD_NAME, Process.THREAD_PRIORITY_BACKGROUND);
            mHandlerThread.start();
            mLocationHandler = new LocationWorkerHandler(mHandlerThread.getLooper());

            // prepare mLocationHandler's dependents
            mLocationFudger = new LocationFudger(mContext, mLocationHandler);
            mBlacklist = new LocationBlacklist(mContext, mLocationHandler);
            mBlacklist.init();
        mLocationFudger = new LocationFudger(mContext, mLocationHandler);
            mGeofenceManager = new GeofenceManager(mContext, mBlacklist);

        synchronized (mLock) {
            // prepare providers
            loadProvidersLocked();
            updateProvidersLocked();
        }

        mGeofenceManager = new GeofenceManager(mContext, mBlacklist);

        // listen for settings changes
        mContext.getContentResolver().registerContentObserver(
                Settings.Secure.getUriFor(Settings.Secure.LOCATION_PROVIDERS_ALLOWED), true,
@@ -233,7 +232,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
                        }
                    }
                }, UserHandle.USER_ALL);
        mPackageMonitor.register(mContext, Looper.myLooper(), true);
        mPackageMonitor.register(mContext, mLocationHandler.getLooper(), true);

        // listen for user change
        IntentFilter intentFilter = new IntentFilter();
@@ -247,9 +246,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
                    switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
                }
            }
        }, UserHandle.ALL, intentFilter, null, null);

        updateProvidersLocked();
        }, UserHandle.ALL, intentFilter, null, mLocationHandler);
    }

    private void ensureFallbackFusedProviderPresentLocked(ArrayList<String> pkgs) {
@@ -329,7 +326,8 @@ public class LocationManagerService extends ILocationManager.Stub implements Run

        if (GpsLocationProvider.isSupported()) {
            // Create a gps location provider
            GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this);
            GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this,
                    mLocationHandler.getLooper());
            mGpsStatusProvider = gpsProvider.getGpsStatusProvider();
            mNetInitiatedListener = gpsProvider.getNetInitiatedListener();
            addProviderLocked(gpsProvider);
@@ -389,7 +387,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run

        // bind to geocoder provider
        mGeocodeProvider = GeocoderProxy.createAndBind(mContext, providerPackageNames,
                mCurrentUserId);
                mLocationHandler, mCurrentUserId);
        if (mGeocodeProvider == null) {
            Slog.e(TAG,  "no geocoder provider found");
        }
@@ -1715,6 +1713,10 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
    }

    private class LocationWorkerHandler extends Handler {
        public LocationWorkerHandler(Looper looper) {
            super(looper, null, true);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
+6 −4
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.content.Context;
import android.location.Address;
import android.location.GeocoderParams;
import android.location.IGeocodeProvider;
import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
@@ -39,8 +40,8 @@ public class GeocoderProxy {
    private final ServiceWatcher mServiceWatcher;

    public static GeocoderProxy createAndBind(Context context,
            List<String> initialPackageNames, int userId) {
        GeocoderProxy proxy = new GeocoderProxy(context, initialPackageNames, userId);
            List<String> initialPackageNames, Handler handler, int userId) {
        GeocoderProxy proxy = new GeocoderProxy(context, initialPackageNames, handler, userId);
        if (proxy.bind()) {
            return proxy;
        } else {
@@ -48,11 +49,12 @@ public class GeocoderProxy {
        }
    }

    public GeocoderProxy(Context context, List<String> initialPackageNames, int userId) {
    public GeocoderProxy(Context context, List<String> initialPackageNames, Handler handler,
            int userId) {
        mContext = context;

        mServiceWatcher = new ServiceWatcher(mContext, TAG, SERVICE_ACTION, initialPackageNames,
                null, null, userId);
                null, handler, userId);
    }

    private boolean bind () {
+6 −4
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteException;
@@ -413,7 +414,8 @@ public class GpsLocationProvider implements LocationProviderInterface {
        return native_is_supported();
    }

    public GpsLocationProvider(Context context, ILocationManager ilocationManager) {
    public GpsLocationProvider(Context context, ILocationManager ilocationManager,
            Looper looper) {
        mContext = context;
        mNtpTime = NtpTrustedTime.getInstance(context);
        mILocationManager = ilocationManager;
@@ -466,7 +468,7 @@ public class GpsLocationProvider implements LocationProviderInterface {
        }

        // construct handler, listen for events
        mHandler = new ProviderHandler();
        mHandler = new ProviderHandler(looper);
        listenForBroadcasts();

        // also listen for PASSIVE_PROVIDER updates
@@ -1488,8 +1490,8 @@ public class GpsLocationProvider implements LocationProviderInterface {
    }

    private final class ProviderHandler extends Handler {
        public ProviderHandler() {
            super(true /*async*/);
        public ProviderHandler(Looper looper) {
            super(looper, null, true /*async*/);
        }

        @Override
+0 −1
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import android.location.LocationProvider;
import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.WorkSource;
import android.util.Log;