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
This commit is contained in:
Svetoslav Ganov
2016-06-17 15:27:43 -07:00
parent 8e8fb7dda0
commit 8c35dcc7ae
2 changed files with 15 additions and 4 deletions

View File

@@ -1311,12 +1311,19 @@ public final class Settings {
/**
* @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
*/
@@ -1467,11 +1474,11 @@ public final class Settings {
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 @@ public final class Settings {
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 @@ public final class Settings {
+ userHandle + " with index:" + index);
}
mGenerationTracker = new GenerationTracker(array, index,
() -> {
generation, () -> {
synchronized (this) {
Log.e(TAG, "Error accessing generation"
+ " tracker - removing");

View File

@@ -76,6 +76,8 @@ final class GenerationRegistry {
bundle.putParcelable(Settings.CALL_METHOD_TRACK_GENERATION_KEY,
backingStore);
bundle.putInt(Settings.CALL_METHOD_GENERATION_INDEX_KEY, index);
bundle.putInt(Settings.CALL_METHOD_GENERATION_KEY,
backingStore.get(index));
if (DEBUG) {
Slog.i(LOG_TAG, "Exported index:" + index + " for key:"
+ SettingsProvider.keyToString(key));