LocationManager: Recover if process containing NetworkLocation provider crashes
Signed-off-by: Mike Lockwood <lockwood@android.com>
This commit is contained in:
@@ -21,6 +21,7 @@ import android.location.ILocationProvider;
|
||||
import android.location.Location;
|
||||
import android.location.LocationManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -31,7 +32,7 @@ import java.util.List;
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public class LocationProviderProxy {
|
||||
public class LocationProviderProxy implements IBinder.DeathRecipient {
|
||||
|
||||
private static final String TAG = "LocationProviderProxy";
|
||||
|
||||
@@ -39,16 +40,27 @@ public class LocationProviderProxy {
|
||||
private final ILocationProvider mProvider;
|
||||
private boolean mLocationTracking = false;
|
||||
private long mMinTime = 0;
|
||||
private boolean mDead;
|
||||
|
||||
public LocationProviderProxy(String name, ILocationProvider provider) {
|
||||
mName = name;
|
||||
mProvider = provider;
|
||||
try {
|
||||
provider.asBinder().linkToDeath(this, 0);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "linkToDeath failed", e);
|
||||
mDead = true;
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
public boolean isDead() {
|
||||
return mDead;
|
||||
}
|
||||
|
||||
public boolean requiresNetwork() {
|
||||
try {
|
||||
return mProvider.requiresNetwork();
|
||||
@@ -231,4 +243,9 @@ public class LocationProviderProxy {
|
||||
Log.e(TAG, "removeListener failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void binderDied() {
|
||||
Log.w(TAG, "Location Provider " + mName + " died");
|
||||
mDead = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,8 +215,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
||||
public int hashCode() {
|
||||
return mKey.hashCode();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (mListener != null) {
|
||||
@@ -611,6 +610,17 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
// check to see if we are reinstalling a dead provider
|
||||
LocationProviderProxy oldProvider = mProvidersByName.get(name);
|
||||
if (oldProvider != null) {
|
||||
if (oldProvider.isDead()) {
|
||||
Log.d(TAG, "replacing dead provider");
|
||||
removeProvider(oldProvider);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Provider \"" + name + "\" already exists");
|
||||
}
|
||||
}
|
||||
|
||||
LocationProviderProxy proxy = new LocationProviderProxy(name, provider);
|
||||
addProvider(proxy);
|
||||
updateProvidersLocked();
|
||||
@@ -1616,6 +1626,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
||||
mCollector.updateLocation(location);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "mCollector.updateLocation failed");
|
||||
mCollector = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1750,6 +1761,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
||||
variant, appName, addrs);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "getFromLocation failed", e);
|
||||
mGeocodeProvider = null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -1768,6 +1780,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
||||
maxResults, language, country, variant, appName, addrs);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "getFromLocationName failed", e);
|
||||
mGeocodeProvider = null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user