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

Commit 94b0f2f5 authored by Ted Bauer's avatar Ted Bauer Committed by Android (Google) Code Review
Browse files

Merge "Add getAllStrings API." into main

parents 74a34a48 861d42c3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -529,6 +529,7 @@ package android.provider {
  public static final class Settings.Config extends android.provider.Settings.NameValueTable {
    method @RequiresPermission(android.Manifest.permission.MONITOR_DEVICE_CONFIG_ACCESS) public static void clearMonitorCallback(@NonNull android.content.ContentResolver);
    method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static boolean deleteString(@NonNull String, @NonNull String);
    method @NonNull public static java.util.Map<java.lang.String,java.lang.String> getAllStrings();
    method @Nullable @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static String getString(@NonNull String);
    method @NonNull @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static java.util.Map<java.lang.String,java.lang.String> getStrings(@NonNull String, @NonNull java.util.List<java.lang.String>);
    method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static int getSyncDisabledMode();
+31 −1
Original line number Diff line number Diff line
@@ -2831,7 +2831,7 @@ public final class Settings {
    /** @hide - Private call() method to query the 'global' table */
    public static final String CALL_METHOD_LIST_GLOBAL = "LIST_global";
    /** @hide - Private call() method to reset to defaults the 'configuration' table */
    /** @hide - Private call() method to query the 'configuration' table */
    public static final String CALL_METHOD_LIST_CONFIG = "LIST_config";
    /** @hide - Private call() method to disable / re-enable syncs to the 'configuration' table */
@@ -19408,6 +19408,36 @@ public final class Settings {
            return getStrings(getContentResolver(), namespace, names);
        }
        /**
         * Return all stored flags.
         *
         * The keys take the form {@code namespace/flag}, and the values are the flag values.
         *
         * @hide
         */
        @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
        @NonNull
        public static Map<String, String> getAllStrings() {
            HashMap<String, String> allFlags = new HashMap<String, String>();
            try {
                ContentResolver resolver = getContentResolver();
                Bundle arg = new Bundle();
                arg.putInt(Settings.CALL_METHOD_USER_KEY, resolver.getUserId());
                IContentProvider cp = sProviderHolder.getProvider(resolver);
                Bundle b = cp.call(resolver.getAttributionSource(),
                        sProviderHolder.mUri.getAuthority(), CALL_METHOD_LIST_CONFIG, null, arg);
                if (b != null) {
                    Map<String, String> flagsToValues =
                            (HashMap) b.getSerializable(Settings.NameValueTable.VALUE,
                                            java.util.HashMap.class);
                    allFlags.putAll(flagsToValues);
                }
            } catch (RemoteException e) {
                Log.w(TAG, "Can't query configuration table for " + CONTENT_URI, e);
            }
            return allFlags;
        }
        /**
         * Look up a list of names in the database, within the specified namespace.
         *
+84 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ public class DeviceConfigTest {
    private static final long WAIT_FOR_PROPERTY_CHANGE_TIMEOUT_MILLIS = 2000; // 2 sec
    private static final String DEFAULT_VALUE = "test_default_value";
    private static final String NAMESPACE = "namespace1";
    private static final String NAMESPACE2 = "namespace2";
    private static final String KEY = "key1";
    private static final String KEY2 = "key2";
    private static final String KEY3 = "key3";
@@ -67,6 +68,89 @@ public class DeviceConfigTest {
        deleteViaContentProvider(NAMESPACE, KEY);
        deleteViaContentProvider(NAMESPACE, KEY2);
        deleteViaContentProvider(NAMESPACE, KEY3);
        DeviceConfig.clearAllLocalOverrides();
    }

    /**
     * Test that creating a sticky local override for a flag prevents further writes to that flag.
     */
    @Test
    public void testAddStickyLocalOverridePreventsWrites() {
        DeviceConfig.setLocalOverride(NAMESPACE, KEY, VALUE);

        String key1Value = DeviceConfig.getProperty(NAMESPACE, KEY);
        assertThat(key1Value).isEqualTo(VALUE);

        DeviceConfig.setProperty(NAMESPACE, KEY, VALUE2, /* makeDefault= */ false);
        key1Value = DeviceConfig.getProperty(NAMESPACE, KEY);
        assertThat(key1Value).isEqualTo(VALUE);
    }

    /**
     * Test that when we locally override a flag, we can still write other flags.
     */
    @Test
    public void testAddStickyLocalOverrideDoesNotAffectOtherFlags() {
        DeviceConfig.setLocalOverride(NAMESPACE, KEY, VALUE);
        DeviceConfig.setProperty(NAMESPACE, KEY2, VALUE2, /* makeDefault= */ false);
        String key2Value = DeviceConfig.getProperty(NAMESPACE, KEY2);
        assertThat(key2Value).isEqualTo(VALUE2);
    }

    /**
     * Test that when we apply some overrides, they show up in the override list.
     */
    @Test
    public void testGetStickyLocalOverrides() {
        DeviceConfig.setProperty(NAMESPACE, KEY, VALUE2, false);
        DeviceConfig.setProperty(NAMESPACE, KEY2, VALUE, false);
        DeviceConfig.setLocalOverride(NAMESPACE, KEY, VALUE);
        DeviceConfig.setLocalOverride(NAMESPACE, KEY2, VALUE2);

        Map<String, Map<String, String>> expectedOverrides = new HashMap<>();
        Map<String, String> expectedInnerMap = new HashMap<>();
        expectedInnerMap.put(KEY, VALUE2);
        expectedInnerMap.put(KEY2, VALUE);
        expectedOverrides.put(NAMESPACE, expectedInnerMap);

        assertThat(DeviceConfig.getUnderlyingValuesForOverriddenFlags())
                .isEqualTo(expectedOverrides);
    }

    /**
     * Test that when we clear all overrides, the override list is empty.
     */
    @Test
    public void testClearStickyLocalOverrides() {
        DeviceConfig.setLocalOverride(NAMESPACE2, KEY, VALUE);
        DeviceConfig.setLocalOverride(NAMESPACE2, KEY2, VALUE2);

        DeviceConfig.clearAllLocalOverrides();

        Map<String, Map<String, String>> overrides =
                DeviceConfig.getUnderlyingValuesForOverriddenFlags();
        assertThat(overrides).isEmpty();
    }

    /**
     * Test that when we clear a single override, it doesn't appear in the list.
     */
    @Test
    public void testClearStickyLocalOverride() {
        DeviceConfig.setProperty(NAMESPACE, KEY, VALUE2, false);
        DeviceConfig.setProperty(NAMESPACE2, KEY2, VALUE, false);
        DeviceConfig.setLocalOverride(NAMESPACE, KEY, VALUE);
        DeviceConfig.setLocalOverride(NAMESPACE2, KEY2, VALUE2);

        DeviceConfig.clearLocalOverride(NAMESPACE, KEY);

        Map<String, Map<String, String>> expectedOverrides = new HashMap<>();
        Map<String, String> expectedInnerMap = new HashMap<>();
        expectedInnerMap.put(KEY2, VALUE);
        expectedOverrides.put(NAMESPACE2, expectedInnerMap);

        assertThat(DeviceConfig.getUnderlyingValuesForOverriddenFlags())
                .isEqualTo(expectedOverrides);
    }

    @Test