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;