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

Commit 2a51042c authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Make FakeSettingsProvider multiuser aware." into main

parents 39c37d2b b1c9ea25
Loading
Loading
Loading
Loading
+51 −6
Original line number Diff line number Diff line
@@ -16,10 +16,14 @@

package com.android.internal.util.test;

import static junit.framework.Assert.assertNull;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import android.content.ContentProvider;
import android.os.Process;
import android.os.UserHandle;
import android.platform.test.annotations.DisabledOnRavenwood;
import android.platform.test.ravenwood.RavenwoodRule;
import android.provider.Settings;
@@ -42,6 +46,9 @@ public class FakeSettingsProviderTest {
    @Rule
    public final RavenwoodRule mRavenwood = new RavenwoodRule();

    private static final String SYSTEM_SETTING = Settings.System.SCREEN_BRIGHTNESS;
    private static final String SECURE_SETTING = Settings.Secure.BLUETOOTH_NAME;

    private MockContentResolver mCr;

    @Before
@@ -53,15 +60,53 @@ public class FakeSettingsProviderTest {
    @Test
    @SmallTest
    public void testBasicOperation() throws Exception {
        String settingName = Settings.System.SCREEN_BRIGHTNESS;

        try {
            Settings.System.getInt(mCr, settingName);
            Settings.System.getInt(mCr, SYSTEM_SETTING);
            fail("FakeSettingsProvider should start off empty.");
        } catch (Settings.SettingNotFoundException expected) {}
        } catch (Settings.SettingNotFoundException expected) {
            // Expected behaviour.
        }

        // Check that fake settings can be written and read back.
        Settings.System.putInt(mCr, settingName, 123);
        assertEquals(123, Settings.System.getInt(mCr, settingName));
        Settings.System.putInt(mCr, SYSTEM_SETTING, 123);
        assertEquals(123, Settings.System.getInt(mCr, SYSTEM_SETTING));
    }

    private void assertUserHandleUnsupported(UserHandle userHandle, String settingName) {
        try {
            Settings.Secure.putStringForUser(mCr, settingName, "currentUserSetting",
                    userHandle.getIdentifier());
            fail("UserHandle " + userHandle + " is unsupported and should throw");
        } catch (UnsupportedOperationException expected) {
            // Expected behaviour.
        }
    }

    @Test
    @SmallTest
    public void testMultiUserOperation() {
        Settings.Secure.putStringForUser(mCr, SECURE_SETTING, "user0Setting", 0);
        Settings.Secure.putStringForUser(mCr, SECURE_SETTING, "user1Setting", 1);
        assertEquals("user0Setting", Settings.Secure.getStringForUser(mCr, SECURE_SETTING, 0));
        assertEquals("user1Setting", Settings.Secure.getStringForUser(mCr, SECURE_SETTING, 1));
        assertNull(Settings.Secure.getStringForUser(mCr, SECURE_SETTING, 2));

        final int currentUserId = UserHandle.getUserId(Process.myUid());
        Settings.Secure.putStringForUser(mCr, SECURE_SETTING, "currentUserSetting", currentUserId);
        assertEquals("currentUserSetting", Settings.Secure.getString(mCr, SECURE_SETTING));

        Settings.Secure.putString(mCr, SECURE_SETTING, "newValue");
        assertEquals("newValue",
                Settings.Secure.getStringForUser(mCr, SECURE_SETTING, currentUserId));

        Settings.Secure.putString(mCr, SECURE_SETTING, "newValue2");
        assertEquals("newValue2",
                Settings.Secure.getStringForUser(mCr, SECURE_SETTING, UserHandle.USER_CURRENT));

        Settings.Secure.putStringForUser(mCr, SECURE_SETTING, "newValue3", UserHandle.USER_CURRENT);
        assertEquals("newValue3", Settings.Secure.getString(mCr, SECURE_SETTING));

        assertUserHandleUnsupported(UserHandle.ALL, SECURE_SETTING);
        assertUserHandleUnsupported(UserHandle.CURRENT_OR_SELF, SECURE_SETTING);
    }
}
+38 −14
Original line number Diff line number Diff line
@@ -18,11 +18,14 @@ package com.android.internal.util.test;

import android.net.Uri;
import android.os.Bundle;
import android.os.Process;
import android.os.UserHandle;
import android.provider.Settings;
import android.test.mock.MockContentProvider;
import android.util.ArrayMap;
import android.util.Log;

import java.util.HashMap;
import java.util.Map;

/**
 * Fake for system settings.
@@ -69,12 +72,19 @@ public class FakeSettingsProvider extends MockContentProvider {
    private static final String TAG = FakeSettingsProvider.class.getSimpleName();
    private static final boolean DBG = false;
    private static final String[] TABLES = { "system", "secure", "global" };
    private static final Map<String, String> EMPTY_MAP = Map.of();

    private final HashMap<String, HashMap<String, String>> mTables = new HashMap<>();
    /**
     * Stores settings values. Keyed by:
     * - Table name (e.g., "system")
     * - User ID (e.g., USER_SYSTEM)
     * - Setting name (e.g., "screen_brightness")
     */
    private final Map<String, Map<Integer, Map<String, String>>> mDb = new ArrayMap<>();

    public FakeSettingsProvider() {
        for (int i = 0; i < TABLES.length; i++) {
            mTables.put(TABLES[i], new HashMap<String, String>());
            mDb.put(TABLES[i], new ArrayMap<>());
        }
    }

@@ -116,27 +126,41 @@ public class FakeSettingsProvider extends MockContentProvider {

        Bundle out = new Bundle();
        String value;
        int userId = extras.getInt(Settings.CALL_METHOD_USER_KEY);
        if (userId == UserHandle.USER_CURRENT) {
            userId = UserHandle.getUserId(Process.myUid());
        }
        if (userId < 0) {
            throw new UnsupportedOperationException("userId " + userId + " is not a real user");
        }
        switch (op) {
            case "GET":
                value = mTables.get(table).get(arg);
                value = mDb.get(table).getOrDefault(userId, EMPTY_MAP).get(arg);
                if (value != null) {
                    if (DBG) {
                        Log.d(TAG, String.format("Returning fake setting %s.%s = %s",
                                table, arg, value));
                    }
                    out.putString(Settings.NameValueTable.VALUE, value);
                }
                if (DBG) {
                    Log.d(TAG, String.format("Returning fake setting %d:%s.%s = %s",
                            userId, table, arg, (value == null) ? "null" : "\"" + value + "\""));
                }
                break;
            case "PUT":
                value = extras.getString(Settings.NameValueTable.VALUE, null);
                final boolean changed;
                if (value != null) {
                    changed = !value.equals(mDb.get(table)
                            .computeIfAbsent(userId, (u) -> new ArrayMap<>())
                            .put(arg, value));
                    if (DBG) {
                    Log.d(TAG, String.format("Inserting fake setting %s.%s = %s",
                            table, arg, value));
                        Log.d(TAG, String.format("Inserting fake setting %d:%s.%s = \"%s\"",
                                userId, table, arg, value));
                    }
                if (value != null) {
                    mTables.get(table).put(arg, value);
                } else {
                    mTables.get(table).remove(arg);
                    changed = mDb.get(table).getOrDefault(userId, EMPTY_MAP).remove(arg) != null;
                    if (DBG) {
                        Log.d(TAG, String.format("Removing fake setting %d:%s.%s", userId, table,
                                arg));
                    }
                }
                break;
            default: