Loading core/java/android/provider/Settings.java +42 −51 Original line number Diff line number Diff line Loading @@ -3236,9 +3236,17 @@ public final class Settings { private static final String NAME_EQ_PLACEHOLDER = "name=?"; // Cached values of queried settings. // Key is the setting's name, value is the setting's value. // Must synchronize on 'this' to access mValues and mValuesVersion. private final ArrayMap<String, String> mValues = new ArrayMap<>(); // Cached values for queried prefixes. // Key is the prefix, value is all of the settings under the prefix, mapped from a setting's // name to a setting's value. The name string doesn't include the prefix. // Must synchronize on 'this' to access. private final ArrayMap<String, ArrayMap<String, String>> mPrefixToValues = new ArrayMap<>(); private final Uri mUri; @UnsupportedAppUsage private final ContentProviderHolder mProviderHolder; Loading Loading @@ -3583,15 +3591,13 @@ public final class Settings { || applicationInfo.isSignedWithPlatformKey(); } private ArrayMap<String, String> getStringsForPrefixStripPrefix( ContentResolver cr, String prefix, String[] names) { private Map<String, String> getStringsForPrefixStripPrefix( ContentResolver cr, String prefix, List<String> names) { String namespace = prefix.substring(0, prefix.length() - 1); ArrayMap<String, String> keyValues = new ArrayMap<>(); int substringLength = prefix.length(); int currentGeneration = -1; boolean needsGenerationTracker = false; synchronized (NameValueCache.this) { final GenerationTracker generationTracker = mGenerationTrackers.get(prefix); if (generationTracker != null) { Loading @@ -3605,40 +3611,22 @@ public final class Settings { // generation tracker and request a new one generationTracker.destroy(); mGenerationTrackers.remove(prefix); for (int i = mValues.size() - 1; i >= 0; i--) { String key = mValues.keyAt(i); if (key.startsWith(prefix)) { mValues.remove(key); } } mPrefixToValues.remove(prefix); needsGenerationTracker = true; } else { boolean prefixCached = mValues.containsKey(prefix); if (prefixCached) { if (DEBUG) { Log.i(TAG, "Cache hit for prefix:" + prefix); } if (names.length > 0) { final ArrayMap<String, String> cachedSettings = mPrefixToValues.get(prefix); if (cachedSettings != null) { if (!names.isEmpty()) { for (String name : names) { // mValues can contain "null" values, need to use containsKey. if (mValues.containsKey(name)) { // The cache can contain "null" values, need to use containsKey. if (cachedSettings.containsKey(name)) { keyValues.put( name.substring(substringLength), mValues.get(name)); name, cachedSettings.get(name)); } } } else { for (int i = 0; i < mValues.size(); ++i) { String key = mValues.keyAt(i); // Explicitly exclude the prefix as it is only there to // signal that the prefix has been cached. if (key.startsWith(prefix) && !key.equals(prefix)) { String value = mValues.valueAt(i); keyValues.put( key.substring(substringLength), value); } } keyValues.putAll(cachedSettings); } return keyValues; } Loading @@ -3648,7 +3636,6 @@ public final class Settings { needsGenerationTracker = true; } } if (mCallListCommand == null) { // No list command specified, return empty map return keyValues; Loading Loading @@ -3693,20 +3680,23 @@ public final class Settings { } // All flags for the namespace Map<String, String> flagsToValues = HashMap<String, String> flagsToValues = (HashMap) b.getSerializable(Settings.NameValueTable.VALUE, java.util.HashMap.class); if (flagsToValues == null) { return keyValues; } // Only the flags requested by the caller if (names.length > 0) { if (!names.isEmpty()) { for (String name : names) { // flagsToValues can contain "null" values, need to use containsKey. if (flagsToValues.containsKey(name)) { final String key = Config.createCompositeName(namespace, name); if (flagsToValues.containsKey(key)) { keyValues.put( name.substring(substringLength), flagsToValues.get(name)); name, flagsToValues.get(key)); } } } else { keyValues.ensureCapacity(keyValues.size() + flagsToValues.size()); for (Map.Entry<String, String> flag : flagsToValues.entrySet()) { keyValues.put( flag.getKey().substring(substringLength), Loading Loading @@ -3740,10 +3730,18 @@ public final class Settings { if (DEBUG) { Log.i(TAG, "Updating cache for prefix:" + prefix); } // cache the complete list of flags for the namespace mValues.putAll(flagsToValues); // Adding the prefix as a signal that the prefix is cached. mValues.put(prefix, null); // Cache the complete list of flags for the namespace for bulk queries. // In this cached list, the setting's name doesn't include the prefix. ArrayMap<String, String> namesToValues = new ArrayMap<>(flagsToValues.size() + 1); for (Map.Entry<String, String> flag : flagsToValues.entrySet()) { namesToValues.put( flag.getKey().substring(substringLength), flag.getValue()); } // Legacy behavior, we return <"", null> when queried with name = "" namesToValues.put("", null); mPrefixToValues.put(prefix, namesToValues); } } return keyValues; Loading Loading @@ -19907,16 +19905,9 @@ public final class Settings { @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) public static Map<String, String> getStrings(@NonNull ContentResolver resolver, @NonNull String namespace, @NonNull List<String> names) { String[] compositeNames = new String[names.size()]; for (int i = 0, size = names.size(); i < size; ++i) { compositeNames[i] = createCompositeName(namespace, names.get(i)); } String prefix = createPrefix(namespace); ArrayMap<String, String> keyValues = sNameValueCache.getStringsForPrefixStripPrefix( resolver, prefix, compositeNames); return keyValues; return sNameValueCache.getStringsForPrefixStripPrefix(resolver, prefix, names); } /** Loading Loading @@ -20238,7 +20229,7 @@ public final class Settings { } } private static String createCompositeName(@NonNull String namespace, @NonNull String name) { static String createCompositeName(@NonNull String namespace, @NonNull String name) { Preconditions.checkNotNull(namespace); Preconditions.checkNotNull(name); var sb = new StringBuilder(namespace.length() + 1 + name.length()); Loading
core/java/android/provider/Settings.java +42 −51 Original line number Diff line number Diff line Loading @@ -3236,9 +3236,17 @@ public final class Settings { private static final String NAME_EQ_PLACEHOLDER = "name=?"; // Cached values of queried settings. // Key is the setting's name, value is the setting's value. // Must synchronize on 'this' to access mValues and mValuesVersion. private final ArrayMap<String, String> mValues = new ArrayMap<>(); // Cached values for queried prefixes. // Key is the prefix, value is all of the settings under the prefix, mapped from a setting's // name to a setting's value. The name string doesn't include the prefix. // Must synchronize on 'this' to access. private final ArrayMap<String, ArrayMap<String, String>> mPrefixToValues = new ArrayMap<>(); private final Uri mUri; @UnsupportedAppUsage private final ContentProviderHolder mProviderHolder; Loading Loading @@ -3583,15 +3591,13 @@ public final class Settings { || applicationInfo.isSignedWithPlatformKey(); } private ArrayMap<String, String> getStringsForPrefixStripPrefix( ContentResolver cr, String prefix, String[] names) { private Map<String, String> getStringsForPrefixStripPrefix( ContentResolver cr, String prefix, List<String> names) { String namespace = prefix.substring(0, prefix.length() - 1); ArrayMap<String, String> keyValues = new ArrayMap<>(); int substringLength = prefix.length(); int currentGeneration = -1; boolean needsGenerationTracker = false; synchronized (NameValueCache.this) { final GenerationTracker generationTracker = mGenerationTrackers.get(prefix); if (generationTracker != null) { Loading @@ -3605,40 +3611,22 @@ public final class Settings { // generation tracker and request a new one generationTracker.destroy(); mGenerationTrackers.remove(prefix); for (int i = mValues.size() - 1; i >= 0; i--) { String key = mValues.keyAt(i); if (key.startsWith(prefix)) { mValues.remove(key); } } mPrefixToValues.remove(prefix); needsGenerationTracker = true; } else { boolean prefixCached = mValues.containsKey(prefix); if (prefixCached) { if (DEBUG) { Log.i(TAG, "Cache hit for prefix:" + prefix); } if (names.length > 0) { final ArrayMap<String, String> cachedSettings = mPrefixToValues.get(prefix); if (cachedSettings != null) { if (!names.isEmpty()) { for (String name : names) { // mValues can contain "null" values, need to use containsKey. if (mValues.containsKey(name)) { // The cache can contain "null" values, need to use containsKey. if (cachedSettings.containsKey(name)) { keyValues.put( name.substring(substringLength), mValues.get(name)); name, cachedSettings.get(name)); } } } else { for (int i = 0; i < mValues.size(); ++i) { String key = mValues.keyAt(i); // Explicitly exclude the prefix as it is only there to // signal that the prefix has been cached. if (key.startsWith(prefix) && !key.equals(prefix)) { String value = mValues.valueAt(i); keyValues.put( key.substring(substringLength), value); } } keyValues.putAll(cachedSettings); } return keyValues; } Loading @@ -3648,7 +3636,6 @@ public final class Settings { needsGenerationTracker = true; } } if (mCallListCommand == null) { // No list command specified, return empty map return keyValues; Loading Loading @@ -3693,20 +3680,23 @@ public final class Settings { } // All flags for the namespace Map<String, String> flagsToValues = HashMap<String, String> flagsToValues = (HashMap) b.getSerializable(Settings.NameValueTable.VALUE, java.util.HashMap.class); if (flagsToValues == null) { return keyValues; } // Only the flags requested by the caller if (names.length > 0) { if (!names.isEmpty()) { for (String name : names) { // flagsToValues can contain "null" values, need to use containsKey. if (flagsToValues.containsKey(name)) { final String key = Config.createCompositeName(namespace, name); if (flagsToValues.containsKey(key)) { keyValues.put( name.substring(substringLength), flagsToValues.get(name)); name, flagsToValues.get(key)); } } } else { keyValues.ensureCapacity(keyValues.size() + flagsToValues.size()); for (Map.Entry<String, String> flag : flagsToValues.entrySet()) { keyValues.put( flag.getKey().substring(substringLength), Loading Loading @@ -3740,10 +3730,18 @@ public final class Settings { if (DEBUG) { Log.i(TAG, "Updating cache for prefix:" + prefix); } // cache the complete list of flags for the namespace mValues.putAll(flagsToValues); // Adding the prefix as a signal that the prefix is cached. mValues.put(prefix, null); // Cache the complete list of flags for the namespace for bulk queries. // In this cached list, the setting's name doesn't include the prefix. ArrayMap<String, String> namesToValues = new ArrayMap<>(flagsToValues.size() + 1); for (Map.Entry<String, String> flag : flagsToValues.entrySet()) { namesToValues.put( flag.getKey().substring(substringLength), flag.getValue()); } // Legacy behavior, we return <"", null> when queried with name = "" namesToValues.put("", null); mPrefixToValues.put(prefix, namesToValues); } } return keyValues; Loading Loading @@ -19907,16 +19905,9 @@ public final class Settings { @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) public static Map<String, String> getStrings(@NonNull ContentResolver resolver, @NonNull String namespace, @NonNull List<String> names) { String[] compositeNames = new String[names.size()]; for (int i = 0, size = names.size(); i < size; ++i) { compositeNames[i] = createCompositeName(namespace, names.get(i)); } String prefix = createPrefix(namespace); ArrayMap<String, String> keyValues = sNameValueCache.getStringsForPrefixStripPrefix( resolver, prefix, compositeNames); return keyValues; return sNameValueCache.getStringsForPrefixStripPrefix(resolver, prefix, names); } /** Loading Loading @@ -20238,7 +20229,7 @@ public final class Settings { } } private static String createCompositeName(@NonNull String namespace, @NonNull String name) { static String createCompositeName(@NonNull String namespace, @NonNull String name) { Preconditions.checkNotNull(namespace); Preconditions.checkNotNull(name); var sb = new StringBuilder(namespace.length() + 1 + name.length());