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

Commit eac47e02 authored by Viktor Tabunshchik's avatar Viktor Tabunshchik Committed by Automerger Merge Worker
Browse files

Merge "Revert "SettingsProvider enhanced cache"" into udc-dev am: 629235fc am: 82a373df

parents 6f6a5e30 82a373df
Loading
Loading
Loading
Loading
+121 −129
Original line number Diff line number Diff line
@@ -115,7 +115,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.
@@ -2978,22 +2977,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) {
@@ -3014,7 +3010,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;
        }
@@ -3024,6 +3022,9 @@ public final class Settings {
                mArray.close();
            } catch (IOException e) {
                Log.e(TAG, "Error closing backing array", e);
                if (mErrorHandler != null) {
                    mErrorHandler.run();
                }
            }
        }
    }
@@ -3086,21 +3087,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,
@@ -3189,43 +3177,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.
@@ -3259,6 +3210,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
@@ -3267,17 +3243,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;
@@ -3314,24 +3297,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);
                                }
                            }
@@ -3374,14 +3366,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);
@@ -3415,29 +3408,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)) {
@@ -3457,9 +3439,9 @@ public final class Settings {
                            return keyValues;
                        }
                    }
                    currentGeneration = generationTracker.getCurrentGeneration();
                } else {
                    needsGenerationTracker = true;
                    if (mGenerationTracker != null) {
                        currentGeneration = mGenerationTracker.getCurrentGeneration();
                    }
                }
            }
@@ -3467,20 +3449,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());
                        }
                    }
                }
@@ -3533,22 +3515,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.
@@ -3564,11 +3556,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