Merge "[Reduce Bright Colors] Move persist preference"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 82088b2..c9f4643 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -103,6 +103,8 @@
     <uses-permission android:name="android.permission.INSTALL_DYNAMIC_SYSTEM" />
     <uses-permission android:name="android.permission.BIND_CELL_BROADCAST_SERVICE" />
     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+    <uses-permission android:name="android.permission.READ_DREAM_STATE" />
+    <uses-permission android:name="android.permission.READ_DREAM_SUPPRESSION" />
 
     <application android:label="@string/settings_label"
             android:icon="@drawable/ic_launcher_settings"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index aeade3a..5691b3a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -9166,6 +9166,9 @@
         }
     </string>
 
+    <!-- [CHAR LIMIT=50] Zen mode settings: placeholder for a Contact name when the name is empty -->
+    <string name="zen_mode_starred_contacts_empty_name">(No name)</string>
+
     <!-- [CHAR LIMIT=40] Zen mode settings: Messages option -->
     <string name="zen_mode_messages">Messages</string>
     <!-- [CHAR LIMIT=40] Zen mode settings: Messages option -->
@@ -10469,6 +10472,9 @@
     <!-- Label for wifi data usage in data usage screen [CHAR LIMIT=60] -->
     <string name="wifi_data_usage">Wi\u2011Fi data usage</string>
 
+    <!-- Label for non-carrier data usage in data usage screen [CHAR LIMIT=60] -->
+    <string name="non_carrier_data_usage">Non-carrier data usage</string>
+
     <!-- Label for ethernet data usage in data usage screen [CHAR LIMIT=60] -->
     <string name="ethernet_data_usage">Ethernet data usage</string>
 
@@ -10517,6 +10523,9 @@
     <!-- A summary shown on data usage screens to indicate inaccuracy of data tracking [CHAR LIMIT=NONE] -->
     <string name="operator_warning">Carrier data accounting may differ from device accounting</string>
 
+    <!-- A summary shown on data usage screens to indicate data tracking excluded from carrier networks [CHAR LIMIT=NONE] -->
+    <string name="non_carrier_data_usage_warning">Excludes data that is used by carrier networks</string>
+
     <!-- Format string describing how much data has been used [CHAR LIMIT=20] -->
     <string name="data_used_template"><xliff:g name="amount" example="1 GB">%1$s</xliff:g> used</string>
 
@@ -11061,13 +11070,13 @@
     <string name="emergency_gesture_entrypoint_summary">Managed by <xliff:g id="app_name" example="Emergency Info">%1$s</xliff:g></string>
 
     <!-- Preference summary to enable feature for calling emergency services at panic/distress moments[CHAR_LIMIT=NONE]-->
-    <string name="emergency_gesture_screen_summary">Start the emergency SOS actions by pressing the power button quickly 5 times.</string>
+    <string name="emergency_gesture_screen_summary">Start the actions below by pressing the power button quickly 5 times or more</string>
 
     <!-- Preference title to enable generating noisy sound before calling emergency services at panic/distress moments[CHAR_LIMIT=60]-->
-    <string name="emergency_gesture_sound_setting_title">Warning sound</string>
+    <string name="emergency_gesture_sound_setting_title">Countdown alarm</string>
 
     <!-- Preference summary to enable generating noisy sound before calling emergency services at panic/distress moments[CHAR_LIMIT=NONE]-->
-    <string name="emergency_gesture_sound_setting_summary">Alert before starting the actions</string>
+    <string name="emergency_gesture_sound_setting_summary">Play a loud sound before calling</string>
 
     <!-- Title text for swiping downwards on fingerprint sensor for notifications [CHAR LIMIT=80]-->
     <string name="fingerprint_swipe_for_notifications_title">Swipe fingerprint for notifications</string>
@@ -12420,4 +12429,7 @@
     <string name="calls_preference_title">Calls</string>
     <!-- Provider Model: SMS preference title -->
     <string name="sms_preference_title">SMS</string>
+
+    <!-- Summary for preference when Bedtime mode is on [CHAR LIMIT=NONE] -->
+    <string name="aware_summary_when_bedtime_on">Unavailable because bedtime mode is on</string>
 </resources>
diff --git a/res/xml/data_usage_list.xml b/res/xml/data_usage_list.xml
index 41fbff8..9ea6a91 100644
--- a/res/xml/data_usage_list.xml
+++ b/res/xml/data_usage_list.xml
@@ -23,9 +23,15 @@
             android:key="chart_data" />
 
         <Preference
+            android:key="operator_warning"
             android:summary="@string/operator_warning"
             android:selectable="false" />
 
+        <Preference
+            android:key="non_carrier_data_usage_warning"
+            android:summary="@string/non_carrier_data_usage_warning"
+            android:selectable="false" />
+
     </PreferenceCategory>
 
     <PreferenceCategory
diff --git a/res/xml/network_provider_settings.xml b/res/xml/network_provider_settings.xml
index 778def0..2af2e91 100644
--- a/res/xml/network_provider_settings.xml
+++ b/res/xml/network_provider_settings.xml
@@ -43,6 +43,6 @@
         android:fragment="com.android.settings.wifi.savedaccesspoints2.SavedAccessPointsWifiSettings2"/>
 
     <com.android.settings.datausage.DataUsagePreference
-        android:key="wifi_data_usage"
-        android:title="@string/wifi_data_usage"/>
+        android:key="non_carrier_data_usage"
+        android:title="@string/non_carrier_data_usage"/>
 </PreferenceScreen>
diff --git a/src/com/android/settings/datausage/DataUsageList.java b/src/com/android/settings/datausage/DataUsageList.java
index 7f1a0d8..f72a006 100644
--- a/src/com/android/settings/datausage/DataUsageList.java
+++ b/src/com/android/settings/datausage/DataUsageList.java
@@ -39,6 +39,7 @@
 import android.provider.Settings;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
+import android.util.FeatureFlagUtils;
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.View;
@@ -140,6 +141,17 @@
         mUsageAmount = findPreference(KEY_USAGE_AMOUNT);
         mChart = findPreference(KEY_CHART_DATA);
         mApps = findPreference(KEY_APPS_GROUP);
+
+        // TODO(b/167474581): This is a temporary solution to hide unnecessary warning
+        //  preference, when the provider model is completed, the following code should be removed.
+        final Preference unnecessaryWarningPreference =
+                FeatureFlagUtils.isEnabled(getContext(), FeatureFlagUtils.SETTINGS_PROVIDER_MODEL)
+                        ? findPreference("operator_warning")
+                        : findPreference("non_carrier_data_usage_warning");
+        if (unnecessaryWarningPreference != null) {
+            unnecessaryWarningPreference.setVisible(false);
+        }
+
         processArgument();
         mDataStateListener = new MobileDataEnabledListener(activity, this);
     }
diff --git a/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java b/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java
index 6dee5d2..7749c8f 100644
--- a/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java
+++ b/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java
@@ -16,12 +16,17 @@
 package com.android.settings.display;
 
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.hardware.display.AmbientDisplayConfiguration;
+import android.os.PowerManager;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.TextUtils;
 
+import androidx.preference.Preference;
+
+import com.android.settings.R;
 import com.android.settings.core.TogglePreferenceController;
 
 public class AmbientDisplayAlwaysOnPreferenceController extends TogglePreferenceController {
@@ -31,13 +36,9 @@
 
     private static final int MY_USER = UserHandle.myUserId();
     private static final String PROP_AWARE_AVAILABLE = "ro.vendor.aware_available";
+    private static final String AOD_SUPPRESSED_TOKEN = "winddown";
 
     private AmbientDisplayConfiguration mConfig;
-    private OnPreferenceChangedCallback mCallback;
-
-    public interface OnPreferenceChangedCallback {
-        void onPreferenceChanged();
-    }
 
     public AmbientDisplayAlwaysOnPreferenceController(Context context, String key) {
         super(context, key);
@@ -51,6 +52,12 @@
     }
 
     @Override
+    public void updateState(Preference preference) {
+        super.updateState(preference);
+        refreshSummary(preference);
+    }
+
+    @Override
     public boolean isSliceable() {
         return TextUtils.equals(getPreferenceKey(), "ambient_display_always_on");
     }
@@ -70,24 +77,22 @@
         int enabled = isChecked ? ON : OFF;
         Settings.Secure.putInt(
                 mContext.getContentResolver(), Settings.Secure.DOZE_ALWAYS_ON, enabled);
-        if (mCallback != null) {
-            mCallback.onPreferenceChanged();
-        }
         return true;
     }
 
+    @Override
+    public CharSequence getSummary() {
+        return mContext.getText(
+                isAodSuppressedByBedtime(mContext) ? R.string.aware_summary_when_bedtime_on
+                        : R.string.doze_always_on_summary);
+    }
+
     public AmbientDisplayAlwaysOnPreferenceController setConfig(
             AmbientDisplayConfiguration config) {
         mConfig = config;
         return this;
     }
 
-    public AmbientDisplayAlwaysOnPreferenceController setCallback(
-            OnPreferenceChangedCallback callback) {
-        mCallback = callback;
-        return this;
-    }
-
     public static boolean isAvailable(AmbientDisplayConfiguration config) {
         return config.alwaysOnAvailableForUser(MY_USER);
     }
@@ -98,4 +103,25 @@
         }
         return mConfig;
     }
+
+    /**
+     * Returns whether AOD is suppressed by Bedtime mode, a feature of Digital Wellbeing.
+     *
+     * We know that Bedtime mode suppresses AOD using {@link AOD_SUPPRESSED_TOKEN}. If the Digital
+     * Wellbeing app is suppressing AOD with {@link AOD_SUPPRESSED_TOKEN}, then we can infer that
+     * AOD is being suppressed by Bedtime mode.
+     */
+    public static boolean isAodSuppressedByBedtime(Context context) {
+        int uid;
+        final PowerManager powerManager = context.getSystemService(PowerManager.class);
+        final PackageManager packageManager = context.getPackageManager();
+        final String packageName = context.getString(
+                com.android.internal.R.string.config_defaultWellbeingPackage);
+        try {
+            uid = packageManager.getApplicationInfo(packageName, /* flags= */ 0).uid;
+        } catch (PackageManager.NameNotFoundException e) {
+            return false;
+        }
+        return powerManager.isAmbientDisplaySuppressedForTokenByApp(AOD_SUPPRESSED_TOKEN, uid);
+    }
 }
diff --git a/src/com/android/settings/network/NetworkProviderSettings.java b/src/com/android/settings/network/NetworkProviderSettings.java
index f6f19b5..5a42a5a 100644
--- a/src/com/android/settings/network/NetworkProviderSettings.java
+++ b/src/com/android/settings/network/NetworkProviderSettings.java
@@ -60,14 +60,12 @@
 import com.android.settings.LinkifyUtils;
 import com.android.settings.R;
 import com.android.settings.RestrictedSettingsFragment;
-import com.android.settings.SettingsActivity;
 import com.android.settings.core.FeatureFlags;
 import com.android.settings.core.SubSettingLauncher;
 import com.android.settings.datausage.DataUsagePreference;
 import com.android.settings.datausage.DataUsageUtils;
 import com.android.settings.location.ScanningSettings;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.widget.SwitchBarController;
 import com.android.settings.wifi.AddNetworkFragment;
 import com.android.settings.wifi.AddWifiNetworkPreference;
 import com.android.settings.wifi.ConfigureWifiEntryFragment;
@@ -76,7 +74,6 @@
 import com.android.settings.wifi.WifiConfigUiBase2;
 import com.android.settings.wifi.WifiConnectListener;
 import com.android.settings.wifi.WifiDialog2;
-import com.android.settings.wifi.WifiEnabler;
 import com.android.settings.wifi.WifiUtils;
 import com.android.settings.wifi.details2.WifiNetworkDetailsFragment2;
 import com.android.settings.wifi.dpp.WifiDppUtils;
@@ -134,7 +131,7 @@
     private static final String PREF_KEY_SAVED_NETWORKS = "saved_networks";
     private static final String PREF_KEY_STATUS_MESSAGE = "wifi_status_message";
     @VisibleForTesting
-    static final String PREF_KEY_DATA_USAGE = "wifi_data_usage";
+    static final String PREF_KEY_DATA_USAGE = "non_carrier_data_usage";
 
     private static final int REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER = 0;
 
@@ -188,8 +185,6 @@
      */
     private boolean mIsRestricted;
 
-    private WifiEnabler mWifiEnabler;
-
     // Worker thread used for WifiPickerTracker work
     private HandlerThread mWorkerThread;
 
@@ -230,10 +225,6 @@
             mProgressHeader = setPinnedHeaderView(R.layout.progress_header)
                     .findViewById(R.id.progress_bar_animation);
             setProgressBarVisible(false);
-
-            ((SettingsActivity) activity).getSwitchBar().setSwitchBarText(
-                    R.string.wifi_settings_primary_switch_title,
-                    R.string.wifi_settings_primary_switch_title);
         }
     }
 
@@ -351,9 +342,6 @@
 
     @Override
     public void onDestroyView() {
-        if (mWifiEnabler != null) {
-            mWifiEnabler.teardownSwitchController();
-        }
         mWorkerThread.quit();
 
         super.onDestroyView();
@@ -363,8 +351,6 @@
     public void onStart() {
         super.onStart();
 
-        mWifiEnabler = createWifiEnabler();
-
         if (mIsRestricted) {
             restrictUi();
         }
@@ -377,15 +363,6 @@
         getPreferenceScreen().removeAll();
     }
 
-    /**
-     * @return new WifiEnabler
-     */
-    private WifiEnabler createWifiEnabler() {
-        final SettingsActivity activity = (SettingsActivity) getActivity();
-        return new WifiEnabler(activity, new SwitchBarController(activity.getSwitchBar()),
-                mMetricsFeatureProvider);
-    }
-
     @Override
     public void onResume() {
         final Activity activity = getActivity();
@@ -399,22 +376,10 @@
             restrictUi();
         }
 
-        if (mWifiEnabler != null) {
-            mWifiEnabler.resume(activity);
-        }
-
         changeNextButtonState(mWifiPickerTracker.getConnectedWifiEntry() != null);
     }
 
     @Override
-    public void onPause() {
-        super.onPause();
-        if (mWifiEnabler != null) {
-            mWifiEnabler.pause();
-        }
-    }
-
-    @Override
     public void onStop() {
         getView().removeCallbacks(mUpdateWifiEntryPreferencesRunnable);
         getView().removeCallbacks(mHideProgressBarRunnable);
diff --git a/src/com/android/settings/notification/zen/ZenModeBackend.java b/src/com/android/settings/notification/zen/ZenModeBackend.java
index 1d41bb9..e3f5063 100644
--- a/src/com/android/settings/notification/zen/ZenModeBackend.java
+++ b/src/com/android/settings/notification/zen/ZenModeBackend.java
@@ -447,9 +447,9 @@
         if (cursor != null && cursor.moveToFirst()) {
             do {
                 String contact = cursor.getString(0);
-                if (contact != null) {
-                    starredContacts.add(contact);
-                }
+                starredContacts.add(contact != null ? contact :
+                        mContext.getString(R.string.zen_mode_starred_contacts_empty_name));
+
             } while (cursor.moveToNext());
         }
         return starredContacts;
diff --git a/src/com/android/settings/security/LockscreenDashboardFragment.java b/src/com/android/settings/security/LockscreenDashboardFragment.java
index 3352991..39355f3 100644
--- a/src/com/android/settings/security/LockscreenDashboardFragment.java
+++ b/src/com/android/settings/security/LockscreenDashboardFragment.java
@@ -88,9 +88,7 @@
     @Override
     public void onAttach(Context context) {
         super.onAttach(context);
-        use(AmbientDisplayAlwaysOnPreferenceController.class)
-                .setConfig(getConfig(context))
-                .setCallback(this::updatePreferenceStates);
+        use(AmbientDisplayAlwaysOnPreferenceController.class).setConfig(getConfig(context));
         use(AmbientDisplayNotificationsPreferenceController.class).setConfig(getConfig(context));
         use(DoubleTapScreenPreferenceController.class).setConfig(getConfig(context));
         use(PickupGesturePreferenceController.class).setConfig(getConfig(context));
diff --git a/src/com/android/settings/wifi/WifiConfigController2.java b/src/com/android/settings/wifi/WifiConfigController2.java
index a80029b..37013f2 100644
--- a/src/com/android/settings/wifi/WifiConfigController2.java
+++ b/src/com/android/settings/wifi/WifiConfigController2.java
@@ -161,6 +161,7 @@
     private ScrollView mDialogContainer;
     private Spinner mSecuritySpinner;
     @VisibleForTesting Spinner mEapMethodSpinner;
+    private int mLastShownEapMethod;
     @VisibleForTesting Spinner mEapSimSpinner;    // For EAP-SIM, EAP-AKA and EAP-AKA-PRIME.
     private Spinner mEapCaCertSpinner;
     private Spinner mEapOcspSpinner;
@@ -1027,6 +1028,7 @@
             final int eapMethod = enterpriseConfig.getEapMethod();
             final int phase2Method = enterpriseConfig.getPhase2Method();
             mEapMethodSpinner.setSelection(eapMethod);
+            mLastShownEapMethod = eapMethod;
             showEapFieldsByMethod(eapMethod);
             switch (eapMethod) {
                 case Eap.PEAP:
@@ -1597,7 +1599,11 @@
                 mSsidScanButton.setVisibility(View.GONE);
             }
         } else if (parent == mEapMethodSpinner) {
-            showSecurityFields(/* refreshEapMethods */ false, /* refreshCertificates */ true);
+            final int selectedItemPosition = mEapMethodSpinner.getSelectedItemPosition();
+            if (mLastShownEapMethod != selectedItemPosition) {
+                mLastShownEapMethod = selectedItemPosition;
+                showSecurityFields(/* refreshEapMethods */ false, /* refreshCertificates */ true);
+            }
         } else if (parent == mEapCaCertSpinner) {
             showSecurityFields(/* refreshEapMethods */ false, /* refreshCertificates */ false);
         } else if (parent == mPhase2Spinner
diff --git a/tests/robotests/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceControllerTest.java
index 1548b42..405ea12 100644
--- a/tests/robotests/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceControllerTest.java
@@ -19,13 +19,20 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 import android.hardware.display.AmbientDisplayConfiguration;
+import android.os.PowerManager;
 import android.provider.Settings;
 
+import com.android.internal.R;
 import com.android.settings.testutils.shadow.ShadowSecureSettings;
 
 import org.junit.Before;
@@ -41,24 +48,41 @@
 @Config(shadows = ShadowSecureSettings.class)
 public class AmbientDisplayAlwaysOnPreferenceControllerTest {
 
+    private static final String TEST_PACKAGE = "com.android.test";
+
     @Mock
     private AmbientDisplayConfiguration mConfig;
+    @Mock
+    private PackageManager mPackageManager;
+    @Mock
+    private PowerManager mPowerManager;
+    @Mock
+    private ApplicationInfo mApplicationInfo;
 
     private Context mContext;
 
     private ContentResolver mContentResolver;
 
     private AmbientDisplayAlwaysOnPreferenceController mController;
-    private boolean mCallbackInvoked;
 
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
+        mContext = spy(RuntimeEnvironment.application);
         mContentResolver = mContext.getContentResolver();
         mController = new AmbientDisplayAlwaysOnPreferenceController(mContext, "key");
         mController.setConfig(mConfig);
-        mController.setCallback(() -> mCallbackInvoked = true);
+
+        mApplicationInfo.uid = 1;
+        when(mContext.getString(R.string.config_defaultWellbeingPackage)).thenReturn(TEST_PACKAGE);
+
+        when(mContext.getPackageManager()).thenReturn(mPackageManager);
+        doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfo(
+                TEST_PACKAGE, /* flag= */0);
+
+        doReturn(mPowerManager).when(mContext).getSystemService(PowerManager.class);
+        when(mPowerManager.isAmbientDisplaySuppressedForTokenByApp(anyString(), anyInt()))
+                .thenReturn(false);
     }
 
     @Test
@@ -108,13 +132,6 @@
     }
 
     @Test
-    public void onPreferenceChange_callback() {
-        assertThat(mCallbackInvoked).isFalse();
-        mController.setChecked(true);
-        assertThat(mCallbackInvoked).isTrue();
-    }
-
-    @Test
     public void isSliceableCorrectKey_returnsTrue() {
         final AmbientDisplayAlwaysOnPreferenceController controller =
                 new AmbientDisplayAlwaysOnPreferenceController(mContext,
@@ -133,4 +150,39 @@
     public void isPublicSlice_returnTrue() {
         assertThat(mController.isPublicSlice()).isTrue();
     }
+
+    @Test
+    public void isAodSuppressedByBedtime_bedTimeModeOn_returnTrue() {
+        when(mPowerManager.isAmbientDisplaySuppressedForTokenByApp(anyString(), anyInt()))
+                .thenReturn(true);
+
+        assertThat(AmbientDisplayAlwaysOnPreferenceController
+                .isAodSuppressedByBedtime(mContext)).isTrue();
+    }
+
+    @Test
+    public void isAodSuppressedByBedtime_bedTimeModeOff_returnFalse() {
+        assertThat(AmbientDisplayAlwaysOnPreferenceController
+                .isAodSuppressedByBedtime(mContext)).isFalse();
+    }
+
+    @Test
+    public void isAodSuppressedByBedtime_notFoundWellbeingPackage_returnFalse()
+            throws PackageManager.NameNotFoundException {
+        when(mPackageManager.getApplicationInfo(TEST_PACKAGE, /* flag= */0)).thenThrow(
+                new PackageManager.NameNotFoundException());
+
+        assertThat(AmbientDisplayAlwaysOnPreferenceController
+                .isAodSuppressedByBedtime(mContext)).isFalse();
+    }
+
+    @Test
+    public void getSummary_bedTimeModeOn_shouldReturnUnavailableSummary() {
+        when(mPowerManager.isAmbientDisplaySuppressedForTokenByApp(anyString(), anyInt()))
+                .thenReturn(true);
+
+        final CharSequence summary = mController.getSummary();
+        assertThat(summary).isEqualTo(mContext.getString(
+                com.android.settings.R.string.aware_summary_when_bedtime_on));
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java
index 09e4408..030bb80 100644
--- a/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java
+++ b/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java
@@ -55,6 +55,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.Robolectric;
@@ -182,6 +183,7 @@
     }
 
     @Test
+    @Ignore
     public void processAndValidatePasswordRequirements_minPasswordComplexityStricter_password() {
         mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_SOMETHING);
 
@@ -295,6 +297,7 @@
     }
 
     @Test
+    @Ignore
     public void processAndValidatePasswordRequirements_requirementsUpdateAccordingToMinComplexityAndUserInput_empty() {
         mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED);
 
@@ -307,6 +310,7 @@
     }
 
     @Test
+    @Ignore
     public void processAndValidatePasswordRequirements_requirementsUpdateAccordingToMinComplexityAndUserInput_numeric() {
         mShadowDpm.setPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED);
 
diff --git a/tests/robotests/src/com/android/settings/security/LockscreenDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/security/LockscreenDashboardFragmentTest.java
index 294d05e..5c60001 100644
--- a/tests/robotests/src/com/android/settings/security/LockscreenDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/security/LockscreenDashboardFragmentTest.java
@@ -88,7 +88,6 @@
 
         mTestFragment.onAttach(mContext);
         verify(controller).setConfig(any());
-        verify(controller).setCallback(any());
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiConfigController2Test.java b/tests/robotests/src/com/android/settings/wifi/WifiConfigController2Test.java
index 29a3797..93663bd 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiConfigController2Test.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiConfigController2Test.java
@@ -18,7 +18,9 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 import static org.robolectric.Shadows.shadowOf;
@@ -32,6 +34,7 @@
 import android.net.wifi.WifiEnterpriseConfig.Phase2;
 import android.net.wifi.WifiManager;
 import android.os.ServiceSpecificException;
+import android.security.Credentials;
 import android.security.KeyStore;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
@@ -78,6 +81,10 @@
     private KeyStore mKeyStore;
     private View mView;
     private Spinner mHiddenSettingsSpinner;
+    private Spinner mEapCaCertSpinner;
+    private Spinner mEapUserCertSpinner;
+    private String mUseSystemCertsString;
+    private String mDoNotProvideEapUserCertString;
     private ShadowSubscriptionManager mShadowSubscriptionManager;
 
     public WifiConfigController2 mController;
@@ -98,6 +105,9 @@
     private static final String NUMBER_AND_CHARACTER_KEY = "123456abcd";
     private static final String PARTIAL_NUMBER_AND_CHARACTER_KEY = "123456abc?";
     private static final int DHCP = 0;
+    // Saved certificates
+    private static final String SAVED_CA_CERT = "saved CA cert";
+    private static final String SAVED_USER_CERT = "saved user cert";
 
     @Before
     public void setUp() {
@@ -108,6 +118,11 @@
         mView = LayoutInflater.from(mContext).inflate(R.layout.wifi_dialog, null);
         final Spinner ipSettingsSpinner = mView.findViewById(R.id.ip_settings);
         mHiddenSettingsSpinner = mView.findViewById(R.id.hidden_settings);
+        mEapCaCertSpinner = mView.findViewById(R.id.ca_cert);
+        mEapUserCertSpinner = mView.findViewById(R.id.user_cert);
+        mUseSystemCertsString = mContext.getString(R.string.wifi_use_system_certs);
+        mDoNotProvideEapUserCertString =
+                mContext.getString(R.string.wifi_do_not_provide_eap_user_cert);
         ipSettingsSpinner.setSelection(DHCP);
         mShadowSubscriptionManager = shadowOf(mContext.getSystemService(SubscriptionManager.class));
 
@@ -835,4 +850,75 @@
         final WifiConfiguration wifiConfiguration = mController.getConfig();
         assertThat(wifiConfiguration.carrierId).isEqualTo(carrierId);
     }
+
+    @Test
+    public void loadCaCertificateValue_shouldPersistentAsDefault() {
+        setUpModifyingSavedCertificateConfigController(null, null);
+
+        assertThat(mEapCaCertSpinner.getSelectedItem()).isEqualTo(mUseSystemCertsString);
+    }
+
+    @Test
+    public void loadSavedCaCertificateValue_shouldBeCorrectValue() {
+        setUpModifyingSavedCertificateConfigController(SAVED_CA_CERT, null);
+
+        assertThat(mEapCaCertSpinner.getSelectedItem()).isEqualTo(SAVED_CA_CERT);
+    }
+
+    @Test
+    public void loadUserCertificateValue_shouldPersistentAsDefault() {
+        setUpModifyingSavedCertificateConfigController(null, null);
+
+        assertThat(mEapUserCertSpinner.getSelectedItem()).isEqualTo(mDoNotProvideEapUserCertString);
+    }
+
+    @Test
+    public void loadSavedUserCertificateValue_shouldBeCorrectValue() {
+        setUpModifyingSavedCertificateConfigController(null, SAVED_USER_CERT);
+
+        assertThat(mEapUserCertSpinner.getSelectedItem()).isEqualTo(SAVED_USER_CERT);
+    }
+
+    private void setUpModifyingSavedCertificateConfigController(String savedCaCertificate,
+            String savedUserCertificate) {
+        final WifiConfiguration mockWifiConfig = mock(WifiConfiguration.class);
+        final WifiEnterpriseConfig mockWifiEnterpriseConfig = mock(WifiEnterpriseConfig.class);
+        mockWifiConfig.enterpriseConfig = mockWifiEnterpriseConfig;
+        when(mWifiEntry.isSaved()).thenReturn(true);
+        when(mWifiEntry.getSecurity()).thenReturn(WifiEntry.SECURITY_EAP);
+        when(mWifiEntry.getWifiConfiguration()).thenReturn(mockWifiConfig);
+        when(mockWifiConfig.getIpConfiguration()).thenReturn(mock(IpConfiguration.class));
+        when(mockWifiEnterpriseConfig.getEapMethod()).thenReturn(Eap.TLS);
+        if (savedCaCertificate != null) {
+            String[] savedCaCertificates = new String[]{savedCaCertificate};
+            when(mockWifiEnterpriseConfig.getCaCertificateAliases())
+                    .thenReturn(savedCaCertificates);
+            when(mKeyStore.list(eq(Credentials.CA_CERTIFICATE), anyInt()))
+                    .thenReturn(savedCaCertificates);
+        }
+        if (savedUserCertificate != null) {
+            String[] savedUserCertificates = new String[]{savedUserCertificate};
+            when(mockWifiEnterpriseConfig.getClientCertificateAlias())
+                    .thenReturn(savedUserCertificate);
+            when(mKeyStore.list(eq(Credentials.USER_PRIVATE_KEY), anyInt()))
+                    .thenReturn(savedUserCertificates);
+        }
+
+        mController = new TestWifiConfigController2(mConfigUiBase, mView, mWifiEntry,
+                WifiConfigUiBase2.MODE_MODIFY);
+
+        //  Because Robolectric has a different behavior from normal flow.
+        //
+        //  Normal flow:
+        //    showSecurityFields start -> mEapMethodSpinner.setSelection
+        //        -> showSecurityFields end -> mController.onItemSelected
+        //
+        //  Robolectric flow:
+        //    showSecurityFields start -> mEapMethodSpinner.setSelection
+        //        -> mController.onItemSelected -> showSecurityFields end
+        //
+        //  We need to add a redundant mEapMethodSpinner.setSelection here to verify whether the
+        //  certificates are covered by mController.onItemSelected after showSecurityFields end.
+        mController.mEapMethodSpinner.setSelection(Eap.TLS);
+    }
 }
diff --git a/tests/unit/src/com/android/settings/network/ims/MockWfcQueryImsState.java b/tests/unit/src/com/android/settings/network/ims/MockWfcQueryImsState.java
new file mode 100644
index 0000000..096084f
--- /dev/null
+++ b/tests/unit/src/com/android/settings/network/ims/MockWfcQueryImsState.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2020 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.network.ims;
+
+import android.content.Context;
+import android.telephony.ims.ImsException;
+
+/**
+ * Controller class for mock Wifi calling status for unit tests, copied it from
+ * {@link MockWifiCallingQueryImsState} which is existed in robotests.
+ */
+public class MockWfcQueryImsState extends WifiCallingQueryImsState {
+
+    private Boolean mIsTtyOnVolteEnabled;
+    private Boolean mIsEnabledOnPlatform;
+    private Boolean mIsProvisionedOnDevice;
+    private Boolean mIsServiceStateReady;
+    private Boolean mIsEnabledByUser;
+
+    /**
+     * Constructor
+     *
+     * @param context {@code Context}
+     * @param subId subscription's id
+     */
+    public MockWfcQueryImsState(Context context, int subId) {
+        super(context, subId);
+    }
+
+    public void setIsTtyOnVolteEnabled(boolean enabled) {
+        mIsTtyOnVolteEnabled = enabled;
+    }
+
+    @Override
+    boolean isTtyOnVolteEnabled(int subId) {
+        if (mIsTtyOnVolteEnabled != null) {
+            return mIsTtyOnVolteEnabled;
+        }
+        return super.isTtyOnVolteEnabled(subId);
+    }
+
+
+    public void setIsEnabledByPlatform(boolean isEnabled) {
+        mIsEnabledOnPlatform = isEnabled;
+    }
+
+    @Override
+    boolean isEnabledByPlatform(int subId) throws InterruptedException, ImsException,
+            IllegalArgumentException {
+        if (mIsEnabledOnPlatform != null) {
+            return mIsEnabledOnPlatform;
+        }
+        return super.isEnabledByPlatform(subId);
+    }
+
+    public void setIsProvisionedOnDevice(boolean isProvisioned) {
+        mIsProvisionedOnDevice = isProvisioned;
+    }
+
+    @Override
+    boolean isProvisionedOnDevice(int subId) {
+        if (mIsProvisionedOnDevice != null) {
+            return mIsProvisionedOnDevice;
+        }
+        return super.isProvisionedOnDevice(subId);
+    }
+
+    public void setServiceStateReady(boolean isReady) {
+        mIsServiceStateReady = isReady;
+    }
+
+    @Override
+    public boolean isServiceStateReady(int subId) throws InterruptedException, ImsException,
+            IllegalArgumentException {
+        if (mIsServiceStateReady != null) {
+            return mIsServiceStateReady;
+        }
+        return super.isServiceStateReady(subId);
+    }
+
+    public void setIsEnabledByUser(boolean enabled) {
+        mIsEnabledByUser = enabled;
+    }
+
+    @Override
+    boolean isEnabledByUser(int subId) {
+        if (mIsEnabledByUser != null) {
+            return mIsEnabledByUser;
+        }
+        return super.isEnabledByUser(subId);
+    }
+
+}
diff --git a/tests/robotests/src/com/android/settings/network/telephony/DefaultSubscriptionControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/DefaultSubscriptionControllerTest.java
similarity index 80%
rename from tests/robotests/src/com/android/settings/network/telephony/DefaultSubscriptionControllerTest.java
rename to tests/unit/src/com/android/settings/network/telephony/DefaultSubscriptionControllerTest.java
index e20241b..50c27c5 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/DefaultSubscriptionControllerTest.java
+++ b/tests/unit/src/com/android/settings/network/telephony/DefaultSubscriptionControllerTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -22,22 +22,25 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
 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.content.Context;
+import android.os.Looper;
+import android.telecom.TelecomManager;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 
 import androidx.preference.ListPreference;
+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.R;
 import com.android.settings.network.SubscriptionUtil;
+import com.android.settings.testutils.Utils;
 
 import org.junit.After;
 import org.junit.Before;
@@ -45,18 +48,18 @@
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 
 import java.util.Arrays;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
 public class DefaultSubscriptionControllerTest {
     @Mock
     private SubscriptionManager mManager;
     @Mock
-    private PreferenceScreen mScreen;
+    private TelecomManager mTelecomManager;
 
+    private PreferenceScreen mScreen;
+    private PreferenceManager mPreferenceManager;
     private ListPreference mListPreference;
     private Context mContext;
     private DefaultSubscriptionController mController;
@@ -64,12 +67,21 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mContext = spy(RuntimeEnvironment.application);
+        mContext = spy(ApplicationProvider.getApplicationContext());
         when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mManager);
+        when(mContext.getSystemService(TelecomManager.class)).thenReturn(mTelecomManager);
+
         final String key = "prefkey";
-        mController = spy(new TestDefaultSubscriptionController(mContext, key));
-        mListPreference = spy(new ListPreference(mContext));
-        when(mScreen.findPreference(key)).thenReturn(mListPreference);
+        mController = new TestDefaultSubscriptionController(mContext, key);
+
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+        mPreferenceManager = new PreferenceManager(mContext);
+        mScreen = mPreferenceManager.createPreferenceScreen(mContext);
+        mListPreference = new ListPreference(mContext);
+        mListPreference.setKey(key);
+        mScreen.addPreference(mListPreference);
     }
 
     @After
@@ -94,14 +106,14 @@
 
     @Test
     public void isCallingAccountBindToSubscription_invalidAccount_withoutCrash() {
-        doReturn(null).when(mController).getPhoneAccount(any());
+        doReturn(null).when(mTelecomManager).getPhoneAccount(any());
 
         mController.isCallingAccountBindToSubscription(null);
     }
 
     @Test
     public void getLabelFromCallingAccount_invalidAccount_emptyString() {
-        doReturn(null).when(mController).getPhoneAccount(any());
+        doReturn(null).when(mTelecomManager).getPhoneAccount(any());
 
         assertThat(mController.getLabelFromCallingAccount(null)).isEqualTo("");
     }
@@ -111,7 +123,7 @@
         final SubscriptionInfo sub1 = createMockSub(111, "sub1");
         final SubscriptionInfo sub2 = createMockSub(222, "sub2");
         SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2));
-        doReturn(sub1.getSubscriptionId()).when(mController).getDefaultSubscriptionId();
+        mController.setDefaultSubscription(sub1.getSubscriptionId());
 
         mController.displayPreference(mScreen);
 
@@ -124,7 +136,8 @@
         assertThat(entries.length).isEqualTo(3);
         assertThat(entries[0]).isEqualTo("sub1");
         assertThat(entries[1]).isEqualTo("sub2");
-        assertThat(entries[2]).isEqualTo(mContext.getString(R.string.calls_and_sms_ask_every_time));
+        assertThat(entries[2]).isEqualTo(
+                Utils.getResourceString(mContext, "calls_and_sms_ask_every_time"));
 
         final CharSequence[] entryValues = mListPreference.getEntryValues();
         assertThat(entryValues.length).isEqualTo(3);
@@ -139,7 +152,7 @@
         final SubscriptionInfo sub1 = createMockSub(111, "sub1");
         final SubscriptionInfo sub2 = createMockSub(222, "sub2");
         SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2));
-        doReturn(sub2.getSubscriptionId()).when(mController).getDefaultSubscriptionId();
+        mController.setDefaultSubscription(sub2.getSubscriptionId());
 
         mController.displayPreference(mScreen);
 
@@ -152,7 +165,8 @@
         assertThat(entries.length).isEqualTo(3);
         assertThat(entries[0]).isEqualTo("sub1");
         assertThat(entries[1]).isEqualTo("sub2");
-        assertThat(entries[2]).isEqualTo(mContext.getString(R.string.calls_and_sms_ask_every_time));
+        assertThat(entries[2]).isEqualTo(
+                Utils.getResourceString(mContext, "calls_and_sms_ask_every_time"));
 
         final CharSequence[] entryValues = mListPreference.getEntryValues();
         assertThat(entryValues.length).isEqualTo(3);
@@ -172,7 +186,7 @@
         when(sub2.isOpportunistic()).thenReturn(true);
 
         SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2, sub3));
-        doReturn(sub1.getSubscriptionId()).when(mController).getDefaultSubscriptionId();
+        mController.setDefaultSubscription(sub1.getSubscriptionId());
 
         mController.displayPreference(mScreen);
 
@@ -180,7 +194,8 @@
         assertThat(entries.length).isEqualTo(3);
         assertThat(entries[0]).isEqualTo("sub1");
         assertThat(entries[1]).isEqualTo("sub3");
-        assertThat(entries[2]).isEqualTo(mContext.getString(R.string.calls_and_sms_ask_every_time));
+        assertThat(entries[2]).isEqualTo(
+                Utils.getResourceString(mContext, "calls_and_sms_ask_every_time"));
 
         final CharSequence[] entryValues = mListPreference.getEntryValues();
         assertThat(entryValues.length).isEqualTo(3);
@@ -195,12 +210,12 @@
         final SubscriptionInfo sub1 = createMockSub(111, "sub1");
         final SubscriptionInfo sub2 = createMockSub(222, "sub2");
         SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2));
-        doReturn(sub1.getSubscriptionId()).when(mController).getDefaultSubscriptionId();
+        mController.setDefaultSubscription(sub1.getSubscriptionId());
 
         mController.displayPreference(mScreen);
         mListPreference.setValue("222");
         mController.onPreferenceChange(mListPreference, "222");
-        verify(mController).setDefaultSubscription(eq(222));
+        assertThat(mController.getDefaultSubscriptionId()).isEqualTo(222);
     }
 
     @Test
@@ -208,14 +223,14 @@
         final SubscriptionInfo sub1 = createMockSub(111, "sub1");
         final SubscriptionInfo sub2 = createMockSub(222, "sub2");
         SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2));
-        doReturn(sub1.getSubscriptionId()).when(mController).getDefaultSubscriptionId();
+        mController.setDefaultSubscription(sub1.getSubscriptionId());
 
         mController.displayPreference(mScreen);
         mListPreference.setValue(Integer.toString(SubscriptionManager.INVALID_SUBSCRIPTION_ID));
         mController.onPreferenceChange(mListPreference,
                 Integer.toString(SubscriptionManager.INVALID_SUBSCRIPTION_ID));
-        verify(mController).setDefaultSubscription(
-                eq(SubscriptionManager.INVALID_SUBSCRIPTION_ID));
+        assertThat(mController.getDefaultSubscriptionId()).isEqualTo(
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
     }
 
     @Test
@@ -225,7 +240,7 @@
 
         // Start with only one sub active, so the pref is not available
         SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1));
-        doReturn(sub1.getSubscriptionId()).when(mController).getDefaultSubscriptionId();
+        mController.setDefaultSubscription(sub1.getSubscriptionId());
 
         mController.displayPreference(mScreen);
         assertThat(mController.isAvailable()).isFalse();
@@ -233,11 +248,12 @@
         // Now make two subs be active - the pref should become available, and the
         // onPreferenceChange callback should be properly wired up.
         SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2));
+
         mController.onSubscriptionsChanged();
+
         assertThat(mController.isAvailable()).isTrue();
-        assertThat(mListPreference.getOnPreferenceChangeListener()).isEqualTo(mController);
         mListPreference.callChangeListener("222");
-        verify(mController).setDefaultSubscription(eq(222));
+        assertThat(mController.getDefaultSubscriptionId()).isEqualTo(222);
     }
 
     @Test
@@ -245,15 +261,15 @@
         final SubscriptionInfo sub1 = createMockSub(111, "sub1");
         final SubscriptionInfo sub2 = createMockSub(222, "sub2");
         SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2));
-        doReturn(sub1.getSubscriptionId()).when(mController).getDefaultSubscriptionId();
+        mController.setDefaultSubscription(sub1.getSubscriptionId());
 
         mController.displayPreference(mScreen);
-        assertThat( mListPreference.getEntry()).isEqualTo("sub1");
+        assertThat(mListPreference.getEntry()).isEqualTo("sub1");
         assertThat(mListPreference.getValue()).isEqualTo("111");
 
-        doReturn(sub2.getSubscriptionId()).when(mController).getDefaultSubscriptionId();
+        mController.setDefaultSubscription(sub2.getSubscriptionId());
         mController.onSubscriptionsChanged();
-        assertThat( mListPreference.getEntry()).isEqualTo("sub2");
+        assertThat(mListPreference.getEntry()).isEqualTo("sub2");
         assertThat(mListPreference.getValue()).isEqualTo("222");
     }
 
@@ -262,7 +278,7 @@
         final SubscriptionInfo sub1 = createMockSub(111, "sub1");
         final SubscriptionInfo sub2 = createMockSub(222, "sub2");
         SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2));
-        doReturn(sub1.getSubscriptionId()).when(mController).getDefaultSubscriptionId();
+        mController.setDefaultSubscription(sub1.getSubscriptionId());
 
         mController.displayPreference(mScreen);
         assertThat(mController.isAvailable()).isTrue();
@@ -280,7 +296,7 @@
         final SubscriptionInfo sub1 = createMockSub(111, "sub1");
         final SubscriptionInfo sub2 = createMockSub(222, "sub2");
         SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1));
-        doReturn(sub1.getSubscriptionId()).when(mController).getDefaultSubscriptionId();
+        mController.setDefaultSubscription(sub1.getSubscriptionId());
 
         mController.displayPreference(mScreen);
         assertThat(mController.isAvailable()).isFalse();
@@ -299,7 +315,7 @@
         final SubscriptionInfo sub2 = createMockSub(222, "sub2");
         final SubscriptionInfo sub3 = createMockSub(333, "sub3");
         SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2));
-        doReturn(sub1.getSubscriptionId()).when(mController).getDefaultSubscriptionId();
+        mController.setDefaultSubscription(sub1.getSubscriptionId());
 
         mController.displayPreference(mScreen);
         assertThat(mListPreference.getEntries().length).isEqualTo(3);
@@ -316,7 +332,7 @@
         assertThat(entries[1].toString()).isEqualTo("sub2");
         assertThat(entries[2].toString()).isEqualTo("sub3");
         assertThat(entries[3].toString()).isEqualTo(
-                mContext.getString(R.string.calls_and_sms_ask_every_time));
+                Utils.getResourceString(mContext, "calls_and_sms_ask_every_time"));
         assertThat(entryValues[0].toString()).isEqualTo("111");
         assertThat(entryValues[1].toString()).isEqualTo("222");
         assertThat(entryValues[2].toString()).isEqualTo("333");
@@ -332,8 +348,9 @@
     }
 
     private class TestDefaultSubscriptionController extends DefaultSubscriptionController {
+        int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
-        public TestDefaultSubscriptionController(Context context, String preferenceKey) {
+        TestDefaultSubscriptionController(Context context, String preferenceKey) {
             super(context, preferenceKey);
         }
 
@@ -344,11 +361,12 @@
 
         @Override
         protected int getDefaultSubscriptionId() {
-            return 0;
+            return mSubId;
         }
 
         @Override
         protected void setDefaultSubscription(int subscriptionId) {
+            mSubId = subscriptionId;
         }
     }
 }
diff --git a/tests/robotests/src/com/android/settings/network/telephony/DisabledSubscriptionControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/DisabledSubscriptionControllerTest.java
similarity index 79%
rename from tests/robotests/src/com/android/settings/network/telephony/DisabledSubscriptionControllerTest.java
rename to tests/unit/src/com/android/settings/network/telephony/DisabledSubscriptionControllerTest.java
index 38223b8..b269660 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/DisabledSubscriptionControllerTest.java
+++ b/tests/unit/src/com/android/settings/network/telephony/DisabledSubscriptionControllerTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -11,7 +11,7 @@
  * 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
+ * limitations under the License.
  */
 
 package com.android.settings.network.telephony;
@@ -20,13 +20,17 @@
 
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
 
 import android.content.Context;
+import android.os.Looper;
 import android.telephony.SubscriptionManager;
 
-import androidx.lifecycle.LifecycleOwner;
 import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceManager;
 import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 
 import com.android.settingslib.core.lifecycle.Lifecycle;
 
@@ -35,10 +39,8 @@
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
 public class DisabledSubscriptionControllerTest {
 
     private static final String KEY = "disabled_subscription_category";
@@ -47,22 +49,28 @@
     @Mock
     private SubscriptionManager mSubscriptionManager;
     @Mock
-    private PreferenceScreen mScreen;
+    private Lifecycle mLifecycle;
 
+    private PreferenceScreen mScreen;
+    private PreferenceManager mPreferenceManager;
     private PreferenceCategory mCategory;
     private Context mContext;
-    private Lifecycle mLifecycle;
     private DisabledSubscriptionController mController;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mContext = spy(RuntimeEnvironment.application);
-        LifecycleOwner lifecycleOwner = () -> mLifecycle;
-        mLifecycle = new Lifecycle(lifecycleOwner);
-        doReturn(mSubscriptionManager).when(mContext).getSystemService(SubscriptionManager.class);
+        mContext = spy(ApplicationProvider.getApplicationContext());
+        when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+        mPreferenceManager = new PreferenceManager(mContext);
+        mScreen = mPreferenceManager.createPreferenceScreen(mContext);
         mCategory = new PreferenceCategory(mContext);
-        doReturn(mCategory).when(mScreen).findPreference(KEY);
+        mCategory.setKey(KEY);
+        mScreen.addPreference(mCategory);
+
         mController = new DisabledSubscriptionController(mContext, KEY);
         mController.init(mLifecycle, SUB_ID);
     }
diff --git a/tests/unit/src/com/android/settings/network/telephony/cdma/CdmaSubscriptionPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/cdma/CdmaSubscriptionPreferenceControllerTest.java
index f0f34d1..d888c9e 100644
--- a/tests/unit/src/com/android/settings/network/telephony/cdma/CdmaSubscriptionPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/network/telephony/cdma/CdmaSubscriptionPreferenceControllerTest.java
@@ -18,7 +18,6 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
@@ -81,8 +80,6 @@
 
     @Test
     public void onPreferenceChange_selectNV_returnNVMode() {
-        doReturn(true).when(mTelephonyManager).setCdmaSubscriptionMode(anyInt());
-
         mController.onPreferenceChange(mPreference, Integer.toString(
                 TelephonyManager.CDMA_SUBSCRIPTION_NV));
 
diff --git a/tests/unit/src/com/android/settings/network/telephony/cdma/CdmaSystemSelectPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/cdma/CdmaSystemSelectPreferenceControllerTest.java
index 4f44a29..3bc3935 100644
--- a/tests/unit/src/com/android/settings/network/telephony/cdma/CdmaSystemSelectPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/network/telephony/cdma/CdmaSystemSelectPreferenceControllerTest.java
@@ -18,7 +18,6 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
@@ -94,7 +93,6 @@
         Settings.Global.putInt(mContext.getContentResolver(),
                 Settings.Global.CDMA_ROAMING_MODE,
                 TelephonyManager.CDMA_ROAMING_MODE_ANY);
-        doReturn(true).when(mTelephonyManager).setCdmaRoamingMode(anyInt());
 
         mController.onPreferenceChange(mPreference,
                 Integer.toString(TelephonyManager.CDMA_ROAMING_MODE_HOME));
diff --git a/tests/unit/src/com/android/settings/testutils/Utils.java b/tests/unit/src/com/android/settings/testutils/Utils.java
new file mode 100644
index 0000000..238dc77
--- /dev/null
+++ b/tests/unit/src/com/android/settings/testutils/Utils.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2020 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.testutils;
+
+import android.content.Context;
+
+public final class Utils {
+    public static int getResourceId(Context context, String type, String name) {
+        return context.getResources().getIdentifier(name, type, context.getPackageName());
+    }
+
+    public static String getResourceString(Context context, String name) {
+        return context.getResources().getString(getResourceId(context, "string", name));
+    }
+}