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

Commit 5c24fd03 authored by Victoria Lease's avatar Victoria Lease
Browse files

Avoid NPE in GpsLocationProvider

Oops, looks like we were spinning up a secondary thread to run some
tasks that will just happen on the main thread regardless. Removed
the secondary thread and fixed up initialisation order regarding
mHandler and things that post to it. Also reordered GPS and
PASSIVE provider initialisation order since GPS depends on PASSIVE.

This should be both safer and easier to read.

Bug: 7248029
Change-Id: I8630caf0a7bd1b2c401603075676f13dda5be4fa
parent ce803d8e
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -228,6 +228,12 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
    }

    private void loadProvidersLocked() {
        // create a passive location provider, which is always enabled
        PassiveProvider passiveProvider = new PassiveProvider(this);
        addProviderLocked(passiveProvider);
        mEnabledProviders.add(passiveProvider.getName());
        mPassiveProvider = passiveProvider;

        if (GpsLocationProvider.isSupported()) {
            // Create a gps location provider
            GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this);
@@ -237,12 +243,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
            mRealProviders.put(LocationManager.GPS_PROVIDER, gpsProvider);
        }

        // create a passive location provider, which is always enabled
        PassiveProvider passiveProvider = new PassiveProvider(this);
        addProviderLocked(passiveProvider);
        mEnabledProviders.add(passiveProvider.getName());
        mPassiveProvider = passiveProvider;

        /*
        Load package name(s) containing location provider support.
        These packages can contain services implementing location providers:
+31 −59
Original line number Diff line number Diff line
@@ -40,10 +40,8 @@ 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.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
@@ -75,7 +73,6 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;

/**
 * A GPS implementation of LocationProvider used by LocationManager.
@@ -287,12 +284,8 @@ public class GpsLocationProvider implements LocationProviderInterface {
    private Bundle mLocationExtras = new Bundle();
    private ArrayList<Listener> mListeners = new ArrayList<Listener>();

    // GpsLocationProvider's handler thread
    private final Thread mThread;
    // Handler for processing events in mThread.
    // Handler for processing events
    private Handler mHandler;
    // Used to signal when our main thread has initialized everything
    private final CountDownLatch mInitializedLatch = new CountDownLatch(1);

    private String mAGpsApn;
    private int mAGpsDataConnectionState;
@@ -437,21 +430,6 @@ public class GpsLocationProvider implements LocationProviderInterface {
        mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
        mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0);

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Intents.DATA_SMS_RECEIVED_ACTION);
        intentFilter.addDataScheme("sms");
        intentFilter.addDataAuthority("localhost","7275");
        context.registerReceiver(mBroadcastReciever, intentFilter);

        intentFilter = new IntentFilter();
        intentFilter.addAction(Intents.WAP_PUSH_RECEIVED_ACTION);
        try {
            intentFilter.addDataType("application/vnd.omaloc-supl-init");
        } catch (IntentFilter.MalformedMimeTypeException e) {
            Log.w(TAG, "Malformed SUPL init mime type");
        }
        context.registerReceiver(mBroadcastReciever, intentFilter);

        mConnMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);

        // Battery statistics service to be notified when GPS turns on or off
@@ -487,26 +465,43 @@ public class GpsLocationProvider implements LocationProviderInterface {
            Log.w(TAG, "Could not open GPS configuration file " + PROPERTIES_FILE);
        }

        // wait until we are fully initialized before returning
        mThread = new GpsLocationProviderThread();
        mThread.start();
        while (true) {
            try {
                mInitializedLatch.await();
                break;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        // construct handler, listen for events
        mHandler = new ProviderHandler();
        listenForBroadcasts();

        // also listen for PASSIVE_PROVIDER updates
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                LocationManager locManager =
                        (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
                locManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER,
                        0, 0, new NetworkLocationListener(), mHandler.getLooper());                
            }
        });
    }

    private void initialize() {
        // register our receiver on our thread rather than the main thread
    private void listenForBroadcasts() {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Intents.DATA_SMS_RECEIVED_ACTION);
        intentFilter.addDataScheme("sms");
        intentFilter.addDataAuthority("localhost","7275");
        mContext.registerReceiver(mBroadcastReciever, intentFilter, null, mHandler);

        intentFilter = new IntentFilter();
        intentFilter.addAction(Intents.WAP_PUSH_RECEIVED_ACTION);
        try {
            intentFilter.addDataType("application/vnd.omaloc-supl-init");
        } catch (IntentFilter.MalformedMimeTypeException e) {
            Log.w(TAG, "Malformed SUPL init mime type");
        }
        mContext.registerReceiver(mBroadcastReciever, intentFilter, null, mHandler);

        intentFilter = new IntentFilter();
        intentFilter.addAction(ALARM_WAKEUP);
        intentFilter.addAction(ALARM_TIMEOUT);
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        mContext.registerReceiver(mBroadcastReciever, intentFilter);
        mContext.registerReceiver(mBroadcastReciever, intentFilter, null, mHandler);
    }

    /**
@@ -1536,29 +1531,6 @@ public class GpsLocationProvider implements LocationProviderInterface {
        }
    };

    private final class GpsLocationProviderThread extends Thread {

        public GpsLocationProviderThread() {
            super("GpsLocationProvider");
        }

        @Override
        public void run() {
            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
            initialize();
            Looper.prepare();

            LocationManager locManager =
                    (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
            mHandler = new ProviderHandler();
            // signal when we are initialized and ready to go
            mInitializedLatch.countDown();
            locManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER,
                    0, 0, new NetworkLocationListener(), Looper.myLooper());
            Looper.loop();
        }
    }

    private final class NetworkLocationListener implements LocationListener {
        @Override
        public void onLocationChanged(Location location) {