Merge "Keystore 2.0: Update credential settings to use public Keystore API." am: 7086917968 am: 08bea2183d am: a409521a64 am: 4e10002367

Original change: https://android-review.googlesource.com/c/platform/packages/apps/Settings/+/1569700

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I2e1974eb69cbdfb0e5323e594ff01e82b69168c2
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 86d7992..5ba05c3 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -81,6 +81,7 @@
     <uses-permission android:name="android.permission.OEM_UNLOCK_STATE" />
     <uses-permission android:name="android.permission.MANAGE_USER_OEM_UNLOCK_STATE" />
     <uses-permission android:name="android.permission.OVERRIDE_WIFI_CONFIG" />
+    <uses-permission android:name="android.permission.RESTART_WIFI_SUBSYSTEM" />
     <uses-permission android:name="android.permission.MANAGE_FINGERPRINT" />
     <uses-permission android:name="android.permission.USE_BIOMETRIC" />
     <uses-permission android:name="android.permission.USE_BIOMETRIC_INTERNAL" />
diff --git a/res/values-mcc234/strings.xml b/res/values-mcc234/strings.xml
new file mode 100644
index 0000000..f7d0d33
--- /dev/null
+++ b/res/values-mcc234/strings.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="cell_broadcast_settings">Emergency alerts</string>
+</resources>
\ No newline at end of file
diff --git a/res/values-nl/arrays.xml b/res/values-nl/arrays.xml
index 54b7224..627fa59 100644
--- a/res/values-nl/arrays.xml
+++ b/res/values-nl/arrays.xml
@@ -273,7 +273,7 @@
     <item msgid="5099026183238335900">"monitorlocatie"</item>
     <item msgid="2297727967385895059">"locatie met hoog energieverbruik controleren"</item>
     <item msgid="8700593962030471569">"gebruiksstatistieken ophalen"</item>
-    <item msgid="4140820386622184831">"microfoon dempen/dempen opheffen"</item>
+    <item msgid="4140820386622184831">"microfoon uit-/aanzetten"</item>
     <item msgid="317746827951691657">"toast weergeven"</item>
     <item msgid="5679422988212309779">"media projecteren"</item>
     <item msgid="6454031639780101439">"VPN activeren"</item>
@@ -340,7 +340,7 @@
     <item msgid="8482874682804856549">"Locatie"</item>
     <item msgid="5186169827582545242">"Locatie"</item>
     <item msgid="6122293931012635638">"Gebruiksstatistieken ophalen"</item>
-    <item msgid="2526677383312751932">"Microfoon dempen/dempen opheffen"</item>
+    <item msgid="2526677383312751932">"Microfoon uit-/aanzetten"</item>
     <item msgid="4000577305179914546">"Toast weergeven"</item>
     <item msgid="8660207174515570558">"Media projecteren"</item>
     <item msgid="3904996949561946108">"VPN activeren"</item>
diff --git a/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java b/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
index c09ea02..3653baf 100644
--- a/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
@@ -17,6 +17,7 @@
 package com.android.settings.deviceinfo;
 
 import android.app.Activity;
+import android.app.ActivityManager;
 import android.app.settings.SettingsEnums;
 import android.content.ComponentName;
 import android.content.Context;
@@ -29,6 +30,7 @@
 import android.text.TextUtils;
 import android.widget.Toast;
 
+import androidx.annotation.VisibleForTesting;
 import androidx.preference.Preference;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -112,7 +114,7 @@
         if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
             return false;
         }
-        if (Utils.isMonkeyRunning()) {
+        if (isUserAMonkey()) {
             return false;
         }
         // Don't enable developer options for secondary non-demo users.
@@ -245,4 +247,9 @@
                 Toast.LENGTH_LONG);
         mDevHitToast.show();
     }
+
+    @VisibleForTesting
+    protected boolean isUserAMonkey() {
+        return ActivityManager.isUserAMonkey();
+    }
 }
diff --git a/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceController.java b/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceController.java
index dcc581c..89d349f 100644
--- a/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceController.java
+++ b/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceController.java
@@ -21,6 +21,7 @@
 import android.text.format.Formatter;
 import android.util.FeatureFlagUtils;
 
+import androidx.annotation.VisibleForTesting;
 import androidx.preference.Preference;
 
 import com.android.settings.R;
@@ -31,6 +32,7 @@
 import com.android.settingslib.utils.ThreadUtils;
 
 import java.text.NumberFormat;
+import java.util.concurrent.Future;
 
 public class TopLevelStoragePreferenceController extends BasePreferenceController {
 
@@ -59,10 +61,15 @@
             return;
         }
 
-        ThreadUtils.postOnBackgroundThread(() -> {
+        refreshSummaryThread(preference);
+    }
+
+    @VisibleForTesting
+    protected Future refreshSummaryThread(Preference preference) {
+        return ThreadUtils.postOnBackgroundThread(() -> {
             final NumberFormat percentageFormat = NumberFormat.getPercentInstance();
             final PrivateStorageInfo info = PrivateStorageInfo.getPrivateStorageInfo(
-                    mStorageManagerVolumeProvider);
+                    getStorageManagerVolumeProvider());
             final double privateUsedBytes = info.totalBytes - info.freeBytes;
 
             ThreadUtils.postOnMainThread(() -> {
@@ -72,4 +79,10 @@
             });
         });
     }
+
+
+    @VisibleForTesting
+    protected StorageManagerVolumeProvider getStorageManagerVolumeProvider() {
+        return mStorageManagerVolumeProvider;
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/BrandedAccountPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/BrandedAccountPreferenceControllerTest.java
deleted file mode 100644
index 87dcb33..0000000
--- a/tests/robotests/src/com/android/settings/deviceinfo/BrandedAccountPreferenceControllerTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.deviceinfo;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.when;
-
-import android.accounts.Account;
-import android.content.Context;
-
-import com.android.settings.testutils.FakeFeatureFactory;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-@RunWith(RobolectricTestRunner.class)
-public class BrandedAccountPreferenceControllerTest {
-
-    private Context mContext;
-    private FakeFeatureFactory fakeFeatureFactory;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
-        fakeFeatureFactory = FakeFeatureFactory.setupForTest();
-
-    }
-
-    @Test
-    public void isAvailable_configOn_noAccount_off() {
-        final BrandedAccountPreferenceController controller =
-                new BrandedAccountPreferenceController(mContext, "test_key");
-        assertThat(controller.isAvailable()).isFalse();
-    }
-
-    @Test
-    public void isAvailable_accountIsAvailable_on() {
-        when(fakeFeatureFactory.mAccountFeatureProvider.getAccounts(any(Context.class)))
-                .thenReturn(new Account[]{new Account("fake@account.foo", "fake.reallyfake")});
-
-        final BrandedAccountPreferenceController controller =
-                new BrandedAccountPreferenceController(mContext, "test_key");
-
-        assertThat(controller.isAvailable()).isTrue();
-    }
-
-    @Test
-    @Config(qualifiers = "mcc999")
-    public void isAvailable_configOff_hasAccount_off() {
-        when(fakeFeatureFactory.mAccountFeatureProvider.getAccounts(any(Context.class)))
-                .thenReturn(new Account[]{new Account("fake@account.foo", "fake.reallyfake")});
-
-        final BrandedAccountPreferenceController controller =
-                new BrandedAccountPreferenceController(mContext, "test_key");
-
-        assertThat(controller.isAvailable()).isFalse();
-    }
-}
diff --git a/tests/unit/src/com/android/settings/deviceinfo/BrandedAccountPreferenceControllerTest.java b/tests/unit/src/com/android/settings/deviceinfo/BrandedAccountPreferenceControllerTest.java
new file mode 100644
index 0000000..6e78d05
--- /dev/null
+++ b/tests/unit/src/com/android/settings/deviceinfo/BrandedAccountPreferenceControllerTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.deviceinfo;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.accounts.Account;
+import android.content.Context;
+import android.content.res.Resources;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.ResourcesUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class BrandedAccountPreferenceControllerTest {
+
+    @Mock
+    private Resources mResources;
+    private Context mContext;
+    private FakeFeatureFactory mFakeFeatureFactory;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(ApplicationProvider.getApplicationContext());
+        when(mContext.getResources()).thenReturn(mResources);
+        mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
+
+    }
+
+    @Test
+    public void isAvailable_configOn_noAccount_off() {
+        final int boolId = ResourcesUtils.getResourcesId(
+                ApplicationProvider.getApplicationContext(), "bool",
+                "config_show_branded_account_in_device_info");
+        when(mResources.getBoolean(boolId)).thenReturn(true);
+
+        final BrandedAccountPreferenceController controller =
+                new BrandedAccountPreferenceController(mContext, "test_key");
+        assertThat(controller.isAvailable()).isFalse();
+    }
+
+    @Test
+    public void isAvailable_accountIsAvailable_on() {
+        final int boolId = ResourcesUtils.getResourcesId(
+                ApplicationProvider.getApplicationContext(), "bool",
+                "config_show_branded_account_in_device_info");
+        when(mResources.getBoolean(boolId)).thenReturn(true);
+        when(mFakeFeatureFactory.mAccountFeatureProvider.getAccounts(any(Context.class)))
+                .thenReturn(new Account[]{new Account("fake@account.foo", "fake.reallyfake")});
+
+        final BrandedAccountPreferenceController controller =
+                new BrandedAccountPreferenceController(mContext, "test_key");
+
+        assertThat(controller.isAvailable()).isTrue();
+    }
+
+    @Test
+    public void isAvailable_configOff_hasAccount_off() {
+        final int boolId = ResourcesUtils.getResourcesId(
+                ApplicationProvider.getApplicationContext(), "bool",
+                "config_show_branded_account_in_device_info");
+        when(mResources.getBoolean(boolId)).thenReturn(false);
+        when(mFakeFeatureFactory.mAccountFeatureProvider.getAccounts(any(Context.class)))
+                .thenReturn(new Account[]{new Account("fake@account.foo", "fake.reallyfake")});
+
+        final BrandedAccountPreferenceController controller =
+                new BrandedAccountPreferenceController(mContext, "test_key");
+
+        assertThat(controller.isAvailable()).isFalse();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java b/tests/unit/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java
similarity index 71%
rename from tests/robotests/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java
rename to tests/unit/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java
index 80a3a11..8c75449 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java
@@ -22,52 +22,51 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.app.Activity;
+import android.content.ClipData;
 import android.content.ClipboardManager;
 import android.content.Context;
-import android.content.pm.UserInfo;
-import android.os.Process;
-import android.os.UserHandle;
+import android.os.Looper;
 import android.os.UserManager;
 import android.provider.Settings;
 
 import androidx.lifecycle.LifecycleOwner;
 import androidx.preference.Preference;
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.core.InstrumentedPreferenceFragment;
 import com.android.settings.testutils.FakeFeatureFactory;
-import com.android.settings.testutils.shadow.ShadowUtils;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.development.DevelopmentSettingsEnabler;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.Shadows;
-import org.robolectric.annotation.Config;
-import org.robolectric.shadows.ShadowUserManager;
 
-@RunWith(RobolectricTestRunner.class)
-@Config(shadows = ShadowUtils.class)
+@RunWith(AndroidJUnit4.class)
 public class BuildNumberPreferenceControllerTest {
 
     private static final String KEY_BUILD_NUMBER = "build_number";
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private InstrumentedPreferenceFragment mFragment;
 
-    private ShadowUserManager mShadowUserManager;
-
     private Context mContext;
+    private UserManager mUserManager;
+    private ClipboardManager mClipboardManager;
     private LifecycleOwner mLifecycleOwner;
     private Lifecycle mLifecycle;
     private FakeFeatureFactory mFactory;
@@ -75,15 +74,23 @@
     private BuildNumberPreferenceController mController;
 
     @Before
+    @UiThreadTest
     public void setUp() {
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
         MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
-        mShadowUserManager = Shadows.shadowOf(
-                RuntimeEnvironment.application.getSystemService(UserManager.class));
+
+        mContext = spy(ApplicationProvider.getApplicationContext());
+        mUserManager = (UserManager) spy(mContext.getSystemService(Context.USER_SERVICE));
+        doReturn(mUserManager).when(mContext).getSystemService(Context.USER_SERVICE);
+        mClipboardManager = (ClipboardManager) spy(mContext.getSystemService(CLIPBOARD_SERVICE));
+        doReturn(mClipboardManager).when(mContext).getSystemService(CLIPBOARD_SERVICE);
+
         mFactory = FakeFeatureFactory.setupForTest();
         mLifecycleOwner = () -> mLifecycle;
         mLifecycle = new Lifecycle(mLifecycleOwner);
-        mController = new BuildNumberPreferenceController(mContext, KEY_BUILD_NUMBER);
+        mController = spy(new BuildNumberPreferenceController(mContext, KEY_BUILD_NUMBER));
         mController.setHost(mFragment);
 
         mPreference = new Preference(mContext);
@@ -93,11 +100,6 @@
                 Settings.Global.DEVICE_PROVISIONED, 1);
     }
 
-    @After
-    public void tearDown() {
-        ShadowUtils.reset();
-    }
-
     @Test
     public void handlePrefTreeClick_onlyHandleBuildNumberPref() {
         assertThat(mController.handlePreferenceTreeClick(mock(Preference.class))).isFalse();
@@ -105,32 +107,32 @@
 
     @Test
     public void handlePrefTreeClick_notAdminUser_notDemoUser_doNothing() {
-        mShadowUserManager.setIsAdminUser(false);
-        mShadowUserManager.setIsDemoUser(false);
+        when(mUserManager.isAdminUser()).thenReturn(false);
+        when(mUserManager.isDemoUser()).thenReturn(false);
 
         assertThat(mController.handlePreferenceTreeClick(mPreference)).isFalse();
     }
 
     @Test
     public void handlePrefTreeClick_isAdminUser_notDemoUser_handleBuildNumberPref() {
-        mShadowUserManager.setIsAdminUser(true);
-        mShadowUserManager.setIsDemoUser(false);
+        when(mUserManager.isAdminUser()).thenReturn(true);
+        when(mUserManager.isDemoUser()).thenReturn(false);
 
         assertThat(mController.handlePreferenceTreeClick(mPreference)).isTrue();
     }
 
     @Test
     public void handlePrefTreeClick_notAdminUser_isDemoUser_handleBuildNumberPref() {
-        mShadowUserManager.setIsAdminUser(false);
-        mShadowUserManager.addUser(UserHandle.myUserId(), "test", UserInfo.FLAG_DEMO);
+        when(mUserManager.isAdminUser()).thenReturn(false);
+        when(mUserManager.isDemoUser()).thenReturn(true);
 
         assertThat(mController.handlePreferenceTreeClick(mPreference)).isTrue();
     }
 
     @Test
     public void handlePrefTreeClick_deviceNotProvisioned_doNothing() {
-        mShadowUserManager.setIsAdminUser(true);
-        mShadowUserManager.setIsDemoUser(false);
+        when(mUserManager.isAdminUser()).thenReturn(true);
+        when(mUserManager.isDemoUser()).thenReturn(false);
 
         Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED,
                 0);
@@ -143,17 +145,16 @@
 
     @Test
     public void handlePrefTreeClick_isMonkeyRun_doNothing() {
-        ShadowUtils.setIsUserAMonkey(true);
+        when(mController.isUserAMonkey()).thenReturn(true);
         assertThat(mController.handlePreferenceTreeClick(mPreference)).isFalse();
     }
 
     @Test
     public void handlePrefTreeClick_userHasRestriction_doNothing() {
-        mShadowUserManager.setIsAdminUser(true);
-        mShadowUserManager.setIsDemoUser(false);
-
-        mShadowUserManager.setUserRestriction(Process.myUserHandle(),
-                UserManager.DISALLOW_DEBUGGING_FEATURES, true);
+        when(mUserManager.isAdminUser()).thenReturn(true);
+        when(mUserManager.isDemoUser()).thenReturn(false);
+        when(mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES))
+                .thenReturn(true);
 
         assertThat(mController.handlePreferenceTreeClick(mPreference)).isFalse();
         verify(mFactory.metricsFeatureProvider).action(
@@ -184,8 +185,9 @@
     }
 
     @Test
+    @UiThreadTest
     public void onActivityResult_confirmPasswordRequestCompleted_enableDevPref() {
-        mShadowUserManager.setIsAdminUser(true);
+        when(mUserManager.isAdminUser()).thenReturn(true);
 
         final boolean activityResultHandled = mController.onActivityResult(
                 BuildNumberPreferenceController.REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF,
@@ -197,12 +199,14 @@
     }
 
     @Test
+    @UiThreadTest
     public void copy_shouldCopyBuildNumberToClipboard() {
+        ArgumentCaptor<ClipData> captor = ArgumentCaptor.forClass(ClipData.class);
+        doNothing().when(mClipboardManager).setPrimaryClip(captor.capture());
+
         mController.copy();
 
-        final ClipboardManager clipboard = (ClipboardManager) mContext.getSystemService(
-                CLIPBOARD_SERVICE);
-        final CharSequence data = clipboard.getPrimaryClip().getItemAt(0).getText();
-        assertThat(data.toString()).isEqualTo(mController.getSummary());
+        final ClipData data = captor.getValue();
+        assertThat(data.getItemAt(0).getText().toString()).isEqualTo(mController.getSummary());
     }
 }
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuControllerTest.java b/tests/unit/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuControllerTest.java
similarity index 76%
rename from tests/robotests/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuControllerTest.java
rename to tests/unit/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuControllerTest.java
index ed7f16b..e3affef 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuControllerTest.java
+++ b/tests/unit/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuControllerTest.java
@@ -18,30 +18,35 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.os.storage.VolumeInfo;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 
-import com.android.settings.R;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.settings.testutils.ResourcesUtils;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.shadows.ShadowApplication;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
 public class PrivateVolumeOptionMenuControllerTest {
 
     @Mock
@@ -57,11 +62,13 @@
     @Mock
     private VolumeInfo mPrimaryInfo;
 
+    private Context mContext;
     private PrivateVolumeOptionMenuController mController;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+        mContext = spy(ApplicationProvider.getApplicationContext());
 
         when(mVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
         when(mVolumeInfo.isMountedWritable()).thenReturn(true);
@@ -69,15 +76,15 @@
         when(mMenu.findItem(anyInt())).thenReturn(mMigrateMenuItem);
         when(mMigrateMenuItem.getItemId()).thenReturn(100);
 
-        mController = new PrivateVolumeOptionMenuController(
-                Robolectric.setupActivity(Activity.class), mPrimaryInfo, mPm);
+        mController = new PrivateVolumeOptionMenuController(mContext, mPrimaryInfo, mPm);
     }
 
     @Test
     public void testMigrateDataMenuItemIsAdded() {
         mController.onCreateOptionsMenu(mMenu, mMenuInflater);
 
-        verify(mMenu).add(Menu.NONE, 100, Menu.NONE, R.string.storage_menu_migrate);
+        verify(mMenu).add(Menu.NONE, 100, Menu.NONE, ResourcesUtils.getResourcesId(
+                mContext, "string", "storage_menu_migrate"));
     }
 
     @Test
@@ -115,14 +122,18 @@
     @Test
     public void testMigrateDataGoesToMigrateWizard() {
         when(mPm.getPrimaryStorageCurrentVolume()).thenReturn(mVolumeInfo);
+        doNothing().when(mContext).startActivity(any(Intent.class));
 
         mController.onCreateOptionsMenu(mMenu, mMenuInflater);
         mController.onPrepareOptionsMenu(mMenu);
 
         assertThat(mController.onOptionsItemSelected(mMigrateMenuItem)).isTrue();
-        ShadowApplication shadowApplication = ShadowApplication.getInstance();
-        assertThat(shadowApplication).isNotNull();
-        assertThat(shadowApplication.getNextStartedActivity().getComponent().getClassName())
+
+        final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(
+                Intent.class);
+        verify(mContext).startActivity(intentCaptor.capture());
+        final Intent startedIntent = intentCaptor.getValue();
+        assertThat(startedIntent.getComponent().getClassName())
                 .isEqualTo(StorageWizardMigrateConfirm.class.getName());
     }
 }
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceControllerTest.java b/tests/unit/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceControllerTest.java
similarity index 68%
rename from tests/robotests/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceControllerTest.java
rename to tests/unit/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceControllerTest.java
index 7e6be9b..d4157b8 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceControllerTest.java
@@ -18,9 +18,11 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
 import android.app.usage.StorageStatsManager;
@@ -31,9 +33,11 @@
 import android.util.FeatureFlagUtils;
 
 import androidx.preference.Preference;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 
-import com.android.settings.R;
 import com.android.settings.core.FeatureFlags;
+import com.android.settings.testutils.ResourcesUtils;
 import com.android.settingslib.deviceinfo.StorageManagerVolumeProvider;
 
 import org.junit.Before;
@@ -41,14 +45,14 @@
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.util.ReflectionHelpers;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
 public class TopLevelStoragePreferenceControllerTest {
 
     @Mock
@@ -62,12 +66,12 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
-        mContext = RuntimeEnvironment.application;
+        mContext = ApplicationProvider.getApplicationContext();
         mVolumes = new ArrayList<>();
         mVolumes.add(mock(VolumeInfo.class, RETURNS_DEEP_STUBS));
         when(mStorageManagerVolumeProvider.getVolumes()).thenReturn(mVolumes);
 
-        mController = new TopLevelStoragePreferenceController(mContext, "test_key");
+        mController = spy(new TopLevelStoragePreferenceController(mContext, "test_key"));
         FeatureFlagUtils.setEnabled(mContext, FeatureFlags.SILKY_HOME, false);
     }
 
@@ -82,16 +86,27 @@
         when(mStorageManagerVolumeProvider
                 .getFreeBytes(nullable(StorageStatsManager.class), nullable(VolumeInfo.class)))
                 .thenReturn(0L);
-        ReflectionHelpers.setField(mController,
-                "mStorageManagerVolumeProvider", mStorageManagerVolumeProvider);
+        when(mController.getStorageManagerVolumeProvider())
+                .thenReturn(mStorageManagerVolumeProvider);
         final String percentage = NumberFormat.getPercentInstance().format(1);
-        final String freeSpace = Formatter.formatFileSize(RuntimeEnvironment.application, 0);
+        final String freeSpace = Formatter.formatFileSize(mContext, 0);
         final Preference preference = new Preference(mContext);
 
-        mController.updateState(preference);
+        // Wait for asynchronous thread to finish, otherwise test will flake.
+        Future thread = mController.refreshSummaryThread(preference);
+        try {
+            thread.get();
+        } catch (ExecutionException | InterruptedException e) {
+            e.printStackTrace();
+            fail("Exception during automatic selection");
+        }
 
-        assertThat(preference.getSummary()).isEqualTo(
-                mContext.getString(R.string.storage_summary, percentage, freeSpace));
+
+        // Sleep for 5 seconds because a function is executed on the main thread from within
+        // the background thread.
+        TimeUnit.SECONDS.sleep(5);
+        assertThat(preference.getSummary()).isEqualTo(ResourcesUtils.getResourcesString(
+                mContext, "storage_summary", percentage, freeSpace));
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoPreferenceControllerTest.java b/tests/unit/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoPreferenceControllerTest.java
similarity index 70%
rename from tests/robotests/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoPreferenceControllerTest.java
rename to tests/unit/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoPreferenceControllerTest.java
index c7c7669..7262615 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoPreferenceControllerTest.java
@@ -17,41 +17,53 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
 import android.content.Context;
+import android.content.res.Resources;
 import android.os.Build;
+import android.os.Looper;
 
 import androidx.preference.Preference;
 import androidx.preference.PreferenceManager;
 import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.deviceinfo.HardwareInfoPreferenceController;
+import com.android.settings.testutils.ResourcesUtils;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
 public class HardwareInfoPreferenceControllerTest {
 
-    private final String KEY = "device_model";
+    private static final String KEY = "device_model";
 
     private Preference mPreference;
     private PreferenceScreen mPreferenceScreen;
     private Context mContext;
+    @Mock
+    private Resources mResources;
     private HardwareInfoPreferenceController mController;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
+        mContext = spy(ApplicationProvider.getApplicationContext());
+        when(mContext.getResources()).thenReturn(mResources);
         mController = new HardwareInfoPreferenceController(mContext, KEY);
         mPreference = new Preference(mContext);
         mPreference.setKey(KEY);
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
         final PreferenceManager preferenceManager = new PreferenceManager(mContext);
         mPreferenceScreen = preferenceManager.createPreferenceScreen(mContext);
         mPreferenceScreen.addPreference(mPreference);
@@ -59,13 +71,20 @@
 
     @Test
     public void isAvailable_returnTrueIfVisible() {
+        final int boolId = ResourcesUtils.getResourcesId(
+                ApplicationProvider.getApplicationContext(), "bool", "config_show_device_model");
+
+        when(mResources.getBoolean(boolId)).thenReturn(true);
         assertThat(mController.getAvailabilityStatus()).isEqualTo(
                 BasePreferenceController.AVAILABLE);
     }
 
     @Test
-    @Config(qualifiers = "mcc999")
     public void isAvailable_returnFalseIfNotVisible() {
+        final int boolId = ResourcesUtils.getResourcesId(
+                ApplicationProvider.getApplicationContext(), "bool", "config_show_device_model");
+
+        when(mResources.getBoolean(boolId)).thenReturn(false);
         assertThat(mController.getAvailabilityStatus()).isEqualTo(
                 BasePreferenceController.UNSUPPORTED_ON_DEVICE);
     }