Merge "Make WifiTether listen to datasaver" into pi-dev
diff --git a/res/layout/hotspot_ap_band_selection_dialog.xml b/res/layout/hotspot_ap_band_selection_dialog.xml
new file mode 100644
index 0000000..e63426d
--- /dev/null
+++ b/res/layout/hotspot_ap_band_selection_dialog.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:padding="8dp"
+    android:paddingStart="@dimen/wifi_ap_band_checkbox_padding">
+
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingStart="8dp"
+        android:text="@string/wifi_ap_band_select_one"
+        android:textAppearance="?android:attr/textAppearanceSmall"/>
+
+    <CheckBox
+        android:id="@+id/box_2g"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="@dimen/wifi_ap_band_checkbox_padding"
+        android:layout_marginTop="@dimen/wifi_ap_band_checkbox_padding"
+        android:paddingStart="@dimen/wifi_ap_band_checkbox_padding"
+        android:textAppearance="?android:attr/textAppearanceMedium"/>
+
+    <CheckBox
+        android:id="@+id/box_5g"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingStart="@dimen/wifi_ap_band_checkbox_padding"
+        android:textAppearance="?android:attr/textAppearanceMedium"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 78b64f2..6912bb4 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -269,7 +269,6 @@
    <!-- Wi-Fi AP band settings.  Either Auto, 2.4GHz or 5GHz. -->
    <!-- Note that adding/removing/moving the items will need wifi settings code change. -->
     <string-array name="wifi_ap_band_config_full">
-        <item>@string/wifi_ap_choose_auto</item>
         <item>@string/wifi_ap_choose_2G</item>
         <item>@string/wifi_ap_choose_5G</item>
     </string-array>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 6a052d2..f95de27 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -191,6 +191,7 @@
 
     <!-- WiFi Preferences -->
     <dimen name="wifi_divider_height">1px</dimen>
+    <dimen name="wifi_ap_band_checkbox_padding">16dp</dimen>
 
     <!-- Color picker -->
     <dimen name="color_swatch_size">16dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 7ba4715..b3b068a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -664,6 +664,8 @@
     <string name="save">Save</string>
     <!-- Button label for generic done action [CHAR LIMIT=20] -->
     <string name="done">Done</string>
+    <!-- Button label for generic apply action [CHAR LIMIT=20] -->
+    <string name="apply">Apply</string>
 
     <!-- Title of the Settings activity shown within the application itself. -->
     <string name="settings_label">Settings</string>
@@ -9078,13 +9080,13 @@
     <!-- Data usage remaining string [CHAR LIMIT=30] -->
     <string name="data_used"><xliff:g name="bytes" example="2 GB">^1</xliff:g> used</string>
 
-    <!-- Data usage remaining string [CHAR LIMIT=30] -->
+    <!-- Data usage remaining string [CHAR LIMIT=13] -->
     <string name="data_used_formatted"><xliff:g name="value" example="500">^1</xliff:g> <xliff:g name="units" example="GB">^2</xliff:g> used</string>
 
-    <!-- Data usage over limit string [CHAR LIMIT=30] -->
+    <!-- Shows the amount of data the user has used over their data limit [CHAR LIMIT=13] -->
     <string name="data_overusage"><xliff:g name="bytes" example="2 GB">^1</xliff:g> over</string>
 
-    <!-- Optional part of data usage showing the remaining amount [CHAR LIMIT=30] -->
+    <!-- Optional part of data usage showing the remaining amount [CHAR LIMIT=13] -->
     <string name="data_remaining"><xliff:g name="bytes" example="2 GB">^1</xliff:g> left</string>
 
     <!-- Informational text about time left in billing cycle [CHAR LIMIT=60] -->
diff --git a/res/xml/security_dashboard_settings.xml b/res/xml/security_dashboard_settings.xml
index 858cbaf..7519cef 100644
--- a/res/xml/security_dashboard_settings.xml
+++ b/res/xml/security_dashboard_settings.xml
@@ -41,7 +41,7 @@
         <com.android.settings.widget.GearPreference
             android:key="unlock_set_or_change"
             android:title="@string/unlock_set_unlock_launch_picker_title"
-            android:summary="@string/unlock_set_unlock_mode_none"
+            android:summary="@string/summary_placeholder"
             settings:keywords="@string/keywords_lockscreen" />
 
         <Preference
diff --git a/res/xml/wifi_tether_settings.xml b/res/xml/wifi_tether_settings.xml
index bb9af88..f9d9596 100644
--- a/res/xml/wifi_tether_settings.xml
+++ b/res/xml/wifi_tether_settings.xml
@@ -35,8 +35,11 @@
         android:title="@string/wifi_hotspot_auto_off_title"
         android:summary="@string/wifi_hotspot_auto_off_summary"/>
 
-    <ListPreference
+    <com.android.settings.widget.HotspotApBandSelectionPreference
         android:key="wifi_tether_network_ap_band"
         android:title="@string/wifi_hotspot_ap_band_title"
-        android:summary="@string/summary_placeholder" />
+        android:dialogLayout="@layout/hotspot_ap_band_selection_dialog"
+        android:dialogTitle="@string/wifi_hotspot_ap_band_title"
+        android:negativeButtonText="@string/cancel"
+        android:positiveButtonText="@string/apply"/>
 </PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/zen_mode_block_settings.xml b/res/xml/zen_mode_block_settings.xml
index 63dbd47..cccc63c 100644
--- a/res/xml/zen_mode_block_settings.xml
+++ b/res/xml/zen_mode_block_settings.xml
@@ -24,15 +24,15 @@
        android:title="@string/zen_mode_block_effects_screen_off"
        android:key="zen_mode_block_screen_off">
 
-       <CheckBoxPreference
+       <com.android.settings.widget.DisabledCheckBoxPreference
            android:key="zen_effect_intent"
            android:title="@string/zen_mode_block_effect_intent" />
 
-       <CheckBoxPreference
+       <com.android.settings.widget.DisabledCheckBoxPreference
            android:key="zen_effect_light"
            android:title="@string/zen_mode_block_effect_light" />
 
-       <CheckBoxPreference
+       <com.android.settings.widget.DisabledCheckBoxPreference
            android:key="zen_effect_ambient"
            android:title="@string/zen_mode_block_effect_ambient" />
 
@@ -40,19 +40,19 @@
     <PreferenceCategory
         android:title="@string/zen_mode_block_effects_screen_on"
         android:key="zen_mode_block_screen_on">
-       <CheckBoxPreference
+       <com.android.settings.widget.DisabledCheckBoxPreference
            android:key="zen_effect_badge"
            android:title="@string/zen_mode_block_effect_badge" />
 
-        <CheckBoxPreference
+        <com.android.settings.widget.DisabledCheckBoxPreference
             android:key="zen_effect_status"
             android:title="@string/zen_mode_block_effect_status" />
 
-        <CheckBoxPreference
+        <com.android.settings.widget.DisabledCheckBoxPreference
             android:key="zen_effect_peek"
             android:title="@string/zen_mode_block_effect_peek" />
 
-       <CheckBoxPreference
+       <com.android.settings.widget.DisabledCheckBoxPreference
            android:key="zen_effect_list"
            android:title="@string/zen_mode_block_effect_list" />
    </PreferenceCategory>
diff --git a/res/xml/zen_mode_settings.xml b/res/xml/zen_mode_settings.xml
index 385e8ff..717b6c5 100644
--- a/res/xml/zen_mode_settings.xml
+++ b/res/xml/zen_mode_settings.xml
@@ -25,7 +25,8 @@
     <!-- sound vibration -->
     <com.android.settings.widget.DisabledCheckBoxPreference
         android:key="zen_effect_sound"
-        android:title="@string/zen_mode_block_effect_sound" />
+        android:title="@string/zen_mode_block_effect_sound"
+        android:enabled="false"/>
 
     <!-- What to block (effects) -->
     <Preference
diff --git a/src/com/android/settings/RestrictedSettingsFragment.java b/src/com/android/settings/RestrictedSettingsFragment.java
index b17ca84..3b69eff 100644
--- a/src/com/android/settings/RestrictedSettingsFragment.java
+++ b/src/com/android/settings/RestrictedSettingsFragment.java
@@ -27,6 +27,7 @@
 import android.os.PersistableBundle;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.support.annotation.VisibleForTesting;
 import android.view.View;
 import android.widget.TextView;
 
@@ -56,7 +57,7 @@
     protected static final String RESTRICT_IF_OVERRIDABLE = "restrict_if_overridable";
 
     // No RestrictedSettingsFragment screens should use this number in startActivityForResult.
-    private static final int REQUEST_PIN_CHALLENGE = 12309;
+    @VisibleForTesting static final int REQUEST_PIN_CHALLENGE = 12309;
 
     private static final String KEY_CHALLENGE_SUCCEEDED = "chsc";
     private static final String KEY_CHALLENGE_REQUESTED = "chrq";
@@ -86,7 +87,8 @@
         }
     };
 
-    private AlertDialog mActionDisabledDialog;
+    @VisibleForTesting
+    AlertDialog mActionDisabledDialog;
 
     /**
      * @param restrictionKey The restriction key to check before pin protecting
@@ -153,6 +155,10 @@
             if (resultCode == Activity.RESULT_OK) {
                 mChallengeSucceeded = true;
                 mChallengeRequested = false;
+                if (mActionDisabledDialog != null && mActionDisabledDialog.isShowing()) {
+                    mActionDisabledDialog.setOnDismissListener(null);
+                    mActionDisabledDialog.dismiss();
+                }
             } else {
                 mChallengeSucceeded = false;
             }
diff --git a/src/com/android/settings/datausage/BillingCycleSettings.java b/src/com/android/settings/datausage/BillingCycleSettings.java
index b82e3be..c0bf16a 100644
--- a/src/com/android/settings/datausage/BillingCycleSettings.java
+++ b/src/com/android/settings/datausage/BillingCycleSettings.java
@@ -402,7 +402,6 @@
      */
     public static class ConfirmLimitFragment extends InstrumentedDialogFragment implements
             DialogInterface.OnClickListener {
-        private static final String EXTRA_MESSAGE = "message";
         @VisibleForTesting static final String EXTRA_LIMIT_BYTES = "limitBytes";
         public static final float FLOAT = 1.2f;
 
@@ -414,16 +413,13 @@
             if (policy == null) return;
 
             final Resources res = parent.getResources();
-            final CharSequence message;
             final long minLimitBytes = (long) (policy.warningBytes * FLOAT);
             final long limitBytes;
 
             // TODO: customize default limits based on network template
-            message = res.getString(R.string.data_usage_limit_dialog_mobile);
             limitBytes = Math.max(5 * GIB_IN_BYTES, minLimitBytes);
 
             final Bundle args = new Bundle();
-            args.putCharSequence(EXTRA_MESSAGE, message);
             args.putLong(EXTRA_LIMIT_BYTES, limitBytes);
 
             final ConfirmLimitFragment dialog = new ConfirmLimitFragment();
@@ -441,11 +437,9 @@
         public Dialog onCreateDialog(Bundle savedInstanceState) {
             final Context context = getActivity();
 
-            final CharSequence message = getArguments().getCharSequence(EXTRA_MESSAGE);
-
             return new AlertDialog.Builder(context)
                     .setTitle(R.string.data_usage_limit_dialog_title)
-                    .setMessage(message)
+                    .setMessage(R.string.data_usage_limit_dialog_mobile)
                     .setPositiveButton(android.R.string.ok, this)
                     .setNegativeButton(android.R.string.cancel, null)
                     .create();
diff --git a/src/com/android/settings/datausage/DataUsagePreference.java b/src/com/android/settings/datausage/DataUsagePreference.java
index 766a2a9..9d0b104 100644
--- a/src/com/android/settings/datausage/DataUsagePreference.java
+++ b/src/com/android/settings/datausage/DataUsagePreference.java
@@ -56,7 +56,7 @@
         DataUsageController.DataUsageInfo usageInfo = controller.getDataUsageInfo(mTemplate);
         if (FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.DATA_USAGE_SETTINGS_V2)) {
             if (mTemplate.isMatchRuleMobile()) {
-                setTitle(getContext().getString(R.string.app_cellular_data_usage));
+                setTitle(R.string.app_cellular_data_usage);
             } else {
                 setTitle(mTitleRes);
                 setSummary(getContext().getString(R.string.data_usage_template,
@@ -83,7 +83,7 @@
                 .setSourceMetricsCategory(MetricsProto.MetricsEvent.VIEW_UNKNOWN);
         if (FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.DATA_USAGE_SETTINGS_V2)) {
             if (mTemplate.isMatchRuleMobile()) {
-                launcher.setTitle(getContext().getString(R.string.app_cellular_data_usage));
+                launcher.setTitle(R.string.app_cellular_data_usage);
             } else {
                 launcher.setTitle(mTitleRes);
             }
diff --git a/src/com/android/settings/deviceinfo/StorageWizardBase.java b/src/com/android/settings/deviceinfo/StorageWizardBase.java
index 4787ac5..40fc249 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardBase.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardBase.java
@@ -22,6 +22,7 @@
 import static com.android.settings.deviceinfo.StorageSettings.TAG;
 
 import android.annotation.LayoutRes;
+import android.annotation.NonNull;
 import android.app.Activity;
 import android.content.Intent;
 import android.graphics.drawable.Drawable;
@@ -145,7 +146,7 @@
         ((TextView) aux.requireViewById(R.id.storage_wizard_migrate_v2_checklist_media))
                 .setText(TextUtils.expandTemplate(
                         getText(R.string.storage_wizard_migrate_v2_checklist_media),
-                        mDisk.getShortDescription()));
+                        getDiskShortDescription()));
     }
 
     protected void setBackButtonText(int resId, CharSequence... args) {
@@ -228,6 +229,26 @@
         }
     }
 
+    protected @NonNull CharSequence getDiskDescription() {
+        if (mDisk != null) {
+            return mDisk.getDescription();
+        } else if (mVolume != null) {
+            return mVolume.getDescription();
+        } else {
+            return getText(R.string.unknown);
+        }
+    }
+
+    protected @NonNull CharSequence getDiskShortDescription() {
+        if (mDisk != null) {
+            return mDisk.getShortDescription();
+        } else if (mVolume != null) {
+            return mVolume.getDescription();
+        } else {
+            return getText(R.string.unknown);
+        }
+    }
+
     private final StorageEventListener mStorageListener = new StorageEventListener() {
         @Override
         public void onDiskDestroyed(DiskInfo disk) {
diff --git a/src/com/android/settings/deviceinfo/StorageWizardFormatProgress.java b/src/com/android/settings/deviceinfo/StorageWizardFormatProgress.java
index 8e3f8ef..0711907 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardFormatProgress.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardFormatProgress.java
@@ -57,8 +57,8 @@
 
         mFormatPrivate = getIntent().getBooleanExtra(EXTRA_FORMAT_PRIVATE, false);
 
-        setHeaderText(R.string.storage_wizard_format_progress_title, mDisk.getShortDescription());
-        setBodyText(R.string.storage_wizard_format_progress_body, mDisk.getDescription());
+        setHeaderText(R.string.storage_wizard_format_progress_title, getDiskShortDescription());
+        setBodyText(R.string.storage_wizard_format_progress_body, getDiskDescription());
 
         mTask = (PartitionTask) getLastNonConfigurationInstance();
         if (mTask == null) {
diff --git a/src/com/android/settings/deviceinfo/StorageWizardFormatSlow.java b/src/com/android/settings/deviceinfo/StorageWizardFormatSlow.java
index 9c80ff6..37df2170 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardFormatSlow.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardFormatSlow.java
@@ -39,10 +39,10 @@
 
         mFormatPrivate = getIntent().getBooleanExtra(EXTRA_FORMAT_PRIVATE, false);
 
-        setHeaderText(R.string.storage_wizard_slow_v2_title, mDisk.getShortDescription());
-        setBodyText(R.string.storage_wizard_slow_v2_body, mDisk.getDescription(),
-                mDisk.getShortDescription(), mDisk.getShortDescription(),
-                mDisk.getShortDescription());
+        setHeaderText(R.string.storage_wizard_slow_v2_title, getDiskShortDescription());
+        setBodyText(R.string.storage_wizard_slow_v2_body, getDiskDescription(),
+                getDiskShortDescription(), getDiskShortDescription(),
+                getDiskShortDescription());
 
         setBackButtonText(R.string.storage_wizard_slow_v2_start_over);
         setNextButtonText(R.string.storage_wizard_slow_v2_continue);
diff --git a/src/com/android/settings/deviceinfo/StorageWizardInit.java b/src/com/android/settings/deviceinfo/StorageWizardInit.java
index 2233cf9..0fc850b 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardInit.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardInit.java
@@ -45,7 +45,7 @@
         mIsPermittedToAdopt = UserManager.get(this).isAdminUser()
                 && !ActivityManager.isUserAMonkey();
 
-        setHeaderText(R.string.storage_wizard_init_v2_title, mDisk.getShortDescription());
+        setHeaderText(R.string.storage_wizard_init_v2_title, getDiskShortDescription());
 
         mExternal = requireViewById(R.id.storage_wizard_init_external);
         mInternal = requireViewById(R.id.storage_wizard_init_internal);
diff --git a/src/com/android/settings/deviceinfo/StorageWizardMigrateConfirm.java b/src/com/android/settings/deviceinfo/StorageWizardMigrateConfirm.java
index 755f093..969a50a 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardMigrateConfirm.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardMigrateConfirm.java
@@ -59,7 +59,7 @@
         }
 
         setIcon(R.drawable.ic_swap_horiz);
-        setHeaderText(R.string.storage_wizard_migrate_v2_title, mDisk.getShortDescription());
+        setHeaderText(R.string.storage_wizard_migrate_v2_title, getDiskShortDescription());
         setBodyText(R.string.memory_calculating_size);
         setAuxChecklist();
 
@@ -67,7 +67,7 @@
             @Override
             public void onPostExecute(String size, String time) {
                 setBodyText(R.string.storage_wizard_migrate_v2_body,
-                        mDisk.getDescription(), size, time);
+                        getDiskDescription(), size, time);
             }
         };
 
diff --git a/src/com/android/settings/deviceinfo/StorageWizardReady.java b/src/com/android/settings/deviceinfo/StorageWizardReady.java
index c5c4ca2..fdb8d8a 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardReady.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardReady.java
@@ -33,20 +33,20 @@
         }
         setContentView(R.layout.storage_wizard_generic);
 
-        setHeaderText(R.string.storage_wizard_ready_title, mDisk.getShortDescription());
+        setHeaderText(R.string.storage_wizard_ready_title, getDiskShortDescription());
 
         final VolumeInfo privateVol = findFirstVolume(VolumeInfo.TYPE_PRIVATE);
         if (privateVol != null) {
             if (getIntent().getBooleanExtra(EXTRA_MIGRATE_SKIP, false)) {
                 setBodyText(R.string.storage_wizard_ready_v2_internal_body,
-                        mDisk.getDescription());
+                        getDiskDescription());
             } else {
                 setBodyText(R.string.storage_wizard_ready_v2_internal_moved_body,
-                        mDisk.getDescription(), mDisk.getShortDescription());
+                        getDiskDescription(), getDiskShortDescription());
             }
         } else {
             setBodyText(R.string.storage_wizard_ready_v2_external_body,
-                    mDisk.getDescription());
+                    getDiskDescription());
         }
 
         setNextButtonText(R.string.done);
diff --git a/src/com/android/settings/fuelgauge/BatteryUtils.java b/src/com/android/settings/fuelgauge/BatteryUtils.java
index c8a5d47..639c1fb 100644
--- a/src/com/android/settings/fuelgauge/BatteryUtils.java
+++ b/src/com/android/settings/fuelgauge/BatteryUtils.java
@@ -416,6 +416,11 @@
         mAppOpsManager.setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid, packageName, mode);
     }
 
+    public boolean isForceAppStandbyEnabled(int uid, String packageName) {
+        return mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid,
+                packageName) == AppOpsManager.MODE_IGNORED;
+    }
+
     public void initBatteryStatsHelper(BatteryStatsHelper statsHelper, Bundle bundle,
             UserManager userManager) {
         statsHelper.create(bundle);
diff --git a/src/com/android/settings/fuelgauge/RestrictedAppDetails.java b/src/com/android/settings/fuelgauge/RestrictedAppDetails.java
index e75112c..96fafb3 100644
--- a/src/com/android/settings/fuelgauge/RestrictedAppDetails.java
+++ b/src/com/android/settings/fuelgauge/RestrictedAppDetails.java
@@ -133,7 +133,8 @@
             try {
                 final ApplicationInfo applicationInfo = mPackageManager.getApplicationInfoAsUser(
                         appInfo.packageName, 0 /* flags */, UserHandle.getUserId(appInfo.uid));
-                checkBoxPreference.setChecked(true);
+                checkBoxPreference.setChecked(
+                        mBatteryUtils.isForceAppStandbyEnabled(appInfo.uid, appInfo.packageName));
                 checkBoxPreference.setTitle(mPackageManager.getApplicationLabel(applicationInfo));
                 checkBoxPreference.setIcon(
                         Utils.getBadgedIcon(mIconDrawableFactory, mPackageManager,
diff --git a/src/com/android/settings/network/ApnEditor.java b/src/com/android/settings/network/ApnEditor.java
index d0ecb71..e2853a6 100644
--- a/src/com/android/settings/network/ApnEditor.java
+++ b/src/com/android/settings/network/ApnEditor.java
@@ -28,6 +28,7 @@
 import android.os.Bundle;
 import android.os.PersistableBundle;
 import android.provider.Telephony;
+import android.support.annotation.VisibleForTesting;
 import android.support.v14.preference.MultiSelectListPreference;
 import android.support.v14.preference.SwitchPreference;
 import android.support.v7.preference.EditTextPreference;
@@ -47,7 +48,6 @@
 import android.view.View;
 import android.view.View.OnKeyListener;
 
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.util.ArrayUtils;
@@ -309,6 +309,16 @@
         fillUI(icicle == null);
     }
 
+    @VisibleForTesting
+    static String formatInteger(String value) {
+        try {
+            final int intValue = Integer.parseInt(value);
+            return String.format("%d", intValue);
+        } catch (NumberFormatException e) {
+            return value;
+        }
+    }
+
     /**
      * Check if passed in array of APN types indicates all APN types
      * @param apnTypes array of APN types. "*" indicates all types.
@@ -547,8 +557,8 @@
         mMmsProxy.setSummary(checkNull(mMmsProxy.getText()));
         mMmsPort.setSummary(checkNull(mMmsPort.getText()));
         mMmsc.setSummary(checkNull(mMmsc.getText()));
-        mMcc.setSummary(checkNull(mMcc.getText()));
-        mMnc.setSummary(checkNull(mMnc.getText()));
+        mMcc.setSummary(formatInteger(checkNull(mMcc.getText())));
+        mMnc.setSummary(formatInteger(checkNull(mMnc.getText())));
         mApnType.setSummary(checkNull(mApnType.getText()));
 
         String authVal = mAuthType.getValue();
@@ -598,20 +608,6 @@
         }
     }
 
-    private String bearerDescription(String raw) {
-        int mBearerIndex = mBearerMulti.findIndexOfValue(raw);
-        if (mBearerIndex == -1) {
-            return null;
-        } else {
-            String[] values = getResources().getStringArray(R.array.bearer_entries);
-            try {
-                return values[mBearerIndex];
-            } catch (ArrayIndexOutOfBoundsException e) {
-                return null;
-            }
-        }
-    }
-
     private String bearerMultiDescription(Set<String> raw) {
         String[] values = getResources().getStringArray(R.array.bearer_entries);
         StringBuilder retVal = new StringBuilder();
diff --git a/src/com/android/settings/notification/ZenModeVisEffectPreferenceController.java b/src/com/android/settings/notification/ZenModeVisEffectPreferenceController.java
index 23723c5..67fd822 100644
--- a/src/com/android/settings/notification/ZenModeVisEffectPreferenceController.java
+++ b/src/com/android/settings/notification/ZenModeVisEffectPreferenceController.java
@@ -24,6 +24,7 @@
 
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settings.widget.DisabledCheckBoxPreference;
 
 public class ZenModeVisEffectPreferenceController
         extends AbstractZenModePreferenceController
@@ -78,9 +79,9 @@
         if (parentSuppressed) {
             ((CheckBoxPreference) preference).setChecked(parentSuppressed);
             onPreferenceChange(preference, parentSuppressed);
-            preference.setEnabled(false);
+            ((DisabledCheckBoxPreference) preference).enableCheckbox(false);
         } else {
-            preference.setEnabled(true);
+            ((DisabledCheckBoxPreference) preference).enableCheckbox(true);
             ((CheckBoxPreference) preference).setChecked(suppressed);
         }
     }
diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java
index ab2cb82..70e9d76 100644
--- a/src/com/android/settings/slices/SettingsSliceProvider.java
+++ b/src/com/android/settings/slices/SettingsSliceProvider.java
@@ -24,6 +24,7 @@
 import android.graphics.drawable.Icon;
 import android.net.Uri;
 import android.net.wifi.WifiManager;
+import android.provider.Settings;
 import android.provider.SettingsSlicesContract;
 import android.support.annotation.VisibleForTesting;
 import android.support.v4.graphics.drawable.IconCompat;
@@ -290,13 +291,14 @@
                         .addEndItem(new SliceAction(getBroadcastIntent(ACTION_WIFI_CHANGED),
                                 null, finalWifiEnabled))
                         .setPrimaryAction(
-                                new SliceAction(getIntent(Intent.ACTION_MAIN),
+                                new SliceAction(getIntent(Settings.ACTION_WIFI_SETTINGS),
                                         (IconCompat) null, null)))
                 .build();
     }
 
     private PendingIntent getIntent(String action) {
         Intent intent = new Intent(action);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         PendingIntent pi = PendingIntent.getActivity(getContext(), 0, intent, 0);
         return pi;
     }
diff --git a/src/com/android/settings/widget/DisabledCheckBoxPreference.java b/src/com/android/settings/widget/DisabledCheckBoxPreference.java
index 482cff3..e441e21 100644
--- a/src/com/android/settings/widget/DisabledCheckBoxPreference.java
+++ b/src/com/android/settings/widget/DisabledCheckBoxPreference.java
@@ -17,46 +17,85 @@
 package com.android.settings.widget;
 
 import android.content.Context;
+import android.content.res.TypedArray;
+import android.support.v7.preference.CheckBoxPreference;
+import android.support.v7.preference.PreferenceViewHolder;
 import android.util.AttributeSet;
 import android.view.View;
 
-import android.support.v7.preference.CheckBoxPreference;
-import android.support.v7.preference.PreferenceViewHolder;
-
 /**
- * A CheckboxPreference with a disabled checkbox. Differs from CheckboxPreference.setDisabled()
- * in that the text is not dimmed.
+ * A CheckboxPreference that can disable its checkbox separate from its text.
+ * Differs from CheckboxPreference.setDisabled() in that the text is not dimmed.
  */
 public class DisabledCheckBoxPreference extends CheckBoxPreference {
+    private PreferenceViewHolder mViewHolder;
+    private View mCheckBox;
+    private boolean mEnabledCheckBox;
 
-    public DisabledCheckBoxPreference(Context context, AttributeSet attrs,
-            int defStyleAttr, int defStyleRes) {
+    public DisabledCheckBoxPreference(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
+        setupDisabledCheckBoxPreference(context, attrs, defStyleAttr, defStyleRes);
     }
 
     public DisabledCheckBoxPreference(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
+        setupDisabledCheckBoxPreference(context, attrs, defStyleAttr, 0);
     }
 
     public DisabledCheckBoxPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
+        setupDisabledCheckBoxPreference(context, attrs, 0, 0);
     }
 
     public DisabledCheckBoxPreference(Context context) {
         super(context);
+        setupDisabledCheckBoxPreference(context, null, 0, 0);
+    }
+
+    private void setupDisabledCheckBoxPreference(Context context, AttributeSet attrs,
+            int defStyleAttr, int defStyleRes) {
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.Preference, defStyleAttr, defStyleRes);
+        for (int i = a.getIndexCount() - 1; i >= 0; i--) {
+            int attr = a.getIndex(i);
+            switch (attr) {
+                case com.android.internal.R.styleable.Preference_enabled:
+                    mEnabledCheckBox = a.getBoolean(attr, true);
+                    break;
+            }
+        }
+        a.recycle();
+
+        // Always tell super class this preference is enabled.
+        // We manually enable/disable checkbox using enableCheckBox.
+        super.setEnabled(true);
+        enableCheckbox(mEnabledCheckBox);
+    }
+
+    public void enableCheckbox(boolean enabled) {
+        mEnabledCheckBox = enabled;
+        if (mViewHolder != null && mCheckBox != null) {
+            mCheckBox.setEnabled(mEnabledCheckBox);
+            mViewHolder.itemView.setEnabled(mEnabledCheckBox);
+        }
     }
 
     @Override
     public void onBindViewHolder(PreferenceViewHolder holder) {
         super.onBindViewHolder(holder);
+        mViewHolder = holder;
+        mCheckBox = holder.findViewById(android.R.id.checkbox);
 
-        View view = holder.findViewById(android.R.id.checkbox);
-        view.setEnabled(false);
-        holder.itemView.setEnabled(false);
+        enableCheckbox(mEnabledCheckBox);
     }
 
     @Override
     protected void performClick(View view) {
-        // Do nothing
+        // only perform clicks if the checkbox is enabled
+        if (mEnabledCheckBox) {
+            super.performClick(view);
+        }
     }
+
 }
diff --git a/src/com/android/settings/widget/HotspotApBandSelectionPreference.java b/src/com/android/settings/widget/HotspotApBandSelectionPreference.java
new file mode 100644
index 0000000..4f127eb
--- /dev/null
+++ b/src/com/android/settings/widget/HotspotApBandSelectionPreference.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settings.widget;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.net.wifi.WifiConfiguration;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.support.annotation.VisibleForTesting;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.LinearLayout;
+
+import com.android.settings.R;
+import com.android.settingslib.CustomDialogPreference;
+
+import java.util.ArrayList;
+
+public class HotspotApBandSelectionPreference extends CustomDialogPreference implements
+        CompoundButton.OnCheckedChangeListener, DialogInterface.OnShowListener {
+    private static final int UNSET = Integer.MIN_VALUE;
+
+    @VisibleForTesting
+    static final String KEY_CHECKED_BANDS = "checked_bands";
+    @VisibleForTesting
+    static final String KEY_HOTSPOT_SUPER_STATE = "hotspot_super_state";
+
+    @VisibleForTesting
+    CheckBox mBox2G;
+    @VisibleForTesting
+    CheckBox mBox5G;
+    @VisibleForTesting
+    ArrayList<Integer> mRestoredBands;
+    @VisibleForTesting
+    boolean mShouldRestore;
+
+    private String[] mBandEntries;
+    private int mExistingConfigValue = UNSET;
+
+    public HotspotApBandSelectionPreference(Context context) {
+        super(context);
+    }
+
+    public HotspotApBandSelectionPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public HotspotApBandSelectionPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public HotspotApBandSelectionPreference(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Parcelable state) {
+        SavedState myState = (SavedState) state;
+
+        super.onRestoreInstanceState(myState.getSuperState());
+
+        mShouldRestore = myState.shouldRestore;
+        if (mShouldRestore) {
+            mRestoredBands = new ArrayList<>();
+            if (myState.enabled2G) {
+                mRestoredBands.add(WifiConfiguration.AP_BAND_2GHZ);
+            }
+            if (myState.enabled5G) {
+                mRestoredBands.add(WifiConfiguration.AP_BAND_5GHZ);
+            }
+        } else {
+            mRestoredBands = null;
+        }
+        updatePositiveButton();
+    }
+
+    @Override
+    protected void onBindDialogView(View view) {
+        super.onBindDialogView(view);
+        final Context context = getContext();
+
+        // Register so we can adjust the buttons if needed once the dialog is available.
+        setOnShowListener(this);
+
+        mBandEntries = context.getResources().getStringArray(R.array.wifi_ap_band_config_full);
+        // add a checkbox for every band entry.
+        addApBandViews((LinearLayout) view);
+        // try to update the button just in case we already missed the onShow call.
+        updatePositiveButton();
+        // clear any saved state so it doesn't leak across multiple rotations/dialog closings
+        mRestoredBands = null;
+        mShouldRestore = false;
+    }
+
+    @Override
+    protected Parcelable onSaveInstanceState() {
+        final Parcelable superState = super.onSaveInstanceState();
+
+        SavedState myState = new SavedState(superState);
+        myState.shouldRestore = getDialog() != null;
+        myState.enabled2G = mBox2G.isChecked();
+        myState.enabled5G = mBox5G.isChecked();
+        return myState;
+    }
+
+    @Override
+    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+        if (!(buttonView instanceof CheckBox)) {
+            return;
+        }
+        updatePositiveButton();
+    }
+
+    @Override
+    protected void onClick(DialogInterface dialog, int which) {
+        // we only want to persist our enabled bands if apply is clicked
+        if (which == DialogInterface.BUTTON_POSITIVE) {
+            if (mBox2G.isChecked() || mBox5G.isChecked()) {
+                int wifiBand = getWifiBand();
+                mExistingConfigValue = wifiBand;
+                callChangeListener(wifiBand);
+            }
+        }
+    }
+
+    /**
+     * Used to set the band selection for the preference if one already exists
+     * @param band the band to set it to from {@link WifiConfiguration}
+     */
+    public void setExistingConfigValue(int band) {
+        mExistingConfigValue = band;
+    }
+
+    private void addApBandViews(LinearLayout view) {
+        mBox2G = view.findViewById(R.id.box_2g);
+        mBox2G.setText(mBandEntries[WifiConfiguration.AP_BAND_2GHZ]);
+        mBox2G.setChecked(restoreBandIfNeeded(WifiConfiguration.AP_BAND_2GHZ));
+        mBox2G.setOnCheckedChangeListener(this);
+
+        mBox5G = view.findViewById(R.id.box_5g);
+        mBox5G.setText(mBandEntries[WifiConfiguration.AP_BAND_5GHZ]);
+        mBox5G.setChecked(restoreBandIfNeeded(WifiConfiguration.AP_BAND_5GHZ));
+        mBox5G.setOnCheckedChangeListener(this);
+    }
+
+    private boolean restoreBandIfNeeded(int band) {
+        // Only use the provided config if we aren't restoring, restore if state available
+        return (isBandPreviouslySelected(band) && !mShouldRestore)
+                || (mShouldRestore && mRestoredBands.contains(band));
+    }
+
+    private void updatePositiveButton() {
+        AlertDialog dialog = (AlertDialog) getDialog();
+        Button button = dialog == null ? null : dialog.getButton(DialogInterface.BUTTON_POSITIVE);
+        if (button != null && mBox5G != null && mBox2G != null) {
+            button.setEnabled(mBox2G.isChecked() || mBox5G.isChecked());
+        }
+    }
+
+    @VisibleForTesting
+    int getWifiBand() {
+        final boolean checked_2g = mBox2G.isChecked();
+        final boolean checked_5g = mBox5G.isChecked();
+        if (checked_2g && checked_5g) {
+            return WifiConfiguration.AP_BAND_ANY;
+        } else if (checked_2g && !checked_5g) {
+            return WifiConfiguration.AP_BAND_2GHZ;
+        } else if (checked_5g && !checked_2g) {
+            return WifiConfiguration.AP_BAND_5GHZ;
+        } else {
+            throw new IllegalStateException("Wifi Config only supports selecting one or all bands");
+        }
+    }
+
+    private boolean isBandPreviouslySelected(int bandIndex) {
+        switch(mExistingConfigValue) {
+            case WifiConfiguration.AP_BAND_ANY:
+                return true;
+            case WifiConfiguration.AP_BAND_2GHZ:
+                return bandIndex == 0;
+            case WifiConfiguration.AP_BAND_5GHZ:
+                return bandIndex == 1;
+            case UNSET:
+            default:
+                return false;
+        }
+    }
+
+    @Override
+    public void onShow(DialogInterface dialog) {
+        updatePositiveButton();
+    }
+
+    private static class SavedState extends BaseSavedState {
+        boolean shouldRestore;
+        boolean enabled2G;
+        boolean enabled5G;
+
+        public SavedState(Parcelable source) {
+            super(source);
+        }
+
+        private SavedState(Parcel in) {
+            super(in);
+            shouldRestore =  in.readByte() == 1;
+            enabled2G = in.readByte() == 1;
+            enabled5G = in.readByte() == 1;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            super.writeToParcel(dest, flags);
+            dest.writeByte((byte) (shouldRestore ? 1 : 0));
+            dest.writeByte((byte) (enabled2G ? 1: 0));
+            dest.writeByte((byte) (enabled5G ? 1 : 0));
+        }
+
+        @Override
+        public String toString() {
+            return "HotspotApBandSelectionPreference.SavedState{"
+                    + Integer.toHexString(System.identityHashCode(this))
+                    + " shouldRestore=" + shouldRestore
+                    + " enabled2G=" + enabled2G
+                    + " enabled5G=" + enabled5G + "}";
+        }
+
+        public static final Parcelable.Creator<SavedState> CREATOR
+                = new Parcelable.Creator<SavedState>() {
+            public SavedState createFromParcel(Parcel in) {
+                return new SavedState(in);
+            }
+
+            public SavedState[] newArray(int size) {
+                return new SavedState[size];
+            }
+        };
+    }
+}
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 4f1c832..7a7caf4 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -912,7 +912,7 @@
 
     private void launchNetworkDetailsFragment(ConnectedAccessPointPreference pref) {
         new SubSettingLauncher(getContext())
-                .setTitle(getContext().getString(R.string.pref_title_network_details))
+                .setTitle(R.string.pref_title_network_details)
                 .setDestination(WifiNetworkDetailsFragment.class.getName())
                 .setArguments(pref.getExtras())
                 .setSourceMetricsCategory(getMetricsCategory())
diff --git a/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceController.java b/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceController.java
index 4c47a0d..b107777 100644
--- a/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceController.java
+++ b/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceController.java
@@ -18,31 +18,34 @@
 
 import static android.net.wifi.WifiConfiguration.AP_BAND_2GHZ;
 import static android.net.wifi.WifiConfiguration.AP_BAND_5GHZ;
-import static android.net.wifi.WifiConfiguration.AP_BAND_ANY;
 
 import android.content.Context;
+import android.content.res.Resources;
+import android.icu.text.ListFormatter;
 import android.net.wifi.WifiConfiguration;
-import android.support.v7.preference.ListPreference;
 import android.support.v7.preference.Preference;
 import android.util.Log;
 
 import com.android.settings.R;
+import com.android.settings.widget.HotspotApBandSelectionPreference;
 
 public class WifiTetherApBandPreferenceController extends WifiTetherBasePreferenceController {
 
     private static final String TAG = "WifiTetherApBandPref";
     private static final String PREF_KEY = "wifi_tether_network_ap_band";
-    private static final String[] BAND_VALUES =
-            {String.valueOf(AP_BAND_ANY), String.valueOf(AP_BAND_2GHZ),
-                    String.valueOf(AP_BAND_5GHZ)};
+    public static final String[] BAND_VALUES =
+            {String.valueOf(AP_BAND_2GHZ), String.valueOf(AP_BAND_5GHZ)};
 
     private final String[] mBandEntries;
+    private final String[] mBandSummaries;
     private int mBandIndex;
 
     public WifiTetherApBandPreferenceController(Context context,
             OnTetherConfigUpdateListener listener) {
         super(context, listener);
-        mBandEntries = mContext.getResources().getStringArray(R.array.wifi_ap_band_config_full);
+        Resources res = mContext.getResources();
+        mBandEntries = res.getStringArray(R.array.wifi_ap_band_config_full);
+        mBandSummaries = res.getStringArray(R.array.wifi_ap_band_summary_full);
     }
 
     @Override
@@ -60,18 +63,25 @@
             mBandIndex = config.apBand;
             Log.d(TAG, "5Ghz not supported, updating band index to " + mBandIndex);
         }
-        ListPreference preference = (ListPreference) mPreference;
+        HotspotApBandSelectionPreference preference =
+                (HotspotApBandSelectionPreference) mPreference;
+
         if (!is5GhzBandSupported()) {
             preference.setEnabled(false);
             preference.setSummary(R.string.wifi_ap_choose_2G);
         } else {
-            preference.setEntries(mBandEntries);
-            preference.setEntryValues(BAND_VALUES);
-            preference.setSummary(mBandEntries[mBandIndex + 1]);
-            preference.setValue(String.valueOf(mBandIndex));
+            preference.setExistingConfigValue(config.apBand);
+            preference.setSummary(getConfigSummary());
         }
     }
 
+    String getConfigSummary() {
+        if (mBandIndex == WifiConfiguration.AP_BAND_ANY) {
+            return ListFormatter.getInstance().format((Object[]) mBandSummaries);
+        }
+        return mBandSummaries[mBandIndex];
+    }
+
     @Override
     public String getPreferenceKey() {
         return PREF_KEY;
@@ -79,9 +89,9 @@
 
     @Override
     public boolean onPreferenceChange(Preference preference, Object newValue) {
-        mBandIndex = Integer.parseInt((String) newValue);
+        mBandIndex = (Integer) newValue;
         Log.d(TAG, "Band preference changed, updating band index to " + mBandIndex);
-        preference.setSummary(mBandEntries[mBandIndex + 1]);
+        preference.setSummary(getConfigSummary());
         mListener.onTetherConfigUpdated();
         return true;
     }
diff --git a/tests/robotests/src/com/android/settings/RestrictedSettingsFragmentTest.java b/tests/robotests/src/com/android/settings/RestrictedSettingsFragmentTest.java
new file mode 100644
index 0000000..e370cda
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/RestrictedSettingsFragmentTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.settings;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class RestrictedSettingsFragmentTest {
+
+    @Mock
+    private AlertDialog mAlertDialog;
+    private RestrictedSettingsFragment mFragment;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void onActivityResult_dismissesDialogOnOk() {
+        mFragment = new RestrictedSettingsFragment("fake_key") {
+            @Override
+            public int getMetricsCategory() {
+                return 0;
+            }
+        };
+        doReturn(true).when(mAlertDialog).isShowing();
+        mFragment.mActionDisabledDialog = mAlertDialog;
+        mFragment.onActivityResult(RestrictedSettingsFragment.REQUEST_PIN_CHALLENGE,
+                Activity.RESULT_OK,
+                null);
+
+        // dialog should be gone
+        verify(mAlertDialog, times(1)).setOnDismissListener(isNull());
+        verify(mAlertDialog, times(1)).dismiss();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
index 772bb8d..dc34016 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
@@ -565,6 +565,22 @@
     }
 
     @Test
+    public void testIsForceAppStandbyEnabled_enabled_returnTrue() {
+        when(mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID,
+                PACKAGE_NAME)).thenReturn(AppOpsManager.MODE_IGNORED);
+
+        assertThat(mBatteryUtils.isForceAppStandbyEnabled(UID, PACKAGE_NAME)).isTrue();
+    }
+
+    @Test
+    public void testIsForceAppStandbyEnabled_disabled_returnFalse() {
+        when(mAppOpsManager.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID,
+                PACKAGE_NAME)).thenReturn(AppOpsManager.MODE_ALLOWED);
+
+        assertThat(mBatteryUtils.isForceAppStandbyEnabled(UID, PACKAGE_NAME)).isFalse();
+    }
+
+    @Test
     public void testIsAppHeavilyUsed_usageMoreThanThreshold_returnTrue() {
         assertThat(mBatteryUtils.isAppHeavilyUsed(mBatteryStatsHelper, mUserManager, UID,
                 10 /* threshold */ )).isTrue();
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/RestrictedAppDetailsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/RestrictedAppDetailsTest.java
index 94a6903..0fad0a7 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/RestrictedAppDetailsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/RestrictedAppDetailsTest.java
@@ -28,10 +28,12 @@
 import android.content.pm.PackageManager;
 import android.os.Bundle;
 import android.os.UserHandle;
+import android.support.v7.preference.CheckBoxPreference;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceCategory;
 import android.support.v7.preference.PreferenceManager;
 import android.util.IconDrawableFactory;
+import android.widget.CheckBox;
 
 import com.android.settings.SettingsActivity;
 import com.android.settings.core.InstrumentedPreferenceFragment;
@@ -93,7 +95,7 @@
         mRestrictedAppDetails.mAppInfos = new ArrayList<>();
         mRestrictedAppDetails.mAppInfos.add(mAppInfo);
         mRestrictedAppDetails.mRestrictedAppListGroup = spy(new PreferenceCategory(mContext));
-        mRestrictedAppDetails.mBatteryUtils = new BatteryUtils(mContext);
+        mRestrictedAppDetails.mBatteryUtils = spy(new BatteryUtils(mContext));
         doReturn(mPreferenceManager).when(
                 mRestrictedAppDetails.mRestrictedAppListGroup).getPreferenceManager();
     }
@@ -103,13 +105,16 @@
         doReturn(mApplicationInfo).when(mPackageManager)
                 .getApplicationInfoAsUser(PACKAGE_NAME, 0, USER_ID);
         doReturn(APP_NAME).when(mPackageManager).getApplicationLabel(mApplicationInfo);
+        doReturn(true).when(mRestrictedAppDetails.mBatteryUtils).isForceAppStandbyEnabled(UID,
+                PACKAGE_NAME);
 
         mRestrictedAppDetails.refreshUi();
 
         assertThat(mRestrictedAppDetails.mRestrictedAppListGroup.getPreferenceCount()).isEqualTo(1);
-        final Preference preference = mRestrictedAppDetails.mRestrictedAppListGroup.getPreference(
-                0);
+        final CheckBoxPreference preference =
+                (CheckBoxPreference) mRestrictedAppDetails.mRestrictedAppListGroup.getPreference(0);
         assertThat(preference.getTitle()).isEqualTo(APP_NAME);
+        assertThat(preference.isChecked()).isTrue();
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/network/ApnEditorTest.java b/tests/robotests/src/com/android/settings/network/ApnEditorTest.java
index 1b34fd3..35f68a0 100644
--- a/tests/robotests/src/com/android/settings/network/ApnEditorTest.java
+++ b/tests/robotests/src/com/android/settings/network/ApnEditorTest.java
@@ -437,6 +437,16 @@
         assertThat(str).isNull();
     }
 
+    @Test
+    public void formatInteger_shouldParseString() {
+        assertThat(ApnEditor.formatInteger("42")).isEqualTo("42");
+    }
+
+    @Test
+    public void formatInteger_shouldIgnoreNonIntegers() {
+        assertThat(ApnEditor.formatInteger("not an int")).isEqualTo("not an int");
+    }
+
     private void initCursor() {
         doReturn(2).when(mCursor).getColumnCount();
         doReturn(Integer.valueOf(2)).when(mCursor).getInt(CURSOR_INTEGER_INDEX);
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeVisEffectPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeVisEffectPreferenceControllerTest.java
index 6ca04ba..29ced0b 100644
--- a/tests/robotests/src/com/android/settings/notification/ZenModeVisEffectPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeVisEffectPreferenceControllerTest.java
@@ -42,6 +42,7 @@
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settings.widget.DisabledCheckBoxPreference;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -58,7 +59,7 @@
     @Mock
     private ZenModeBackend mBackend;
     @Mock
-    private CheckBoxPreference mockPref;
+    private DisabledCheckBoxPreference mockPref;
     private Context mContext;
     private FakeFeatureFactory mFeatureFactory;
     @Mock
@@ -114,7 +115,7 @@
         mController.updateState(mockPref);
 
         verify(mockPref).setChecked(false);
-        verify(mockPref).setEnabled(true);
+        verify(mockPref).enableCheckbox(true);
     }
 
     @Test
@@ -123,7 +124,7 @@
         mController.updateState(mockPref);
 
         verify(mockPref).setChecked(true);
-        verify(mockPref).setEnabled(true);
+        verify(mockPref).enableCheckbox(true);
     }
 
     @Test
@@ -138,7 +139,7 @@
         mController.updateState(mockPref);
 
         verify(mockPref).setChecked(true);
-        verify(mockPref).setEnabled(false);
+        verify(mockPref).enableCheckbox(false);
         verify(mBackend, times(1)).saveVisualEffectsPolicy(SUPPRESSED_EFFECT_PEEK, true);
     }
 
@@ -154,7 +155,7 @@
         mController.updateState(mockPref);
 
         verify(mockPref).setChecked(false);
-        verify(mockPref).setEnabled(true);
+        verify(mockPref).enableCheckbox(true);
         verify(mBackend, never()).saveVisualEffectsPolicy(SUPPRESSED_EFFECT_PEEK, true);
     }
 
diff --git a/tests/robotests/src/com/android/settings/widget/DisabledCheckBoxPreferenceTest.java b/tests/robotests/src/com/android/settings/widget/DisabledCheckBoxPreferenceTest.java
index 5ab7013..ff10833 100644
--- a/tests/robotests/src/com/android/settings/widget/DisabledCheckBoxPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/widget/DisabledCheckBoxPreferenceTest.java
@@ -21,6 +21,7 @@
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
 import android.content.Context;
@@ -70,14 +71,28 @@
     }
 
     @Test
-    public void checkboxOnClick_doesNothing() {
+    public void checkboxOnClick_checkboxDisabled() {
         Preference.OnPreferenceClickListener onClick =
                 mock(Preference.OnPreferenceClickListener.class);
         mPref.setOnPreferenceClickListener(onClick);
         inflatePreference();
 
+        mPref.enableCheckbox(false);
         mPref.performClick(mRootView);
 
         verify(onClick, never()).onPreferenceClick(any());
     }
+
+    @Test
+    public void checkboxOnClick_checkboxEnabled() {
+        Preference.OnPreferenceClickListener onClick =
+                mock(Preference.OnPreferenceClickListener.class);
+        mPref.setOnPreferenceClickListener(onClick);
+        inflatePreference();
+
+        mPref.enableCheckbox(true);
+        mPref.performClick(mRootView);
+
+        verify(onClick, times(1)).onPreferenceClick(any());
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/widget/HotspotApBandSelectionPreferenceTest.java b/tests/robotests/src/com/android/settings/widget/HotspotApBandSelectionPreferenceTest.java
new file mode 100644
index 0000000..6bfc968
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/widget/HotspotApBandSelectionPreferenceTest.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.widget;
+
+import static com.android.settingslib.CustomDialogPreference.CustomPreferenceDialogFragment;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.net.wifi.WifiConfiguration;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.LinearLayout;
+
+import com.android.settings.R;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.util.ReflectionHelpers;
+
+import java.util.List;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class HotspotApBandSelectionPreferenceTest {
+    private HotspotApBandSelectionPreference mPreference;
+    private Context mContext;
+    private Button mSaveButton;
+    private View mLayout;
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application;
+        mSaveButton = spy(new Button(mContext));
+
+        final CustomPreferenceDialogFragment fragment = mock(CustomPreferenceDialogFragment.class);
+        final AlertDialog dialog = mock(AlertDialog.class);
+        when(fragment.getDialog()).thenReturn(dialog);
+        when(dialog.getButton(anyInt())).thenReturn(mSaveButton);
+
+        mPreference = new HotspotApBandSelectionPreference(mContext);
+        ReflectionHelpers.setField(mPreference, "mFragment", fragment);
+
+        final LayoutInflater inflater = LayoutInflater.from(mContext);
+        mLayout = inflater.inflate(R.layout.hotspot_ap_band_selection_dialog,
+                new LinearLayout(mContext), false);
+    }
+
+    @Test
+    public void getWifiBand_updatesBandPresetConfigProvided() {
+        mPreference.setExistingConfigValue(WifiConfiguration.AP_BAND_ANY);
+        mPreference.onBindDialogView(mLayout);
+
+        // check that the boxes are set correctly when a pre-existing config is set
+        assertThat(mPreference.getWifiBand()).isEqualTo(WifiConfiguration.AP_BAND_ANY);
+    }
+
+    @Test
+    public void getWifiBand_updatesBandWhenBoxesToggled() {
+        mPreference.setExistingConfigValue(WifiConfiguration.AP_BAND_ANY);
+        mPreference.onBindDialogView(mLayout);
+
+        assertThat(mPreference.getWifiBand()).isEqualTo(WifiConfiguration.AP_BAND_ANY);
+
+        // make sure we have the expected box then toggle it
+        mPreference.mBox2G.setChecked(false);
+
+        // check that band is updated
+        assertThat(mPreference.getWifiBand()).isEqualTo(WifiConfiguration.AP_BAND_5GHZ);
+    }
+
+    @Test
+    public void onSaveInstanceState_skipWhenDialogGone() {
+        mPreference.setExistingConfigValue(WifiConfiguration.AP_BAND_2GHZ);
+        mPreference.onBindDialogView(mLayout);
+        // remove the fragment to make the dialog unavailable
+        ReflectionHelpers.setField(mPreference, "mFragment", null);
+
+        mPreference.setExistingConfigValue(WifiConfiguration.AP_BAND_ANY);
+        mPreference.onBindDialogView(mLayout);
+
+        // state should only be saved when the dialog is available
+        Parcelable parcelable = mPreference.onSaveInstanceState();
+        mPreference.onRestoreInstanceState(parcelable);
+        assertThat(mPreference.mShouldRestore).isFalse();
+    }
+
+    @Test
+    public void onSaveInstanceState_presentWhenDialogPresent() {
+        mPreference.setExistingConfigValue(WifiConfiguration.AP_BAND_2GHZ);
+        mPreference.onBindDialogView(mLayout);
+
+        Parcelable parcelable = mPreference.onSaveInstanceState();
+        mPreference.onRestoreInstanceState(parcelable);
+        assertThat(mPreference.mShouldRestore).isTrue();
+    }
+
+    @Test
+    public void positiveButton_updatedCorrectly() {
+        mPreference.setExistingConfigValue(WifiConfiguration.AP_BAND_ANY);
+        mPreference.onBindDialogView(mLayout);
+
+        // button is enabled whole time so far since we have a pre-existing selection
+        verify(mSaveButton, never()).setEnabled(false);
+
+        // clear all boxes and make sure it stays enabled until empty
+        mPreference.mBox2G.setChecked(false);
+        mPreference.mBox5G.setChecked(false);
+
+        // button should be disabled now
+        verify(mSaveButton, times(1)).setEnabled(false);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceControllerTest.java
index 3f364f9..d9c867c 100644
--- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceControllerTest.java
@@ -24,12 +24,13 @@
 
 import android.content.Context;
 import android.net.ConnectivityManager;
+import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
-import android.support.v7.preference.ListPreference;
 import android.support.v7.preference.PreferenceScreen;
 
 import com.android.settings.R;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.widget.HotspotApBandSelectionPreference;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -42,6 +43,7 @@
 @RunWith(SettingsRobolectricTestRunner.class)
 public class WifiTetherApBandPreferenceControllerTest {
 
+    private static final String ALL_BANDS = "2.4 GHz and 5.0 GHz";
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private Context mContext;
     @Mock
@@ -54,18 +56,21 @@
     private PreferenceScreen mScreen;
 
     private WifiTetherApBandPreferenceController mController;
-    private ListPreference mListPreference;
+    private HotspotApBandSelectionPreference mPreference;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mListPreference = new ListPreference(RuntimeEnvironment.application);
+        mPreference = new HotspotApBandSelectionPreference(RuntimeEnvironment.application);
         when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager);
         when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE))
                 .thenReturn(mConnectivityManager);
         when(mConnectivityManager.getTetherableWifiRegexs()).thenReturn(new String[]{"1", "2"});
         when(mContext.getResources()).thenReturn(RuntimeEnvironment.application.getResources());
-        when(mScreen.findPreference(anyString())).thenReturn(mListPreference);
+        when(mScreen.findPreference(anyString())).thenReturn(mPreference);
+        WifiConfiguration config = new WifiConfiguration();
+        config.apBand = WifiConfiguration.AP_BAND_ANY;
+        when(mWifiManager.getWifiApConfiguration()).thenReturn(new WifiConfiguration());
 
         mController = new WifiTetherApBandPreferenceController(mContext, mListener);
     }
@@ -76,8 +81,9 @@
         when(mWifiManager.isDualBandSupported()).thenReturn(true);
 
         mController.displayPreference(mScreen);
+        mController.onPreferenceChange(mPreference, -1);
 
-        assertThat(mListPreference.getEntries().length).isEqualTo(3);
+        assertThat(mPreference.getSummary()).isEqualTo(ALL_BANDS);
     }
 
     @Test
@@ -87,9 +93,8 @@
 
         mController.displayPreference(mScreen);
 
-        assertThat(mListPreference.getEntries()).isNull();
-        assertThat(mListPreference.isEnabled()).isFalse();
-        assertThat(mListPreference.getSummary())
+        assertThat(mPreference.isEnabled()).isFalse();
+        assertThat(mPreference.getSummary())
                 .isEqualTo(RuntimeEnvironment.application.getString(R.string.wifi_ap_choose_2G));
     }
 
@@ -99,9 +104,8 @@
 
         mController.displayPreference(mScreen);
 
-        assertThat(mListPreference.getEntries()).isNull();
-        assertThat(mListPreference.isEnabled()).isFalse();
-        assertThat(mListPreference.getSummary())
+        assertThat(mPreference.isEnabled()).isFalse();
+        assertThat(mPreference.getSummary())
                 .isEqualTo(RuntimeEnvironment.application.getString(R.string.wifi_ap_choose_2G));
     }
 
@@ -112,14 +116,17 @@
         mController.displayPreference(mScreen);
 
         // -1 is WifiConfiguration.AP_BAND_ANY, for 'Auto' option.
-        mController.onPreferenceChange(mListPreference, "-1");
+        mController.onPreferenceChange(mPreference, -1);
         assertThat(mController.getBandIndex()).isEqualTo(-1);
+        assertThat(mPreference.getSummary()).isEqualTo(ALL_BANDS);
 
-        mController.onPreferenceChange(mListPreference, "1");
+        mController.onPreferenceChange(mPreference, 1);
         assertThat(mController.getBandIndex()).isEqualTo(1);
+        assertThat(mPreference.getSummary()).isEqualTo("5.0 GHz");
 
-        mController.onPreferenceChange(mListPreference, "0");
+        mController.onPreferenceChange(mPreference, 0);
         assertThat(mController.getBandIndex()).isEqualTo(0);
+        assertThat(mPreference.getSummary()).isEqualTo("2.4 GHz");
 
         verify(mListener, times(3)).onTetherConfigUpdated();
     }
@@ -129,7 +136,7 @@
         // Set controller band index to 1 and verify is set.
         when(mWifiManager.is5GHzBandSupported()).thenReturn(true);
         mController.displayPreference(mScreen);
-        mController.onPreferenceChange(mListPreference, "1");
+        mController.onPreferenceChange(mPreference, 1);
         assertThat(mController.getBandIndex()).isEqualTo(1);
 
         // Disable 5Ghz band