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.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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user