Merge "If backup service is not available, remove Settings->Backup and Backup->"Backup is disabled by admin" from search results." into qt-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 76a8770..a370d35 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -2692,10 +2692,12 @@
             android:excludeFromRecents="true"
             android:exported="false" />
 
-        <activity android:name=".sim.SimDialogActivity"
-                android:theme="@style/Theme.AlertDialog"
-                android:label="@string/sim_settings_title"
-                android:excludeFromRecents="true">
+        <activity
+            android:name=".sim.SimDialogActivity"
+            android:theme="@style/Theme.AlertDialog"
+            android:label="@string/sim_settings_title"
+            android:launchMode="singleTop"
+            android:excludeFromRecents="true">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
             </intent-filter>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 9c24dd3..be86b86 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2791,7 +2791,7 @@
     <!-- Display settings screen, display white balance settings title [CHAR LIMIT=30] -->
     <string name="display_white_balance_title">Display white balance</string>
     <!-- Display settings screen, setting option name to enable adaptive sleep [CHAR LIMIT=30] -->
-    <string name="adaptive_sleep_title">Screen aware</string>
+    <string name="adaptive_sleep_title">Screen attention</string>
     <!-- Setting option summary when adaptive sleep is on [CHAR LIMIT=NONE] -->
     <string name="adaptive_sleep_summary_on">On / Screen won’t turn off if you’re looking at it</string>
     <!-- Setting option summary when adaptive sleep is off [CHAR LIMIT=NONE] -->
@@ -2799,7 +2799,7 @@
     <!-- Description about the feature adaptive sleep [CHAR LIMIT=NONE]-->
     <string name="adaptive_sleep_description">Prevents your screen from turning off if you’re looking at it.</string>
     <!-- Description feature's privacy sensitive details to make sure users understand what feature users, what it saves/sends etc [CHAR LIMIT=NONE]-->
-    <string name="adaptive_sleep_privacy">Screen aware uses the front camera to see if someone is looking at the screen. It works on device, and images are never stored or sent to Google.</string>
+    <string name="adaptive_sleep_privacy">Screen attention uses the front camera to see if someone is looking at the screen. It works on device, and images are never stored or sent to Google.</string>
 
 
     <!-- Night display screen, setting option name to enable night display (renamed "Night Light" with title caps). [CHAR LIMIT=30] -->
@@ -5329,11 +5329,11 @@
     <!-- Summary for the battery high usage tip, which presents battery may run out earlier [CHAR LIMIT=NONE] -->
     <string name="battery_tip_high_usage_summary">Battery may run out earlier than usual</string>
     <!-- Message for battery tip dialog to show the status about the battery [CHAR LIMIT=NONE] -->
-    <string name="battery_tip_dialog_message" product="default">Your phone has been used more than usual. Your battery may run out sooner than expected.\n\nMost used apps since full charge:</string>
+    <string name="battery_tip_dialog_message" product="default">Your phone has been used more than usual. Your battery may run out sooner than expected.\n\nTop apps by battery usage:</string>
     <!-- Message for battery tip dialog to show the status about the battery [CHAR LIMIT=NONE] -->
-    <string name="battery_tip_dialog_message" product="tablet">Your tablet has been used more than usual. Your battery may run out sooner than expected.\n\nMost used apps since full charge:</string>
+    <string name="battery_tip_dialog_message" product="tablet">Your tablet has been used more than usual. Your battery may run out sooner than expected.\n\nTop apps by battery usage:</string>
     <!-- Message for battery tip dialog to show the status about the battery [CHAR LIMIT=NONE] -->
-    <string name="battery_tip_dialog_message" product="device">Your device has been used more than usual. Your battery may run out sooner than expected.\n\nMost used apps since full charge:</string>
+    <string name="battery_tip_dialog_message" product="device">Your device has been used more than usual. Your battery may run out sooner than expected.\n\nTop apps by battery usage:</string>
     <!-- Footer message for battery tip dialog to show the status about the battery [CHAR LIMIT=NONE] -->
     <string name="battery_tip_dialog_message_footer">Includes high-power background activity</string>
     <!-- Title for restricted app preference, showing how many app need to be restricted [CHAR LIMIT=NONE] -->
@@ -11025,12 +11025,12 @@
     <!-- Message for forget passpoint dialog [CHAR LIMIT=none] -->
     <string name="forget_passpoint_dialog_message">You may lose access to any remaining time or data. Check with your provider before removing.</string>
 
-    <!-- Keywords for Content Capture / Smart Suggestions feature [CHAR_LIMIT=none] -->
-    <string name="keywords_content_capture">content capture, smart suggestions</string>
+    <!-- Keywords for Content Capture feature [CHAR_LIMIT=none] -->
+    <string name="keywords_content_capture">content capture</string>
     <!-- Title of the 'Content Capture' feature toggle in the Settings -> Privacy screen [CHAR LIMIT=none]-->
-    <string name="content_capture">Smart Suggestions</string>
-    <!-- Description of the 'Content Capture / Smart Suggestions' feature toggle in the Settings -> Privacy screen [CHAR LIMIT=NONE]-->
-    <string name="content_capture_summary">Allow Android to save information seen on your screen or heard in video or audio content. Android makes helpful suggestions based on your device activity.</string>
+    <string name="content_capture">Content Capture</string>
+    <!-- Description of the 'Content Capture' feature toggle in the Settings -> Privacy screen [CHAR LIMIT=NONE]-->
+    <string name="content_capture_summary">Allow apps to send content to the Android system</string>
 
     <!-- Title for the button to initiate a heap dump for the system server. [CHAR LIMIT=NONE] -->
     <string name="capture_system_heap_dump_title">Capture system heap dump</string>
diff --git a/res/values/themes_suw.xml b/res/values/themes_suw.xml
index 9bb67cf..0df6991 100644
--- a/res/values/themes_suw.xml
+++ b/res/values/themes_suw.xml
@@ -191,12 +191,14 @@
     </style>
 
     <style name="SuwAlertDialogThemeCompat" parent="@style/Theme.AppCompat.Dialog.Alert">
+        <item name="android:windowSoftInputMode">adjustResize</item>
         <!-- copied from Theme.DeviceDefault.Light.Dialog.Alert -->
         <item name="colorAccent">@*android:color/accent_device_default_light</item>
         <item name="dialogCornerRadius">@*android:dimen/config_dialogCornerRadius</item>
     </style>
 
     <style name="SuwAlertDialogThemeCompat.Light" parent="@style/Theme.AppCompat.Light.Dialog.Alert">
+        <item name="android:windowSoftInputMode">adjustResize</item>
         <!-- copied from Theme.DeviceDefault.Light.Dialog.Alert -->
         <item name="colorAccent">@*android:color/accent_device_default_light</item>
         <item name="dialogCornerRadius">@*android:dimen/config_dialogCornerRadius</item>
diff --git a/res/xml/sound_settings.xml b/res/xml/sound_settings.xml
index e610df2..d99cc00 100644
--- a/res/xml/sound_settings.xml
+++ b/res/xml/sound_settings.xml
@@ -103,7 +103,7 @@
         settings:useAdminDisabledSummary="true"
         settings:keywords="@string/keywords_sounds_and_notifications_interruptions"
         settings:allowDividerAbove="true"
-        settings:controller="com.android.settings.notification.ZenModeSoundSettingsPreferenceController"/>
+        settings:controller="com.android.settings.notification.ZenModePreferenceController"/>
 
     <Preference
         android:key="gesture_prevent_ringing_sound"
diff --git a/res/xml/zen_mode_settings.xml b/res/xml/zen_mode_settings.xml
index 832150a..320a37c 100644
--- a/res/xml/zen_mode_settings.xml
+++ b/res/xml/zen_mode_settings.xml
@@ -20,7 +20,7 @@
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:key="zen_mode_settings"
     android:title="@string/zen_mode_settings_title"
-    settings:keywords="@string/keywords_zen_mode_settings">
+    settings:searchable="false">
 
     <PreferenceCategory
         android:key="zen_mode_settings_category_behavior"
@@ -66,11 +66,13 @@
 
     <!-- Turn on DND button -->
     <com.android.settingslib.widget.LayoutPreference
-        android:key="zen_mode_settings_button_container"
+        android:key="zen_mode_toggle"
+        android:title="@string/zen_mode_settings_title"
         android:selectable="false"
         android:layout="@layout/zen_mode_settings_button"
         settings:allowDividerAbove="true"
-        settings:allowDividerBelow="true"/>
+        settings:allowDividerBelow="true"
+        settings:keywords="@string/keywords_zen_mode_settings"/>
 
     <!-- Footer that shows if user is put into alarms only or total silence mode by an app -->
     <com.android.settingslib.widget.FooterPreference/>
diff --git a/src/com/android/settings/fuelgauge/batterytip/HighUsageAdapter.java b/src/com/android/settings/fuelgauge/batterytip/HighUsageAdapter.java
index d832640..cd79ea0 100644
--- a/src/com/android/settings/fuelgauge/batterytip/HighUsageAdapter.java
+++ b/src/com/android/settings/fuelgauge/batterytip/HighUsageAdapter.java
@@ -79,9 +79,6 @@
                 Utils.getBadgedIcon(mIconDrawableFactory, mPackageManager, app.packageName,
                         UserHandle.getUserId(app.uid)));
         holder.appName.setText(Utils.getApplicationLabel(mContext, app.packageName));
-        if (app.screenOnTimeMs != 0) {
-            holder.appTime.setText(StringUtil.formatElapsedTime(mContext, app.screenOnTimeMs, false));
-        }
     }
 
     @Override
diff --git a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
index 725f087..9898834 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.homepage.contextualcards.slices;
 
+import static android.app.slice.Slice.HINT_ERROR;
+
 import android.content.ContentResolver;
 import android.content.Context;
 import android.net.Uri;
@@ -117,6 +119,14 @@
                 return;
             }
 
+            if (slice.hasHint(HINT_ERROR)) {
+                Log.w(TAG, "Slice has HINT_ERROR, skipping rendering. uri=" + slice.getUri());
+                mSliceLiveDataMap.get(slice.getUri()).removeObservers(mLifecycleOwner);
+                mContext.getContentResolver().notifyChange(CardContentProvider.REFRESH_CARD_URI,
+                        null);
+                return;
+            }
+
             switch (holder.getItemViewType()) {
                 case VIEW_TYPE_DEFERRED_SETUP:
                     mDeferredSetupCardHelper.bindView(holder, card, slice);
diff --git a/src/com/android/settings/notification/VolumeSeekBarPreference.java b/src/com/android/settings/notification/VolumeSeekBarPreference.java
index 7f36791..92b3cae 100644
--- a/src/com/android/settings/notification/VolumeSeekBarPreference.java
+++ b/src/com/android/settings/notification/VolumeSeekBarPreference.java
@@ -80,11 +80,6 @@
         mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
     }
 
-    @Override
-    public boolean isSelectable() {
-        return false;
-    }
-
     public void setStream(int stream) {
         mStream = stream;
         setMax(mAudioManager.getStreamMaxVolume(mStream));
diff --git a/src/com/android/settings/notification/ZenModeButtonPreferenceController.java b/src/com/android/settings/notification/ZenModeButtonPreferenceController.java
index 4829a28..3a9bcb7 100644
--- a/src/com/android/settings/notification/ZenModeButtonPreferenceController.java
+++ b/src/com/android/settings/notification/ZenModeButtonPreferenceController.java
@@ -33,11 +33,12 @@
 public class ZenModeButtonPreferenceController extends AbstractZenModePreferenceController
         implements PreferenceControllerMixin {
 
+    public static final String KEY = "zen_mode_toggle";
+
     private static final String TAG = "EnableZenModeButton";
-    protected static final String KEY = "zen_mode_settings_button_container";
+    private final FragmentManager mFragment;
     private Button mZenButtonOn;
     private Button mZenButtonOff;
-    private FragmentManager mFragment;
 
     public ZenModeButtonPreferenceController(Context context, Lifecycle lifecycle, FragmentManager
             fragment) {
@@ -60,13 +61,13 @@
         super.updateState(preference);
 
         if (null == mZenButtonOn) {
-            mZenButtonOn = (Button) ((LayoutPreference) preference)
+            mZenButtonOn = ((LayoutPreference) preference)
                     .findViewById(R.id.zen_mode_settings_turn_on_button);
             updateZenButtonOnClickListener();
         }
 
         if (null == mZenButtonOff) {
-            mZenButtonOff = (Button) ((LayoutPreference) preference)
+            mZenButtonOff = ((LayoutPreference) preference)
                     .findViewById(R.id.zen_mode_settings_turn_off_button);
             mZenButtonOff.setOnClickListener(v -> {
                 mMetricsFeatureProvider.action(mContext,
diff --git a/src/com/android/settings/notification/ZenModeSettings.java b/src/com/android/settings/notification/ZenModeSettings.java
index 9360a33..f35c649 100644
--- a/src/com/android/settings/notification/ZenModeSettings.java
+++ b/src/com/android/settings/notification/ZenModeSettings.java
@@ -328,7 +328,6 @@
                 public List<String> getNonIndexableKeys(Context context) {
                     List<String> keys = super.getNonIndexableKeys(context);
                     keys.add(ZenModeDurationPreferenceController.KEY);
-                    keys.add(ZenModeButtonPreferenceController.KEY);
                     return keys;
                 }
 
diff --git a/src/com/android/settings/notification/ZenModeSliceBuilder.java b/src/com/android/settings/notification/ZenModeSliceBuilder.java
index e8b181a..9e88cea 100644
--- a/src/com/android/settings/notification/ZenModeSliceBuilder.java
+++ b/src/com/android/settings/notification/ZenModeSliceBuilder.java
@@ -18,8 +18,6 @@
 
 import static android.app.slice.Slice.EXTRA_TOGGLE_STATE;
 
-import static com.android.settings.notification.ZenModeSoundSettingsPreferenceController.ZEN_MODE_KEY;
-
 import android.annotation.ColorInt;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -47,6 +45,8 @@
 
     private static final String TAG = "ZenModeSliceBuilder";
 
+    private static final String ZEN_MODE_SLICE_KEY = ZenModeButtonPreferenceController.KEY;
+
     /**
      * Action notifying a change on the Zen Mode Slice.
      */
@@ -78,7 +78,8 @@
         final PendingIntent primaryAction = getPrimaryAction(context);
         final SliceAction primarySliceAction = SliceAction.createDeeplink(primaryAction,
                 (IconCompat) null /* icon */, ListBuilder.ICON_IMAGE, title);
-        final SliceAction toggleSliceAction = SliceAction.createToggle(toggleAction, null /* actionTitle */,
+        final SliceAction toggleSliceAction = SliceAction.createToggle(toggleAction,
+                null /* actionTitle */,
                 isZenModeEnabled);
 
         return new ListBuilder(context, CustomSliceRegistry.ZEN_MODE_SLICE_URI,
@@ -110,10 +111,10 @@
     }
 
     public static Intent getIntent(Context context) {
-        final Uri contentUri = new Uri.Builder().appendPath(ZEN_MODE_KEY).build();
+        final Uri contentUri = new Uri.Builder().appendPath(ZEN_MODE_SLICE_KEY).build();
         final String screenTitle = context.getText(R.string.zen_mode_settings_title).toString();
         return SliceBuilderUtils.buildSearchResultPageIntent(context,
-                ZenModeSettings.class.getName(), ZEN_MODE_KEY, screenTitle,
+                ZenModeSettings.class.getName(), ZEN_MODE_SLICE_KEY, screenTitle,
                 SettingsEnums.NOTIFICATION_ZEN_MODE)
                 .setClassName(context.getPackageName(), SubSettings.class.getName())
                 .setData(contentUri);
diff --git a/src/com/android/settings/notification/ZenModeSoundSettingsPreferenceController.java b/src/com/android/settings/notification/ZenModeSoundSettingsPreferenceController.java
deleted file mode 100644
index 842c49d..0000000
--- a/src/com/android/settings/notification/ZenModeSoundSettingsPreferenceController.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2019 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.notification;
-
-import android.content.Context;
-
-public class ZenModeSoundSettingsPreferenceController extends ZenModePreferenceController {
-
-    public static final String ZEN_MODE_KEY = "zen_mode";
-
-    public ZenModeSoundSettingsPreferenceController(Context context, String key) {
-        super(context, key);
-    }
-
-    @Override
-    public int getAvailabilityStatus() {
-        return AVAILABLE;
-    }
-}
diff --git a/src/com/android/settings/sim/CallsSimListDialogFragment.java b/src/com/android/settings/sim/CallsSimListDialogFragment.java
new file mode 100644
index 0000000..bb5a003
--- /dev/null
+++ b/src/com/android/settings/sim/CallsSimListDialogFragment.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2019 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.sim;
+
+import android.content.Context;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Specialized version of SimListDialogFragment that fetches a list of SIMs which support calls.
+ */
+public class CallsSimListDialogFragment extends SimListDialogFragment {
+    @Override
+    protected List<SubscriptionInfo> getCurrentSubscriptions() {
+        final Context context = getContext();
+        final SubscriptionManager subscriptionManager = context.getSystemService(
+                SubscriptionManager.class);
+        final TelecomManager telecomManager = context.getSystemService(TelecomManager.class);
+        final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class);
+        final List<PhoneAccountHandle> phoneAccounts =
+                telecomManager.getCallCapablePhoneAccounts();
+        final List<SubscriptionInfo> result = new ArrayList<>();
+
+        if (phoneAccounts == null) {
+            return result;
+        }
+        for (PhoneAccountHandle handle : phoneAccounts) {
+            final PhoneAccount phoneAccount = telecomManager.getPhoneAccount(handle);
+            final int subId = telephonyManager.getSubIdForPhoneAccount(phoneAccount);
+
+            if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+                continue;
+            }
+            result.add(subscriptionManager.getActiveSubscriptionInfo(subId));
+        }
+        return result;
+    }
+}
diff --git a/src/com/android/settings/sim/PreferredSimDialogFragment.java b/src/com/android/settings/sim/PreferredSimDialogFragment.java
new file mode 100644
index 0000000..5b81e62
--- /dev/null
+++ b/src/com/android/settings/sim/PreferredSimDialogFragment.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2019 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.sim;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.appcompat.app.AlertDialog;
+
+import com.android.settings.R;
+
+/**
+ * Presents a dialog asking the user if they want to update all services to use a given "preferred"
+ * SIM. Typically this would be used in a case where a device goes from having multiple SIMs down to
+ * only one.
+ */
+public class PreferredSimDialogFragment extends SimDialogFragment implements
+        DialogInterface.OnClickListener {
+    private static final String TAG = "PreferredSimDialogFrag";
+
+    public static PreferredSimDialogFragment newInstance() {
+        final PreferredSimDialogFragment fragment = new PreferredSimDialogFragment();
+        final Bundle args = initArguments(SimDialogActivity.PREFERRED_PICK,
+                R.string.sim_preferred_title);
+        fragment.setArguments(args);
+        return fragment;
+    }
+
+    @NonNull
+    @Override
+    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+        final AlertDialog dialog = new AlertDialog.Builder(getContext())
+                .setTitle(getTitleResId())
+                .setPositiveButton(R.string.yes, this)
+                .setNegativeButton(R.string.no, null)
+                .create();
+        updateDialog(dialog);
+        return dialog;
+    }
+
+    @Override
+    public void onClick(DialogInterface dialog, int buttonClicked) {
+        if (buttonClicked != DialogInterface.BUTTON_POSITIVE) {
+            return;
+        }
+        final SimDialogActivity activity = (SimDialogActivity) getActivity();
+        final SubscriptionInfo info = getPreferredSubscription();
+        if (info != null) {
+            activity.onSubscriptionSelected(getDialogType(), info.getSubscriptionId());
+        }
+    }
+
+    public SubscriptionInfo getPreferredSubscription() {
+        final Activity activity = getActivity();
+        final int slotId = activity.getIntent().getIntExtra(SimDialogActivity.PREFERRED_SIM,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        return getSubscriptionManager().getActiveSubscriptionInfoForSimSlotIndex(slotId);
+    }
+
+    private void updateDialog(AlertDialog dialog) {
+        final SubscriptionInfo info = getPreferredSubscription();
+        if (info == null) {
+            dismiss();
+            return;
+        }
+        final String message =
+                getContext().getString(R.string.sim_preferred_message, info.getDisplayName());
+        dialog.setMessage(message);
+    }
+
+    @Override
+    public void updateDialog() {
+        updateDialog((AlertDialog) getDialog());
+    }
+
+    @VisibleForTesting
+    protected SubscriptionManager getSubscriptionManager() {
+        return getContext().getSystemService(SubscriptionManager.class);
+    }
+}
diff --git a/src/com/android/settings/sim/SimDialogActivity.java b/src/com/android/settings/sim/SimDialogActivity.java
index 487dace..d721efd 100644
--- a/src/com/android/settings/sim/SimDialogActivity.java
+++ b/src/com/android/settings/sim/SimDialogActivity.java
@@ -16,37 +16,30 @@
 
 package com.android.settings.sim;
 
-import android.app.Activity;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.res.Resources;
+import android.content.Intent;
 import android.os.Bundle;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
-import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.ImageView;
-import android.widget.ListAdapter;
-import android.widget.TextView;
+import android.util.Log;
 import android.widget.Toast;
 
-import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentManager;
 
 import com.android.settings.R;
 
-import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
-public class SimDialogActivity extends Activity {
+/**
+ * This activity provides singleton semantics per dialog type for showing various kinds of
+ * dialogs asking the user to make choices about which SIM to use for various services
+ * (calls, SMS, and data).
+ */
+public class SimDialogActivity extends FragmentActivity {
     private static String TAG = "SimDialogActivity";
 
     public static String PREFERRED_SIM = "preferred_sim";
@@ -60,276 +53,118 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        final int dialogType = getIntent().getIntExtra(DIALOG_TYPE_KEY, INVALID_PICK);
+        showOrUpdateDialog();
+    }
 
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        setIntent(intent);
+        showOrUpdateDialog();
+    }
+
+    private void showOrUpdateDialog() {
+        final int dialogType = getIntent().getIntExtra(DIALOG_TYPE_KEY, INVALID_PICK);
+        final String tag = Integer.toString(dialogType);
+        final FragmentManager fragmentManager = getSupportFragmentManager();
+        SimDialogFragment fragment = (SimDialogFragment) fragmentManager.findFragmentByTag(tag);
+
+        if (fragment == null) {
+            fragment = createFragment(dialogType);
+            fragment.show(fragmentManager, tag);
+        } else {
+            fragment.updateDialog();
+        }
+    }
+
+    private SimDialogFragment createFragment(int dialogType) {
+        switch(dialogType) {
+            case DATA_PICK:
+                return SimListDialogFragment.newInstance(dialogType, R.string.select_sim_for_data,
+                        false /* includeAskEveryTime */);
+            case CALLS_PICK:
+                return CallsSimListDialogFragment.newInstance(dialogType, R.string.select_sim_for_calls,
+                        true /* includeAskEveryTime */);
+            case SMS_PICK:
+                return SimListDialogFragment.newInstance(dialogType, R.string.select_sim_for_sms,
+                        false /* includeAskEveryTime */);
+            case PREFERRED_PICK:
+                if (!getIntent().hasExtra(PREFERRED_SIM)) {
+                    throw new IllegalArgumentException("Missing required extra " + PREFERRED_SIM);
+                }
+                return PreferredSimDialogFragment.newInstance();
+            default:
+                throw new IllegalArgumentException( "Invalid dialog type " + dialogType + " sent.");
+        }
+    }
+
+    public void onSubscriptionSelected(int dialogType, int subId) {
+        if (getSupportFragmentManager().findFragmentByTag(Integer.toString(dialogType)) == null) {
+            Log.w(TAG, "onSubscriptionSelected ignored because stored fragment was null");
+            return;
+        }
         switch (dialogType) {
             case DATA_PICK:
+                setDefaultDataSubId(subId);
+                break;
             case CALLS_PICK:
+                setDefaultCallsSubId(subId);
+                break;
             case SMS_PICK:
-                createDialog(this, dialogType).show();
+                setDefaultSmsSubId(subId);
                 break;
             case PREFERRED_PICK:
-                displayPreferredDialog(getIntent().getIntExtra(PREFERRED_SIM, 0));
+                setPreferredSim(subId);
                 break;
             default:
-                throw new IllegalArgumentException("Invalid dialog type " + dialogType + " sent.");
-        }
-
-    }
-
-    private void displayPreferredDialog(final int slotId) {
-        final Resources res = getResources();
-        final Context context = getApplicationContext();
-        final SubscriptionInfo sir = SubscriptionManager.from(context)
-                .getActiveSubscriptionInfoForSimSlotIndex(slotId);
-
-        if (sir != null) {
-            AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
-            alertDialogBuilder.setTitle(R.string.sim_preferred_title);
-            alertDialogBuilder.setMessage(res.getString(
-                        R.string.sim_preferred_message, sir.getDisplayName()));
-
-            alertDialogBuilder.setPositiveButton(R.string.yes, new
-                    DialogInterface.OnClickListener() {
-                @Override
-                public void onClick(DialogInterface dialog, int id) {
-                    final int subId = sir.getSubscriptionId();
-                    PhoneAccountHandle phoneAccountHandle =
-                            subscriptionIdToPhoneAccountHandle(subId);
-                    setDefaultDataSubId(context, subId);
-                    setDefaultSmsSubId(context, subId);
-                    setUserSelectedOutgoingPhoneAccount(phoneAccountHandle);
-                    finish();
-                }
-            });
-            alertDialogBuilder.setNegativeButton(R.string.no, new
-                    DialogInterface.OnClickListener() {
-                @Override
-                public void onClick(DialogInterface dialog,int id) {
-                    finish();
-                }
-            });
-
-            alertDialogBuilder.create().show();
-        } else {
-            finish();
+                throw new IllegalArgumentException(
+                        "Invalid dialog type " + dialogType + " sent.");
         }
     }
 
-    private static void setDefaultDataSubId(final Context context, final int subId) {
-        final SubscriptionManager subscriptionManager = SubscriptionManager.from(context);
-        final TelephonyManager telephonyManager = TelephonyManager.from(context)
-                .createForSubscriptionId(subId);
+    public void onFragmentDismissed(SimDialogFragment simDialogFragment) {
+        final List<Fragment> fragments = getSupportFragmentManager().getFragments();
+        if (fragments.size() == 1 && fragments.get(0) == simDialogFragment) {
+            finishAndRemoveTask();
+        }
+    }
+
+    private void setDefaultDataSubId(final int subId) {
+        final SubscriptionManager subscriptionManager = getSystemService(SubscriptionManager.class);
+        final TelephonyManager telephonyManager = getSystemService(
+                TelephonyManager.class).createForSubscriptionId(subId);
         subscriptionManager.setDefaultDataSubId(subId);
         telephonyManager.setDataEnabled(true);
-        Toast.makeText(context, R.string.data_switch_started, Toast.LENGTH_LONG).show();
+        Toast.makeText(this, R.string.data_switch_started, Toast.LENGTH_LONG).show();
     }
 
-    private static void setDefaultSmsSubId(final Context context, final int subId) {
-        final SubscriptionManager subscriptionManager = SubscriptionManager.from(context);
-        subscriptionManager.setDefaultSmsSubId(subId);
-    }
-
-    private void setUserSelectedOutgoingPhoneAccount(PhoneAccountHandle phoneAccount) {
-        final TelecomManager telecomManager = TelecomManager.from(this);
+    private void setDefaultCallsSubId(final int subId) {
+        final PhoneAccountHandle phoneAccount = subscriptionIdToPhoneAccountHandle(subId);
+        final TelecomManager telecomManager = getSystemService(TelecomManager.class);
         telecomManager.setUserSelectedOutgoingPhoneAccount(phoneAccount);
     }
 
+    private void setDefaultSmsSubId(final int subId) {
+        final SubscriptionManager subscriptionManager = getSystemService(SubscriptionManager.class);
+        subscriptionManager.setDefaultSmsSubId(subId);
+    }
+
+    private void setPreferredSim(final int subId) {
+        setDefaultDataSubId(subId);
+        setDefaultSmsSubId(subId);
+        setDefaultCallsSubId(subId);
+    }
+
     private PhoneAccountHandle subscriptionIdToPhoneAccountHandle(final int subId) {
-        final TelecomManager telecomManager = TelecomManager.from(this);
-        final TelephonyManager telephonyManager = TelephonyManager.from(this);
-        final Iterator<PhoneAccountHandle> phoneAccounts =
-                telecomManager.getCallCapablePhoneAccounts().listIterator();
+        final TelecomManager telecomManager = getSystemService(TelecomManager.class);
+        final TelephonyManager telephonyManager = getSystemService(TelephonyManager.class);
 
-        while (phoneAccounts.hasNext()) {
-            final PhoneAccountHandle phoneAccountHandle = phoneAccounts.next();
-            final PhoneAccount phoneAccount = telecomManager.getPhoneAccount(phoneAccountHandle);
+        for (PhoneAccountHandle handle : telecomManager.getCallCapablePhoneAccounts()) {
+            final PhoneAccount phoneAccount = telecomManager.getPhoneAccount(handle);
             if (subId == telephonyManager.getSubIdForPhoneAccount(phoneAccount)) {
-                return phoneAccountHandle;
+                return handle;
             }
         }
-
         return null;
     }
-
-    public Dialog createDialog(final Context context, final int id) {
-        final ArrayList<String> list = new ArrayList<String>();
-        final SubscriptionManager subscriptionManager = SubscriptionManager.from(context);
-        final List<SubscriptionInfo> subInfoList =
-            subscriptionManager.getActiveSubscriptionInfoList(true);
-        final int selectableSubInfoLength = subInfoList == null ? 0 : subInfoList.size();
-
-        final DialogInterface.OnClickListener selectionListener =
-                new DialogInterface.OnClickListener() {
-                    @Override
-                    public void onClick(DialogInterface dialog, int value) {
-
-                        final SubscriptionInfo sir;
-
-                        switch (id) {
-                            case DATA_PICK:
-                                sir = subInfoList.get(value);
-                                setDefaultDataSubId(context, sir.getSubscriptionId());
-                                break;
-                            case CALLS_PICK:
-                                final TelecomManager telecomManager =
-                                        TelecomManager.from(context);
-                                final List<PhoneAccountHandle> phoneAccountsList =
-                                        telecomManager.getCallCapablePhoneAccounts();
-                                setUserSelectedOutgoingPhoneAccount(
-                                        value < 1 ? null : phoneAccountsList.get(value - 1));
-                                break;
-                            case SMS_PICK:
-                                sir = subInfoList.get(value);
-                                setDefaultSmsSubId(context, sir.getSubscriptionId());
-                                break;
-                            default:
-                                throw new IllegalArgumentException("Invalid dialog type "
-                                        + id + " in SIM dialog.");
-                        }
-
-                        finish();
-                    }
-                };
-
-        Dialog.OnKeyListener keyListener = new Dialog.OnKeyListener() {
-            @Override
-            public boolean onKey(DialogInterface arg0, int keyCode,
-                    KeyEvent event) {
-                    if (keyCode == KeyEvent.KEYCODE_BACK) {
-                        finish();
-                    }
-                    return true;
-                }
-            };
-
-        ArrayList<SubscriptionInfo> callsSubInfoList = new ArrayList<SubscriptionInfo>();
-        if (id == CALLS_PICK) {
-            final TelecomManager telecomManager = TelecomManager.from(context);
-            final TelephonyManager telephonyManager = TelephonyManager.from(context);
-            final Iterator<PhoneAccountHandle> phoneAccounts =
-                    telecomManager.getCallCapablePhoneAccounts().listIterator();
-
-            list.add(getResources().getString(R.string.sim_calls_ask_first_prefs_title));
-            callsSubInfoList.add(null);
-            while (phoneAccounts.hasNext()) {
-                final PhoneAccount phoneAccount =
-                        telecomManager.getPhoneAccount(phoneAccounts.next());
-                list.add((String)phoneAccount.getLabel());
-                int subId = telephonyManager.getSubIdForPhoneAccount(phoneAccount);
-                if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-                    final SubscriptionInfo sir = SubscriptionManager.from(context)
-                            .getActiveSubscriptionInfo(subId);
-                    callsSubInfoList.add(sir);
-                } else {
-                    callsSubInfoList.add(null);
-                }
-            }
-        } else {
-            for (int i = 0; i < selectableSubInfoLength; ++i) {
-                final SubscriptionInfo sir = subInfoList.get(i);
-                CharSequence displayName = sir.getDisplayName();
-                if (displayName == null) {
-                    displayName = "";
-                }
-                list.add(displayName.toString());
-            }
-        }
-
-        String[] arr = list.toArray(new String[0]);
-
-        AlertDialog.Builder builder = new AlertDialog.Builder(context);
-
-        ListAdapter adapter = new SelectAccountListAdapter(
-                id == CALLS_PICK ? callsSubInfoList : subInfoList,
-                builder.getContext(),
-                R.layout.select_account_list_item,
-                arr, id);
-
-        switch (id) {
-            case DATA_PICK:
-                builder.setTitle(R.string.select_sim_for_data);
-                break;
-            case CALLS_PICK:
-                builder.setTitle(R.string.select_sim_for_calls);
-                break;
-            case SMS_PICK:
-                builder.setTitle(R.string.select_sim_for_sms);
-                break;
-            default:
-                throw new IllegalArgumentException("Invalid dialog type "
-                        + id + " in SIM dialog.");
-        }
-
-        Dialog dialog = builder.setAdapter(adapter, selectionListener).create();
-        dialog.setOnKeyListener(keyListener);
-
-        dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
-            @Override
-            public void onCancel(DialogInterface dialogInterface) {
-                finish();
-            }
-        });
-
-        return dialog;
-
-    }
-
-    private class SelectAccountListAdapter extends ArrayAdapter<String> {
-        private Context mContext;
-        private int mResId;
-        private int mDialogId;
-        private final float OPACITY = 0.54f;
-        private List<SubscriptionInfo> mSubInfoList;
-
-        public SelectAccountListAdapter(List<SubscriptionInfo> subInfoList,
-                Context context, int resource, String[] arr, int dialogId) {
-            super(context, resource, arr);
-            mContext = context;
-            mResId = resource;
-            mDialogId = dialogId;
-            mSubInfoList = subInfoList;
-        }
-
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            LayoutInflater inflater = (LayoutInflater)
-                    mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-            View rowView;
-            final ViewHolder holder;
-
-            if (convertView == null) {
-                // Cache views for faster scrolling
-                rowView = inflater.inflate(mResId, null);
-                holder = new ViewHolder();
-                holder.title = (TextView) rowView.findViewById(R.id.title);
-                holder.summary = (TextView) rowView.findViewById(R.id.summary);
-                holder.icon = (ImageView) rowView.findViewById(R.id.icon);
-                rowView.setTag(holder);
-            } else {
-                rowView = convertView;
-                holder = (ViewHolder) rowView.getTag();
-            }
-
-            final SubscriptionInfo sir = mSubInfoList.get(position);
-            if (sir == null) {
-                holder.title.setText(getItem(position));
-                holder.summary.setText("");
-                holder.icon.setImageDrawable(getResources()
-                        .getDrawable(R.drawable.ic_live_help));
-                holder.icon.setAlpha(OPACITY);
-            } else {
-                holder.title.setText(sir.getDisplayName());
-                holder.summary.setText(sir.getNumber());
-                holder.icon.setImageBitmap(sir.createIconBitmap(mContext));
-            }
-            return rowView;
-        }
-
-        private class ViewHolder {
-            TextView title;
-            TextView summary;
-            ImageView icon;
-        }
-    }
 }
diff --git a/src/com/android/settings/sim/SimDialogFragment.java b/src/com/android/settings/sim/SimDialogFragment.java
new file mode 100644
index 0000000..10815fd
--- /dev/null
+++ b/src/com/android/settings/sim/SimDialogFragment.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2019 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.sim;
+
+import android.content.DialogInterface;
+import android.os.Bundle;
+
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;
+
+/** Common functionality for showing a dialog in SimDialogActivity. */
+public abstract class SimDialogFragment extends DialogFragment {
+    private static final String TAG = "SimDialogFragment";
+
+    private static final String KEY_TITLE_ID = "title_id";
+    private static final String KEY_DIALOG_TYPE = "dialog_type";
+
+    protected static Bundle initArguments(int dialogType, int titleResId) {
+        final Bundle args = new Bundle();
+        args.putInt(KEY_DIALOG_TYPE, dialogType);
+        args.putInt(KEY_TITLE_ID, titleResId);
+        return args;
+    }
+
+    public int getDialogType() {
+        return getArguments().getInt(KEY_DIALOG_TYPE);
+    }
+
+    public int getTitleResId() {
+        return getArguments().getInt(KEY_TITLE_ID);
+    }
+
+    @Override
+    public void onDismiss(@NonNull DialogInterface dialog) {
+        super.onDismiss(dialog);
+        final SimDialogActivity activity = (SimDialogActivity) getActivity();
+        if (activity != null && !activity.isFinishing()) {
+            activity.onFragmentDismissed(this);
+        }
+    }
+
+    public abstract void updateDialog();
+}
diff --git a/src/com/android/settings/sim/SimListDialogFragment.java b/src/com/android/settings/sim/SimListDialogFragment.java
new file mode 100644
index 0000000..f78c4e7
--- /dev/null
+++ b/src/com/android/settings/sim/SimListDialogFragment.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2019 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.sim;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.appcompat.app.AlertDialog;
+
+import com.android.settings.R;
+import com.android.settings.Utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Shows a dialog consisting of a list of SIMs (aka subscriptions), possibly including an additional
+ * entry indicating "ask me every time".
+ */
+public class SimListDialogFragment extends SimDialogFragment implements
+        DialogInterface.OnClickListener {
+    protected static final String KEY_INCLUDE_ASK_EVERY_TIME = "include_ask_every_time";
+
+    protected SelectSubscriptionAdapter mAdapter;
+    @VisibleForTesting
+    List<SubscriptionInfo>  mSubscriptions;
+
+    public static SimListDialogFragment newInstance(int dialogType, int titleResId,
+            boolean includeAskEveryTime) {
+        final SimListDialogFragment fragment = new SimListDialogFragment();
+        final Bundle args = initArguments(dialogType, titleResId);
+        args.putBoolean(KEY_INCLUDE_ASK_EVERY_TIME, includeAskEveryTime);
+        fragment.setArguments(args);
+        return fragment;
+    }
+
+    @NonNull
+    @Override
+    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+        mSubscriptions = new ArrayList<>();
+
+        final AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
+        builder.setTitle(getTitleResId());
+
+        mAdapter = new SelectSubscriptionAdapter(builder.getContext(), mSubscriptions);
+
+        setAdapter(builder);
+        final Dialog dialog = builder.create();
+        updateDialog();
+        return dialog;
+    }
+
+    @Override
+    public void onClick(DialogInterface dialog, int selectionIndex) {
+        if (selectionIndex >= 0 && selectionIndex < mSubscriptions.size()) {
+            int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+            final SubscriptionInfo subscription = mSubscriptions.get(selectionIndex);
+            if (subscription != null) {
+                subId = subscription.getSubscriptionId();
+            }
+            final SimDialogActivity activity = (SimDialogActivity) getActivity();
+            activity.onSubscriptionSelected(getDialogType(), subId);
+        }
+    }
+
+    protected List<SubscriptionInfo> getCurrentSubscriptions() {
+        final SubscriptionManager manager = getContext().getSystemService(
+                SubscriptionManager.class);
+        return manager.getActiveSubscriptionInfoList(true);
+    }
+
+    @Override
+    public void updateDialog() {
+        List<SubscriptionInfo> currentSubscriptions = getCurrentSubscriptions();
+        if (currentSubscriptions == null) {
+            dismiss();
+            return;
+        }
+        if (getArguments().getBoolean(KEY_INCLUDE_ASK_EVERY_TIME)) {
+            final List<SubscriptionInfo> tmp = new ArrayList<>(currentSubscriptions.size() + 1);
+            tmp.add(null);
+            tmp.addAll(currentSubscriptions);
+            currentSubscriptions = tmp;
+        }
+        if (currentSubscriptions.equals(mSubscriptions)) {
+            return;
+        }
+        mSubscriptions.clear();
+        mSubscriptions.addAll(currentSubscriptions);
+        mAdapter.notifyDataSetChanged();
+    }
+
+    @VisibleForTesting
+    void setAdapter(AlertDialog.Builder builder) {
+        builder.setAdapter(mAdapter, this);
+    }
+
+    private static class SelectSubscriptionAdapter extends BaseAdapter {
+        private Context mContext;
+        private LayoutInflater mInflater;
+        List<SubscriptionInfo> mSubscriptions;
+
+        public SelectSubscriptionAdapter(Context context, List<SubscriptionInfo> subscriptions) {
+            mSubscriptions = subscriptions;
+            mContext = context;
+        }
+
+        @Override
+        public int getCount() {
+            return mSubscriptions.size();
+        }
+
+        @Override
+        public SubscriptionInfo getItem(int position) {
+            return mSubscriptions.get(position);
+        }
+
+        @Override
+        public long getItemId(int position) {
+            final SubscriptionInfo info = mSubscriptions.get(position);
+            if (info == null) {
+                return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+            }
+            return info.getSubscriptionId();
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            if (convertView == null) {
+                if (mInflater == null) {
+                    mInflater = LayoutInflater.from(parent.getContext());
+                }
+                convertView = mInflater.inflate(R.layout.select_account_list_item, parent, false);
+            }
+            final SubscriptionInfo sub = getItem(position);
+
+            final TextView title = convertView.findViewById(R.id.title);
+            final TextView summary = convertView.findViewById(R.id.summary);
+            final ImageView icon = convertView.findViewById(R.id.icon);
+
+            if (sub == null) {
+                title.setText(R.string.sim_calls_ask_first_prefs_title);
+                summary.setText("");
+                icon.setImageDrawable(mContext.getDrawable(R.drawable.ic_help));
+                icon.setImageTintList(
+                        Utils.getColorAttr(mContext, android.R.attr.textColorSecondary));
+            } else {
+                title.setText(sub.getDisplayName());
+                summary.setText(sub.getNumber());
+                icon.setImageBitmap(sub.createIconBitmap(mContext));
+
+            }
+            return convertView;
+        }
+    }
+}
diff --git a/src/com/android/settings/slices/CustomSliceRegistry.java b/src/com/android/settings/slices/CustomSliceRegistry.java
index e400815..dc3324b 100644
--- a/src/com/android/settings/slices/CustomSliceRegistry.java
+++ b/src/com/android/settings/slices/CustomSliceRegistry.java
@@ -19,8 +19,6 @@
 import static android.provider.SettingsSlicesContract.KEY_LOCATION;
 import static android.provider.SettingsSlicesContract.KEY_WIFI;
 
-import static com.android.settings.notification.ZenModeSoundSettingsPreferenceController.ZEN_MODE_KEY;
-
 import android.content.ContentResolver;
 import android.net.Uri;
 import android.provider.SettingsSlicesContract;
@@ -43,6 +41,7 @@
 import com.android.settings.media.MediaOutputIndicatorSlice;
 import com.android.settings.media.MediaOutputSlice;
 import com.android.settings.network.telephony.MobileDataSlice;
+import com.android.settings.notification.ZenModeButtonPreferenceController;
 import com.android.settings.wifi.calling.WifiCallingSliceHelper;
 import com.android.settings.wifi.slice.ContextualWifiSlice;
 import com.android.settings.wifi.slice.WifiSlice;
@@ -298,7 +297,7 @@
             .scheme(ContentResolver.SCHEME_CONTENT)
             .authority(SettingsSliceProvider.SLICE_AUTHORITY)
             .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
-            .appendPath(ZEN_MODE_KEY)
+            .appendPath(ZenModeButtonPreferenceController.KEY)
             .build();
 
     /**
diff --git a/src/com/android/settings/widget/SeekBarPreference.java b/src/com/android/settings/widget/SeekBarPreference.java
index f4d2aac..44def11 100644
--- a/src/com/android/settings/widget/SeekBarPreference.java
+++ b/src/com/android/settings/widget/SeekBarPreference.java
@@ -93,7 +93,7 @@
 
     @Override
     public boolean isSelectable() {
-        return false;
+        return isDisabledByAdmin();
     }
 
     @Override
diff --git a/src/com/android/settings/wifi/WifiDialog.java b/src/com/android/settings/wifi/WifiDialog.java
index fbea824..875f35d 100644
--- a/src/com/android/settings/wifi/WifiDialog.java
+++ b/src/com/android/settings/wifi/WifiDialog.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.wifi;
 
+import android.annotation.StyleRes;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
@@ -64,11 +65,21 @@
     public static WifiDialog createModal(Context context, WifiDialogListener listener,
             AccessPoint accessPoint, int mode) {
         return new WifiDialog(context, listener, accessPoint, mode, 0 /* style */,
-                mode == WifiConfigUiBase.MODE_VIEW /* hideSubmitButton*/);
+                mode == WifiConfigUiBase.MODE_VIEW /* hideSubmitButton */);
+    }
+
+    /**
+     * Creates a WifiDialog with customized style. It displays as a dialog above the current
+     * view.
+     */
+    public static WifiDialog createModal(Context context, WifiDialogListener listener,
+        AccessPoint accessPoint, int mode, @StyleRes int style) {
+        return new WifiDialog(context, listener, accessPoint, mode, style,
+                mode == WifiConfigUiBase.MODE_VIEW /* hideSubmitButton */);
     }
 
     /* package */ WifiDialog(Context context, WifiDialogListener listener, AccessPoint accessPoint,
-            int mode, int style, boolean hideSubmitButton) {
+            int mode, @StyleRes int style, boolean hideSubmitButton) {
         super(context, style);
         mMode = mode;
         mListener = listener;
diff --git a/src/com/android/settings/wifi/WifiDialogActivity.java b/src/com/android/settings/wifi/WifiDialogActivity.java
index 35de66e..8268ecc 100644
--- a/src/com/android/settings/wifi/WifiDialogActivity.java
+++ b/src/com/android/settings/wifi/WifiDialogActivity.java
@@ -28,6 +28,7 @@
 
 import androidx.annotation.VisibleForTesting;
 
+import com.android.settings.R;
 import com.android.settings.SetupWizardUtils;
 import com.android.settings.wifi.dpp.WifiDppUtils;
 import com.android.settingslib.wifi.AccessPoint;
@@ -74,8 +75,13 @@
             accessPoint = new AccessPoint(this, accessPointState);
         }
 
-        mDialog = WifiDialog.createModal(
-                this, this, accessPoint, WifiConfigUiBase.MODE_CONNECT);
+        if (WizardManagerHelper.isAnySetupWizard(getIntent())) {
+            mDialog = WifiDialog.createModal(this, this, accessPoint,
+                    WifiConfigUiBase.MODE_CONNECT, R.style.SuwAlertDialogThemeCompat_Light);
+        } else {
+            mDialog = WifiDialog.createModal(
+                    this, this, accessPoint, WifiConfigUiBase.MODE_CONNECT);
+        }
         mDialog.show();
         mDialog.setOnDismissListener(this);
     }
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeSoundSettingsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeSoundSettingsPreferenceControllerTest.java
deleted file mode 100644
index a08a4d7..0000000
--- a/tests/robotests/src/com/android/settings/notification/ZenModeSoundSettingsPreferenceControllerTest.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2019 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.notification;
-
-import static com.android.settings.core.BasePreferenceController.AVAILABLE;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.Context;
-
-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;
-
-@RunWith(RobolectricTestRunner.class)
-public class ZenModeSoundSettingsPreferenceControllerTest {
-
-    private Context mContext;
-    private ZenModeSoundSettingsPreferenceController mController;
-    private static final String KEY_ZEN_MODE = "zen_mode";
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
-        mController = new ZenModeSoundSettingsPreferenceController(mContext, KEY_ZEN_MODE);
-    }
-
-    @Test
-    public void getAvailabilityStatus_available() {
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/sim/PreferredSimDialogFragmentTest.java b/tests/robotests/src/com/android/settings/sim/PreferredSimDialogFragmentTest.java
new file mode 100644
index 0000000..0b85c37
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/sim/PreferredSimDialogFragmentTest.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2019 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.sim;
+
+import static com.android.settings.sim.SimDialogActivity.PREFERRED_PICK;
+import static com.android.settings.sim.SimDialogActivity.PREFERRED_SIM;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.DialogInterface;
+
+import androidx.appcompat.app.AlertDialog;
+
+import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = ShadowAlertDialogCompat.class)
+public class PreferredSimDialogFragmentTest extends
+        SimDialogFragmentTestBase<PreferredSimDialogFragment> {
+
+    @Override
+    public void setUp() {
+        super.setUp();
+        setDialogType(PREFERRED_PICK);
+        mFragment = spy(PreferredSimDialogFragment.newInstance());
+        doReturn(mSubscriptionManager).when(mFragment).getSubscriptionManager();
+    }
+
+    @Test
+    public void onCreateDialog_noSims_dismissed() {
+        when(mSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(anyInt()))
+                .thenReturn(null);
+        mIntent.putExtra(PREFERRED_SIM, 0);
+        startDialog();
+        verify(mFragment).dismiss();
+    }
+
+    @Test
+    public void onCreateDialog_oneSimWrongSlotArgument_dismissed() {
+        when(mSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(1)).thenReturn(null);
+        mIntent.putExtra(PREFERRED_SIM, 1);
+        startDialog();
+        verify(mFragment).dismiss();
+    }
+
+    @Test
+    public void onCreateDialog_twoSimsSelectFirst_correctMessage() {
+        mIntent.putExtra(PREFERRED_SIM, 0);
+
+        final AlertDialog alertDialog = startDialog();
+        final ShadowAlertDialogCompat shadowDialog = ShadowAlertDialogCompat.shadowOf(alertDialog);
+        final String message = (String) shadowDialog.getMessage();
+        assertThat(message).contains(SIM1_NAME);
+        assertThat(message).doesNotContain(SIM2_NAME);
+    }
+
+    @Test
+    public void onCreateDialog_twoSimsSelectSecond_correctMessage() {
+        mIntent.putExtra(PREFERRED_SIM, 1);
+
+        final AlertDialog alertDialog = startDialog();
+        final ShadowAlertDialogCompat shadowDialog = ShadowAlertDialogCompat.shadowOf(alertDialog);
+        final String message = (String) shadowDialog.getMessage();
+        assertThat(message).contains(SIM2_NAME);
+        assertThat(message).doesNotContain(SIM1_NAME);
+    }
+
+    @Test
+    public void onClick_yesClicked_callsOnSubscriptionSelected() {
+        mIntent.putExtra(PREFERRED_SIM, 0);
+
+        final AlertDialog alertDialog = startDialog();
+
+        final SimDialogActivity activity = (SimDialogActivity) spy(mFragment.getActivity());
+        doReturn(activity).when(mFragment).getActivity();
+        doNothing().when(activity).onSubscriptionSelected(anyInt(), anyInt());
+
+        mFragment.onClick(alertDialog, DialogInterface.BUTTON_POSITIVE);
+        verify(activity).onSubscriptionSelected(PREFERRED_PICK, SIM1_ID);
+    }
+
+    @Test
+    public void onClick_noClicked_doesNotCallOnSubscriptionSelected() {
+        mIntent.putExtra(PREFERRED_SIM, 0);
+
+        final AlertDialog alertDialog = startDialog();
+
+        final SimDialogActivity activity = (SimDialogActivity) spy(mFragment.getActivity());
+        doReturn(activity).when(mFragment).getActivity();
+        doNothing().when(activity).onSubscriptionSelected(anyInt(), anyInt());
+
+        mFragment.onClick(alertDialog, DialogInterface.BUTTON_NEGATIVE);
+        verify(activity, never()).onSubscriptionSelected(anyInt(), anyInt());
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/sim/SimDialogFragmentTestBase.java b/tests/robotests/src/com/android/settings/sim/SimDialogFragmentTestBase.java
new file mode 100644
index 0000000..904b831
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/sim/SimDialogFragmentTestBase.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2019 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.sim;
+
+import static com.android.settings.sim.SimDialogActivity.DIALOG_TYPE_KEY;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Intent;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+
+import androidx.appcompat.app.AlertDialog;
+
+import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
+
+import org.junit.Before;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.shadows.androidx.fragment.FragmentController;
+
+public abstract class SimDialogFragmentTestBase<T extends SimDialogFragment> {
+    protected static final int SIM1_ID = 111;
+    protected static final int SIM2_ID = 222;
+    protected static final String SIM1_NAME = "sim111";
+    protected static final String SIM2_NAME = "sim222";
+
+    @Mock
+    protected SubscriptionManager mSubscriptionManager;
+    @Mock
+    protected SubscriptionInfo mSim1;
+    @Mock
+    protected SubscriptionInfo mSim2;
+
+    protected T mFragment;
+    protected Intent mIntent;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mIntent = new Intent();
+
+        when(mSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(0)).thenReturn(mSim1);
+        when(mSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(1)).thenReturn(mSim2);
+
+        when(mSim1.getSubscriptionId()).thenReturn(SIM1_ID);
+        when(mSim1.getDisplayName()).thenReturn(SIM1_NAME);
+        when(mSim2.getSubscriptionId()).thenReturn(SIM2_ID);
+        when(mSim2.getDisplayName()).thenReturn(SIM2_NAME);
+    }
+
+    protected void setDialogType(int dialogType) {
+        mIntent.putExtra(DIALOG_TYPE_KEY, dialogType);
+    }
+
+    protected AlertDialog startDialog() {
+        final FragmentController controller = FragmentController.of(mFragment,
+                SimDialogActivity.class, mIntent);
+        controller.create(0 /* containerViewId */, null /* bundle */).start().visible();
+        return ShadowAlertDialogCompat.getLatestAlertDialog();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/sim/SimListDialogFragmentTest.java b/tests/robotests/src/com/android/settings/sim/SimListDialogFragmentTest.java
new file mode 100644
index 0000000..2b33ebe
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/sim/SimListDialogFragmentTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2019 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.sim;
+
+import static com.android.settings.sim.SimDialogActivity.DATA_PICK;
+import static com.android.settings.sim.SimDialogActivity.SMS_PICK;
+
+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.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.telephony.SubscriptionManager;
+
+import androidx.appcompat.app.AlertDialog;
+
+import com.android.settings.R;
+import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+
+import java.util.Arrays;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = ShadowAlertDialogCompat.class)
+public class SimListDialogFragmentTest extends SimDialogFragmentTestBase<SimListDialogFragment> {
+
+    @Test
+    public void onCreateDialog_noSubscriptions_dismissed() {
+        final int dialogType = DATA_PICK;
+        setDialogType(dialogType);
+        mFragment = spy(SimListDialogFragment.newInstance(dialogType, R.string.select_sim_for_data,
+                false /* includeAskEveryTime */));
+        doReturn(null).when(mFragment).getCurrentSubscriptions();
+        startDialog();
+        verify(mFragment).dismiss();
+    }
+
+    @Test
+    public void onCreateDialog_twoSubscriptionsNoAskEveryTime_twoSubsForDisplay() {
+        final int dialogType = DATA_PICK;
+        setDialogType(dialogType);
+        mFragment = spy(SimListDialogFragment.newInstance(dialogType, R.string.select_sim_for_data,
+                false /* includeAskEveryTime */));
+        doReturn(Arrays.asList(mSim1, mSim2)).when(mFragment).getCurrentSubscriptions();
+        // Avoid problems robolectric has with our real adapter.
+        doNothing().when(mFragment).setAdapter(any());
+        final AlertDialog alertDialog = startDialog();
+        assertThat(mFragment.mSubscriptions).hasSize(2);
+
+        final SimDialogActivity activity = (SimDialogActivity) spy(mFragment.getActivity());
+        doReturn(activity).when(mFragment).getActivity();
+        doNothing().when(activity).onSubscriptionSelected(anyInt(), anyInt());
+
+        mFragment.onClick(alertDialog, 1);
+        verify(activity).onSubscriptionSelected(dialogType, SIM2_ID);
+    }
+
+    @Test
+    public void onCreateDialog_twoSubscriptionsAskEveryTime_threeSubsForDisplay() {
+        final int dialogType = SMS_PICK;
+        setDialogType(dialogType);
+        mFragment = spy(SimListDialogFragment.newInstance(dialogType, R.string.select_sim_for_sms,
+                true /* includeAskEveryTime */));
+        doReturn(Arrays.asList(mSim1, mSim2)).when(mFragment).getCurrentSubscriptions();
+        // Avoid problems robolectric has with our real adapter.
+        doNothing().when(mFragment).setAdapter(any());
+        final AlertDialog alertDialog = startDialog();
+        assertThat(mFragment.mSubscriptions).hasSize(3);
+        assertThat(mFragment.mSubscriptions.get(0)).isNull();
+
+        final SimDialogActivity activity = (SimDialogActivity) spy(mFragment.getActivity());
+        doReturn(activity).when(mFragment).getActivity();
+        doNothing().when(activity).onSubscriptionSelected(anyInt(), anyInt());
+
+        mFragment.onClick(alertDialog, 0);
+        verify(activity).onSubscriptionSelected(dialogType,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/widget/SeekBarPreferenceTest.java b/tests/robotests/src/com/android/settings/widget/SeekBarPreferenceTest.java
index a675e02..0a1d5d8 100644
--- a/tests/robotests/src/com/android/settings/widget/SeekBarPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/widget/SeekBarPreferenceTest.java
@@ -18,12 +18,16 @@
 
 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.os.Parcelable;
 
 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;
 
@@ -39,9 +43,10 @@
 
     @Before
     public void setUp() {
+        MockitoAnnotations.initMocks(this);
         mContext = RuntimeEnvironment.application;
 
-        mSeekBarPreference = new SeekBarPreference(mContext);
+        mSeekBarPreference = spy(new SeekBarPreference(mContext));
         mSeekBarPreference.setMax(MAX);
         mSeekBarPreference.setMin(MIN);
         mSeekBarPreference.setProgress(PROGRESS);
@@ -59,4 +64,18 @@
         assertThat(preference.getMin()).isEqualTo(MIN);
         assertThat(preference.getProgress()).isEqualTo(PROGRESS);
     }
+
+    @Test
+    public void isSelectable_disabledByAdmin_returnTrue() {
+        when(mSeekBarPreference.isDisabledByAdmin()).thenReturn(true);
+
+        assertThat(mSeekBarPreference.isSelectable()).isTrue();
+    }
+
+    @Test
+    public void isSelectable_notDisabledByAdmin_returnFalse() {
+        when(mSeekBarPreference.isDisabledByAdmin()).thenReturn(false);
+
+        assertThat(mSeekBarPreference.isSelectable()).isFalse();
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java b/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java
index d7f8ef8..41d1bbe 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java
@@ -23,10 +23,13 @@
 import android.content.Intent;
 import android.net.wifi.WifiConfiguration;
 
+import com.android.settings.R;
 import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
 import com.android.settings.testutils.shadow.ShadowConnectivityManager;
 import com.android.settings.testutils.shadow.ShadowWifiManager;
 
+import com.google.android.setupcompat.util.WizardManagerHelper;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -72,7 +75,7 @@
     }
 
     @Test
-    public void onSubmit_shouldNotConnectToNetwork_whenConnectForCallerIsFalse() {
+    public void onSubmit_whenConnectForCallerIsFalse_shouldNotConnectToNetwork() {
         WifiDialogActivity activity =
                 Robolectric.buildActivity(
                         WifiDialogActivity.class,
@@ -88,4 +91,24 @@
 
         assertThat(ShadowWifiManager.get().savedWifiConfig).isNull();
     }
+
+    @Test
+    public void onSubmit_whenLaunchInSetupFlow_shouldBeLightThemeForWifiDialog() {
+        WifiDialogActivity activity =
+                Robolectric.buildActivity(
+                        WifiDialogActivity.class,
+                        new Intent()
+                                .putExtra(WifiDialogActivity.KEY_CONNECT_FOR_CALLER, false)
+                                .putExtra(WizardManagerHelper.EXTRA_IS_FIRST_RUN, true)
+                                .putExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, true))
+                        .setup().get();
+        WifiDialog dialog = (WifiDialog) ShadowAlertDialogCompat.getLatestAlertDialog();
+
+        assertThat(dialog).isNotNull();
+
+        activity.onSubmit(dialog);
+
+        assertThat(dialog.getContext().getThemeResId())
+                .isEqualTo(R.style.SuwAlertDialogThemeCompat_Light);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiDialogTest.java b/tests/robotests/src/com/android/settings/wifi/WifiDialogTest.java
index 4ce29aa..ed9b851 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiDialogTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiDialogTest.java
@@ -4,6 +4,7 @@
 
 import android.content.Context;
 
+import com.android.settings.R;
 import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
 import com.android.settings.wifi.WifiDialog.WifiDialogListener;
 import com.android.settingslib.wifi.AccessPoint;
@@ -41,4 +42,16 @@
         assertThat(modal.getContext().getThemeResId())
                 .isEqualTo(wifiDialog.getContext().getThemeResId());
     }
+
+    @Test
+    public void createModal_whenSetTheme_shouldBeCustomizedTheme() {
+        WifiDialog modal = WifiDialog.createModal(mContext, mListener, mockAccessPoint,
+                WifiConfigUiBase.MODE_CONNECT, R.style.SuwAlertDialogThemeCompat_Light);
+
+        WifiDialog wifiDialog = new WifiDialog(mContext, mListener, mockAccessPoint,
+                WifiConfigUiBase.MODE_CONNECT, R.style.SuwAlertDialogThemeCompat_Light,
+                        false /* hideSubmitButton */);
+        assertThat(modal.getContext().getThemeResId())
+                .isEqualTo(wifiDialog.getContext().getThemeResId());
+    }
 }