Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b8d8b933 authored by Sam Dubey's avatar Sam Dubey Committed by Android (Google) Code Review
Browse files

Revert "SettingsProvider enhanced cache"

This reverts commit 6c5d9a1a.

Reason for revert: testing for b/270623927

Change-Id: I625ff474ca1923ba09a20ceb7669f8e371c22026
parent 6c5d9a1a
Loading
Loading
Loading
Loading
+121 −129
Original line number Diff line number Diff line
@@ -116,7 +116,6 @@ import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
/**
 * The Settings provider contains global system-level device preferences.
@@ -2979,22 +2978,19 @@ public final class Settings {
    }
    private static final class GenerationTracker {
        @NonNull private final String mName;
        @NonNull private final MemoryIntArray mArray;
        @NonNull private final Consumer<String> mErrorHandler;
        private final MemoryIntArray mArray;
        private final Runnable mErrorHandler;
        private final int mIndex;
        private int mCurrentGeneration;
        GenerationTracker(@NonNull String name, @NonNull MemoryIntArray array, int index,
                int generation, Consumer<String> errorHandler) {
            mName = name;
        public GenerationTracker(@NonNull MemoryIntArray array, int index,
                int generation, Runnable errorHandler) {
            mArray = array;
            mIndex = index;
            mErrorHandler = errorHandler;
            mCurrentGeneration = generation;
        }
        // This method also updates the obsolete generation code stored locally
        public boolean isGenerationChanged() {
            final int currentGeneration = readCurrentGeneration();
            if (currentGeneration >= 0) {
@@ -3015,7 +3011,9 @@ public final class Settings {
                return mArray.get(mIndex);
            } catch (IOException e) {
                Log.e(TAG, "Error getting current generation", e);
                mErrorHandler.accept(mName);
                if (mErrorHandler != null) {
                    mErrorHandler.run();
                }
            }
            return -1;
        }
@@ -3025,6 +3023,9 @@ public final class Settings {
                mArray.close();
            } catch (IOException e) {
                Log.e(TAG, "Error closing backing array", e);
                if (mErrorHandler != null) {
                    mErrorHandler.run();
                }
            }
        }
    }
@@ -3087,21 +3088,8 @@ public final class Settings {
        private final ArraySet<String> mAllFields;
        private final ArrayMap<String, Integer> mReadableFieldsWithMaxTargetSdk;
        // Mapping from the name of a setting (or the prefix of a namespace) to a generation tracker
        @GuardedBy("this")
        private ArrayMap<String, GenerationTracker> mGenerationTrackers = new ArrayMap<>();
        private Consumer<String> mGenerationTrackerErrorHandler = (String name) -> {
            synchronized (NameValueCache.this) {
                Log.e(TAG, "Error accessing generation tracker - removing");
                final GenerationTracker tracker = mGenerationTrackers.get(name);
                if (tracker != null) {
                    tracker.destroy();
                    mGenerationTrackers.remove(name);
                }
                mValues.remove(name);
            }
        };
        private GenerationTracker mGenerationTracker;
        <T extends NameValueTable> NameValueCache(Uri uri, String getCommand,
                String setCommand, String deleteCommand, ContentProviderHolder providerHolder,
@@ -3190,43 +3178,6 @@ public final class Settings {
        @UnsupportedAppUsage
        public String getStringForUser(ContentResolver cr, String name, final int userHandle) {
            final boolean isSelf = (userHandle == UserHandle.myUserId());
            int currentGeneration = -1;
            boolean needsGenerationTracker = false;
            if (isSelf) {
                synchronized (NameValueCache.this) {
                    final GenerationTracker generationTracker = mGenerationTrackers.get(name);
                    if (generationTracker != null) {
                        if (generationTracker.isGenerationChanged()) {
                            if (DEBUG) {
                                Log.i(TAG, "Generation changed for setting:" + name
                                        + " type:" + mUri.getPath()
                                        + " in package:" + cr.getPackageName()
                                        + " and user:" + userHandle);
                            }
                            mValues.remove(name);
                        } else if (mValues.containsKey(name)) {
                            if (DEBUG) {
                                Log.i(TAG, "Cache hit for setting:" + name);
                            }
                            return mValues.get(name);
                        }
                        currentGeneration = generationTracker.getCurrentGeneration();
                    } else {
                        needsGenerationTracker = true;
                    }
                }
            } else {
                if (LOCAL_LOGV) {
                    Log.v(TAG, "get setting for user " + userHandle
                            + " by user " + UserHandle.myUserId() + " so skipping cache");
                }
            }
            if (DEBUG) {
                Log.i(TAG, "Cache miss for setting:" + name);
            }
            // Check if the target settings key is readable. Reject if the caller is not system and
            // is trying to access a settings key defined in the Settings.Secure, Settings.System or
            // Settings.Global and is not annotated as @Readable.
@@ -3260,6 +3211,31 @@ public final class Settings {
                }
            }
            final boolean isSelf = (userHandle == UserHandle.myUserId());
            int currentGeneration = -1;
            if (isSelf) {
                synchronized (NameValueCache.this) {
                    if (mGenerationTracker != null) {
                        if (mGenerationTracker.isGenerationChanged()) {
                            if (DEBUG) {
                                Log.i(TAG, "Generation changed for type:"
                                        + mUri.getPath() + " in package:"
                                        + cr.getPackageName() +" and user:" + userHandle);
                            }
                            mValues.clear();
                        } else if (mValues.containsKey(name)) {
                            return mValues.get(name);
                        }
                        if (mGenerationTracker != null) {
                            currentGeneration = mGenerationTracker.getCurrentGeneration();
                        }
                    }
                }
            } else {
                if (LOCAL_LOGV) Log.v(TAG, "get setting for user " + userHandle
                        + " by user " + UserHandle.myUserId() + " so skipping cache");
            }
            IContentProvider cp = mProviderHolder.getProvider(cr);
            // Try the fast path first, not using query().  If this
@@ -3268,17 +3244,24 @@ public final class Settings {
            // interface.
            if (mCallGetCommand != null) {
                try {
                    Bundle args = new Bundle();
                    Bundle args = null;
                    if (!isSelf) {
                        args = new Bundle();
                        args.putInt(CALL_METHOD_USER_KEY, userHandle);
                    }
                    if (needsGenerationTracker) {
                    boolean needsGenerationTracker = false;
                    synchronized (NameValueCache.this) {
                        if (isSelf && mGenerationTracker == null) {
                            needsGenerationTracker = true;
                            if (args == null) {
                                args = new Bundle();
                            }
                            args.putString(CALL_METHOD_TRACK_GENERATION_KEY, null);
                            if (DEBUG) {
                            Log.i(TAG, "Requested generation tracker for setting:" + name
                                    + " type:" + mUri.getPath()
                                    + " in package:" + cr.getPackageName()
                                    + " and user:" + userHandle);
                                Log.i(TAG, "Requested generation tracker for type: "+ mUri.getPath()
                                        + " in package:" + cr.getPackageName() +" and user:"
                                        + userHandle);
                            }
                        }
                    }
                    Bundle b;
@@ -3315,24 +3298,33 @@ public final class Settings {
                                        final int generation = b.getInt(
                                                CALL_METHOD_GENERATION_KEY, 0);
                                        if (DEBUG) {
                                            Log.i(TAG, "Received generation tracker for setting:"
                                                    + name
                                                    + " type:" + mUri.getPath()
                                                    + " in package:" + cr.getPackageName()
                                                    + " and user:" + userHandle
                                                    + " with index:" + index);
                                        }
                                        mGenerationTrackers.put(name, new GenerationTracker(name,
                                                array, index, generation,
                                                mGenerationTrackerErrorHandler));
                                        currentGeneration = generation;
                                            Log.i(TAG, "Received generation tracker for type:"
                                                    + mUri.getPath() + " in package:"
                                                    + cr.getPackageName() + " and user:"
                                                    + userHandle + " with index:" + index);
                                        }
                                        if (mGenerationTracker != null) {
                                            mGenerationTracker.destroy();
                                        }
                                        mGenerationTracker = new GenerationTracker(array, index,
                                                generation, () -> {
                                            synchronized (NameValueCache.this) {
                                                Log.e(TAG, "Error accessing generation"
                                                        + " tracker - removing");
                                                if (mGenerationTracker != null) {
                                                    GenerationTracker generationTracker =
                                                            mGenerationTracker;
                                                    mGenerationTracker = null;
                                                    generationTracker.destroy();
                                                    mValues.clear();
                                                }
                                            }
                                        });
                                        currentGeneration = generation;
                                    }
                                if (mGenerationTrackers.get(name) != null && currentGeneration
                                        == mGenerationTrackers.get(name).getCurrentGeneration()) {
                                    if (DEBUG) {
                                        Log.i(TAG, "Updating cache for setting:" + name);
                                }
                                if (mGenerationTracker != null && currentGeneration ==
                                        mGenerationTracker.getCurrentGeneration()) {
                                    mValues.put(name, value);
                                }
                            }
@@ -3375,14 +3367,15 @@ public final class Settings {
                String value = c.moveToNext() ? c.getString(0) : null;
                synchronized (NameValueCache.this) {
                    if (mGenerationTrackers.get(name) != null && currentGeneration
                            == mGenerationTrackers.get(name).getCurrentGeneration()) {
                        if (DEBUG) {
                            Log.i(TAG, "Updating cache for setting:" + name + " using query");
                        }
                    if (mGenerationTracker != null
                            && currentGeneration == mGenerationTracker.getCurrentGeneration()) {
                        mValues.put(name, value);
                    }
                }
                if (LOCAL_LOGV) {
                    Log.v(TAG, "cache miss [" + mUri.getLastPathSegment() + "]: " +
                            name + " = " + (value == null ? "(null)" : value));
                }
                return value;
            } catch (RemoteException e) {
                Log.w(TAG, "Can't get key " + name + " from " + mUri, e);
@@ -3416,29 +3409,18 @@ public final class Settings {
            Config.enforceReadPermission(namespace);
            ArrayMap<String, String> keyValues = new ArrayMap<>();
            int currentGeneration = -1;
            boolean needsGenerationTracker = false;
            synchronized (NameValueCache.this) {
                final GenerationTracker generationTracker = mGenerationTrackers.get(prefix);
                if (generationTracker != null) {
                    if (generationTracker.isGenerationChanged()) {
                if (mGenerationTracker != null) {
                    if (mGenerationTracker.isGenerationChanged()) {
                        if (DEBUG) {
                            Log.i(TAG, "Generation changed for prefix:" + prefix
                                    + " type:" + mUri.getPath()
                            Log.i(TAG, "Generation changed for type:" + mUri.getPath()
                                    + " in package:" + cr.getPackageName());
                        }
                        for (int i = 0; i < mValues.size(); ++i) {
                            String key = mValues.keyAt(i);
                            if (key.startsWith(prefix)) {
                                mValues.remove(key);
                            }
                        }
                        mValues.clear();
                    } else {
                        boolean prefixCached = mValues.containsKey(prefix);
                        if (prefixCached) {
                            if (DEBUG) {
                                Log.i(TAG, "Cache hit for prefix:" + prefix);
                            }
                            if (!names.isEmpty()) {
                                for (String name : names) {
                                    if (mValues.containsKey(name)) {
@@ -3458,9 +3440,9 @@ public final class Settings {
                            return keyValues;
                        }
                    }
                    currentGeneration = generationTracker.getCurrentGeneration();
                } else {
                    needsGenerationTracker = true;
                    if (mGenerationTracker != null) {
                        currentGeneration = mGenerationTracker.getCurrentGeneration();
                    }
                }
            }
@@ -3468,20 +3450,20 @@ public final class Settings {
                // No list command specified, return empty map
                return keyValues;
            }
            if (DEBUG) {
                Log.i(TAG, "Cache miss for prefix:" + prefix);
            }
            IContentProvider cp = mProviderHolder.getProvider(cr);
            try {
                Bundle args = new Bundle();
                args.putString(Settings.CALL_METHOD_PREFIX_KEY, prefix);
                if (needsGenerationTracker) {
                boolean needsGenerationTracker = false;
                synchronized (NameValueCache.this) {
                    if (mGenerationTracker == null) {
                        needsGenerationTracker = true;
                        args.putString(CALL_METHOD_TRACK_GENERATION_KEY, null);
                        if (DEBUG) {
                        Log.i(TAG, "Requested generation tracker for prefix:" + prefix
                                + " type: " + mUri.getPath()
                                + " in package:" + cr.getPackageName());
                            Log.i(TAG, "Requested generation tracker for type: "
                                    + mUri.getPath() + " in package:" + cr.getPackageName());
                        }
                    }
                }
@@ -3534,22 +3516,32 @@ public final class Settings {
                            final int generation = b.getInt(
                                    CALL_METHOD_GENERATION_KEY, 0);
                            if (DEBUG) {
                                Log.i(TAG, "Received generation tracker for prefix:" + prefix
                                        + " type:" + mUri.getPath()
                                        + " in package:" + cr.getPackageName()
                                        + " with index:" + index);
                            }
                            mGenerationTrackers.put(prefix,
                                    new GenerationTracker(prefix, array, index, generation,
                                            mGenerationTrackerErrorHandler));
                            currentGeneration = generation;
                                Log.i(TAG, "Received generation tracker for type:"
                                        + mUri.getPath() + " in package:"
                                        + cr.getPackageName() + " with index:" + index);
                            }
                            if (mGenerationTracker != null) {
                                mGenerationTracker.destroy();
                            }
                            mGenerationTracker = new GenerationTracker(array, index,
                                    generation, () -> {
                                synchronized (NameValueCache.this) {
                                    Log.e(TAG, "Error accessing generation tracker"
                                            + " - removing");
                                    if (mGenerationTracker != null) {
                                        GenerationTracker generationTracker =
                                                mGenerationTracker;
                                        mGenerationTracker = null;
                                        generationTracker.destroy();
                                        mValues.clear();
                                    }
                                }
                            });
                            currentGeneration = generation;
                        }
                    if (mGenerationTrackers.get(prefix) != null && currentGeneration
                            == mGenerationTrackers.get(prefix).getCurrentGeneration()) {
                        if (DEBUG) {
                            Log.i(TAG, "Updating cache for prefix:" + prefix);
                    }
                    if (mGenerationTracker != null && currentGeneration
                            == mGenerationTracker.getCurrentGeneration()) {
                        // cache the complete list of flags for the namespace
                        mValues.putAll(flagsToValues);
                        // Adding the prefix as a signal that the prefix is cached.
@@ -3565,11 +3557,11 @@ public final class Settings {
        public void clearGenerationTrackerForTest() {
            synchronized (NameValueCache.this) {
                for (int i = 0; i < mGenerationTrackers.size(); i++) {
                    mGenerationTrackers.valueAt(i).destroy();
                if (mGenerationTracker != null) {
                    mGenerationTracker.destroy();
                }
                mGenerationTrackers.clear();
                mValues.clear();
                mGenerationTracker = null;
            }
        }
    }
+59 −200

File changed.

Preview size limit exceeded, changes collapsed.

+0 −1
Original line number Diff line number Diff line
@@ -48,7 +48,6 @@ android_test {
        "test/**/*.java",
        "src/android/provider/settings/backup/*",
        "src/android/provider/settings/validators/*",
        "src/com/android/providers/settings/GenerationRegistry.java",
        "src/com/android/providers/settings/SettingsBackupAgent.java",
        "src/com/android/providers/settings/SettingsState.java",
        "src/com/android/providers/settings/SettingsHelper.java",
+80 −129

File changed.

Preview size limit exceeded, changes collapsed.

+18 −21
Original line number Diff line number Diff line
@@ -35,7 +35,6 @@ import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OV
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
import static com.android.internal.accessibility.util.AccessibilityUtils.ACCESSIBILITY_MENU_IN_SYSTEM;
import static com.android.providers.settings.SettingsState.FALLBACK_FILE_SUFFIX;
import static com.android.providers.settings.SettingsState.makeKey;

import android.Manifest;
import android.annotation.NonNull;
@@ -376,6 +375,10 @@ public class SettingsProvider extends ContentProvider {
    @GuardedBy("mLock")
    private boolean mSyncConfigDisabledUntilReboot;

    public static int makeKey(int type, int userId) {
        return SettingsState.makeKey(type, userId);
    }

    public static int getTypeFromKey(int key) {
        return SettingsState.getTypeFromKey(key);
    }
@@ -384,6 +387,9 @@ public class SettingsProvider extends ContentProvider {
        return SettingsState.getUserIdFromKey(key);
    }

    public static String keyToString(int key) {
        return SettingsState.keyToString(key);
    }
    @ChangeId
    @EnabledSince(targetSdkVersion=android.os.Build.VERSION_CODES.S)
    private static final long ENFORCE_READ_PERMISSION_FOR_MULTI_SIM_DATA_CALL = 172670679L;
@@ -547,7 +553,7 @@ public class SettingsProvider extends ContentProvider {

            case Settings.CALL_METHOD_LIST_CONFIG: {
                String prefix = getSettingPrefix(args);
                Bundle result = packageValuesForCallResult(prefix, getAllConfigFlags(prefix),
                Bundle result = packageValuesForCallResult(getAllConfigFlags(prefix),
                        isTrackingGeneration(args));
                reportDeviceConfigAccess(prefix);
                return result;
@@ -1313,7 +1319,6 @@ public class SettingsProvider extends ContentProvider {
        return false;
    }

    @NonNull
    private HashMap<String, String> getAllConfigFlags(@Nullable String prefix) {
        if (DEBUG) {
            Slog.v(LOG_TAG, "getAllConfigFlags() for " + prefix);
@@ -2311,8 +2316,7 @@ public class SettingsProvider extends ContentProvider {
                "get/set setting for user", null);
    }

    private Bundle packageValueForCallResult(@Nullable Setting setting,
            boolean trackingGeneration) {
    private Bundle packageValueForCallResult(Setting setting, boolean trackingGeneration) {
        if (!trackingGeneration) {
            if (setting == null || setting.isNull()) {
                return NULL_SETTING_BUNDLE;
@@ -2323,26 +2327,19 @@ public class SettingsProvider extends ContentProvider {
        result.putString(Settings.NameValueTable.VALUE,
                !setting.isNull() ? setting.getValue() : null);

        if (setting != null && !setting.isNull()) {
            // No need to track generation if the setting doesn't exist
            synchronized (mLock) {
                mSettingsRegistry.mGenerationRegistry.addGenerationData(result, setting.getKey(),
                        setting.getName());
            }
        }
        mSettingsRegistry.mGenerationRegistry.addGenerationData(result, setting.getKey());
        return result;
    }

    private Bundle packageValuesForCallResult(String prefix,
            @NonNull HashMap<String, String> keyValues, boolean trackingGeneration) {
    private Bundle packageValuesForCallResult(HashMap<String, String> keyValues,
            boolean trackingGeneration) {
        Bundle result = new Bundle();
        result.putSerializable(Settings.NameValueTable.VALUE, keyValues);
        if (trackingGeneration && !keyValues.isEmpty()) {
            // No need to track generation if the namespace is empty
        if (trackingGeneration) {
            synchronized (mLock) {
                mSettingsRegistry.mGenerationRegistry.addGenerationData(result,
                        mSettingsRegistry.getSettingsLocked(SETTINGS_TYPE_CONFIG,
                                UserHandle.USER_SYSTEM).mKey, prefix);
                        mSettingsRegistry.getSettingsLocked(
                                SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM).mKey);
            }
        }

@@ -3452,7 +3449,7 @@ public class SettingsProvider extends ContentProvider {

        private void notifyForSettingsChange(int key, String name) {
            // Increment the generation first, so observers always see the new value
            mGenerationRegistry.incrementGeneration(key, name);
            mGenerationRegistry.incrementGeneration(key);

            if (isGlobalSettingsKey(key) || isConfigSettingsKey(key)) {
                final long token = Binder.clearCallingIdentity();
@@ -3490,7 +3487,7 @@ public class SettingsProvider extends ContentProvider {
                List<String> changedSettings) {

            // Increment the generation first, so observers always see the new value
            mGenerationRegistry.incrementGeneration(key, prefix);
            mGenerationRegistry.incrementGeneration(key);

            StringBuilder stringBuilder = new StringBuilder(prefix);
            for (int i = 0; i < changedSettings.size(); ++i) {
@@ -3516,7 +3513,7 @@ public class SettingsProvider extends ContentProvider {
                    if (profileId != userId) {
                        final int key = makeKey(type, profileId);
                        // Increment the generation first, so observers always see the new value
                        mGenerationRegistry.incrementGeneration(key, name);
                        mGenerationRegistry.incrementGeneration(key);
                        mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED,
                                profileId, 0, uri).sendToTarget();
                    }
Loading