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
This commit is contained in:
Victoria Lease
2012-10-01 11:00:50 -07:00
parent ce803d8ed8
commit 5c24fd0342
2 changed files with 37 additions and 65 deletions

View File

@@ -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:

View File

@@ -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) {