LocationManager: Recover if process containing NetworkLocation provider crashes

Signed-off-by: Mike Lockwood <lockwood@android.com>
This commit is contained in:
Mike Lockwood
2009-05-12 10:52:03 -04:00
parent 2677d0da34
commit 3681f2614f
2 changed files with 33 additions and 3 deletions

View File

@@ -21,6 +21,7 @@ import android.location.ILocationProvider;
import android.location.Location; import android.location.Location;
import android.location.LocationManager; import android.location.LocationManager;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException; import android.os.RemoteException;
import android.util.Log; import android.util.Log;
@@ -31,7 +32,7 @@ import java.util.List;
* *
* {@hide} * {@hide}
*/ */
public class LocationProviderProxy { public class LocationProviderProxy implements IBinder.DeathRecipient {
private static final String TAG = "LocationProviderProxy"; private static final String TAG = "LocationProviderProxy";
@@ -39,16 +40,27 @@ public class LocationProviderProxy {
private final ILocationProvider mProvider; private final ILocationProvider mProvider;
private boolean mLocationTracking = false; private boolean mLocationTracking = false;
private long mMinTime = 0; private long mMinTime = 0;
private boolean mDead;
public LocationProviderProxy(String name, ILocationProvider provider) { public LocationProviderProxy(String name, ILocationProvider provider) {
mName = name; mName = name;
mProvider = provider; mProvider = provider;
try {
provider.asBinder().linkToDeath(this, 0);
} catch (RemoteException e) {
Log.e(TAG, "linkToDeath failed", e);
mDead = true;
}
} }
public String getName() { public String getName() {
return mName; return mName;
} }
public boolean isDead() {
return mDead;
}
public boolean requiresNetwork() { public boolean requiresNetwork() {
try { try {
return mProvider.requiresNetwork(); return mProvider.requiresNetwork();
@@ -231,4 +243,9 @@ public class LocationProviderProxy {
Log.e(TAG, "removeListener failed", e); Log.e(TAG, "removeListener failed", e);
} }
} }
public void binderDied() {
Log.w(TAG, "Location Provider " + mName + " died");
mDead = true;
}
} }

View File

@@ -216,7 +216,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
return mKey.hashCode(); return mKey.hashCode();
} }
@Override @Override
public String toString() { public String toString() {
if (mListener != null) { if (mListener != null) {
@@ -611,6 +610,17 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
} }
synchronized (mLock) { 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); LocationProviderProxy proxy = new LocationProviderProxy(name, provider);
addProvider(proxy); addProvider(proxy);
updateProvidersLocked(); updateProvidersLocked();
@@ -1616,6 +1626,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
mCollector.updateLocation(location); mCollector.updateLocation(location);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.w(TAG, "mCollector.updateLocation failed"); Log.w(TAG, "mCollector.updateLocation failed");
mCollector = null;
} }
} }
@@ -1750,6 +1761,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
variant, appName, addrs); variant, appName, addrs);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "getFromLocation failed", e); Log.e(TAG, "getFromLocation failed", e);
mGeocodeProvider = null;
} }
} }
return null; return null;
@@ -1768,6 +1780,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
maxResults, language, country, variant, appName, addrs); maxResults, language, country, variant, appName, addrs);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "getFromLocationName failed", e); Log.e(TAG, "getFromLocationName failed", e);
mGeocodeProvider = null;
} }
} }
return null; return null;