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:
@@ -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");
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user