Merge "Set setNetworkSelectionModeManual with AccessNetworkType into RIL/Modem" into sc-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 6a4b8d5..71941d1 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -107,6 +107,7 @@
     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
     <uses-permission android:name="android.permission.READ_DREAM_STATE" />
     <uses-permission android:name="android.permission.READ_DREAM_SUPPRESSION" />
+    <uses-permission android:name="android.permission.MANAGE_APP_HIBERNATION" />
 
     <application android:label="@string/settings_label"
             android:icon="@drawable/ic_launcher_settings"
diff --git a/res/drawable/ic_homepage_search.xml b/res/drawable/ic_homepage_search.xml
index 3895b6b..3da1cc7 100644
--- a/res/drawable/ic_homepage_search.xml
+++ b/res/drawable/ic_homepage_search.xml
@@ -20,7 +20,7 @@
         android:height="24dp"
         android:viewportWidth="24"
         android:viewportHeight="24"
-        android:tint="?android:attr/colorAccent">
+        android:tint="?android:attr/textColorSecondary">
     <path
         android:fillColor="#FF000000"
         android:pathData="M20.49,19l-5.73,-5.73C15.53,12.2 16,10.91 16,9.5C16,5.91 13.09,3 9.5,3S3,5.91 3,9.5C3,13.09 5.91,16 9.5,16c1.41,0 2.7,-0.47 3.77,-1.24L19,20.49L20.49,19zM5,9.5C5,7.01 7.01,5 9.5,5S14,7.01 14,9.5S11.99,14 9.5,14S5,11.99 5,9.5z"/>
diff --git a/res/drawable/ic_refresh_24dp.xml b/res/drawable/ic_refresh_24dp.xml
deleted file mode 100644
index 9b78fcd..0000000
--- a/res/drawable/ic_refresh_24dp.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2021 The Android Open Source Project
-
-  Licensed under the Apache License, Version 2.0 (the "License");
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-  -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24"
-        android:viewportHeight="24"
-        android:tint="?android:attr/colorAccent">
-    <path
-        android:fillColor="@android:color/white"
-        android:pathData="M13,9v2h7V4h-2v2.74C16.53,5.07 14.4,4 12,4c-2.21,0 -4.21,0.9 -5.66,2.34S4,9.79 4,12c0,4.42 3.58,8 8,8 2.21,0 4.21,-0.9 5.66,-2.34l-1.42,-1.42C15.15,17.33 13.65,18 12,18c-3.31,0 -6,-2.69 -6,-6 0,-1.65 0.67,-3.15 1.76,-4.24C8.85,6.67 10.35,6 12,6c2.21,0 4.15,1.21 5.19,3H13z"/>
-</vector>
diff --git a/res/drawable/ic_repair_24dp.xml b/res/drawable/ic_repair_24dp.xml
new file mode 100644
index 0000000..da351fc
--- /dev/null
+++ b/res/drawable/ic_repair_24dp.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2021 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    android:tint="?android:attr/colorControlNormal">
+  <path
+      android:fillColor="@android:color/black"
+      android:pathData="M12,5c3.53,0 6.44,2.61 6.93,6h2.02c-0.5,-4.5 -4.31,-8 -8.95,-8c-4.97,0 -9,4.03 -9,9c0,3.48 1.98,6.5 4.87,8H5v2h6v-6H9v2.33C6.64,17.2 5,14.79 5,12C5,8.13 8.13,5 12,5z"/>
+  <path
+      android:fillColor="@android:color/black"
+      android:pathData="M22.16,16.5c0,1.93 -1.57,3.5 -3.5,3.5c-0.41,0 -0.8,-0.08 -1.16,-0.21l-2.34,2.33L13.04,20l2.33,-2.34c-0.13,-0.36 -0.21,-0.75 -0.21,-1.16c0,-1.93 1.57,-3.5 3.5,-3.5c0.58,0 1.12,0.16 1.6,0.41l-2.7,2.7l1.49,1.49l2.7,-2.7C22,15.38 22.16,15.92 22.16,16.5z"/>
+</vector>
diff --git a/res/layout/search_bar.xml b/res/layout/search_bar.xml
index 63f1c95..7cdf04d 100644
--- a/res/layout/search_bar.xml
+++ b/res/layout/search_bar.xml
@@ -19,10 +19,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:layout_marginTop="@dimen/search_bar_margin"
-    android:layout_marginStart="@dimen/search_bar_margin"
-    android:layout_marginEnd="@dimen/search_bar_margin"
-    android:layout_marginBottom="@dimen/search_bar_margin_bottom">
+    android:layout_margin="@dimen/search_bar_margin">
 
     <com.google.android.material.card.MaterialCardView
         android:id="@+id/search_bar"
@@ -34,7 +31,7 @@
             android:id="@+id/search_action_bar"
             android:layout_width="match_parent"
             android:layout_height="@dimen/search_bar_height"
-            android:layout_marginStart="-2dp"
+            android:paddingStart="4dp"
             android:background="@drawable/search_bar_selected_background"
             android:contentInsetStartWithNavigation="@dimen/search_bar_content_inset"
             android:navigationIcon="@drawable/ic_homepage_search">
@@ -43,16 +40,11 @@
                 style="@style/TextAppearance.SearchBar"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
+                android:paddingStart="-4dp"
                 android:layout_gravity="start"
                 android:text="@string/search_menu"/>
         </Toolbar>
     </com.google.android.material.card.MaterialCardView>
 
-   <ImageView
-        android:id="@+id/account_avatar"
-        android:layout_width="@dimen/avatar_length"
-        android:layout_height="@dimen/avatar_length"
-        android:layout_gravity="center_vertical"
-        android:contentDescription="@string/search_bar_account_avatar_content_description"/>
 </LinearLayout>
 
diff --git a/res/layout/settings_homepage_container.xml b/res/layout/settings_homepage_container.xml
index d9bcb83..4fd62fd 100644
--- a/res/layout/settings_homepage_container.xml
+++ b/res/layout/settings_homepage_container.xml
@@ -65,34 +65,26 @@
             android:orientation="vertical"
             app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed">
 
-            <LinearLayout
-                android:id="@+id/contextual_suggestion_content"
+            <ImageView
+                android:id="@+id/account_avatar"
+                android:layout_width="@dimen/avatar_length"
+                android:layout_height="@dimen/avatar_length"
+                android:layout_marginTop="@dimen/avatar_margin_top"
+                android:layout_marginEnd="@dimen/avatar_margin_end"
+                android:layout_gravity="end"
+                android:visibility="invisible"
+                android:accessibilityTraversalAfter="@id/homepage_title"
+                android:contentDescription="@string/search_bar_account_avatar_content_description"/>
+
+            <TextView
+                android:id="@+id/homepage_title"
+                android:text="@string/settings_label"
+                style="@style/HomepageTitleText"/>
+
+            <FrameLayout
+                android:id="@+id/suggestion_content"
                 android:layout_width="match_parent"
-                android:layout_height="@dimen/suggestion_height"
-                android:paddingHorizontal="@dimen/suggestion_padding_horizontal"
-                android:paddingVertical="@dimen/suggestion_padding_vertical"
-                android:orientation="vertical"
-                android:gravity="bottom"
-                android:visibility="gone">
-
-                <TextView
-                    android:id="@+id/suggestion_title"
-                    android:layout_width="match_parent"
-                    android:layout_height="0dp"
-                    android:layout_weight="1"
-                    android:text="@string/settings_label"
-                    style="@style/ContextualSuggestionText"/>
-
-                <Button
-                    android:id="@+id/suggestion_button"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_marginTop="@dimen/suggestion_button_margin_top"
-                    android:paddingHorizontal="@dimen/suggestion_button_padding_horizontal"
-                    android:visibility="gone"
-                    style="@style/ActionPrimaryButton"/>
-
-            </LinearLayout>
+                android:layout_height="wrap_content"/>
 
             <include layout="@layout/search_bar"/>
 
diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml
index 4eb0afd..b2f9a89 100644
--- a/res/values-night/colors.xml
+++ b/res/values-night/colors.xml
@@ -21,7 +21,7 @@
     <color name="homepage_support_background">#3F5FBD</color>
     <color name="homepage_card_dismissal_background">@*android:color/material_grey_900</color>
     <color name="contextual_card_background">@*android:color/material_grey_900</color>
-    <color name="search_bar_background">@*android:color/material_grey_800</color>
+    <color name="search_bar_background">@*android:color/material_grey_900</color>
     <!-- Dialog background color. -->
     <color name="dialog_background">@*android:color/material_grey_800</color>
     <color name="notification_importance_selection_bg">@*android:color/material_grey_800</color>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 0ee39cd..e0e0219 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -131,25 +131,21 @@
     <dimen name="switchbar_subsettings_margin_start">72dp</dimen>
     <dimen name="switchbar_subsettings_margin_end">16dp</dimen>
 
-    <!-- Search bar and avatar -->
-    <dimen name="search_bar_margin">24dp</dimen>
-    <dimen name="search_bar_margin_bottom">16dp</dimen>
-    <dimen name="search_bar_height">48dp</dimen>
-    <dimen name="search_bar_text_size">16sp</dimen>
-    <dimen name="search_bar_card_elevation">2dp</dimen>
-    <dimen name="search_bar_content_inset">64dp</dimen>
-    <dimen name="avatar_length">@dimen/search_bar_height</dimen>
+    <!-- Search bar -->
+    <dimen name="search_bar_margin">16dp</dimen>
+    <dimen name="search_bar_height">52dp</dimen>
+    <dimen name="search_bar_text_size">20sp</dimen>
+    <dimen name="search_bar_corner_radius">28dp</dimen>
+    <dimen name="search_bar_content_inset">56dp</dimen>
 
-    <!-- Contextual suggestions -->
-    <dimen name="suggestion_height">232dp</dimen>
-    <dimen name="suggestion_padding_horizontal">24dp</dimen>
-    <dimen name="suggestion_padding_vertical">8dp</dimen>
-    <dimen name="suggestion_button_margin_top">16dp</dimen>
-    <dimen name="suggestion_button_padding_horizontal">24dp</dimen>
+    <!-- Avatar -->
+    <dimen name="avatar_length">48dp</dimen>
+    <dimen name="avatar_margin_top">56dp</dimen>
+    <dimen name="avatar_margin_end">24dp</dimen>
 
-    <!-- Tool bar text -->
-    <dimen name="tool_bar_max_text_size">36sp</dimen>
-    <dimen name="tool_bar_min_text_size">24sp</dimen>
+    <!-- Homepage title -->
+    <dimen name="homepage_title_margin_bottom">8dp</dimen>
+    <dimen name="homepage_title_margin_horizontal">24dp</dimen>
 
     <!-- Dimensions for Wifi Assistant Card -->
     <dimen name="wifi_assistant_padding_top_bottom">16dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2369864..4c16c14 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -12912,10 +12912,12 @@
     <string name="category_name_brightness">Brightness</string>
     <!-- Lock screen category name in Display Settings [CHAR LIMIT=none] -->
     <string name="category_name_lock_display">Lock Display</string>
-    <!-- Visibility category name in Display Settings [CHAR LIMIT=none] -->
-    <string name="category_name_visibility">Visibility</string>
+    <!-- Appearance category name in Display Settings [CHAR LIMIT=none] -->
+    <string name="category_name_appearance">Appearance</string>
     <!-- Color category name in Display Settings [CHAR LIMIT=none] -->
     <string name="category_name_color">Color</string>
+    <!-- Name of Other display controls category in Display Settings [CHAR LIMIT=none] -->
+    <string name="category_name_display_controls">Other Display Controls</string>
     <!-- Others category name [CHAR LIMIT=none] -->
     <string name="category_name_others">Others</string>
     <!-- General category name [CHAR LIMIT=none] -->
@@ -12999,4 +13001,7 @@
 
     <!-- Summary for toggle controlling whether notifications are shown when an app pastes from clipboard. [CHAR LIMIT=NONE] -->
     <string name="show_clip_access_notification_summary">Show a message when apps access text, images, or other content you\u2019ve copied</string>
+
+    <!-- All apps screen title, entry name on Apps page for the user to go to the all apps page. [CHAR LIMIT=30] -->
+    <string name="all_apps">All apps</string>
 </resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 0d773f1..8ca72db 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -310,6 +310,7 @@
     <style name="TextAppearance.SearchBar"
            parent="@*android:style/TextAppearance.DeviceDefault.Widget.Toolbar.Subtitle">
         <item name="android:textSize">@dimen/search_bar_text_size</item>
+        <item name="android:textColor">?android:attr/textColorTertiary</item>
         <item name="android:singleLine">true</item>
     </style>
 
@@ -418,7 +419,6 @@
     </style>
 
     <style name="ActionPrimaryButton" parent="android:Widget.DeviceDefault.Button.Colored"/>
-
     <style name="ActionSecondaryButton" parent="android:Widget.DeviceDefault.Button"/>
 
     <style name="LockPatternContainerStyle">
@@ -481,11 +481,8 @@
     </style>
 
     <style name="SearchBarStyle">
-        <item name="android:layout_marginEnd">@dimen/search_bar_margin</item>
-        <item name="cardCornerRadius">34dp</item>
-        <item name="enforceMaterialTheme">true</item>
-        <item name="cardElevation">3dp</item>
-        <item name="shapeAppearance">@null</item>
+        <item name="cardCornerRadius">@dimen/search_bar_corner_radius</item>
+        <item name="cardElevation">0dp</item>
     </style>
 
     <style name="ConditionCardBorderlessButton"
@@ -789,13 +786,11 @@
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
     </style>
 
-    <style name="ContextualSuggestionText"
-           parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
-        <item name="android:autoSizeTextType">uniform</item>
-        <item name="android:autoSizeMaxTextSize">@dimen/tool_bar_max_text_size</item>
-        <item name="android:autoSizeMinTextSize">@dimen/tool_bar_min_text_size</item>
-        <item name="android:maxLines">3</item>
-        <item name="android:gravity">bottom</item>
+    <style name="HomepageTitleText" parent="ToolbarText">
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_marginBottom">@dimen/homepage_title_margin_bottom</item>
+        <item name="android:layout_marginHorizontal">@dimen/homepage_title_margin_horizontal</item>
     </style>
 
     <style name="RequestManageCredentialsButtonPanel">
@@ -883,16 +878,7 @@
         <item name="android:textColor">?android:attr/textColorSecondary</item>
     </style>
 
-    <style name="ToolbarText.Collapsed"
-           parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
-    </style>
-
-    <style name="ToolbarText"
-           parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
-        <item name="android:textSize">@dimen/tool_bar_max_text_size</item>
-    </style>
-
-    <style name="ToolbarText.MoreThanTwoLines">
-        <item name="android:textSize">@dimen/tool_bar_min_text_size</item>
-    </style>
+    <style name="ToolbarText.Collapsed" parent="CollapsingToolbarTitle.Collapsed"/>
+    <style name="ToolbarText" parent="CollapsingToolbarTitle"/>
+    <style name="ToolbarText.MoreThanTwoLines" parent="CollapsingToolbarTitle.MoreThanTwoLines"/>
 </resources>
diff --git a/res/xml/apps.xml b/res/xml/apps.xml
index cefb67a..68b5c9a 100644
--- a/res/xml/apps.xml
+++ b/res/xml/apps.xml
@@ -23,7 +23,7 @@
 
     <Preference
         android:key="all_app_infos"
-        android:title="@string/applications_settings"
+        android:title="@string/all_apps"
         android:summary="@string/summary_placeholder"
         android:order="-999"
         android:fragment="com.android.settings.applications.manageapplications.ManageApplications"
diff --git a/res/xml/display_settings_v2.xml b/res/xml/display_settings_v2.xml
index 0b43914..50879da 100644
--- a/res/xml/display_settings_v2.xml
+++ b/res/xml/display_settings_v2.xml
@@ -59,7 +59,7 @@
     </PreferenceCategory>
 
     <PreferenceCategory
-        android:title="@string/category_name_visibility">
+        android:title="@string/category_name_appearance">
 
         <com.android.settings.display.darkmode.DarkModePreference
             android:key="dark_ui_mode"
@@ -102,7 +102,7 @@
     </PreferenceCategory>
 
     <PreferenceCategory
-        android:title="@string/category_name_general">
+        android:title="@string/category_name_display_controls">
 
         <SwitchPreference
             android:key="auto_rotate"
diff --git a/res/xml/network_provider_internet.xml b/res/xml/network_provider_internet.xml
index bb7117d..4c760aa 100644
--- a/res/xml/network_provider_internet.xml
+++ b/res/xml/network_provider_internet.xml
@@ -98,7 +98,7 @@
         android:order="10"
         android:fragment="com.android.settings.datausage.DataSaverSummary"/>
 
-    <com.android.settingslib.RestrictedPreference
+    <com.android.settings.vpn2.VpnInfoPreference
         android:fragment="com.android.settings.vpn2.VpnSettings"
         android:key="vpn_settings"
         android:title="@string/vpn_settings_title"
diff --git a/src/com/android/settings/accounts/AvatarViewMixin.java b/src/com/android/settings/accounts/AvatarViewMixin.java
index 7eb8cab..c4ab55a 100644
--- a/src/com/android/settings/accounts/AvatarViewMixin.java
+++ b/src/com/android/settings/accounts/AvatarViewMixin.java
@@ -17,7 +17,6 @@
 package com.android.settings.accounts;
 
 import android.accounts.Account;
-import android.app.ActivityManager;
 import android.app.settings.SettingsEnums;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -65,14 +64,23 @@
     private final Context mContext;
     private final ImageView mAvatarView;
     private final MutableLiveData<Bitmap> mAvatarImage;
-    private final ActivityManager mActivityManager;
 
     @VisibleForTesting
     String mAccountName;
 
+    /**
+     * @return true if the avatar icon is supported.
+     */
+    public static boolean isAvatarSupported(Context context) {
+        if (!context.getResources().getBoolean(R.bool.config_show_avatar_in_homepage)) {
+            Log.d(TAG, "Feature disabled by config. Skipping");
+            return false;
+        }
+        return true;
+    }
+
     public AvatarViewMixin(SettingsHomepageActivity activity, ImageView avatarView) {
         mContext = activity.getApplicationContext();
-        mActivityManager = mContext.getSystemService(ActivityManager.class);
         mAvatarView = avatarView;
         mAvatarView.setOnClickListener(v -> {
             Intent intent;
@@ -117,14 +125,6 @@
 
     @OnLifecycleEvent(Lifecycle.Event.ON_START)
     public void onStart() {
-        if (!mContext.getResources().getBoolean(R.bool.config_show_avatar_in_homepage)) {
-            Log.d(TAG, "Feature disabled by config. Skipping");
-            return;
-        }
-        if (mActivityManager.isLowRamDevice()) {
-            Log.d(TAG, "Feature disabled on low ram device. Skipping");
-            return;
-        }
         if (hasAccount()) {
             loadAccount();
         } else {
diff --git a/src/com/android/settings/applications/HibernatedAppsPreferenceController.java b/src/com/android/settings/applications/HibernatedAppsPreferenceController.java
index 40cbb2e..4088d3a 100644
--- a/src/com/android/settings/applications/HibernatedAppsPreferenceController.java
+++ b/src/com/android/settings/applications/HibernatedAppsPreferenceController.java
@@ -20,15 +20,19 @@
 
 import static com.android.settings.Utils.PROPERTY_APP_HIBERNATION_ENABLED;
 
+import android.apphibernation.AppHibernationManager;
 import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 import android.provider.DeviceConfig;
 
 import com.android.settings.R;
 import com.android.settings.core.BasePreferenceController;
 
+import java.util.List;
+
 /**
  * A preference controller handling the logic for updating summary of hibernated apps.
- * TODO(b/181172051): add intent to launch Auto Revoke UI in app_and_notification.xml
  */
 public final class HibernatedAppsPreferenceController extends BasePreferenceController {
     private static final String TAG = "HibernatedAppsPrefController";
@@ -39,7 +43,8 @@
 
     @Override
     public int getAvailabilityStatus() {
-        return isHibernationEnabled() ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
+        return isHibernationEnabled() && getNumHibernated() > 0
+                ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
     }
 
     @Override
@@ -50,8 +55,27 @@
     }
 
     private int getNumHibernated() {
-        //TODO(b/181172051): hook into hibernation service to get the number of hibernated apps.
-        return 0;
+        final PackageManager pm = mContext.getPackageManager();
+        final AppHibernationManager ahm = mContext.getSystemService(AppHibernationManager.class);
+        final List<String> hibernatedPackages = ahm.getHibernatingPackagesForUser();
+        int numHibernated = hibernatedPackages.size();
+
+        // Also need to count packages that are auto revoked but not hibernated.
+        final List<PackageInfo> packages = pm.getInstalledPackages(
+                PackageManager.MATCH_DISABLED_COMPONENTS | PackageManager.GET_PERMISSIONS);
+        for (PackageInfo pi : packages) {
+            final String packageName = pi.packageName;
+            if (!hibernatedPackages.contains(packageName) && pi.requestedPermissions != null) {
+                for (String perm : pi.requestedPermissions) {
+                    if ((pm.getPermissionFlags(perm, packageName, mContext.getUser())
+                            & PackageManager.FLAG_PERMISSION_AUTO_REVOKED) != 0) {
+                        numHibernated++;
+                        break;
+                    }
+                }
+            }
+        }
+        return numHibernated;
     }
 
     private static boolean isHibernationEnabled() {
diff --git a/src/com/android/settings/applications/appinfo/HibernationSwitchPreferenceController.java b/src/com/android/settings/applications/appinfo/HibernationSwitchPreferenceController.java
index 8ab2c9d..40be629 100644
--- a/src/com/android/settings/applications/appinfo/HibernationSwitchPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/HibernationSwitchPreferenceController.java
@@ -80,7 +80,8 @@
 
     /**
      * Set the package. And also retrieve details from package manager. Some packages may be
-     * exempted from hibernation by default.
+     * exempted from hibernation by default. This method should only be called to initialize the
+     * controller.
      * @param packageName The name of the package whose hibernation state to be managed.
      */
     void setPackage(@NonNull String packageName) {
@@ -93,8 +94,7 @@
                         ? android.os.Build.VERSION_CODES.R
                         : android.os.Build.VERSION_CODES.Q;
         try {
-            mPackageUid = packageManager.getPackageUidAsUser(
-                    packageName, mContext.getUserId());
+            mPackageUid = packageManager.getPackageUid(packageName, /* flags */ 0);
             mIsPackageExemptByDefault = packageManager.getTargetSdkVersion(packageName)
                     <= maxTargetSdkVersionForExemptApps;
             mIsPackageSet = true;
diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java
index e98555b..a92f539 100644
--- a/src/com/android/settings/applications/manageapplications/ManageApplications.java
+++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java
@@ -277,7 +277,7 @@
         Intent intent = activity.getIntent();
         Bundle args = getArguments();
         int screenTitle = intent.getIntExtra(
-                SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE_RESID, R.string.application_info_label);
+                SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE_RESID, R.string.all_apps);
         String className = args != null ? args.getString(EXTRA_CLASSNAME) : null;
         if (className == null) {
             className = intent.getComponent().getClassName();
@@ -342,7 +342,7 @@
             screenTitle = R.string.app_notifications_title;
         } else {
             if (screenTitle == -1) {
-                screenTitle = R.string.application_info_label;
+                screenTitle = R.string.all_apps;
             }
             mListType = LIST_TYPE_MAIN;
         }
diff --git a/src/com/android/settings/development/DefaultUsbConfigurationPreferenceController.java b/src/com/android/settings/development/DefaultUsbConfigurationPreferenceController.java
index 905c552..be7704f 100644
--- a/src/com/android/settings/development/DefaultUsbConfigurationPreferenceController.java
+++ b/src/com/android/settings/development/DefaultUsbConfigurationPreferenceController.java
@@ -54,4 +54,11 @@
         mPreference.setDisabledByAdmin(
                 checkIfUsbDataSignalingIsDisabled(mContext, UserHandle.myUserId()));
     }
+
+    @Override
+    protected void onDeveloperOptionsSwitchEnabled() {
+        super.onDeveloperOptionsSwitchEnabled();
+        mPreference.setDisabledByAdmin(
+                checkIfUsbDataSignalingIsDisabled(mContext, UserHandle.myUserId()));
+    }
 }
diff --git a/src/com/android/settings/development/UsbAudioRoutingPreferenceController.java b/src/com/android/settings/development/UsbAudioRoutingPreferenceController.java
index 8aa4f3c..e130b2b 100644
--- a/src/com/android/settings/development/UsbAudioRoutingPreferenceController.java
+++ b/src/com/android/settings/development/UsbAudioRoutingPreferenceController.java
@@ -83,4 +83,11 @@
                 Settings.Secure.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED, SETTING_VALUE_OFF);
         ((SwitchPreference) mPreference).setChecked(false);
     }
+
+    @Override
+    protected void onDeveloperOptionsSwitchEnabled() {
+        super.onDeveloperOptionsSwitchEnabled();
+        mPreference.setDisabledByAdmin(
+                checkIfUsbDataSignalingIsDisabled(mContext, UserHandle.myUserId()));
+    }
 }
diff --git a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
index 47b2a0a..a55d0d3 100644
--- a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
@@ -257,6 +257,27 @@
         BatteryEntry.startRequestQueue();
     }
 
+    /**
+     * Gets the BatteryEntry list by using the supplied BatteryUsageStats.
+     */
+    public List<BatteryEntry> getBatteryEntryList(
+            BatteryUsageStats batteryUsageStats, boolean showAllApps) {
+        mBatteryUsageStats = USE_FAKE_DATA ? getFakeStats() : batteryUsageStats;
+        if (!sConfig.shouldShowBatteryAttributionList(mContext)) {
+            return null;
+        }
+        final int dischargePercentage = getDischargePercentage(batteryUsageStats);
+        final List<BatteryEntry> usageList = getCoalescedUsageList(showAllApps);
+        final double totalPower = batteryUsageStats.getConsumedPower();
+        for (int i = 0; i < usageList.size(); i++) {
+            final BatteryEntry entry = usageList.get(i);
+            final double percentOfTotal = mBatteryUtils.calculateBatteryPercent(
+                    entry.getConsumedPower(), totalPower, dischargePercentage);
+            entry.percent = percentOfTotal;
+        }
+        return usageList;
+    }
+
     private int getDischargePercentage(BatteryUsageStats batteryUsageStats) {
         int dischargePercentage = batteryUsageStats.getDischargePercentage();
         if (dischargePercentage < 0) {
@@ -311,7 +332,7 @@
             final int index = batteryEntryList.indexOfKey(realUid);
             if (index < 0) {
                 // New entry.
-                batteryEntryList.put(realUid, new BatteryEntry(mActivity, mHandler, mUserManager,
+                batteryEntryList.put(realUid, new BatteryEntry(mContext, mHandler, mUserManager,
                         consumer, isHidden, packages, null));
             } else {
                 // Combine BatterySippers if we already have one with this UID.
@@ -328,7 +349,7 @@
                 continue;
             }
 
-            results.add(new BatteryEntry(mActivity, mHandler, mUserManager,
+            results.add(new BatteryEntry(mContext, mHandler, mUserManager,
                     consumer, /* isHidden */ true, null, null));
         }
 
@@ -337,7 +358,7 @@
                     mBatteryUsageStats.getUserBatteryConsumers();
             for (int i = 0, size = userBatteryConsumers.size(); i < size; i++) {
                 final UserBatteryConsumer consumer = userBatteryConsumers.get(i);
-                results.add(new BatteryEntry(mActivity, mHandler, mUserManager,
+                results.add(new BatteryEntry(mContext, mHandler, mUserManager,
                         consumer, /* isHidden */ true, null, null));
             }
         }
diff --git a/src/com/android/settings/fuelgauge/BatteryEntry.java b/src/com/android/settings/fuelgauge/BatteryEntry.java
index 9fafefd..6c3add3 100644
--- a/src/com/android/settings/fuelgauge/BatteryEntry.java
+++ b/src/com/android/settings/fuelgauge/BatteryEntry.java
@@ -35,6 +35,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.Log;
+import android.util.Pair;
 
 import androidx.annotation.NonNull;
 
@@ -182,49 +183,10 @@
             getQuickNameIconForUid(uid, packages);
             return;
         } else if (batteryConsumer instanceof SystemBatteryConsumer) {
-            switch(((SystemBatteryConsumer) batteryConsumer).getDrainType()) {
-                case SystemBatteryConsumer.DRAIN_TYPE_AMBIENT_DISPLAY:
-                    name = context.getResources().getString(R.string.ambient_display_screen_title);
-                    iconId = R.drawable.ic_settings_aod;
-                    break;
-                case SystemBatteryConsumer.DRAIN_TYPE_BLUETOOTH:
-                    name = context.getResources().getString(R.string.power_bluetooth);
-                    iconId = com.android.internal.R.drawable.ic_settings_bluetooth;
-                    break;
-                case SystemBatteryConsumer.DRAIN_TYPE_CAMERA:
-                    name = context.getResources().getString(R.string.power_camera);
-                    iconId = R.drawable.ic_settings_camera;
-                    break;
-                case SystemBatteryConsumer.DRAIN_TYPE_MOBILE_RADIO:
-                    name = context.getResources().getString(R.string.power_cell);
-                    iconId = R.drawable.ic_cellular_1_bar;
-                    break;
-                case SystemBatteryConsumer.DRAIN_TYPE_FLASHLIGHT:
-                    name = context.getResources().getString(R.string.power_flashlight);
-                    iconId = R.drawable.ic_settings_display;
-                    break;
-                case SystemBatteryConsumer.DRAIN_TYPE_PHONE:
-                    name = context.getResources().getString(R.string.power_phone);
-                    iconId = R.drawable.ic_settings_voice_calls;
-                    break;
-                case SystemBatteryConsumer.DRAIN_TYPE_SCREEN:
-                    name = context.getResources().getString(R.string.power_screen);
-                    iconId = R.drawable.ic_settings_display;
-                    break;
-                case SystemBatteryConsumer.DRAIN_TYPE_WIFI:
-                    name = context.getResources().getString(R.string.power_wifi);
-                    iconId = R.drawable.ic_settings_wireless;
-                    break;
-                case SystemBatteryConsumer.DRAIN_TYPE_IDLE:
-                case SystemBatteryConsumer.DRAIN_TYPE_MEMORY:
-                    name = context.getResources().getString(R.string.power_idle);
-                    iconId = R.drawable.ic_settings_phone_idle;
-                    break;
-                case SystemBatteryConsumer.DRAIN_TYPE_CUSTOM:
-                    name = null;
-                    iconId = R.drawable.ic_power_system;
-                    break;
-            }
+            final Pair<Integer, String> resourcePair = getResourcePairFromDrainType(
+                    context, ((SystemBatteryConsumer) batteryConsumer).getDrainType());
+            iconId = resourcePair.first;
+            name = resourcePair.second;
         } else if (batteryConsumer instanceof UserBatteryConsumer) {
             UserInfo info = um.getUserInfo(((UserBatteryConsumer) batteryConsumer).getUserId());
             if (info != null) {
@@ -493,4 +455,57 @@
                     ((UidBatteryConsumer) batteryConsumer).getPackageWithHighestDrain();
         }
     }
+
+    /**
+     * Gets icon ID and name from system battery consumer drain type.
+     */
+    public static Pair<Integer, String> getResourcePairFromDrainType(
+            Context context, int drainType) {
+        String name = null;
+        int iconId = 0;
+        switch (drainType) {
+            case SystemBatteryConsumer.DRAIN_TYPE_AMBIENT_DISPLAY:
+                name = context.getResources().getString(R.string.ambient_display_screen_title);
+                iconId = R.drawable.ic_settings_aod;
+                break;
+            case SystemBatteryConsumer.DRAIN_TYPE_BLUETOOTH:
+                name = context.getResources().getString(R.string.power_bluetooth);
+                iconId = com.android.internal.R.drawable.ic_settings_bluetooth;
+                break;
+            case SystemBatteryConsumer.DRAIN_TYPE_CAMERA:
+                name = context.getResources().getString(R.string.power_camera);
+                iconId = R.drawable.ic_settings_camera;
+                break;
+            case SystemBatteryConsumer.DRAIN_TYPE_MOBILE_RADIO:
+                name = context.getResources().getString(R.string.power_cell);
+                iconId = R.drawable.ic_cellular_1_bar;
+                break;
+            case SystemBatteryConsumer.DRAIN_TYPE_FLASHLIGHT:
+                name = context.getResources().getString(R.string.power_flashlight);
+                iconId = R.drawable.ic_settings_display;
+                break;
+            case SystemBatteryConsumer.DRAIN_TYPE_PHONE:
+                name = context.getResources().getString(R.string.power_phone);
+                iconId = R.drawable.ic_settings_voice_calls;
+                break;
+            case SystemBatteryConsumer.DRAIN_TYPE_SCREEN:
+                name = context.getResources().getString(R.string.power_screen);
+                iconId = R.drawable.ic_settings_display;
+                break;
+            case SystemBatteryConsumer.DRAIN_TYPE_WIFI:
+                name = context.getResources().getString(R.string.power_wifi);
+                iconId = R.drawable.ic_settings_wireless;
+                break;
+            case SystemBatteryConsumer.DRAIN_TYPE_IDLE:
+            case SystemBatteryConsumer.DRAIN_TYPE_MEMORY:
+                name = context.getResources().getString(R.string.power_idle);
+                iconId = R.drawable.ic_settings_phone_idle;
+                break;
+            case SystemBatteryConsumer.DRAIN_TYPE_CUSTOM:
+                name = null;
+                iconId = R.drawable.ic_power_system;
+                break;
+        }
+        return new Pair<>(Integer.valueOf(iconId), name);
+    }
 }
diff --git a/src/com/android/settings/fuelgauge/batterytip/detectors/EarlyWarningDetector.java b/src/com/android/settings/fuelgauge/batterytip/detectors/EarlyWarningDetector.java
index 9b6b9b5..f7a4f8c 100644
--- a/src/com/android/settings/fuelgauge/batterytip/detectors/EarlyWarningDetector.java
+++ b/src/com/android/settings/fuelgauge/batterytip/detectors/EarlyWarningDetector.java
@@ -56,7 +56,7 @@
                 EarlyWarningDetector.class.getName()) || mPolicy.testBatterySaverTip;
 
         final int state = powerSaveModeOn
-                ? BatteryTip.StateType.HANDLED
+                ? BatteryTip.StateType.INVISIBLE
                 : mPolicy.batterySaverTipEnabled && discharging && earlyWarning
                         ? BatteryTip.StateType.NEW
                         : BatteryTip.StateType.INVISIBLE;
diff --git a/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetector.java b/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetector.java
index ca9141d..75f47a7 100644
--- a/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetector.java
+++ b/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetector.java
@@ -49,16 +49,16 @@
         final boolean lowBattery = mBatteryInfo.batteryLevel <= mWarningLevel
                 || (mBatteryInfo.discharging && mBatteryInfo.remainingTimeUs != 0
                 && mBatteryInfo.remainingTimeUs < TimeUnit.HOURS.toMicros(mPolicy.lowBatteryHour));
+        final boolean lowBatteryEnabled = mPolicy.lowBatteryEnabled && !powerSaveModeOn;
+        final boolean dischargingLowBatteryState =
+                mPolicy.testLowBatteryTip || (mBatteryInfo.discharging && lowBattery);
 
         int state = BatteryTip.StateType.INVISIBLE;
-        if (mPolicy.lowBatteryEnabled) {
-            if (powerSaveModeOn) {
-                // Show it is handled if battery saver is on
-                state = BatteryTip.StateType.HANDLED;
-            } else if (mPolicy.testLowBatteryTip || (mBatteryInfo.discharging && lowBattery)) {
-                // Show it is new if in test or in discharging low battery state
-                state = BatteryTip.StateType.NEW;
-            }
+
+        // Show it as new if in test or in discharging low battery state,
+        // dismiss it if battery saver is on or disabled by config.
+        if (lowBatteryEnabled && dischargingLowBatteryState) {
+            state = BatteryTip.StateType.NEW;
         }
 
         return new LowBatteryTip(
diff --git a/src/com/android/settings/fuelgauge/batterytip/tips/EarlyWarningTip.java b/src/com/android/settings/fuelgauge/batterytip/tips/EarlyWarningTip.java
index 0c2bb03..6701314 100644
--- a/src/com/android/settings/fuelgauge/batterytip/tips/EarlyWarningTip.java
+++ b/src/com/android/settings/fuelgauge/batterytip/tips/EarlyWarningTip.java
@@ -18,7 +18,6 @@
 
 import android.app.settings.SettingsEnums;
 import android.content.Context;
-import android.content.res.ColorStateList;
 import android.os.Parcel;
 
 import com.android.settings.R;
@@ -43,31 +42,23 @@
     @Override
     public CharSequence getTitle(Context context) {
         return context.getString(
-                mState == StateType.HANDLED
-                        ? R.string.battery_tip_early_heads_up_done_title
-                        : R.string.battery_tip_early_heads_up_title);
+                mState = R.string.battery_tip_early_heads_up_title);
     }
 
     @Override
     public CharSequence getSummary(Context context) {
         return context.getString(
-                mState == StateType.HANDLED
-                        ? R.string.battery_tip_early_heads_up_done_summary
-                        : R.string.battery_tip_early_heads_up_summary);
+                mState = R.string.battery_tip_early_heads_up_summary);
     }
 
     @Override
     public int getIconId() {
-        return mState == StateType.HANDLED
-                ? R.drawable.ic_battery_status_maybe_24dp
-                : R.drawable.ic_battery_status_bad_24dp;
+        return mState = R.drawable.ic_battery_status_bad_24dp;
     }
 
     @Override
     public int getIconTintColorId() {
-        return mState == StateType.HANDLED
-                ? R.color.battery_maybe_color_light
-                : R.color.battery_bad_color_light;
+        return mState = R.color.battery_bad_color_light;
     }
 
     @Override
@@ -76,9 +67,9 @@
         if (earlyWarningTip.mState == StateType.NEW) {
             // Display it if there is early warning
             mState = StateType.NEW;
-        } else if (mState == StateType.NEW && earlyWarningTip.mState == StateType.INVISIBLE) {
-            // If powerSaveMode is really on, show it as handled, otherwise just dismiss it.
-            mState = earlyWarningTip.mPowerSaveModeOn ? StateType.HANDLED : StateType.INVISIBLE;
+        } else if (earlyWarningTip.mPowerSaveModeOn) {
+            // If powerSaveMode is really on, dismiss it.
+            mState = StateType.INVISIBLE;
         } else {
             mState = earlyWarningTip.getState();
         }
diff --git a/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTip.java b/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTip.java
index d7acdd2..7790b10 100644
--- a/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTip.java
+++ b/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTip.java
@@ -21,7 +21,6 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
-import com.android.settings.R;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 /**
@@ -43,8 +42,7 @@
 
     @Override
     public CharSequence getSummary(Context context) {
-        return mState == StateType.HANDLED ? context.getString(
-                R.string.battery_tip_early_heads_up_done_summary) : mSummary;
+        return mSummary;
     }
 
     @Override
diff --git a/src/com/android/settings/homepage/SettingsHomepageActivity.java b/src/com/android/settings/homepage/SettingsHomepageActivity.java
index aa7b2d1..881e39c 100644
--- a/src/com/android/settings/homepage/SettingsHomepageActivity.java
+++ b/src/com/android/settings/homepage/SettingsHomepageActivity.java
@@ -43,6 +43,25 @@
 
     private static final String TAG = "SettingsHomepageActivity";
 
+    private static final long HOMEPAGE_LOADING_TIMEOUT_MS = 300;
+
+    private View mHomepageView;
+    private View mSuggestionView;
+
+    /**
+     * Shows the homepage and shows/hides the suggestion together. Only allows to be executed once
+     * to avoid the flicker caused by the suggestion suddenly appearing/disappearing.
+     */
+    public void showHomepageWithSuggestion(boolean showSuggestion) {
+        if (mHomepageView == null) {
+            return;
+        }
+        Log.i(TAG, "showHomepageWithSuggestion: " + showSuggestion);
+        mSuggestionView.setVisibility(showSuggestion ? View.VISIBLE : View.GONE);
+        mHomepageView.setVisibility(View.VISIBLE);
+        mHomepageView = null;
+    }
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -56,15 +75,23 @@
         FeatureFactory.getFactory(this).getSearchFeatureProvider()
                 .initSearchToolbar(this /* activity */, toolbar, SettingsEnums.SETTINGS_HOMEPAGE);
 
-        final ImageView avatarView = findViewById(R.id.account_avatar);
-        getLifecycle().addObserver(new AvatarViewMixin(this, avatarView));
         getLifecycle().addObserver(new HideNonSystemOverlayMixin(this));
 
         if (!getSystemService(ActivityManager.class).isLowRamDevice()) {
-            // Only allow contextual features on high ram devices.
+            // Only allow features on high ram devices.
+            final ImageView avatarView = findViewById(R.id.account_avatar);
+            if (AvatarViewMixin.isAvatarSupported(this)) {
+                avatarView.setVisibility(View.VISIBLE);
+                getLifecycle().addObserver(new AvatarViewMixin(this, avatarView));
+            }
+
             if (FeatureFlagUtils.isEnabled(this, FeatureFlags.SILKY_HOME)) {
                 showSuggestionFragment();
+            } else {
+                findViewById(R.id.homepage_title).setVisibility(View.GONE);
+                avatarView.setVisibility(View.GONE);
             }
+
             if (FeatureFlagUtils.isEnabled(this, FeatureFlags.CONTEXTUAL_HOME)) {
                 showFragment(new ContextualCardsFragment(), R.id.contextual_cards_content);
             }
@@ -81,9 +108,16 @@
             return;
         }
 
+        mSuggestionView = findViewById(R.id.suggestion_content);
+        mHomepageView = findViewById(R.id.settings_homepage_container);
+        // Hide the homepage for preparing the suggestion.
+        mHomepageView.setVisibility(View.GONE);
+        // Schedule a timer to show the homepage and hide the suggestion on timeout.
+        mHomepageView.postDelayed(() -> showHomepageWithSuggestion(false),
+                HOMEPAGE_LOADING_TIMEOUT_MS);
         try {
-            showFragment(fragment.newInstance(), R.id.contextual_suggestion_content);
-        } catch (IllegalAccessException | InstantiationException e) {
+            showFragment(fragment.getConstructor().newInstance(), R.id.suggestion_content);
+        } catch (Exception e) {
             Log.w(TAG, "Cannot show fragment", e);
         }
     }
@@ -110,10 +144,7 @@
 
     private int getSearchBoxHeight() {
         final int searchBarHeight = getResources().getDimensionPixelSize(R.dimen.search_bar_height);
-        final int searchBarMarginTop = getResources().getDimensionPixelSize(
-                R.dimen.search_bar_margin);
-        final int searchBarMarginBottom = getResources().getDimensionPixelSize(
-                R.dimen.search_bar_margin_bottom);
-        return searchBarHeight + searchBarMarginTop + searchBarMarginBottom;
+        final int searchBarMargin = getResources().getDimensionPixelSize(R.dimen.search_bar_margin);
+        return searchBarHeight + searchBarMargin * 2;
     }
 }
diff --git a/src/com/android/settings/network/NetworkProviderSettings.java b/src/com/android/settings/network/NetworkProviderSettings.java
index 803b981..1d8ee7a 100644
--- a/src/com/android/settings/network/NetworkProviderSettings.java
+++ b/src/com/android/settings/network/NetworkProviderSettings.java
@@ -1129,7 +1129,7 @@
     @Override
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         MenuItem item = menu.add(0, MENU_FIX_CONNECTIVITY, 0, R.string.fix_connectivity);
-        item.setIcon(R.drawable.ic_refresh_24dp);
+        item.setIcon(R.drawable.ic_repair_24dp);
         item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
         super.onCreateOptionsMenu(menu, inflater);
     }
diff --git a/src/com/android/settings/network/VpnPreferenceController.java b/src/com/android/settings/network/VpnPreferenceController.java
index e815d49..3116dd4 100644
--- a/src/com/android/settings/network/VpnPreferenceController.java
+++ b/src/com/android/settings/network/VpnPreferenceController.java
@@ -27,6 +27,8 @@
 import android.os.UserManager;
 import android.provider.Settings;
 import android.provider.SettingsSlicesContract;
+import android.security.Credentials;
+import android.security.LegacyVpnProfileStore;
 import android.util.Log;
 import android.util.SparseArray;
 
@@ -36,8 +38,11 @@
 
 import com.android.internal.net.LegacyVpnInfo;
 import com.android.internal.net.VpnConfig;
+import com.android.internal.net.VpnProfile;
 import com.android.settings.R;
+import com.android.settings.Utils;
 import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.vpn2.VpnInfoPreference;
 import com.android.settingslib.RestrictedLockUtilsInternal;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
@@ -147,6 +152,10 @@
         } else {
             summary = getNameForVpnConfig(vpn, UserHandle.of(uid));
         }
+        // Optionally add warning icon if an insecure VPN is present.
+        if (Utils.isProviderModelEnabled(mContext) && mPreference instanceof VpnInfoPreference) {
+            ((VpnInfoPreference) mPreference).setInsecureVpn(hasInsecureVpn());
+        }
         ThreadUtils.postOnMainThread(() -> mPreference.setSummary(summary));
     }
 
@@ -167,6 +176,20 @@
         }
     }
 
+    @VisibleForTesting
+    protected boolean hasInsecureVpn() {
+        for (String key : LegacyVpnProfileStore.list(Credentials.VPN)) {
+            final VpnProfile profile = VpnProfile.decode(key,
+                    LegacyVpnProfileStore.get(Credentials.VPN + key));
+            // Return whether any profile is an insecure type.
+            if (VpnProfile.isLegacyType(profile.type)) {
+                return true;
+            }
+        }
+        // We did not find any insecure VPNs.
+        return false;
+    }
+
     // Copied from SystemUI::SecurityControllerImpl
     private final ConnectivityManager.NetworkCallback
             mNetworkCallback = new ConnectivityManager.NetworkCallback() {
diff --git a/src/com/android/settings/vpn2/VpnInfoPreference.java b/src/com/android/settings/vpn2/VpnInfoPreference.java
new file mode 100644
index 0000000..cca45b5
--- /dev/null
+++ b/src/com/android/settings/vpn2/VpnInfoPreference.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.vpn2;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.View;
+
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.settings.R;
+import com.android.settingslib.HelpUtils;
+import com.android.settingslib.RestrictedPreference;
+
+
+/**
+ * A preference with an Info icon on the side
+ */
+public class VpnInfoPreference extends RestrictedPreference implements View.OnClickListener {
+
+    private boolean mIsInsecureVpn = false;
+    private String mHelpUrl;
+
+    public VpnInfoPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mHelpUrl = context.getString(R.string.help_url_insecure_vpn);
+    }
+
+    @Override
+    protected int getSecondTargetResId() {
+        // Note: in the future, we will probably want to provide a configuration option
+        // for this info to not be the warning color.
+        return R.layout.preference_widget_warning;
+    }
+
+    @Override
+    protected boolean shouldHideSecondTarget() {
+        return false;
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+        final View icon = holder.findViewById(R.id.warning_button);
+        if (mIsInsecureVpn && !TextUtils.isEmpty(mHelpUrl)) {
+            icon.setVisibility(View.VISIBLE);
+            icon.setOnClickListener(this);
+            icon.setEnabled(true);
+        } else {
+            icon.setVisibility(View.GONE);
+            icon.setOnClickListener(this);
+            icon.setEnabled(false);
+        }
+
+        // Hide the divider from view
+        final View divider = holder.findViewById(R.id.two_target_divider);
+        divider.setVisibility(View.GONE);
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (v.getId() == R.id.warning_button) {
+            final Intent intent = HelpUtils.getHelpIntent(
+                    getContext(), mHelpUrl, this.getClass().getName());
+
+            if (intent != null) {
+                ((Activity) getContext()).startActivityForResult(intent, 0);
+            }
+        }
+    }
+
+    /**
+     * Sets whether this preference corresponds to an insecure VPN. This will also affect whether
+     * the warning icon appears to the user.
+     */
+    public void setInsecureVpn(boolean isInsecureVpn) {
+        if (mIsInsecureVpn != isInsecureVpn) {
+            mIsInsecureVpn = isInsecureVpn;
+            notifyChanged();
+        }
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/accounts/AvatarViewMixinTest.java b/tests/robotests/src/com/android/settings/accounts/AvatarViewMixinTest.java
index 534d3c6..04db527 100644
--- a/tests/robotests/src/com/android/settings/accounts/AvatarViewMixinTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/AvatarViewMixinTest.java
@@ -27,7 +27,6 @@
 import static org.mockito.Mockito.verify;
 
 import android.accounts.Account;
-import android.app.ActivityManager;
 import android.content.ContentProvider;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -57,7 +56,6 @@
 import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
 import org.robolectric.shadow.api.Shadow;
-import org.robolectric.shadows.ShadowActivityManager;
 import org.robolectric.shadows.ShadowContentResolver;
 import org.robolectric.shadows.ShadowPackageManager;
 
@@ -97,31 +95,7 @@
     }
 
     @Test
-    public void onStart_configDisabled_doNothing() {
-        final AvatarViewMixin mixin = spy(new AvatarViewMixin(mActivity, mImageView));
-        mixin.onStart();
-
-        verify(mixin, never()).hasAccount();
-    }
-
-    @Test
-    public void onStart_lowRamDevice_doNothing() {
-        final AvatarViewMixin mixin = spy(new AvatarViewMixin(mActivity, mImageView));
-
-        final ShadowActivityManager activityManager =
-                Shadow.extract(mContext.getSystemService(ActivityManager.class));
-        activityManager.setIsLowRamDevice(true);
-
-        mixin.onStart();
-
-        verify(mixin, never()).hasAccount();
-    }
-
-    @Test
-    @Config(qualifiers = "mcc999",
-            shadows = {
-                    BatteryFixSliceTest.ShadowBatteryTipLoader.class
-            })
+    @Config(shadows = BatteryFixSliceTest.ShadowBatteryTipLoader.class)
     public void onStart_useMockAvatarViewMixin_shouldBeExecuted() {
         final AvatarViewMixin mockAvatar = spy(new AvatarViewMixin(mActivity, mImageView));
 
@@ -132,7 +106,6 @@
     }
 
     @Test
-    @Config(qualifiers = "mcc999")
     public void onStart_noAccount_mAccountNameShouldBeNull() {
         final AvatarViewMixin avatarViewMixin = new AvatarViewMixin(mActivity, mImageView);
         avatarViewMixin.mAccountName = FAKE_ACCOUNT;
diff --git a/tests/robotests/src/com/android/settings/development/DefaultUsbConfigurationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/DefaultUsbConfigurationPreferenceControllerTest.java
index 15f4eb9..c9b13e27 100644
--- a/tests/robotests/src/com/android/settings/development/DefaultUsbConfigurationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/DefaultUsbConfigurationPreferenceControllerTest.java
@@ -91,4 +91,27 @@
         verify(mPreference).setDisabledByAdmin(eq(new RestrictedLockUtils.EnforcedAdmin(
                 TEST_COMPONENT_NAME, null, UserHandle.SYSTEM)));
     }
+
+    @Test
+    public void onDeveloperOptionsSwitchEnabled_usbEnabled_shouldNotDisablePreference() {
+        when(mDevicePolicyManager.isUsbDataSignalingEnabledForUser(
+                UserHandle.myUserId())).thenReturn(true);
+        when(mDevicePolicyManager.getProfileOwner()).thenReturn(TEST_COMPONENT_NAME);
+
+        mController.onDeveloperOptionsSwitchEnabled();
+
+        verify(mPreference).setDisabledByAdmin(null);
+    }
+
+    @Test
+    public void onDeveloperOptionsSwitchEnabled_usbDisabled_shouldDisablePreference() {
+        when(mDevicePolicyManager.isUsbDataSignalingEnabledForUser(
+                UserHandle.myUserId())).thenReturn(false);
+        when(mDevicePolicyManager.getProfileOwner()).thenReturn(TEST_COMPONENT_NAME);
+
+        mController.onDeveloperOptionsSwitchEnabled();
+
+        verify(mPreference).setDisabledByAdmin(eq(new RestrictedLockUtils.EnforcedAdmin(
+                TEST_COMPONENT_NAME, null, UserHandle.SYSTEM)));
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/development/UsbAudioRoutingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/UsbAudioRoutingPreferenceControllerTest.java
index 1d45c1b..69d2c99 100644
--- a/tests/robotests/src/com/android/settings/development/UsbAudioRoutingPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/UsbAudioRoutingPreferenceControllerTest.java
@@ -147,4 +147,27 @@
         verify(mPreference).setEnabled(false);
         verify(mPreference).setChecked(false);
     }
+
+    @Test
+    public void onDeveloperOptionsSwitchEnabled_usbEnabled_shouldNotDisablePreference() {
+        when(mDevicePolicyManager.isUsbDataSignalingEnabledForUser(
+                UserHandle.myUserId())).thenReturn(true);
+        when(mDevicePolicyManager.getProfileOwner()).thenReturn(TEST_COMPONENT_NAME);
+
+        mController.onDeveloperOptionsSwitchEnabled();
+
+        verify(mPreference).setDisabledByAdmin(null);
+    }
+
+    @Test
+    public void onDeveloperOptionsSwitchEnabled_usbDisabled_shouldDisablePreference() {
+        when(mDevicePolicyManager.isUsbDataSignalingEnabledForUser(
+                UserHandle.myUserId())).thenReturn(false);
+        when(mDevicePolicyManager.getProfileOwner()).thenReturn(TEST_COMPONENT_NAME);
+
+        mController.onDeveloperOptionsSwitchEnabled();
+
+        verify(mPreference).setDisabledByAdmin(eq(new RestrictedLockUtils.EnforcedAdmin(
+                TEST_COMPONENT_NAME, null, UserHandle.SYSTEM)));
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/EarlyWarningDetectorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/EarlyWarningDetectorTest.java
index dbee7f1..84411a7 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/EarlyWarningDetectorTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/EarlyWarningDetectorTest.java
@@ -86,11 +86,11 @@
     }
 
     @Test
-    public void testDetect_batterySaverOn_tipHandled() {
+    public void testDetect_batterySaverOn_tipInvisible() {
         doReturn(true).when(mPowerManager).isPowerSaveMode();
 
         assertThat(mEarlyWarningDetector.detect().getState())
-                .isEqualTo(BatteryTip.StateType.HANDLED);
+                .isEqualTo(BatteryTip.StateType.INVISIBLE);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetectorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetectorTest.java
index 55020e2..245bacc 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetectorTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetectorTest.java
@@ -91,10 +91,11 @@
     }
 
     @Test
-    public void testDetect_batterySaverOn_tipHandled() {
+    public void testDetect_batterySaverOn_tipInvisible() {
         mShadowPowerManager.setIsPowerSaveMode(true);
 
-        assertThat(mLowBatteryDetector.detect().getState()).isEqualTo(BatteryTip.StateType.HANDLED);
+        assertThat(mLowBatteryDetector.detect().getState())
+                .isEqualTo(BatteryTip.StateType.INVISIBLE);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/EarlyWarningTipTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/EarlyWarningTipTest.java
index 85b00c8..aeea10f 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/EarlyWarningTipTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/EarlyWarningTipTest.java
@@ -74,24 +74,13 @@
     }
 
     @Test
-    public void testInfo_stateHandled_displayPowerModeHandledInfo() {
-        final EarlyWarningTip tip =
-                new EarlyWarningTip(BatteryTip.StateType.HANDLED, false /* powerModeOn */);
-
-        assertThat(tip.getTitle(mContext)).isEqualTo("Battery Saver is on");
-        assertThat(tip.getSummary(mContext)).isEqualTo("Some features may be limited");
-        assertThat(tip.getIconId()).isEqualTo(R.drawable.ic_battery_status_maybe_24dp);
-        assertThat(tip.getIconTintColorId()).isEqualTo(R.color.battery_maybe_color_light);
-    }
-
-    @Test
-    public void testUpdate_powerModeTurnedOn_typeBecomeHandled() {
+    public void testUpdate_powerModeTurnedOn_typeBecomeInvisible() {
         final EarlyWarningTip nextTip =
                 new EarlyWarningTip(BatteryTip.StateType.INVISIBLE, true /* powerModeOn */);
 
         mEarlyWarningTip.updateState(nextTip);
 
-        assertThat(mEarlyWarningTip.getState()).isEqualTo(BatteryTip.StateType.HANDLED);
+        assertThat(mEarlyWarningTip.getState()).isEqualTo(BatteryTip.StateType.INVISIBLE);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTipTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTipTest.java
index 11dffcd..244faea 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTipTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTipTest.java
@@ -65,13 +65,6 @@
     }
 
     @Test
-    public void getSummary_tipHandled_showSummary() {
-        mLowBatteryTip.mState = BatteryTip.StateType.HANDLED;
-
-        assertThat(mLowBatteryTip.getSummary(mContext)).isEqualTo("Some features may be limited");
-    }
-
-    @Test
     public void getSummary_tipNew_showSummary() {
         mLowBatteryTip.mState = BatteryTip.StateType.NEW;
 
diff --git a/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java b/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
index 173f625..c7a2650 100644
--- a/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
@@ -25,16 +25,20 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.ActivityManager;
 import android.os.Build;
-import android.util.FeatureFlagUtils;
+import android.view.View;
 import android.view.Window;
 import android.view.WindowManager;
 import android.widget.FrameLayout;
 
+import androidx.fragment.app.Fragment;
+
 import com.android.settings.R;
-import com.android.settings.core.FeatureFlags;
 import com.android.settings.core.HideNonSystemOverlayMixin;
+import com.android.settings.dashboard.suggestions.SuggestionFeatureProviderImpl;
 import com.android.settings.homepage.contextualcards.slices.BatteryFixSliceTest;
+import com.android.settings.testutils.shadow.ShadowUserManager;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -46,15 +50,20 @@
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.android.controller.ActivityController;
 import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowActivityManager;
 import org.robolectric.util.ReflectionHelpers;
 
 @RunWith(RobolectricTestRunner.class)
+@Config(shadows = {ShadowUserManager.class,
+        SettingsHomepageActivityTest.ShadowSuggestionFeatureProviderImpl.class})
 public class SettingsHomepageActivityTest {
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        FeatureFlagUtils.setEnabled(RuntimeEnvironment.application, FeatureFlags.SILKY_HOME, false);
     }
 
     @Test
@@ -67,6 +76,77 @@
     }
 
     @Test
+    public void launch_configDisabled_shouldHideAvatar() {
+        final SettingsHomepageActivity activity = Robolectric.buildActivity(
+                SettingsHomepageActivity.class).create().get();
+
+        final View avatarView = activity.findViewById(R.id.account_avatar);
+        assertThat(avatarView.getVisibility()).isNotEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    @Config(qualifiers = "mcc999")
+    public void launch_configEnabled_shouldShowAvatar() {
+        final SettingsHomepageActivity activity = Robolectric.buildActivity(
+                SettingsHomepageActivity.class).create().get();
+
+        final View avatarView = activity.findViewById(R.id.account_avatar);
+        assertThat(avatarView.getVisibility()).isEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    @Config(qualifiers = "mcc999")
+    public void launch_LowRamDevice_shouldHideAvatar() {
+        final ShadowActivityManager activityManager = Shadow.extract(
+                RuntimeEnvironment.application.getSystemService(ActivityManager.class));
+        activityManager.setIsLowRamDevice(true);
+
+        final SettingsHomepageActivity activity = Robolectric.buildActivity(
+                SettingsHomepageActivity.class).create().get();
+
+        final View avatarView = activity.findViewById(R.id.account_avatar);
+        assertThat(avatarView.getVisibility()).isNotEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    public void showHomepageWithSuggestion_showSuggestion() {
+        final SettingsHomepageActivity activity = Robolectric.buildActivity(
+                SettingsHomepageActivity.class).create().get();
+        final View viewRoot = activity.findViewById(R.id.settings_homepage_container);
+        final View suggestionTile = activity.findViewById(R.id.suggestion_content);
+
+        activity.showHomepageWithSuggestion(true);
+
+        assertThat(viewRoot.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(suggestionTile.getVisibility()).isEqualTo(View.VISIBLE);
+    }
+
+    @Test
+    public void showHomepageWithSuggestion_hideSuggestion() {
+        final SettingsHomepageActivity activity = Robolectric.buildActivity(
+                SettingsHomepageActivity.class).create().get();
+        final View viewRoot = activity.findViewById(R.id.settings_homepage_container);
+        final View suggestionTile = activity.findViewById(R.id.suggestion_content);
+
+        activity.showHomepageWithSuggestion(false);
+
+        assertThat(viewRoot.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(suggestionTile.getVisibility()).isEqualTo(View.GONE);
+    }
+
+    @Test
+    public void showHomepageWithSuggestion_callTwice_shouldKeepPreviousVisibility() {
+        final SettingsHomepageActivity activity = Robolectric.buildActivity(
+                SettingsHomepageActivity.class).create().get();
+        final View suggestionTile = activity.findViewById(R.id.suggestion_content);
+
+        activity.showHomepageWithSuggestion(false);
+        activity.showHomepageWithSuggestion(true);
+
+        assertThat(suggestionTile.getVisibility()).isEqualTo(View.GONE);
+    }
+
+    @Test
     @Config(shadows = {
             BatteryFixSliceTest.ShadowBatteryTipLoader.class
     })
@@ -114,4 +194,13 @@
         assertThat(paramCaptor.getValue().privateFlags
                 & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS).isEqualTo(0);
     }
+
+    @Implements(SuggestionFeatureProviderImpl.class)
+    public static class ShadowSuggestionFeatureProviderImpl {
+
+        @Implementation
+        public Class<? extends Fragment> getContextualSuggestionFragment() {
+            return Fragment.class;
+        }
+    }
 }
diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp
index b7ac4b1..408f2d3 100644
--- a/tests/unit/Android.bp
+++ b/tests/unit/Android.bp
@@ -34,6 +34,7 @@
         "ub-uiautomator",
         "SettingsLibSettingsSpinner",
         "SettingsLibUsageProgressBarPreference",
+        "SettingsLibTwoTargetPreference",
     ],
 
     // Include all test java files.
diff --git a/tests/unit/src/com/android/settings/applications/HibernatedAppsPreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/HibernatedAppsPreferenceControllerTest.java
index cf4c53e..a34e634 100644
--- a/tests/unit/src/com/android/settings/applications/HibernatedAppsPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/applications/HibernatedAppsPreferenceControllerTest.java
@@ -23,9 +23,18 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
+import android.apphibernation.AppHibernationManager;
 import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
 import android.provider.DeviceConfig;
 
 import androidx.test.core.app.ApplicationProvider;
@@ -34,23 +43,40 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
-/**
- * TODO(b/181172051): test getNumberHibernated() when the API implemented
- */
+import java.util.Arrays;
+
 @RunWith(AndroidJUnit4.class)
 public class HibernatedAppsPreferenceControllerTest {
 
+    public static final String HIBERNATED_PACKAGE_NAME = "hibernated_package";
+    public static final String AUTO_REVOKED_PACKAGE_NAME = "auto_revoked_package";
+    public static final String PERMISSION = "permission";
+    @Mock
+    PackageManager mPackageManager;
+    @Mock
+    AppHibernationManager mAppHibernationManager;
     private static final String KEY = "key";
     private Context mContext;
     private HibernatedAppsPreferenceController mController;
+    private PackageInfo mHibernatedPackage;
+    private PackageInfo mAutoRevokedPackage;
 
     @Before
     public void setUp() {
+        MockitoAnnotations.initMocks(this);
         DeviceConfig.setProperty(NAMESPACE_APP_HIBERNATION, PROPERTY_APP_HIBERNATION_ENABLED,
                 "true", false);
         mContext = spy(ApplicationProvider.getApplicationContext());
+        when(mContext.getPackageManager()).thenReturn(mPackageManager);
+        when(mContext.getSystemService(AppHibernationManager.class))
+                .thenReturn(mAppHibernationManager);
         mController = new HibernatedAppsPreferenceController(mContext, KEY);
+        mHibernatedPackage =
+                getHibernatedPackage(mAppHibernationManager, mPackageManager, mContext);
+        mAutoRevokedPackage = getAutoRevokedPackage(mPackageManager, mContext);
     }
 
     @Test
@@ -60,4 +86,38 @@
 
         assertThat((mController).getAvailabilityStatus()).isNotEqualTo(AVAILABLE);
     }
+
+    @Test
+    public void getSummary_shouldReturnCorrectly() {
+        when(mPackageManager.getInstalledPackages(anyInt())).thenReturn(
+                Arrays.asList(mHibernatedPackage, mAutoRevokedPackage, new PackageInfo()));
+        when(mContext.getResources()).thenReturn(mock(Resources.class));
+        final int totalHibernated = 2;
+
+        mController.getSummary();
+        verify(mContext.getResources()).getQuantityString(
+                anyInt(), eq(totalHibernated), eq(totalHibernated));
+    }
+
+    private static PackageInfo getHibernatedPackage(
+            AppHibernationManager apm, PackageManager pm, Context context) {
+        final PackageInfo pi = new PackageInfo();
+        pi.packageName = HIBERNATED_PACKAGE_NAME;
+        pi.requestedPermissions = new String[] {PERMISSION};
+        when(apm.getHibernatingPackagesForUser()).thenReturn(Arrays.asList(pi.packageName));
+        when(pm.getPermissionFlags(
+                pi.requestedPermissions[0], pi.packageName, context.getUser()))
+                .thenReturn(PackageManager.FLAG_PERMISSION_AUTO_REVOKED);
+        return pi;
+    }
+
+    private static PackageInfo getAutoRevokedPackage(PackageManager pm, Context context) {
+        final PackageInfo pi = new PackageInfo();
+        pi.packageName = AUTO_REVOKED_PACKAGE_NAME;
+        pi.requestedPermissions = new String[] {PERMISSION};
+        when(pm.getPermissionFlags(
+                pi.requestedPermissions[0], pi.packageName, context.getUser()))
+                .thenReturn(PackageManager.FLAG_PERMISSION_AUTO_REVOKED);
+        return pi;
+    }
 }