Merge "Fix channel screen launching" into pi-dev
diff --git a/res/layout/data_usage_summary_preference.xml b/res/layout/data_usage_summary_preference.xml
index c2e1581..eda8a81 100644
--- a/res/layout/data_usage_summary_preference.xml
+++ b/res/layout/data_usage_summary_preference.xml
@@ -35,15 +35,34 @@
         android:textColor="?android:attr/textColorSecondary"
         android:text="@string/data_usage_title" />
 
-    <TextView
-        android:id="@android:id/title"
-        android:paddingTop="12dp"
-        android:paddingBottom="4dp"
+    <LinearLayout
+        android:id="@+id/usage_layout"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:fontFamily="@*android:string/config_headlineFontFamily"
-        android:textColor="?android:attr/colorAccent"
-        android:textAppearance="@android:style/TextAppearance.Material.Large" />
+        android:paddingTop="12dp"
+        android:paddingBottom="4dp"
+        android:orientation="horizontal">
+
+        <TextView android:id="@+id/data_usage_view"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:fontFamily="@*android:string/config_headlineFontFamily"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textColor="?android:attr/colorAccent" />
+
+        <Space
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1" />
+
+        <TextView android:id="@+id/data_remaining_view"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:fontFamily="@*android:string/config_headlineFontFamily"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textColor="?android:attr/colorAccent" />
+
+    </LinearLayout>
 
     <android.widget.ProgressBar
         android:id="@+id/determinateBar"
diff --git a/res/layout/preference_widget_gear_optional_background.xml b/res/layout/preference_widget_gear_optional_background.xml
new file mode 100644
index 0000000..d02f638
--- /dev/null
+++ b/res/layout/preference_widget_gear_optional_background.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<!-- Settings button with optional ripple background through toggling visiblity. -->
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <ImageView
+        android:id="@+id/settings_button_no_background"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_gravity="center"
+        android:scaleType="center"
+        android:src="@drawable/ic_settings"
+        android:contentDescription="@string/settings_button" />
+    <!-- Additional overdraw background to stop parent's material ripple -->
+    <FrameLayout
+        android:id="@+id/settings_button"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="invisible"
+        android:background="?android:attr/colorBackground">
+        <ImageView
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_gravity="center"
+            android:paddingStart="?android:attr/listPreferredItemPaddingEnd"
+            android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+            android:background="?android:attr/selectableItemBackground"
+            android:scaleType="center"
+            android:src="@drawable/ic_settings"
+            android:contentDescription="@string/settings_button" />
+    </FrameLayout>
+</FrameLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 162674b..d388946 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1731,6 +1731,8 @@
     <string name="wifi_band_5ghz">5 GHz</string>
     <!-- Wifi Sign in text for button [CHAR LIMIT = 40]-->
     <string name="wifi_sign_in_button_text">Sign in</string>
+    <!-- Wifi Sign in CTA for wifi settings when captive portal auth is required [CHAR LIMIT = 50] -->
+    <string name="wifi_tap_to_sign_in">Tap here to sign in to network</string>
     <!-- Link speed on Wifi Status screen -->
     <string name="link_speed">%1$d Mbps</string>
 
@@ -3402,14 +3404,11 @@
     <!-- [CHAR LIMIT=130] Preference title for Wi-Fi always scanning -->
     <string name="location_scanning_wifi_always_scanning_title">Wi\u2011Fi scanning</string>
     <!-- Preference description text for Wi-Fi always scanning -->
-    <string name="location_scanning_wifi_always_scanning_description">Improve location by allowing
-      system apps and services to detect Wi\u2011Fi networks at any time.</string>
+    <string name="location_scanning_wifi_always_scanning_description">Allow apps and services to scan for Wi\u2011Fi networks at any time, even when Wi\u2011Fi is off. This can be used, for example, to improve location-based features and services.</string>
     <!-- [CHAR LIMIT=130] Description text for Bluetooth always scanning -->
     <string name="location_scanning_bluetooth_always_scanning_title">Bluetooth scanning</string>
     <!-- Description text for Bluetooth always scanning -->
-    <string name="location_scanning_bluetooth_always_scanning_description">
-        Improve location by allowing system apps and services to detect Bluetooth devices at any
-        time.</string>
+    <string name="location_scanning_bluetooth_always_scanning_description">Allow apps and services to scan for nearby devices at any time, even when Bluetooth is off. This can be used, for example, to improve location-based features and services.</string>
 
     <!-- [CHAR LIMIT=30] Security & location settings screen, setting check box label for Google location service (cell ID, wifi, etc.) -->
     <string name="location_network_based">Wi\u2011Fi &amp; mobile network location</string>
@@ -4728,7 +4727,7 @@
     <string name="power_charge_remaining"><xliff:g id="until_charged">%1$s</xliff:g> to charge</string>
 
     <!-- Title for the background activity setting, which allows a user to control whether an app can run in the background [CHAR_LIMIT=40] -->
-    <string name="background_activity_title">Restricted</string>
+    <string name="background_activity_title">Battery restrictions</string>
     <!-- Summary for the background activity [CHAR_LIMIT=120] -->
     <string name="background_activity_summary">Allow the app to run in the background</string>
     <!-- Summary for the background activity when it is on [CHAR_LIMIT=120] -->
@@ -4879,8 +4878,12 @@
         <item quantity="one">Restrict app?</item>
         <item quantity="other">Restrict %1$d apps?</item>
     </plurals>
-    <!-- Message for battery tip dialog to show the restrict app list [CHAR LIMIT=NONE] -->
-    <string name="battery_tip_restrict_app_dialog_message">To save battery, you can stop this app from running in the background when it’s not being used.</string>
+    <!-- Message for battery tip dialog to show the info to restrict the app [CHAR LIMIT=NONE] -->
+    <string name="battery_tip_restrict_app_dialog_message">To save battery, stop <xliff:g id="app">%1$s</xliff:g> from using battery in the background.</string>
+    <!-- Message for battery tip dialog to show the info to restrict the app, below it app list will be shown as a view [CHAR LIMIT=NONE] -->
+    <string name="battery_tip_restrict_apps_less_than_5_dialog_message">To save battery, stop these apps from using battery in the background.\n\nApps:\n</string>
+    <!-- Message for battery tip dialog to show the info to restrict the app, below it app list will be shown as raw string[CHAR LIMIT=NONE] -->
+    <string name="battery_tip_restrict_apps_more_than_5_dialog_message">To save battery, stop these apps from using battery in the background.\n\nApps:\n<xliff:g id="app_list">%1$s</xliff:g>.</string>
     <!-- OK button for battery tip dialog to show the restrict app list [CHAR LIMIT=NONE] -->
     <string name="battery_tip_restrict_app_dialog_ok">Restrict</string>
     <!-- Title for dialog to remove restriction for the app [CHAR LIMIT=NONE] -->
@@ -7755,9 +7758,9 @@
     <string name="encryption_interstitial_no">No</string>
 
     <!-- Label to say yes to the question of whether app is restricted. [CHAR LIMIT=20] -->
-    <string name="restricted_true_label">Yes</string>
+    <string name="restricted_true_label">On / Background usage restricted</string>
     <!-- Label to say no to the question of whether app is restricted. [CHAR LIMIT=20] -->
-    <string name="restricted_false_label">No</string>
+    <string name="restricted_false_label">Off / Uses battery in background</string>
 
     <!-- Title for encryption dialog that disables TalkBack. [CHAR_LIMIT=25] -->
     <string name="encrypt_talkback_dialog_require_pin">Require PIN?</string>
@@ -8693,6 +8696,15 @@
     <!-- Title of button for application usage cycle preferences [CHAR LIMIT=40] -->
     <string name="app_usage_cycle">App data usage cycle</string>
 
+    <!-- Format for a summary describing the amount of data before the user is warned [CHAR LIMIT=NONE] -->
+    <string name="cell_data_warning"><xliff:g name="amount" example="1 GB">^1</xliff:g> data warning</string>
+
+    <!-- Format for a summary describing the amount of data the limit is set to [CHAR LIMIT=NONE] -->
+    <string name="cell_data_limit"><xliff:g name="amount" example="1 GB">^1</xliff:g> data limit</string>
+
+    <!-- Format for a summary describing the amount of data before the user is warned or limited [CHAR LIMIT=NONE] -->
+    <string name="cell_data_warning_and_limit"><xliff:g name="amount" example="1 GB">^1</xliff:g> data warning / <xliff:g name="amount" example="2 GB">^2</xliff:g> data limit</string>
+
     <!-- Summary describing when the billing cycle for their phone carrier starts [CHAR LIMIT=NONE] -->
     <string name="billing_cycle_fragment_summary">Monthly on day <xliff:g name="day_of_month" example="17">%1$s</xliff:g></string>
 
@@ -8745,14 +8757,26 @@
     <!-- Data usage title text [CHAR LIMIT=30] -->
     <string name="data_usage_title">Primary data</string>
 
-    <!-- Data usage string [CHAR LIMIT=30] -->
+    <!-- Data usage remaining string [CHAR LIMIT=30] -->
     <string name="data_used"><xliff:g name="bytes" example="2 GB">^1</xliff:g> used</string>
 
-    <!-- Optional part of data usage showing the remaining amount [CHAR LIMIT=30] -->
-    <string name="data_remaining"><xliff:g name="bytes" example="2 GB">, ^1</xliff:g> left</string>
+    <!-- Data usage over limit string [CHAR LIMIT=30] -->
+    <string name="data_overusage"><xliff:g name="bytes" example="2 GB">^1</xliff:g> over</string>
 
-    <!-- Informational text about time left in billing cycle [CHAR LIMIT=30] -->
-    <string name="cycle_left_time_text"><xliff:g name="time" example="2d">%1$s</xliff:g> left in this cycle</string>
+    <!-- Optional part of data usage showing the remaining amount [CHAR LIMIT=30] -->
+    <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] -->
+    <string name="cycle_left_multiple_days"><xliff:g name="time" example="2d">%d</xliff:g> days left</string>
+
+    <!-- Informational text about time left in billing cycle [CHAR LIMIT=60] -->
+    <plurals name="billing_cycle_days_left">
+        <item quantity="one">%d day left</item>
+        <item quantity="other">%d days left</item>
+    </plurals>
+
+    <!-- Informational text about time left in billing cycle [CHAR LIMIT=60] -->
+    <string name="billing_cycle_less_than_one_day_left">Less than 1 day left</string>
 
     <!-- Informational text about carrier and update time [CHAR LIMIT=30] -->
     <string name="carrier_and_update_text">Updated by <xliff:g name="carrier" example="T-mobile">%1$s</xliff:g> <xliff:g name="time" example="3m">%2$s</xliff:g></string>
diff --git a/src/com/android/settings/datausage/DataUsageSummary.java b/src/com/android/settings/datausage/DataUsageSummary.java
index 2d50589..6d9ef38 100644
--- a/src/com/android/settings/datausage/DataUsageSummary.java
+++ b/src/com/android/settings/datausage/DataUsageSummary.java
@@ -234,12 +234,17 @@
     static CharSequence formatUsage(Context context, String template, long usageLevel) {
         final float LARGER_SIZE = 1.25f * 1.25f;  // (1/0.8)^2
         final float SMALLER_SIZE = 1.0f / LARGER_SIZE;  // 0.8^2
+        return formatUsage(context, template, usageLevel, LARGER_SIZE, SMALLER_SIZE);
+    }
+
+    static CharSequence formatUsage(Context context, String template, long usageLevel,
+                                    float larger, float smaller) {
         final int FLAGS = Spannable.SPAN_INCLUSIVE_INCLUSIVE;
 
         final Formatter.BytesResult usedResult = Formatter.formatBytes(context.getResources(),
                 usageLevel, Formatter.FLAG_CALCULATE_ROUNDED);
         final SpannableString enlargedValue = new SpannableString(usedResult.value);
-        enlargedValue.setSpan(new RelativeSizeSpan(LARGER_SIZE), 0, enlargedValue.length(), FLAGS);
+        enlargedValue.setSpan(new RelativeSizeSpan(larger), 0, enlargedValue.length(), FLAGS);
 
         final SpannableString amountTemplate = new SpannableString(
                 context.getString(com.android.internal.R.string.fileSizeSuffix)
@@ -248,7 +253,7 @@
                 enlargedValue, usedResult.units);
 
         final SpannableString fullTemplate = new SpannableString(template);
-        fullTemplate.setSpan(new RelativeSizeSpan(SMALLER_SIZE), 0, fullTemplate.length(), FLAGS);
+        fullTemplate.setSpan(new RelativeSizeSpan(smaller), 0, fullTemplate.length(), FLAGS);
         return TextUtils.expandTemplate(fullTemplate,
                 BidiFormatter.getInstance().unicodeWrap(formattedUsage.toString()));
     }
diff --git a/src/com/android/settings/datausage/DataUsageSummaryPreference.java b/src/com/android/settings/datausage/DataUsageSummaryPreference.java
index dbf87fe..e8715aa 100644
--- a/src/com/android/settings/datausage/DataUsageSummaryPreference.java
+++ b/src/com/android/settings/datausage/DataUsageSummaryPreference.java
@@ -21,6 +21,7 @@
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceViewHolder;
 import android.text.TextUtils;
+import android.text.format.Formatter;
 import android.util.AttributeSet;
 import android.view.View;
 import android.widget.Button;
@@ -28,19 +29,29 @@
 import android.widget.TextView;
 
 import com.android.settings.R;
+import com.android.settingslib.Utils;
 import com.android.settingslib.utils.StringUtil;
 
 import java.util.Objects;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Provides a summary of data usage.
  */
 public class DataUsageSummaryPreference extends Preference {
+    private static final long MILLIS_IN_A_DAY = TimeUnit.DAYS.toMillis(1);
+    private static final long WARNING_AGE = TimeUnit.HOURS.toMillis(6L);
 
     private boolean mChartEnabled = true;
     private String mStartLabel;
     private String mEndLabel;
 
+    /** large vs small size is 36/16 ~ 2.25 */
+    private static final float LARGER_FONT_RATIO = 2.25f;
+    private static final float SMALLER_FONT_RATIO = 1.0f;
+
+    private boolean mDefaultTextColorSet;
+    private int mDefaultTextColor;
     private int mNumPlans;
     /** The ending time of the billing cycle in milliseconds since epoch. */
     private long mCycleEndTimeMs;
@@ -53,6 +64,16 @@
 
     /** Progress to display on ProgressBar */
     private float mProgress;
+    private boolean mHasMobileData;
+
+    /**
+     * The size of the first registered plan if one exists or the size of the warning if it is set.
+     * -1 if no information is available.
+     */
+    private long mDataplanSize;
+
+    /** The number of bytes used since the start of the cycle. */
+    private long mDataplanUse;
 
     public DataUsageSummaryPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -94,10 +115,18 @@
         notifyChanged();
     }
 
+    void setUsageNumbers(long used, long dataPlanSize, boolean hasMobileData) {
+        mDataplanUse = used;
+        mDataplanSize = dataPlanSize;
+        mHasMobileData = hasMobileData;
+        notifyChanged();
+    }
+
     @Override
     public void onBindViewHolder(PreferenceViewHolder holder) {
         super.onBindViewHolder(holder);
 
+
         if (mChartEnabled && (!TextUtils.isEmpty(mStartLabel) || !TextUtils.isEmpty(mEndLabel))) {
             holder.findViewById(R.id.label_bar).setVisibility(View.VISIBLE);
             ProgressBar bar = (ProgressBar) holder.findViewById(R.id.determinateBar);
@@ -108,16 +137,15 @@
             holder.findViewById(R.id.label_bar).setVisibility(View.GONE);
         }
 
+        updateDataUsageLabels(holder);
+
         TextView usageTitle = (TextView) holder.findViewById(R.id.usage_title);
         usageTitle.setVisibility(mNumPlans > 1 ? View.VISIBLE : View.GONE);
 
-        TextView cycleTime = (TextView) holder.findViewById(R.id.cycle_left_time);
-        cycleTime.setText(getContext().getString(R.string.cycle_left_time_text,
-                StringUtil.formatElapsedTime(getContext(),
-                        mCycleEndTimeMs - System.currentTimeMillis(),false /* withSeconds */)));
+        updateCycleTimeText(holder);
 
-        TextView carrierInfo = (TextView) holder.findViewById(R.id.carrier_and_update);
-        setCarrierInfo(carrierInfo, mCarrierName, mSnapshotTimeMs);
+
+        updateCarrierInfo((TextView) holder.findViewById(R.id.carrier_and_update));
 
         Button launchButton = (Button) holder.findViewById(R.id.launch_mdp_app_button);
         launchButton.setOnClickListener((view) -> {
@@ -135,18 +163,61 @@
         limitInfo.setText(mLimitInfoText);
     }
 
-    private void setCarrierInfo(TextView carrierInfo, CharSequence carrierName, long updateAge) {
-        if (mNumPlans > 0 && updateAge >= 0L) {
+
+    private void updateDataUsageLabels(PreferenceViewHolder holder) {
+        TextView usageNumberField = (TextView) holder.findViewById(R.id.data_usage_view);
+        usageNumberField.setText(TextUtils.expandTemplate(
+                getContext().getString(R.string.data_used),
+                Formatter.formatFileSize(getContext(), mDataplanUse)));
+        if (mHasMobileData && mNumPlans >= 0 && mDataplanSize > 0L) {
+            TextView usageRemainingField = (TextView) holder.findViewById(R.id.data_remaining_view);
+            long dataRemaining = mDataplanSize - mDataplanUse;
+            if (dataRemaining >= 0) {
+                usageRemainingField.setText(
+                        TextUtils.expandTemplate(getContext().getText(R.string.data_remaining),
+                                Formatter.formatFileSize(getContext(), dataRemaining)));
+            } else {
+                usageRemainingField.setText(
+                        TextUtils.expandTemplate(getContext().getText(R.string.data_overusage),
+                                Formatter.formatFileSize(getContext(), -dataRemaining)));
+            }
+        }
+    }
+
+    private void updateCycleTimeText(PreferenceViewHolder holder) {
+        float daysLeft =
+                ((float) mCycleEndTimeMs - System.currentTimeMillis()) / MILLIS_IN_A_DAY;
+        if (daysLeft < 0) {
+            daysLeft = 0;
+        }
+
+        TextView cycleTime = (TextView) holder.findViewById(R.id.cycle_left_time);
+        cycleTime.setText(
+                (daysLeft > 0 && daysLeft < 1)
+                ? getContext().getString(R.string.billing_cycle_less_than_one_day_left)
+                : getContext().getResources().getQuantityString(
+                        R.plurals.billing_cycle_days_left, (int) daysLeft, (int) daysLeft));
+    }
+
+
+    private void updateCarrierInfo(TextView carrierInfo) {
+        if (mNumPlans > 0 && mSnapshotTimeMs >= 0L) {
+            long updateAge = System.currentTimeMillis() - mSnapshotTimeMs;
             carrierInfo.setVisibility(View.VISIBLE);
-            if (carrierName != null) {
+            if (mCarrierName != null) {
                 carrierInfo.setText(getContext().getString(R.string.carrier_and_update_text,
-                        carrierName, StringUtil.formatRelativeTime(
+                        mCarrierName, StringUtil.formatRelativeTime(
                                 getContext(), updateAge, false /* withSeconds */)));
             } else {
                 carrierInfo.setText(getContext().getString(R.string.no_carrier_update_text,
                         StringUtil.formatRelativeTime(
                                 getContext(), updateAge, false /* withSeconds */)));
             }
+
+            carrierInfo.setTextColor(
+                    updateAge <= WARNING_AGE
+                    ? Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary)
+                    : Utils.getColorAttr(getContext(), android.R.attr.colorError));
         } else {
             carrierInfo.setVisibility(View.GONE);
         }
diff --git a/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.java b/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.java
index 0729fff..6deced7 100644
--- a/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.java
+++ b/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.java
@@ -37,6 +37,7 @@
 import com.android.internal.util.CollectionUtils;
 import com.android.settings.R;
 import com.android.settings.core.BasePreferenceController;
+import com.android.settings.core.FeatureFlags;
 import com.android.settingslib.NetworkPolicyEditor;
 import com.android.settingslib.net.DataUsageController;
 
@@ -164,29 +165,24 @@
             refreshDataplanInfo(info);
         }
 
-        if (mDataplanCount == 0 && (info.warningLevel > 0 || info.limitLevel > 0)) {
-            final String warning = Formatter.formatFileSize(mContext, info.warningLevel);
-            final String limit = Formatter.formatFileSize(mContext, info.limitLevel);
-            summaryPreference.setLimitInfo(mContext.getString(info.limitLevel <= 0
-                    ? R.string.cell_warning_only
-                    : R.string.cell_warning_and_limit, warning, limit));
+        if (info.warningLevel > 0 && info.limitLevel > 0) {
+                summaryPreference.setLimitInfo(TextUtils.expandTemplate(
+                        mContext.getText(R.string.cell_data_warning_and_limit),
+                        Formatter.formatFileSize(mContext, info.warningLevel),
+                        Formatter.formatFileSize(mContext, info.limitLevel)).toString());
+        } else if (info.warningLevel > 0) {
+                summaryPreference.setLimitInfo(TextUtils.expandTemplate(
+                        mContext.getText(R.string.cell_data_warning),
+                        Formatter.formatFileSize(mContext, info.warningLevel)).toString());
+        } else if (info.limitLevel > 0) {
+            summaryPreference.setLimitInfo(TextUtils.expandTemplate(
+                    mContext.getText(R.string.cell_data_limit),
+                    Formatter.formatFileSize(mContext, info.limitLevel)).toString());
         } else {
             summaryPreference.setLimitInfo(null);
         }
 
-        final StringBuilder title = new StringBuilder();
-        if (mHasMobileData) {
-            title.append(formatUsage(mContext, mContext.getString(R.string.data_used),
-                    mDataplanUse));
-            if (mDataplanCount >= 0 && mDataplanSize > 0L) {
-                title.append(formatUsage(mContext, mContext.getString(R.string.data_remaining),
-                        mDataplanSize - mDataplanUse));
-            }
-        } else {
-            title.append(formatUsage(mContext, mContext.getString(mDataUsageTemplate),
-                    mDataplanUse));
-        }
-        summaryPreference.setTitle(title.toString());
+        summaryPreference.setUsageNumbers(mDataplanUse, mDataplanSize, mHasMobileData);
 
         if (mDataplanSize <= 0) {
             summaryPreference.setChartEnabled(false);
@@ -200,6 +196,13 @@
                 mDataplanCount, mManageSubscriptionIntent);
     }
 
+    private String getLimitText(long limit, int textId) {
+        if (limit <= 0) {
+            return null;
+        }
+        return mContext.getString(textId, Formatter.formatFileSize(mContext, limit));
+    }
+
     // TODO(b/70950124) add test for this method once the robolectric shadow run script is
     // completed (b/3526807)
     private void refreshDataplanInfo(DataUsageController.DataUsageInfo info) {
@@ -231,7 +234,7 @@
                     mCycleStart = rule.start.toEpochSecond() * 1000L;
                     mCycleEnd = rule.end.toEpochSecond() * 1000L;
                 }
-                mSnapshotTime = System.currentTimeMillis() - primaryPlan.getDataUsageTime();
+                mSnapshotTime = primaryPlan.getDataUsageTime();
             }
         }
         mManageSubscriptionIntent =
diff --git a/src/com/android/settings/fuelgauge/RestrictAppPreferenceController.java b/src/com/android/settings/fuelgauge/RestrictAppPreferenceController.java
index e41a94b..02a2cf6 100644
--- a/src/com/android/settings/fuelgauge/RestrictAppPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/RestrictAppPreferenceController.java
@@ -67,17 +67,26 @@
 
         final List<AppOpsManager.PackageOps> packageOpsList = mAppOpsManager.getPackagesForOps(
                 new int[]{AppOpsManager.OP_RUN_ANY_IN_BACKGROUND});
-        final int num = CollectionUtils.size(packageOpsList);
         mAppInfos = new ArrayList<>();
 
-        for (int i = 0; i < num; i++) {
+        for (int i = 0, size = CollectionUtils.size(packageOpsList); i < size; i++) {
             final AppOpsManager.PackageOps packageOps = packageOpsList.get(i);
-            mAppInfos.add(new AppInfo.Builder()
-                    .setPackageName(packageOps.getPackageName())
-                    .setUid(packageOps.getUid())
-                    .build());
+            final List<AppOpsManager.OpEntry> entries = packageOps.getOps();
+            for (int j = 0; j < entries.size(); j++) {
+                AppOpsManager.OpEntry ent = entries.get(j);
+                if (ent.getOp() != AppOpsManager.OP_RUN_ANY_IN_BACKGROUND) {
+                    continue;
+                }
+                if (ent.getMode() != AppOpsManager.MODE_ALLOWED) {
+                    mAppInfos.add(new AppInfo.Builder()
+                            .setPackageName(packageOps.getPackageName())
+                            .setUid(packageOps.getUid())
+                            .build());
+                }
+            }
         }
 
+        final int num = mAppInfos.size();
         // Enable the preference if some apps already been restricted, otherwise disable it
         preference.setEnabled(num > 0);
         preference.setSummary(
diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryTipDialogFragment.java b/src/com/android/settings/fuelgauge/batterytip/BatteryTipDialogFragment.java
index b39e4ef..a7d542c 100644
--- a/src/com/android/settings/fuelgauge/batterytip/BatteryTipDialogFragment.java
+++ b/src/com/android/settings/fuelgauge/batterytip/BatteryTipDialogFragment.java
@@ -107,21 +107,30 @@
                 final RestrictAppTip restrictAppTip = (RestrictAppTip) mBatteryTip;
                 final List<AppInfo> restrictedAppList = restrictAppTip.getRestrictAppList();
                 final int num = restrictedAppList.size();
+                final CharSequence appLabel = Utils.getApplicationLabel(context,
+                        restrictedAppList.get(0).packageName);
 
                 final AlertDialog.Builder builder = new AlertDialog.Builder(context)
                         .setTitle(context.getResources().getQuantityString(
                                 R.plurals.battery_tip_restrict_app_dialog_title, num, num))
-                        .setMessage(getString(R.string.battery_tip_restrict_app_dialog_message))
                         .setPositiveButton(R.string.battery_tip_restrict_app_dialog_ok, this)
                         .setNegativeButton(android.R.string.cancel, null);
-
-                // TODO(b/72385333): consider building dialog with 5+ apps when strings are done
-                if (num > 1) {
+                if (num == 1) {
+                    builder.setMessage(
+                            getString(R.string.battery_tip_restrict_app_dialog_message, appLabel));
+                } else if (num <= 5) {
+                    builder.setMessage(
+                            getString(
+                                    R.string.battery_tip_restrict_apps_less_than_5_dialog_message));
                     final RecyclerView restrictionView = (RecyclerView) LayoutInflater.from(
                             context).inflate(R.layout.recycler_view, null);
                     restrictionView.setLayoutManager(new LinearLayoutManager(context));
                     restrictionView.setAdapter(new HighUsageAdapter(context, restrictedAppList));
                     builder.setView(restrictionView);
+                } else {
+                    builder.setMessage(context.getString(
+                            R.string.battery_tip_restrict_apps_more_than_5_dialog_message,
+                            restrictAppTip.getRestrictAppsString(context)));
                 }
 
                 return builder.create();
diff --git a/src/com/android/settings/fuelgauge/batterytip/tips/RestrictAppTip.java b/src/com/android/settings/fuelgauge/batterytip/tips/RestrictAppTip.java
index 566cbfa..9c3a9bd 100644
--- a/src/com/android/settings/fuelgauge/batterytip/tips/RestrictAppTip.java
+++ b/src/com/android/settings/fuelgauge/batterytip/tips/RestrictAppTip.java
@@ -17,8 +17,9 @@
 package com.android.settings.fuelgauge.batterytip.tips;
 
 import android.content.Context;
-import android.content.res.Resources;
+import android.icu.text.ListFormatter;
 import android.os.Parcel;
+import android.text.TextUtils;
 import android.util.Pair;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -72,7 +73,7 @@
         return mState == StateType.HANDLED
                 ? context.getString(R.string.battery_tip_restrict_handled_summary)
                 : context.getResources().getQuantityString(R.plurals.battery_tip_restrict_summary,
-                num, appLabel, num);
+                        num, appLabel, num);
     }
 
     @Override
@@ -118,6 +119,19 @@
         return mRestrictAppList;
     }
 
+    /**
+     * Construct the app list string(e.g. app1, app2, and app3)
+     */
+    public CharSequence getRestrictAppsString(Context context) {
+        final List<CharSequence> appLabels = new ArrayList<>();
+        for (int i = 0, size = mRestrictAppList.size(); i < size; i++) {
+            appLabels.add(Utils.getApplicationLabel(context,
+                    mRestrictAppList.get(i).packageName));
+        }
+
+        return ListFormatter.getInstance().format(appLabels);
+    }
+
     @Override
     public String toString() {
         final StringBuilder stringBuilder = new StringBuilder(super.toString());
diff --git a/src/com/android/settings/notification/NotificationSettingsBase.java b/src/com/android/settings/notification/NotificationSettingsBase.java
index c318d90..7583ec9 100644
--- a/src/com/android/settings/notification/NotificationSettingsBase.java
+++ b/src/com/android/settings/notification/NotificationSettingsBase.java
@@ -360,7 +360,13 @@
             (left, right) -> {
                 if (left.isDeleted() != right.isDeleted()) {
                     return Boolean.compare(left.isDeleted(), right.isDeleted());
+                } else if (left.getId().equals(NotificationChannel.DEFAULT_CHANNEL_ID)) {
+                    // Uncategorized/miscellaneous legacy channel goes last
+                    return 1;
+                } else if (right.getId().equals(NotificationChannel.DEFAULT_CHANNEL_ID)) {
+                    return -1;
                 }
+
                 return left.getId().compareTo(right.getId());
             };
 
diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java
index 68c9731..ddda5d8 100644
--- a/src/com/android/settings/slices/SettingsSliceProvider.java
+++ b/src/com/android/settings/slices/SettingsSliceProvider.java
@@ -34,10 +34,10 @@
 import java.util.Map;
 import java.util.WeakHashMap;
 
-import androidx.app.slice.Slice;
-import androidx.app.slice.SliceProvider;
-import androidx.app.slice.builders.SliceAction;
-import androidx.app.slice.builders.ListBuilder;
+import androidx.slice.Slice;
+import androidx.slice.SliceProvider;
+import androidx.slice.builders.SliceAction;
+import androidx.slice.builders.ListBuilder;
 
 /**
  * A {@link SliceProvider} for Settings to enabled inline results in system apps.
diff --git a/src/com/android/settings/slices/SliceBuilderUtils.java b/src/com/android/settings/slices/SliceBuilderUtils.java
index e90ea8e..a1f27d1 100644
--- a/src/com/android/settings/slices/SliceBuilderUtils.java
+++ b/src/com/android/settings/slices/SliceBuilderUtils.java
@@ -35,10 +35,10 @@
 import com.android.settings.search.DatabaseIndexingUtils;
 import com.android.settingslib.core.AbstractPreferenceController;
 
-import androidx.app.slice.Slice;
-import androidx.app.slice.builders.SliceAction;
-import androidx.app.slice.builders.ListBuilder;
-import androidx.app.slice.builders.ListBuilder.RowBuilder;
+import androidx.slice.Slice;
+import androidx.slice.builders.SliceAction;
+import androidx.slice.builders.ListBuilder;
+import androidx.slice.builders.ListBuilder.RowBuilder;
 
 /**
  * Utility class to build Slices objects and Preference Controllers based on the Database managed
diff --git a/src/com/android/settings/slices/SlicesDatabaseAccessor.java b/src/com/android/settings/slices/SlicesDatabaseAccessor.java
index 4fca63a..acd296b 100644
--- a/src/com/android/settings/slices/SlicesDatabaseAccessor.java
+++ b/src/com/android/settings/slices/SlicesDatabaseAccessor.java
@@ -28,7 +28,7 @@
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.slices.SlicesDatabaseHelper.IndexColumns;
 
-import androidx.app.slice.Slice;
+import androidx.slice.Slice;
 
 /**
  * Class used to map a {@link Uri} from {@link SettingsSliceProvider} to a Slice.
diff --git a/src/com/android/settings/wifi/ConnectedAccessPointPreference.java b/src/com/android/settings/wifi/ConnectedAccessPointPreference.java
index 514525c..e9e1560 100644
--- a/src/com/android/settings/wifi/ConnectedAccessPointPreference.java
+++ b/src/com/android/settings/wifi/ConnectedAccessPointPreference.java
@@ -31,12 +31,31 @@
 public class ConnectedAccessPointPreference extends AccessPointPreference implements
         View.OnClickListener {
 
+    private final CaptivePortalStatus mCaptivePortalStatus;
     private OnGearClickListener mOnGearClickListener;
+    private boolean mCaptivePortalNetwork;
 
     public ConnectedAccessPointPreference(AccessPoint accessPoint, Context context,
-            UserBadgeCache cache, @DrawableRes int iconResId, boolean forSavedNetworks) {
+            UserBadgeCache cache, @DrawableRes int iconResId, boolean forSavedNetworks,
+            CaptivePortalStatus captivePortalStatus) {
         super(accessPoint, context, cache, iconResId, forSavedNetworks);
-        setWidgetLayoutResource(R.layout.preference_widget_gear_no_bg);
+        mCaptivePortalStatus = captivePortalStatus;
+    }
+
+    @Override
+    protected int getWidgetLayoutResourceId() {
+        return R.layout.preference_widget_gear_optional_background;
+    }
+
+    @Override
+    public void refresh() {
+        super.refresh();
+
+        mCaptivePortalNetwork = mCaptivePortalStatus.isCaptivePortalNetwork();
+        setShowDivider(mCaptivePortalNetwork);
+        if (mCaptivePortalNetwork) {
+            setSummary(R.string.wifi_tap_to_sign_in);
+        }
     }
 
     public void setOnGearClickListener(OnGearClickListener l) {
@@ -45,6 +64,18 @@
     }
 
     @Override
+    public void onBindViewHolder(PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+
+        final View gear = holder.findViewById(R.id.settings_button);
+        gear.setOnClickListener(this);
+
+        final View gearNoBg = holder.findViewById(R.id.settings_button_no_background);
+        gearNoBg.setVisibility(mCaptivePortalNetwork ? View.INVISIBLE : View.VISIBLE);
+        gear.setVisibility(mCaptivePortalNetwork ? View.VISIBLE : View.INVISIBLE);
+    }
+
+    @Override
     public void onClick(View v) {
         if (v.getId() == R.id.settings_button) {
             if (mOnGearClickListener != null) {
@@ -56,4 +87,8 @@
     public interface OnGearClickListener {
         void onGearClick(ConnectedAccessPointPreference p);
     }
+
+    public interface CaptivePortalStatus {
+        boolean isCaptivePortalNetwork();
+    }
 }
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 3972b85..4f67012 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -26,6 +26,8 @@
 import android.content.Intent;
 import android.content.res.Resources;
 import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.State;
 import android.net.wifi.WifiConfiguration;
@@ -60,6 +62,7 @@
 import com.android.settings.widget.SummaryUpdater.OnSummaryChangeListener;
 import com.android.settings.widget.SwitchBarController;
 import com.android.settings.wifi.details.WifiNetworkDetailsFragment;
+import com.android.settings.wrapper.ConnectivityManagerWrapper;
 import com.android.settings.wrapper.WifiManagerWrapper;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.wifi.AccessPoint;
@@ -117,6 +120,7 @@
     };
 
     protected WifiManager mWifiManager;
+    private ConnectivityManager mConnectivityManager;
     private WifiManager.ActionListener mConnectListener;
     private WifiManager.ActionListener mSaveListener;
     private WifiManager.ActionListener mForgetListener;
@@ -238,6 +242,11 @@
                 getActivity(), this, getLifecycle(), true, true);
         mWifiManager = mWifiTracker.getManager();
 
+        final Activity activity = getActivity();
+        if (activity != null) {
+            mConnectivityManager = getActivity().getSystemService(ConnectivityManager.class);
+        }
+
         mConnectListener = new WifiManager.ActionListener() {
                                    @Override
                                    public void onSuccess() {
@@ -777,9 +786,11 @@
 
     @NonNull
     private ConnectedAccessPointPreference createConnectedAccessPointPreference(
-            AccessPoint accessPoint) {
+            AccessPoint accessPoint,
+            ConnectedAccessPointPreference.CaptivePortalStatus captivePortalStatus) {
         return new ConnectedAccessPointPreference(accessPoint, getPrefContext(), mUserBadgeCache,
-                R.drawable.ic_wifi_signal_0, false /* forSavedNetworks */);
+                R.drawable.ic_wifi_signal_0, false /* forSavedNetworks */,
+                captivePortalStatus);
     }
 
     /**
@@ -828,21 +839,30 @@
      * {@link #mConnectedAccessPointPreferenceCategory}.
      */
     private void addConnectedAccessPointPreference(AccessPoint connectedAp) {
-        final ConnectedAccessPointPreference pref = createConnectedAccessPointPreference(
-                connectedAp);
+        final ConnectedAccessPointPreference pref =
+                createConnectedAccessPointPreference(
+                        connectedAp, this::isConnectedToCaptivePortalNetwork);
 
-        // Launch details page on click.
-        pref.setOnPreferenceClickListener(preference -> {
-            pref.getAccessPoint().saveWifiState(pref.getExtras());
+        // Launch details page or captive portal on click.
+        pref.setOnPreferenceClickListener(
+                preference -> {
+                    pref.getAccessPoint().saveWifiState(pref.getExtras());
+                    Network network = getConnectedWifiNetwork();
+                    if (isConnectedToCaptivePortalNetwork(network)) {
+                        ConnectivityManagerWrapper connectivityManagerWrapper =
+                                new ConnectivityManagerWrapper(mConnectivityManager);
+                        connectivityManagerWrapper.startCaptivePortalApp(network);
+                    } else {
+                        launchNetworkDetailsFragment(pref);
+                    }
+                    return true;
+                });
 
-            new SubSettingLauncher(getContext())
-                    .setTitle(pref.getTitle())
-                    .setDestination(WifiNetworkDetailsFragment.class.getName())
-                    .setArguments(pref.getExtras())
-                    .setSourceMetricsCategory(getMetricsCategory())
-                    .launch();
-            return true;
-        });
+        pref.setOnGearClickListener(
+                preference -> {
+                    pref.getAccessPoint().saveWifiState(pref.getExtras());
+                    launchNetworkDetailsFragment(pref);
+                });
 
         pref.refresh();
 
@@ -854,6 +874,43 @@
         }
     }
 
+    private void launchNetworkDetailsFragment(ConnectedAccessPointPreference pref) {
+        new SubSettingLauncher(getContext())
+                .setTitle(pref.getTitle())
+                .setDestination(WifiNetworkDetailsFragment.class.getName())
+                .setArguments(pref.getExtras())
+                .setSourceMetricsCategory(getMetricsCategory())
+                .launch();
+    }
+
+    private boolean isConnectedToCaptivePortalNetwork() {
+        return isConnectedToCaptivePortalNetwork(getConnectedWifiNetwork());
+    }
+
+    private boolean isConnectedToCaptivePortalNetwork(Network network) {
+        if (mConnectivityManager == null || network == null) {
+            return false;
+        }
+        return WifiUtils.canSignIntoNetwork(mConnectivityManager.getNetworkCapabilities(network));
+    }
+
+    private Network getConnectedWifiNetwork() {
+        if (mConnectivityManager != null) {
+            Network networks[] = mConnectivityManager.getAllNetworks();
+            if (networks != null) {
+                for (Network network : networks) {
+                    NetworkCapabilities capabilities =
+                            mConnectivityManager.getNetworkCapabilities(network);
+                    if (capabilities != null
+                            && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
+                        return network;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
     /** Removes all preferences and hide the {@link #mConnectedAccessPointPreferenceCategory}. */
     private void removeConnectedAccessPointPreference() {
         mConnectedAccessPointPreferenceCategory.removeAll();
diff --git a/src/com/android/settings/wifi/WifiUtils.java b/src/com/android/settings/wifi/WifiUtils.java
index 34c86d1..5ef66c0 100644
--- a/src/com/android/settings/wifi/WifiUtils.java
+++ b/src/com/android/settings/wifi/WifiUtils.java
@@ -16,11 +16,11 @@
 
 package com.android.settings.wifi;
 
-import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.net.NetworkCapabilities;
 import android.net.wifi.WifiConfiguration;
 import android.provider.Settings;
 import android.text.TextUtils;
@@ -101,4 +101,10 @@
                 Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, 0) != 0;
         return isLockdownFeatureEnabled;
     }
+
+    /** Returns true if the provided NetworkCapabilities indicate a captive portal network. */
+    public static boolean canSignIntoNetwork(NetworkCapabilities capabilities) {
+        return (capabilities != null
+                && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL));
+    }
 }
diff --git a/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java b/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java
index 6f2accd..6f170a0 100644
--- a/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java
+++ b/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java
@@ -203,9 +203,6 @@
                 // not show notification, we are changing result code here.
                 setResultCode(Activity.RESULT_CANCELED);
 
-                // UX requirement is to disable WFC in case of "permanent" registration failures.
-                mSwitch.setChecked(false);
-
                 showAlert(intent);
             }
         }
diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
index 4d9ad27..e7f0fdd 100644
--- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
+++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
@@ -511,8 +511,7 @@
      * Returns whether the user can sign into the network represented by this preference.
      */
     private boolean canSignIntoNetwork() {
-        return mNetworkCapabilities != null && mNetworkCapabilities.hasCapability(
-                NET_CAPABILITY_CAPTIVE_PORTAL);
+        return WifiUtils.canSignIntoNetwork(mNetworkCapabilities);
     }
 
     /**
diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceControllerTest.java
index eb94d8d..1914250 100644
--- a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceControllerTest.java
@@ -90,12 +90,12 @@
 
         final Intent intent = new Intent();
 
-        when(mDataUsageController.getDataUsageInfo()).thenReturn(info);
+        when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info);
         mController.setPlanValues(1 /* dataPlanCount */, LIMIT1, USAGE1);
         mController.setCarrierValues(CARRIER_NAME, now - UPDATE_BACKOFF_MS, info.cycleEnd, intent);
 
         mController.updateState(mSummaryPreference);
-        verify(mSummaryPreference).setLimitInfo(null);
+        verify(mSummaryPreference).setLimitInfo("500 MB data warning / 1.00 GB data limit");
         verify(mSummaryPreference).setUsageInfo(info.cycleEnd, now - UPDATE_BACKOFF_MS,
                 CARRIER_NAME, 1 /* numPlans */, intent);
         verify(mSummaryPreference).setChartEnabled(true);
@@ -113,7 +113,7 @@
         mController.setCarrierValues(CARRIER_NAME, now - UPDATE_BACKOFF_MS, info.cycleEnd, intent);
 
         mController.updateState(mSummaryPreference);
-        verify(mSummaryPreference).setLimitInfo("500 MB Data warning / 1.00 GB Data limit");
+        verify(mSummaryPreference).setLimitInfo("500 MB data warning / 1.00 GB data limit");
         verify(mSummaryPreference).setUsageInfo(info.cycleEnd, now - UPDATE_BACKOFF_MS,
                 CARRIER_NAME, 0 /* numPlans */, intent);
         verify(mSummaryPreference).setChartEnabled(true);
@@ -130,7 +130,7 @@
                 info.cycleEnd, null /* intent */);
         mController.updateState(mSummaryPreference);
 
-        verify(mSummaryPreference).setLimitInfo("500 MB Data warning / 1.00 GB Data limit");
+        verify(mSummaryPreference).setLimitInfo("500 MB data warning / 1.00 GB data limit");
         verify(mSummaryPreference).setUsageInfo(
                 info.cycleEnd,
                 -1L /* snapshotTime */,
@@ -152,7 +152,7 @@
                 info.cycleEnd, null /* intent */);
         mController.updateState(mSummaryPreference);
 
-        verify(mSummaryPreference).setLimitInfo("500 MB Data warning / 1.00 GB Data limit");
+        verify(mSummaryPreference).setLimitInfo("500 MB data warning / 1.00 GB data limit");
         verify(mSummaryPreference).setUsageInfo(
                 info.cycleEnd,
                 -1L /* snapshotTime */,
@@ -162,6 +162,74 @@
         verify(mSummaryPreference).setChartEnabled(false);
     }
 
+    @Test
+    public void testSummaryUpdate_noLimitNoWarning() {
+        final long now = System.currentTimeMillis();
+        final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now);
+        info.warningLevel = 0L;
+        info.limitLevel = 0L;
+
+        final Intent intent = new Intent();
+
+        when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info);
+        mController.setPlanValues(0 /* dataPlanCount */, LIMIT1, USAGE1);
+        mController.setCarrierValues(CARRIER_NAME, now - UPDATE_BACKOFF_MS, info.cycleEnd, intent);
+
+        mController.updateState(mSummaryPreference);
+        verify(mSummaryPreference).setLimitInfo(null);
+    }
+
+    @Test
+    public void testSummaryUpdate_warningOnly() {
+        final long now = System.currentTimeMillis();
+        final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now);
+        info.warningLevel = 1000000L;
+        info.limitLevel = 0L;
+
+        final Intent intent = new Intent();
+
+        when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info);
+        mController.setPlanValues(0 /* dataPlanCount */, LIMIT1, USAGE1);
+        mController.setCarrierValues(CARRIER_NAME, now - UPDATE_BACKOFF_MS, info.cycleEnd, intent);
+
+        mController.updateState(mSummaryPreference);
+        verify(mSummaryPreference).setLimitInfo("1.00 MB data warning");
+    }
+
+    @Test
+    public void testSummaryUpdate_limitOnly() {
+        final long now = System.currentTimeMillis();
+        final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now);
+        info.warningLevel = 0L;
+        info.limitLevel = 1000000L;
+
+        final Intent intent = new Intent();
+
+        when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info);
+        mController.setPlanValues(0 /* dataPlanCount */, LIMIT1, USAGE1);
+        mController.setCarrierValues(CARRIER_NAME, now - UPDATE_BACKOFF_MS, info.cycleEnd, intent);
+
+        mController.updateState(mSummaryPreference);
+        verify(mSummaryPreference).setLimitInfo("1.00 MB data limit");
+    }
+
+    @Test
+    public void testSummaryUpdate_limitAndWarning() {
+        final long now = System.currentTimeMillis();
+        final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now);
+        info.warningLevel = 1000000L;
+        info.limitLevel = 1000000L;
+
+        final Intent intent = new Intent();
+
+        when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info);
+        mController.setPlanValues(0 /* dataPlanCount */, LIMIT1, USAGE1);
+        mController.setCarrierValues(CARRIER_NAME, now - UPDATE_BACKOFF_MS, info.cycleEnd, intent);
+
+        mController.updateState(mSummaryPreference);
+        verify(mSummaryPreference).setLimitInfo("1.00 MB data warning / 1.00 MB data limit");
+    }
+
     private DataUsageController.DataUsageInfo createTestDataUsageInfo(long now) {
         DataUsageController.DataUsageInfo info = new DataUsageController.DataUsageInfo();
         info.carrier = CARRIER_NAME;
diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceTest.java
index 57f1f8c..638ee79 100644
--- a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceTest.java
@@ -16,8 +16,6 @@
 
 package com.android.settings.datausage;
 
-import static com.google.common.truth.Truth.assertThat;
-
 import android.content.Context;
 import android.content.Intent;
 import android.support.v7.preference.PreferenceViewHolder;
@@ -31,7 +29,9 @@
 import com.android.settings.R;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowResourcesImpl;
+import com.android.settingslib.Utils;
 import com.android.settingslib.utils.StringUtil;
+import java.util.concurrent.TimeUnit;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -40,6 +40,10 @@
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 
+import java.util.concurrent.TimeUnit;
+
+import static com.google.common.truth.Truth.assertThat;
+
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(shadows = SettingsShadowResourcesImpl.class)
 public class DataUsageSummaryPreferenceTest {
@@ -55,6 +59,8 @@
     private TextView mCycleTime;
     private TextView mCarrierInfo;
     private TextView mDataLimits;
+    private TextView mDataUsed;
+    private TextView mDataRemaining;
     private Button mLaunchButton;
     private LinearLayout mLabelBar;
     private TextView mLabel1;
@@ -117,6 +123,31 @@
     }
 
     @Test
+    public void testSetUsageInfo_withRecentCarrierUpdate_doesNotSetCarrierInfoWarningColor() {
+        final long updateTime = System.currentTimeMillis() - TimeUnit.HOURS.toMillis(1);
+        mCarrierInfo = (TextView) mHolder.findViewById(R.id.carrier_and_update);
+        mSummaryPreference.setUsageInfo(mCycleEnd, updateTime, DUMMY_CARRIER, 1 /* numPlans */,
+                new Intent());
+
+        bindViewHolder();
+        assertThat(mCarrierInfo.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mCarrierInfo.getCurrentTextColor()).isEqualTo(
+                Utils.getColorAttr(mContext, android.R.attr.textColorPrimary));
+    }
+
+    @Test
+    public void testSetUsageInfo_withStaleCarrierUpdate_setsCarrierInfoWarningColor() {
+        final long updateTime = System.currentTimeMillis() - TimeUnit.HOURS.toMillis(7);
+        mSummaryPreference.setUsageInfo(mCycleEnd, updateTime, DUMMY_CARRIER, 1 /* numPlans */,
+                new Intent());
+
+        bindViewHolder();
+        assertThat(mCarrierInfo.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mCarrierInfo.getCurrentTextColor()).isEqualTo(
+                Utils.getColorAttr(mContext, android.R.attr.colorError));
+    }
+
+    @Test
     public void testSetUsageInfo_withNoDataPlans_usageTitleNotShown() {
         mSummaryPreference.setUsageInfo(mCycleEnd, mUpdateTime, DUMMY_CARRIER, 0 /* numPlans */,
                 new Intent());
@@ -135,16 +166,41 @@
     }
 
     @Test
-    public void testSetUsageInfo_cycleRemainingTimeShown() {
-        mSummaryPreference.setUsageInfo(mCycleEnd, mUpdateTime, DUMMY_CARRIER, 0 /* numPlans */,
+    public void testSetUsageInfo_cycleRemainingTimeIsLessOneDay() {
+        // just under one day
+        final long cycleEnd = System.currentTimeMillis() + TimeUnit.HOURS.toMillis(23);
+        mSummaryPreference.setUsageInfo(cycleEnd, mUpdateTime, DUMMY_CARRIER, 0 /* numPlans */,
                 new Intent());
-        String cyclePrefix = StringUtil.formatElapsedTime(mContext, CYCLE_DURATION_MILLIS,
-                false /* withSeconds */).toString();
-        String text = mContext.getString(R.string.cycle_left_time_text, cyclePrefix);
 
         bindViewHolder();
         assertThat(mCycleTime.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mCycleTime.getText()).isEqualTo(text);
+        assertThat(mCycleTime.getText()).isEqualTo(
+                mContext.getString(R.string.billing_cycle_less_than_one_day_left));
+    }
+
+    @Test
+    public void testSetUsageInfo_cycleRemainingTimeNegativeDaysLeft_shouldDisplayZeroDays() {
+        final long cycleEnd = System.currentTimeMillis() - 1L;
+        mSummaryPreference.setUsageInfo(cycleEnd, mUpdateTime, DUMMY_CARRIER, 0 /* numPlans */,
+                new Intent());
+
+        bindViewHolder();
+        assertThat(mCycleTime.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mCycleTime.getText()).isEqualTo(
+                mContext.getResources().getQuantityString(R.plurals.billing_cycle_days_left, 0, 0));
+    }
+
+    @Test
+    public void testSetUsageInfo_cycleRemainingTimeDaysLeft_shouldUsePlurals() {
+        final int daysLeft = 3;
+        final long cycleEnd = System.currentTimeMillis() + TimeUnit.DAYS.toMillis(daysLeft)
+                + TimeUnit.HOURS.toMillis(1);
+        mSummaryPreference.setUsageInfo(cycleEnd, mUpdateTime, DUMMY_CARRIER, 0 /* numPlans */,
+                new Intent());
+
+        bindViewHolder();
+        assertThat(mCycleTime.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mCycleTime.getText()).isEqualTo(daysLeft + " days left");
     }
 
     @Test
@@ -205,12 +261,47 @@
         mSummaryPreference.setLabels("0.0 GB", "5.0 GB");
     }
 
+    @Test
+    public void testSetUsageAndRemainingInfo_withUsageInfo_dataUsageAndRemainingShown() {
+        mSummaryPreference.setUsageInfo(mCycleEnd, mUpdateTime, DUMMY_CARRIER, 1 /* numPlans */,
+                new Intent());
+        mSummaryPreference.setUsageNumbers(1000000L, 10000000L, true);
+
+        bindViewHolder();
+        assertThat(mDataUsed.getText().toString()).isEqualTo("1.00 MB used");
+        assertThat(mDataRemaining.getText().toString()).isEqualTo("9.00 MB left");
+    }
+
+    @Test
+    public void testSetUsageInfo_withDataOverusage() {
+        mSummaryPreference.setUsageInfo(mCycleEnd, mUpdateTime, DUMMY_CARRIER, 1 /* numPlans */,
+                new Intent());
+        mSummaryPreference.setUsageNumbers(11_000_000L, 10_000_000L, true);
+
+        bindViewHolder();
+        assertThat(mDataUsed.getText().toString()).isEqualTo("11.00 MB used");
+        assertThat(mDataRemaining.getText().toString()).isEqualTo("1.00 MB over");
+    }
+
+    @Test
+    public void testSetUsageInfo_withUsageInfo_dataUsageShown() {
+        mSummaryPreference.setUsageInfo(mCycleEnd, mUpdateTime, DUMMY_CARRIER, 0 /* numPlans */,
+                new Intent());
+        mSummaryPreference.setUsageNumbers(1000000L, -1L, true);
+
+        bindViewHolder();
+        assertThat(mDataUsed.getText().toString()).isEqualTo("1.00 MB used");
+        assertThat(mDataRemaining.getText()).isEqualTo("");
+    }
+
     private void bindViewHolder() {
         mSummaryPreference.onBindViewHolder(mHolder);
         mUsageTitle = (TextView) mHolder.findViewById(R.id.usage_title);
         mCycleTime = (TextView) mHolder.findViewById(R.id.cycle_left_time);
         mCarrierInfo = (TextView) mHolder.findViewById(R.id.carrier_and_update);
         mDataLimits = (TextView) mHolder.findViewById(R.id.data_limits);
+        mDataUsed = (TextView) mHolder.findViewById(R.id.data_usage_view);
+        mDataRemaining = (TextView) mHolder.findViewById(R.id.data_remaining_view);
         mLaunchButton = (Button) mHolder.findViewById(R.id.launch_mdp_app_button);
         mLabelBar = (LinearLayout) mHolder.findViewById(R.id.label_bar);
         mLabel1 = (TextView) mHolder.findViewById(R.id.text1);
diff --git a/tests/robotests/src/com/android/settings/datetime/timezone/model/TimeZoneDataTest.java b/tests/robotests/src/com/android/settings/datetime/timezone/model/TimeZoneDataTest.java
index 4a624b7..0359cfc 100644
--- a/tests/robotests/src/com/android/settings/datetime/timezone/model/TimeZoneDataTest.java
+++ b/tests/robotests/src/com/android/settings/datetime/timezone/model/TimeZoneDataTest.java
@@ -73,13 +73,13 @@
         CountryTimeZones US = mock(CountryTimeZones.class);
         when(US.getCountryIso()).thenReturn("us");
         when(US.getTimeZoneMappings()).thenReturn(Arrays.asList(
-           TimeZoneMapping.createForTests("Unknown/Secret_City", true),
-           TimeZoneMapping.createForTests("Unknown/Secret_City2", false)
+           TimeZoneMapping.createForTests("Unknown/Secret_City", true, null /* notUsedAfter */),
+           TimeZoneMapping.createForTests("Unknown/Secret_City2", false, null /* notUsedAfter */)
         ));
         CountryTimeZones GB = mock(CountryTimeZones.class);
         when(GB.getCountryIso()).thenReturn("gb");
         when(GB.getTimeZoneMappings()).thenReturn(Collections.singletonList(
-            TimeZoneMapping.createForTests("Unknown/Secret_City", true)
+            TimeZoneMapping.createForTests("Unknown/Secret_City", true, null /* notUsedAfter */)
         ));
         when(mCountryZonesFinder.lookupCountryTimeZonesForZoneId("Unknown/Secret_City"))
                 .thenReturn(Arrays.asList(US, GB));
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java
index ee8e798..9deec6b 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BackgroundActivityPreferenceControllerTest.java
@@ -174,7 +174,7 @@
 
         mController.updateSummary(mPreference);
 
-        assertThat(mPreference.getSummary()).isEqualTo("No");
+        assertThat(mPreference.getSummary()).isEqualTo("Off / Uses battery in background");
     }
 
     @Test
@@ -184,7 +184,7 @@
 
         mController.updateSummary(mPreference);
 
-        assertThat(mPreference.getSummary()).isEqualTo("Yes");
+        assertThat(mPreference.getSummary()).isEqualTo("On / Background usage restricted");
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/RestrictAppPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/RestrictAppPreferenceControllerTest.java
index c9c82c2..57eff56 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/RestrictAppPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/RestrictAppPreferenceControllerTest.java
@@ -18,7 +18,9 @@
 
 import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT;
 import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE_RESID;
+
 import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
@@ -47,11 +49,17 @@
 
 @RunWith(RobolectricTestRunner.class)
 public class RestrictAppPreferenceControllerTest {
+    private static final int ALLOWED_UID = 111;
+    private static final String ALLOWED_PACKAGE_NAME = "com.android.allowed.package";
+    private static final int RESTRICTED_UID = 222;
+    private static final String RESTRICTED_PACKAGE_NAME = "com.android.restricted.package";
 
     @Mock
     private AppOpsManager mAppOpsManager;
     @Mock
-    private AppOpsManager.PackageOps mPackageOps;
+    private AppOpsManager.PackageOps mRestrictedPackageOps;
+    @Mock
+    private AppOpsManager.PackageOps mAllowedPackageOps;
     @Mock
     private SettingsActivity mSettingsActivity;
     @Mock
@@ -65,11 +73,26 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
+        final AppOpsManager.OpEntry allowOpEntry = new AppOpsManager.OpEntry(
+                AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, AppOpsManager.MODE_ALLOWED, 0, 0, 0, 0, "");
+        final List<AppOpsManager.OpEntry> allowOps = new ArrayList<>();
+        allowOps.add(allowOpEntry);
+        final AppOpsManager.OpEntry restrictedOpEntry = new AppOpsManager.OpEntry(
+                AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, "");
+        final List<AppOpsManager.OpEntry> restrictedOps = new ArrayList<>();
+        restrictedOps.add(restrictedOpEntry);
+        doReturn(ALLOWED_UID).when(mAllowedPackageOps).getUid();
+        doReturn(ALLOWED_PACKAGE_NAME).when(mAllowedPackageOps).getPackageName();
+        doReturn(allowOps).when(mAllowedPackageOps).getOps();
+        doReturn(RESTRICTED_UID).when(mRestrictedPackageOps).getUid();
+        doReturn(RESTRICTED_PACKAGE_NAME).when(mRestrictedPackageOps).getPackageName();
+        doReturn(restrictedOps).when(mRestrictedPackageOps).getOps();
+
         mContext = spy(RuntimeEnvironment.application);
         doReturn(mAppOpsManager).when(mContext).getSystemService(Context.APP_OPS_SERVICE);
         doReturn(mContext).when(mSettingsActivity).getApplicationContext();
         mRestrictAppPreferenceController =
-            new RestrictAppPreferenceController(mSettingsActivity, mFragment);
+                new RestrictAppPreferenceController(mSettingsActivity, mFragment);
         mPackageOpsList = new ArrayList<>();
         mPreference = new Preference(mContext);
         mPreference.setKey(mRestrictAppPreferenceController.getPreferenceKey());
@@ -77,7 +100,7 @@
 
     @Test
     public void testUpdateState_oneApp_showCorrectSummary() {
-        mPackageOpsList.add(mPackageOps);
+        mPackageOpsList.add(mRestrictedPackageOps);
         doReturn(mPackageOpsList).when(mAppOpsManager).getPackagesForOps(any());
 
         mRestrictAppPreferenceController.updateState(mPreference);
@@ -86,9 +109,10 @@
     }
 
     @Test
-    public void testUpdateState_twoApps_showCorrectSummary() {
-        mPackageOpsList.add(mPackageOps);
-        mPackageOpsList.add(mPackageOps);
+    public void testUpdateState_twoRestrictApps_showCorrectSummary() {
+        mPackageOpsList.add(mRestrictedPackageOps);
+        mPackageOpsList.add(mRestrictedPackageOps);
+        mPackageOpsList.add(mAllowedPackageOps);
         doReturn(mPackageOpsList).when(mAppOpsManager).getPackagesForOps(any());
 
         mRestrictAppPreferenceController.updateState(mPreference);
@@ -97,7 +121,8 @@
     }
 
     @Test
-    public void testUpdateState_zeroApp_disabled() {
+    public void testUpdateState_zeroRestrictApp_disabled() {
+        mPackageOpsList.add(mAllowedPackageOps);
         doReturn(mPackageOpsList).when(mAppOpsManager).getPackagesForOps(any());
 
         mRestrictAppPreferenceController.updateState(mPreference);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipDialogFragmentTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipDialogFragmentTest.java
index 6f8bb26..85e5b1e 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipDialogFragmentTest.java
@@ -33,6 +33,7 @@
 import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
 import com.android.settings.fuelgauge.batterytip.tips.SummaryTip;
 import com.android.settings.fuelgauge.batterytip.tips.UnrestrictAppTip;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.ShadowUtils;
 
@@ -63,33 +64,36 @@
     private Context mContext;
     private HighUsageTip mHighUsageTip;
     private RestrictAppTip mRestrictedOneAppTip;
-    private RestrictAppTip mRestrictAppsTip;
+    private RestrictAppTip mRestrictTwoAppsTip;
     private UnrestrictAppTip mUnrestrictAppTip;
     private SummaryTip mSummaryTip;
+    private AppInfo mAppInfo;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
         mContext = spy(RuntimeEnvironment.application);
+        FakeFeatureFactory.setupForTest();
+        ShadowUtils.setApplicationLabel(PACKAGE_NAME, DISPLAY_NAME);
 
         List<AppInfo> highUsageTips = new ArrayList<>();
-        final AppInfo appInfo = new AppInfo.Builder()
+        mAppInfo = new AppInfo.Builder()
                 .setScreenOnTimeMs(SCREEN_TIME_MS)
                 .setPackageName(PACKAGE_NAME)
                 .build();
-        highUsageTips.add(appInfo);
+        highUsageTips.add(mAppInfo);
         mHighUsageTip = new HighUsageTip(SCREEN_TIME_MS, highUsageTips);
 
         final List<AppInfo> restrictApps = new ArrayList<>();
-        restrictApps.add(appInfo);
+        restrictApps.add(mAppInfo);
         mRestrictedOneAppTip = new RestrictAppTip(BatteryTip.StateType.NEW,
                 new ArrayList<>(restrictApps));
-        restrictApps.add(appInfo);
-        mRestrictAppsTip = new RestrictAppTip(BatteryTip.StateType.NEW,
+        restrictApps.add(mAppInfo);
+        mRestrictTwoAppsTip = new RestrictAppTip(BatteryTip.StateType.NEW,
                 new ArrayList<>(restrictApps));
 
-        mUnrestrictAppTip = new UnrestrictAppTip(BatteryTip.StateType.NEW, appInfo);
+        mUnrestrictAppTip = new UnrestrictAppTip(BatteryTip.StateType.NEW, mAppInfo);
         mSummaryTip = spy(new SummaryTip(BatteryTip.StateType.NEW,
                 Estimate.AVERAGE_TIME_TO_DISCHARGE_UNKNOWN));
     }
@@ -122,14 +126,15 @@
 
         assertThat(shadowDialog.getTitle()).isEqualTo("Restrict app?");
         assertThat(shadowDialog.getMessage())
-                .isEqualTo(mContext.getString(R.string.battery_tip_restrict_app_dialog_message));
+                .isEqualTo("To save battery, stop app from using "
+                        + "battery in the background.");
     }
 
     @Test
-    public void testOnCreateDialog_restrictAppsTip_fireRestrictAppsDialog() {
+    public void testOnCreateDialog_restrictTwoAppsTip_fireRestrictTwoAppsDialog() {
         Robolectric.getForegroundThreadScheduler().pause();
 
-        mDialogFragment = BatteryTipDialogFragment.newInstance(mRestrictAppsTip);
+        mDialogFragment = BatteryTipDialogFragment.newInstance(mRestrictTwoAppsTip);
 
         FragmentTestUtil.startFragment(mDialogFragment);
 
@@ -140,14 +145,40 @@
 
         assertThat(shadowDialog.getTitle()).isEqualTo("Restrict 2 apps?");
         assertThat(shadowDialog.getMessage())
-                .isEqualTo(mContext.getString(R.string.battery_tip_restrict_app_dialog_message));
+                .isEqualTo("To save battery, stop these apps from using battery in the background"
+                        + ".\n\nApps:\n");
         assertThat(shadowDialog.getView()).isNotNull();
     }
 
     @Test
+    public void testOnCreateDialog_restrictSixAppsTip_fireRestrictSixAppsDialog() {
+        Robolectric.getForegroundThreadScheduler().pause();
+
+        final List<AppInfo> appInfos = new ArrayList<>();
+        for (int i = 0; i < 6; i++) {
+            appInfos.add(mAppInfo);
+        }
+        final RestrictAppTip restrictSixAppsTip = new RestrictAppTip(BatteryTip.StateType.NEW,
+                appInfos);
+
+        mDialogFragment = BatteryTipDialogFragment.newInstance(restrictSixAppsTip);
+
+        FragmentTestUtil.startFragment(mDialogFragment);
+
+        Robolectric.getForegroundThreadScheduler().advanceToLastPostedRunnable();
+
+        final AlertDialog dialog = (AlertDialog) ShadowDialog.getLatestDialog();
+        ShadowAlertDialog shadowDialog = shadowOf(dialog);
+
+        assertThat(shadowDialog.getTitle()).isEqualTo("Restrict 6 apps?");
+        assertThat(shadowDialog.getMessage())
+                .isEqualTo("To save battery, stop these apps from using battery in the background"
+                        + ".\n\nApps:\napp, app, app, app, app, and app.");
+    }
+
+    @Test
     public void testOnCreateDialog_unRestrictAppTip_fireUnRestrictDialog() {
         mDialogFragment = BatteryTipDialogFragment.newInstance(mUnrestrictAppTip);
-        ShadowUtils.setApplicationLabel(PACKAGE_NAME, DISPLAY_NAME);
 
         FragmentTestUtil.startFragment(mDialogFragment);
 
diff --git a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
index 9edae7e..8ddd48a 100644
--- a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
@@ -39,7 +39,7 @@
 import org.junit.runner.RunWith;
 import org.robolectric.RuntimeEnvironment;
 
-import androidx.app.slice.Slice;
+import androidx.slice.Slice;
 
 import java.util.HashMap;
 
diff --git a/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java b/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
index 0fcce5f..39b381d 100644
--- a/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
@@ -35,7 +35,7 @@
 import org.junit.runner.RunWith;
 import org.robolectric.RuntimeEnvironment;
 
-import androidx.app.slice.Slice;
+import androidx.slice.Slice;
 
 @RunWith(SettingsRobolectricTestRunner.class)
 public class SliceBuilderUtilsTest {
diff --git a/tests/robotests/src/com/android/settings/wifi/ConnectedAccessPointPreferenceTest.java b/tests/robotests/src/com/android/settings/wifi/ConnectedAccessPointPreferenceTest.java
index 8d1b8ac..b9b29d2 100644
--- a/tests/robotests/src/com/android/settings/wifi/ConnectedAccessPointPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/ConnectedAccessPointPreferenceTest.java
@@ -32,6 +32,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RuntimeEnvironment;
 
@@ -44,6 +45,8 @@
     private View mView;
     @Mock
     private ConnectedAccessPointPreference.OnGearClickListener mOnGearClickListener;
+    @Mock
+    private ConnectedAccessPointPreference.CaptivePortalStatus mCaptivePortalStatus;
     private Context mContext;
     private ConnectedAccessPointPreference mConnectedAccessPointPreference;
 
@@ -53,7 +56,7 @@
 
         mContext = RuntimeEnvironment.application;
         mConnectedAccessPointPreference = new ConnectedAccessPointPreference(mAccessPoint, mContext,
-                null, 0 /* iconResId */, false /* forSavedNetworks */);
+                null, 0 /* iconResId */, false /* forSavedNetworks */, mCaptivePortalStatus);
         mConnectedAccessPointPreference.setOnGearClickListener(mOnGearClickListener);
     }
 
@@ -74,8 +77,22 @@
     }
 
     @Test
+    public void testCaptivePortalStatus_isCaptivePortal_dividerDrawn() {
+        Mockito.when(mCaptivePortalStatus.isCaptivePortalNetwork()).thenReturn(true);
+        mConnectedAccessPointPreference.refresh();
+        assertThat(mConnectedAccessPointPreference.shouldShowDivider()).isTrue();
+    }
+
+    @Test
+    public void testCaptivePortalStatus_isNotCaptivePortal_dividerNotDrawn() {
+        Mockito.when(mCaptivePortalStatus.isCaptivePortalNetwork()).thenReturn(false);
+        mConnectedAccessPointPreference.refresh();
+        assertThat(mConnectedAccessPointPreference.shouldShowDivider()).isFalse();
+    }
+
+    @Test
     public void testWidgetLayoutPreference() {
         assertThat(mConnectedAccessPointPreference.getWidgetLayoutResource())
-            .isEqualTo(R.layout.preference_widget_gear_no_bg);
+            .isEqualTo(R.layout.preference_widget_gear_optional_background);
     }
 }