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

Commit 861d42c3 authored by Ted Bauer's avatar Ted Bauer
Browse files

Add getAllStrings API.

Bug: 293307017
Test: new CTS tests
Change-Id: Id8acec66e553fb17a323cd7b575d635fa8f3445a
parent 60c2853e
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 */
@@ -19373,6 +19373,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