Fix a race in local settings caches

We send a handle to the generation tracker along with the first accessed
setting but don't send the generation id of when the setting was
actually looked up. So by the time the client gets the setting with the
generation tracker from which to get and cache the last generation the
setting may have changed. We need to pass the generation id along with
the value and the generation tracker.

bug:29458487

Change-Id: I0ac4955ba5b10b547f8fe653a7c28e048a4691eb
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index ab2506e..293eb9b 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1311,13 +1311,20 @@
 
     /**
      * @hide Key with the location in the {@link android.util.MemoryIntArray} where
-     * to look up the generation id of the backing table.
+     * to look up the generation id of the backing table. The value is an integer.
      *
      * @see #CALL_METHOD_TRACK_GENERATION_KEY
      */
     public static final String CALL_METHOD_GENERATION_INDEX_KEY = "_generation_index";
 
     /**
+     * @hide Key with the settings table generation. The value is an integer.
+     *
+     * @see #CALL_METHOD_TRACK_GENERATION_KEY
+     */
+    public static final String CALL_METHOD_GENERATION_KEY = "_generation";
+
+    /**
      * @hide - User handle argument extra to the fast-path call()-based requests
      */
     public static final String CALL_METHOD_USER_KEY = "_user";
@@ -1467,11 +1474,11 @@
         private int mCurrentGeneration;
 
         public GenerationTracker(@NonNull MemoryIntArray array, int index,
-                Runnable errorHandler) {
+                int generation, Runnable errorHandler) {
             mArray = array;
             mIndex = index;
             mErrorHandler = errorHandler;
-            mCurrentGeneration = readCurrentGeneration();
+            mCurrentGeneration = generation;
         }
 
         public boolean isGenerationChanged() {
@@ -1627,6 +1634,8 @@
                                     final int index = b.getInt(
                                             CALL_METHOD_GENERATION_INDEX_KEY, -1);
                                     if (array != null && index >= 0) {
+                                        final int generation = b.getInt(
+                                                CALL_METHOD_GENERATION_KEY, 0);
                                         if (DEBUG) {
                                             Log.i(TAG, "Received generation tracker for type:"
                                                     + mUri.getPath() + " in package:"
@@ -1634,7 +1643,7 @@
                                                     + userHandle + " with index:" + index);
                                         }
                                         mGenerationTracker = new GenerationTracker(array, index,
-                                                () -> {
+                                                generation, () -> {
                                             synchronized (this) {
                                                 Log.e(TAG, "Error accessing generation"
                                                         + " tracker - removing");