Remove races in Geocoder/LocationProvider Proxy

The proxy must ensure that enable/disable calls are not reordered when
proxied; this change adds synchronization to prevent such reordering
that could happen following an onServiceConnected() callback, and to
ensure cross-thread visibility of writes.

Also, when the package is updated, the old service instance must be
unbound and the new one bound.  This changes uses a separate
Connection object per service instance (package version) to avoid
confusing the binder objects.

Change-Id: I0907f7eed211b97ccfffa395754f1eb8ea8d8fec
This commit is contained in:
Mark Vandevoorde
2010-10-04 14:23:24 -07:00
parent b9a40068b5
commit 8863c43d9e
3 changed files with 252 additions and 200 deletions

View File

@@ -130,6 +130,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
// Handler messages
private static final int MESSAGE_LOCATION_CHANGED = 1;
private static final int MESSAGE_PACKAGE_UPDATED = 2;
// wakelock variables
private final static String WAKELOCK_KEY = "LocationManagerService";
@@ -1826,6 +1827,19 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
handleLocationChangedLocked(location, passive);
}
}
} else if (msg.what == MESSAGE_PACKAGE_UPDATED) {
String packageName = (String) msg.obj;
String packageDot = packageName + ".";
// reconnect to external providers after their packages have been updated
if (mNetworkLocationProvider != null &&
mNetworkLocationProviderPackageName.startsWith(packageDot)) {
mNetworkLocationProvider.reconnect();
}
if (mGeocodeProvider != null &&
mGeocodeProviderPackageName.startsWith(packageDot)) {
mGeocodeProvider.reconnect();
}
}
} catch (Exception e) {
// Log, don't crash!
@@ -1928,17 +1942,8 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
private final PackageMonitor mPackageMonitor = new PackageMonitor() {
@Override
public void onPackageUpdateFinished(String packageName, int uid) {
String packageDot = packageName + ".";
// reconnect to external providers after their packages have been updated
if (mNetworkLocationProvider != null &&
mNetworkLocationProviderPackageName.startsWith(packageDot)) {
mNetworkLocationProvider.reconnect();
}
if (mGeocodeProvider != null &&
mGeocodeProviderPackageName.startsWith(packageDot)) {
mGeocodeProvider.reconnect();
}
// Called by main thread; divert work to LocationWorker.
Message.obtain(mLocationHandler, MESSAGE_PACKAGE_UPDATED, packageName).sendToTarget();
}
};