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

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

Merge "Add a test mode to SecureSettingsWrapper" into main

parents ae9a5d98 1ce603c3
Loading
Loading
Loading
Loading
+86 −0
Original line number Diff line number Diff line
@@ -44,6 +44,32 @@ final class SecureSettingsWrapper {
    @Nullable
    private static volatile ContentResolver sContentResolver = null;

    private static volatile boolean sTestMode = false;

    /**
     * Can be called from unit tests to start the test mode, where a fake implementation will be
     * used instead.
     *
     * <p>The fake implementation is just an {@link ArrayMap}. By default it is empty, and the data
     * written can be read back later.</p>
     */
    @AnyThread
    static void startTestMode() {
        sTestMode = true;
    }

    /**
     * Can be called from unit tests to end the test mode, where a fake implementation will be used
     * instead.
     */
    @AnyThread
    static void endTestMode() {
        synchronized (sUserMap) {
            sUserMap.clear();
        }
        sTestMode = false;
    }

    /**
     * Not intended to be instantiated.
     */
@@ -78,6 +104,52 @@ final class SecureSettingsWrapper {
        int getInt(String key, int defaultValue);
    }

    private static class FakeReaderWriterImpl implements ReaderWriter {
        @GuardedBy("mNonPersistentKeyValues")
        private final ArrayMap<String, String> mNonPersistentKeyValues = new ArrayMap<>();

        @AnyThread
        @Override
        public void putString(String key, String value) {
            synchronized (mNonPersistentKeyValues) {
                mNonPersistentKeyValues.put(key, value);
            }
        }

        @AnyThread
        @Nullable
        @Override
        public String getString(String key, String defaultValue) {
            synchronized (mNonPersistentKeyValues) {
                if (mNonPersistentKeyValues.containsKey(key)) {
                    final String result = mNonPersistentKeyValues.get(key);
                    return result != null ? result : defaultValue;
                }
                return defaultValue;
            }
        }

        @AnyThread
        @Override
        public void putInt(String key, int value) {
            synchronized (mNonPersistentKeyValues) {
                mNonPersistentKeyValues.put(key, String.valueOf(value));
            }
        }

        @AnyThread
        @Override
        public int getInt(String key, int defaultValue) {
            synchronized (mNonPersistentKeyValues) {
                if (mNonPersistentKeyValues.containsKey(key)) {
                    final String result = mNonPersistentKeyValues.get(key);
                    return result != null ? Integer.parseInt(result) : defaultValue;
                }
                return defaultValue;
            }
        }
    }

    private static class UnlockedUserImpl implements ReaderWriter {
        @UserIdInt
        private final int mUserId;
@@ -200,6 +272,9 @@ final class SecureSettingsWrapper {

    private static ReaderWriter createImpl(@NonNull UserManagerInternal userManagerInternal,
            @UserIdInt int userId) {
        if (sTestMode) {
            return new FakeReaderWriterImpl();
        }
        return userManagerInternal.isUserUnlockingOrUnlocked(userId)
                ? new UnlockedUserImpl(userId, sContentResolver)
                : new LockedUserImpl(userId, sContentResolver);
@@ -234,6 +309,9 @@ final class SecureSettingsWrapper {
                return readerWriter;
            }
        }
        if (sTestMode) {
            return putOrGet(userId, new FakeReaderWriterImpl());
        }
        final UserManagerInternal userManagerInternal =
                LocalServices.getService(UserManagerInternal.class);
        if (!userManagerInternal.exists(userId)) {
@@ -276,6 +354,10 @@ final class SecureSettingsWrapper {
     */
    @AnyThread
    static void onUserStarting(@UserIdInt int userId) {
        if (sTestMode) {
            putOrGet(userId, new FakeReaderWriterImpl());
            return;
        }
        putOrGet(userId, createImpl(LocalServices.getService(UserManagerInternal.class), userId));
    }

@@ -286,6 +368,10 @@ final class SecureSettingsWrapper {
     */
    @AnyThread
    static void onUserUnlocking(@UserIdInt int userId) {
        if (sTestMode) {
            putOrGet(userId, new FakeReaderWriterImpl());
            return;
        }
        final ReaderWriter readerWriter = new UnlockedUserImpl(userId, sContentResolver);
        putOrGet(userId, readerWriter);
    }
+7 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.platform.test.ravenwood.RavenwoodRule;

import com.android.server.pm.UserManagerInternal;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -63,6 +64,7 @@ public final class UserDataRepositoryTest {
    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        SecureSettingsWrapper.startTestMode();
        mHandler = new Handler(Looper.getMainLooper());
        mBindingControllerFactory = new IntFunction<InputMethodBindingController>() {

@@ -73,6 +75,11 @@ public final class UserDataRepositoryTest {
        };
    }

    @After
    public void tearDown() {
        SecureSettingsWrapper.endTestMode();
    }

    @Test
    public void testUserDataRepository_addsNewUserInfoOnUserCreatedEvent() {
        // Create UserDataRepository and capture the user lifecycle listener