Fix race condition generating READY and NOT_SUPPORTED statuses.
The race condition only affects when the client registers for several (all) location listeners.
And the side efects are benign: only the measurement and navigation message status are incurrectly
being sent to the application, but there are no crashes or any real data from GPS being
misscommunicated.
Also:
- cache the last reported status to filter sending notifications when no changes have occurred
- do some cleanup and refactoring in the code changed
Change-Id: I0692e6b70847dc1ee092d7a05a2c6ba3cd9fa147
diff --git a/services/core/java/com/android/server/location/GpsNavigationMessageProvider.java b/services/core/java/com/android/server/location/GpsNavigationMessageProvider.java
index 13d22fc..e6bbe56 100644
--- a/services/core/java/com/android/server/location/GpsNavigationMessageProvider.java
+++ b/services/core/java/com/android/server/location/GpsNavigationMessageProvider.java
@@ -33,7 +33,7 @@
extends RemoteListenerHelper<IGpsNavigationMessageListener> {
private static final String TAG = "GpsNavigationMessageProvider";
- public GpsNavigationMessageProvider(Handler handler) {
+ protected GpsNavigationMessageProvider(Handler handler) {
super(handler, TAG);
}
@@ -50,15 +50,19 @@
}
public void onCapabilitiesUpdated(boolean isGpsNavigationMessageSupported) {
- int status = isGpsNavigationMessageSupported ?
- GpsNavigationMessageEvent.STATUS_READY :
- GpsNavigationMessageEvent.STATUS_NOT_SUPPORTED;
- setSupported(isGpsNavigationMessageSupported, new StatusChangedOperation(status));
+ setSupported(isGpsNavigationMessageSupported);
+ updateResult();
+ }
+
+ public void onGpsEnabledChanged() {
+ if (tryUpdateRegistrationWithService()) {
+ updateResult();
+ }
}
@Override
protected ListenerOperation<IGpsNavigationMessageListener> getHandlerOperation(int result) {
- final int status;
+ int status;
switch (result) {
case RESULT_SUCCESS:
status = GpsNavigationMessageEvent.STATUS_READY;
@@ -71,6 +75,8 @@
case RESULT_GPS_LOCATION_DISABLED:
status = GpsNavigationMessageEvent.STATUS_GPS_LOCATION_DISABLED;
break;
+ case RESULT_UNKNOWN:
+ return null;
default:
Log.v(TAG, "Unhandled addListener result: " + result);
return null;
@@ -78,15 +84,7 @@
return new StatusChangedOperation(status);
}
- @Override
- protected void handleGpsEnabledChanged(boolean enabled) {
- int status = enabled ?
- GpsNavigationMessageEvent.STATUS_READY :
- GpsNavigationMessageEvent.STATUS_GPS_LOCATION_DISABLED;
- foreach(new StatusChangedOperation(status));
- }
-
- private class StatusChangedOperation
+ private static class StatusChangedOperation
implements ListenerOperation<IGpsNavigationMessageListener> {
private final int mStatus;