Merge "Follow up comments to 0cdc103e8287d3bd01944cdd2afb5c11897998fe."
diff --git a/res/layout/master_clear.xml b/res/layout/master_clear.xml
index 9f89961..921347e 100644
--- a/res/layout/master_clear.xml
+++ b/res/layout/master_clear.xml
@@ -23,8 +23,8 @@
             android:id="@+id/master_clear_scrollview"
             android:layout_width="match_parent"
             android:layout_height="0dip"
-            android:layout_marginStart="@dimen/preference_no_icon_padding_start"
-            android:layout_marginEnd="12dp"
+            android:layout_marginStart="@dimen/reset_master_clear_margin_start"
+            android:layout_marginEnd="@dimen/reset_master_clear_margin_end"
             android:layout_marginTop="12dp"
             android:layout_weight="1">
         <LinearLayout
diff --git a/res/layout/reset_network.xml b/res/layout/reset_network.xml
index 1850bb2..7eb5d2a 100644
--- a/res/layout/reset_network.xml
+++ b/res/layout/reset_network.xml
@@ -23,8 +23,8 @@
     <ScrollView
         android:layout_width="match_parent"
         android:layout_height="0dip"
-        android:layout_marginStart="@dimen/preference_no_icon_padding_start"
-        android:layout_marginEnd="12dp"
+        android:layout_marginStart="@dimen/reset_network_margin_start"
+        android:layout_marginEnd="@dimen/reset_network_margin_end"
         android:layout_marginTop="12dp"
         android:layout_weight="1">
 
diff --git a/res/layout/screen_pinning_instructions.xml b/res/layout/screen_pinning_instructions.xml
index 80fec3c..fea5ed8 100644
--- a/res/layout/screen_pinning_instructions.xml
+++ b/res/layout/screen_pinning_instructions.xml
@@ -31,8 +31,8 @@
         android:paddingTop="@dimen/screen_pinning_textview_padding"
         android:text="@string/screen_pinning_description"
         android:textAppearance="@style/TextAppearance.Medium"
-        android:paddingStart="@dimen/screen_margin_sides"
-        android:paddingEnd="@dimen/screen_margin_sides"
+        android:paddingStart="@dimen/screen_pinning_padding_start"
+        android:paddingEnd="@dimen/screen_pinning_padding_end"
         />
 
 </ScrollView>
diff --git a/res/values-sw600dp-land/dimens.xml b/res/values-sw600dp-land/dimens.xml
index d5ea762..afdcd0e 100755
--- a/res/values-sw600dp-land/dimens.xml
+++ b/res/values-sw600dp-land/dimens.xml
@@ -29,4 +29,8 @@
 
     <dimen name="confirm_credentials_top_padding">20dp</dimen>
     <dimen name="confirm_credentials_top_margin">24dp</dimen>
+
+    <!-- Padding for screen pinning -->
+    <dimen name="screen_pinning_padding_start">128dp</dimen>
+    <dimen name="screen_pinning_padding_end">128dp</dimen>
 </resources>
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
index 273225e..241471c 100755
--- a/res/values-sw600dp/dimens.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -62,4 +62,8 @@
     <dimen name="confirm_credentials_top_padding">48dp</dimen>
     <dimen name="confirm_credentials_side_margin">0dp</dimen>
     <dimen name="confirm_credentials_top_margin">64dp</dimen>
+
+    <!-- Padding for screen pinning -->
+    <dimen name="screen_pinning_padding_start">40dp</dimen>
+    <dimen name="screen_pinning_padding_end">40dp</dimen>
 </resources>
diff --git a/res/values-xlarge/dimens.xml b/res/values-xlarge/dimens.xml
index b6b4591..df9d56f 100755
--- a/res/values-xlarge/dimens.xml
+++ b/res/values-xlarge/dimens.xml
@@ -18,4 +18,8 @@
     <dimen name="screen_margin_sides">128dip</dimen>
     <dimen name="datetime_margin_top">154dip</dimen>
     <dimen name="datetime_margin_bottom">96dip</dimen>
+
+    <!-- Padding for screen pinning -->
+    <dimen name="screen_pinning_padding_start">128dp</dimen>
+    <dimen name="screen_pinning_padding_end">128dp</dimen>
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index be57bf7..16d9f96 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -297,6 +297,16 @@
     <dimen name="battery_meter_width">66dp</dimen>
     <dimen name="battery_meter_height">100dp</dimen>
 
+    <!-- Margin for the reset screens -->
+    <dimen name="reset_network_margin_start">72dp</dimen>
+    <dimen name="reset_network_margin_end">12dp</dimen>
+    <dimen name="reset_master_clear_margin_start">72dp</dimen>
+    <dimen name="reset_master_clear_margin_end">12dp</dimen>
+
+    <!-- Padding for screen pinning -->
+    <dimen name="screen_pinning_padding_start">64dp</dimen>
+    <dimen name="screen_pinning_padding_end">64dp</dimen>
+
     <!-- Suggestion/condition header padding -->
     <dimen name="suggestion_condition_header_padding_collapsed">10dp</dimen>
     <dimen name="suggestion_condition_header_padding_expanded">5dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2b37268..c99d7ad 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -8948,8 +8948,6 @@
     <string name="disabled_by_policy_title_camera">Camera not allowed</string>
     <!-- Title for dialog displayed to tell user that screenshots are disabled by an admin [CHAR LIMIT=50] -->
     <string name="disabled_by_policy_title_screen_capture">Screenshot not allowed</string>
-    <!-- Title for dialog displayed to tell user that turning off backups is disallowed by an admin [CHAR LIMIT=50] -->
-    <string name="disabled_by_policy_title_turn_off_backups">Can’t turn off backups</string>
     <!-- Title for dialog displayed to tell user that the app was suspended by an admin [CHAR LIMIT=50] -->
     <string name="disabled_by_policy_title_suspend_packages">Can’t open this app</string>
     <!-- Shown when the user tries to change a settings locked by an admin [CHAR LIMIT=200] -->
@@ -9749,8 +9747,6 @@
         <item quantity="one"><xliff:g id="count">%d</xliff:g> attempt</item>
         <item quantity="other"><xliff:g id="count">%d</xliff:g> attempts</item>
     </plurals>
-    <!-- List item in a work device's settings. This text lets the user know that their IT administrator requires their device's data to be backed up. The user can't change this setting. [CHAR LIMIT=NONE] -->
-    <string name="enterprise_privacy_backups_enabled">This device\'s data is being backed up</string>
     <!-- Message indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=NONE] -->
     <string name="do_disclosure_generic">This device is managed by your organization.</string>
     <!-- Message indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=NONE] -->
diff --git a/res/xml/enterprise_privacy_settings.xml b/res/xml/enterprise_privacy_settings.xml
index 0aa1415..4fa50e7 100644
--- a/res/xml/enterprise_privacy_settings.xml
+++ b/res/xml/enterprise_privacy_settings.xml
@@ -83,9 +83,6 @@
         <Preference android:key="ca_certs_managed_profile"
                     android:title="@string/enterprise_privacy_ca_certs_work"
                     android:selectable="false"/>
-        <Preference android:key="backups_enabled"
-                    android:title="@string/enterprise_privacy_backups_enabled"
-                    android:selectable="false"/>
     </PreferenceCategory>
 
     <PreferenceCategory android:key="device_access_category"
diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java
index 4197e2f..87a3511 100644
--- a/src/com/android/settings/SettingsPreferenceFragment.java
+++ b/src/com/android/settings/SettingsPreferenceFragment.java
@@ -541,10 +541,6 @@
         private DialogInterface.OnCancelListener mOnCancelListener;
         private DialogInterface.OnDismissListener mOnDismissListener;
 
-        public SettingsDialogFragment() {
-            /* do nothing */
-        }
-
         public SettingsDialogFragment(DialogCreatable fragment, int dialogId) {
             super(fragment, dialogId);
             if (!(fragment instanceof Fragment)) {
diff --git a/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceController.java b/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceController.java
index ec6ea8c..9e76ff5 100644
--- a/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceController.java
+++ b/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceController.java
@@ -111,7 +111,7 @@
         final List<ResolveInfo> candidates = new ArrayList<>();
         // Resolve that intent and check that the handleAllWebDataURI boolean is set
         final List<ResolveInfo> list = packageManager.queryIntentActivitiesAsUser(
-            BROWSE_PROBE, PackageManager.MATCH_ALL, userId);
+            BROWSE_PROBE, 0 /* flags */, userId);
         if (list != null) {
             final Set<String> addedPackages = new ArraySet<>();
             for (ResolveInfo info : list) {
@@ -181,13 +181,12 @@
      * Whether or not the pkg is the default browser
      */
     public boolean isBrowserDefault(String pkg, int userId) {
-        String defaultPackage = mPackageManager.getDefaultBrowserPackageNameAsUser(userId);
+        final String defaultPackage = mPackageManager.getDefaultBrowserPackageNameAsUser(userId);
         if (defaultPackage != null) {
             return defaultPackage.equals(pkg);
         }
 
-        final List<ResolveInfo> list = mPackageManager.queryIntentActivitiesAsUser(BROWSE_PROBE,
-                PackageManager.MATCH_ALL, userId);
+        final List<ResolveInfo> list = getCandidates(mPackageManager, userId);
         // There is only 1 app, it must be the default browser.
         return list != null && list.size() == 1;
     }
diff --git a/src/com/android/settings/connecteddevice/usb/UsbDetailsFragment.java b/src/com/android/settings/connecteddevice/usb/UsbDetailsFragment.java
index 4b717e0..936a4c0 100644
--- a/src/com/android/settings/connecteddevice/usb/UsbDetailsFragment.java
+++ b/src/com/android/settings/connecteddevice/usb/UsbDetailsFragment.java
@@ -17,7 +17,6 @@
 package com.android.settings.connecteddevice.usb;
 
 import android.content.Context;
-import android.os.Bundle;
 import android.provider.SearchIndexableResource;
 
 import androidx.annotation.VisibleForTesting;
@@ -71,15 +70,6 @@
     }
 
     @Override
-    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
-        super.onCreatePreferences(savedInstanceState, rootKey);
-    }
-
-    public boolean isConnected() {
-        return mUsbReceiver.isConnected();
-    }
-
-    @Override
     protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
         mUsbBackend = new UsbBackend(context);
         mControllers = createControllerList(context, mUsbBackend, this);
diff --git a/src/com/android/settings/core/FeatureFlags.java b/src/com/android/settings/core/FeatureFlags.java
index 08b4e82..1062811 100644
--- a/src/com/android/settings/core/FeatureFlags.java
+++ b/src/com/android/settings/core/FeatureFlags.java
@@ -20,7 +20,6 @@
  * This class keeps track of all feature flags in Settings.
  */
 public class FeatureFlags {
-    public static final String BATTERY_DISPLAY_APP_LIST = "settings_battery_display_app_list";
     public static final String BLUETOOTH_WHILE_DRIVING = "settings_bluetooth_while_driving";
     public static final String AUDIO_SWITCHER_SETTINGS = "settings_audio_switcher";
     public static final String DYNAMIC_HOMEPAGE = "settings_dynamic_homepage";
diff --git a/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java b/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java
index 41703fb..ac1939c 100644
--- a/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java
+++ b/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java
@@ -137,9 +137,6 @@
             case DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE:
                 titleView.setText(R.string.disabled_by_policy_title_screen_capture);
                 break;
-            case DevicePolicyManager.POLICY_MANDATORY_BACKUPS:
-                titleView.setText(R.string.disabled_by_policy_title_turn_off_backups);
-                break;
             case DevicePolicyManager.POLICY_SUSPEND_PACKAGES:
                 titleView.setText(R.string.disabled_by_policy_title_suspend_packages);
                 break;
diff --git a/src/com/android/settings/enterprise/BackupsEnabledPreferenceController.java b/src/com/android/settings/enterprise/BackupsEnabledPreferenceController.java
deleted file mode 100644
index b24f8dc..0000000
--- a/src/com/android/settings/enterprise/BackupsEnabledPreferenceController.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.android.settings.enterprise;
-
-import android.content.Context;
-
-import com.android.settings.core.BasePreferenceController;
-import com.android.settings.overlay.FeatureFactory;
-
-public class BackupsEnabledPreferenceController extends BasePreferenceController {
-
-    private static final String KEY_BACKUPS_ENABLED = "backups_enabled";
-    private final EnterprisePrivacyFeatureProvider mFeatureProvider;
-
-    public BackupsEnabledPreferenceController(Context context) {
-        super(context, KEY_BACKUPS_ENABLED);
-        mFeatureProvider = FeatureFactory.getFactory(context)
-                .getEnterprisePrivacyFeatureProvider(context);
-    }
-
-    @Override
-    public int getAvailabilityStatus() {
-        return mFeatureProvider.areBackupsMandatory() ? AVAILABLE : DISABLED_FOR_USER;
-    }
-}
-
diff --git a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java
index 51d125d..048782e 100644
--- a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java
+++ b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProvider.java
@@ -124,9 +124,4 @@
      * profile (if any).
      */
     int getNumberOfActiveDeviceAdminsForCurrentUserAndManagedProfile();
-
-    /*
-     * Returns whether backups are mandatory.
-     */
-    boolean areBackupsMandatory();
 }
diff --git a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java
index 5505683..4085988 100644
--- a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java
+++ b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java
@@ -234,11 +234,6 @@
         return activeAdmins;
     }
 
-    @Override
-    public boolean areBackupsMandatory() {
-        return null != mDpm.getMandatoryBackupTransport();
-    }
-
     protected static class EnterprisePrivacySpan extends ClickableSpan {
         private final Context mContext;
 
diff --git a/src/com/android/settings/enterprise/EnterprisePrivacySettings.java b/src/com/android/settings/enterprise/EnterprisePrivacySettings.java
index f04c421..dab1395 100644
--- a/src/com/android/settings/enterprise/EnterprisePrivacySettings.java
+++ b/src/com/android/settings/enterprise/EnterprisePrivacySettings.java
@@ -84,7 +84,6 @@
         exposureChangesCategoryControllers.add(new CaCertsCurrentUserPreferenceController(context));
         exposureChangesCategoryControllers.add(new CaCertsManagedProfilePreferenceController(
                 context));
-        exposureChangesCategoryControllers.add(new BackupsEnabledPreferenceController(context));
         controllers.addAll(exposureChangesCategoryControllers);
         controllers.add(new PreferenceCategoryController(context, "exposure_changes_category")
                 .setChildren(exposureChangesCategoryControllers));
diff --git a/src/com/android/settings/homepage/CardContentLoader.java b/src/com/android/settings/homepage/CardContentLoader.java
index 47ba59a..9805ae3 100644
--- a/src/com/android/settings/homepage/CardContentLoader.java
+++ b/src/com/android/settings/homepage/CardContentLoader.java
@@ -17,46 +17,52 @@
 package com.android.settings.homepage;
 
 import android.content.Context;
+import android.database.Cursor;
 
-import androidx.annotation.Nullable;
+import androidx.annotation.NonNull;
 
 import com.android.settingslib.utils.AsyncLoaderCompat;
 
+import java.util.ArrayList;
 import java.util.List;
 
-//TODO(b/112521307): Implement this to make it work with the card database.
-public class CardContentLoader {
+public class CardContentLoader extends AsyncLoaderCompat<List<ContextualCard>> {
+    static final int CARD_CONTENT_LOADER_ID = 1;
 
-    private static final String TAG = "CardContentLoader";
-
-    private CardContentLoaderListener mListener;
+    private Context mContext;
 
     public interface CardContentLoaderListener {
         void onFinishCardLoading(List<ContextualCard> contextualCards);
     }
 
-    public CardContentLoader() {
+    CardContentLoader(Context context) {
+        super(context);
+        mContext = context.getApplicationContext();
     }
 
-    void setListener(CardContentLoaderListener listener) {
-        mListener = listener;
+    @Override
+    protected void onDiscardResult(List<ContextualCard> result) {
+
     }
 
-    private static class CardLoader extends AsyncLoaderCompat<List<ContextualCard>> {
-
-        public CardLoader(Context context) {
-            super(context);
+    @NonNull
+    @Override
+    public List<ContextualCard> loadInBackground() {
+        final List<ContextualCard> result = new ArrayList<>();
+        try (Cursor cursor = CardDatabaseHelper.getInstance(mContext).getContextualCards()) {
+            if (cursor.getCount() == 0) {
+                //TODO(b/113372471): Load Default static cards and return 3 static cards
+                return result;
+            }
+            for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
+                final ContextualCard card = new ContextualCard(cursor);
+                if (card.isCustomCard()) {
+                    //TODO(b/114688391): Load and generate custom card,then add into list
+                } else {
+                    result.add(card);
+                }
+            }
         }
-
-        @Override
-        protected void onDiscardResult(List<ContextualCard> result) {
-
-        }
-
-        @Nullable
-        @Override
-        public List<ContextualCard> loadInBackground() {
-            return null;
-        }
+        return result;
     }
 }
diff --git a/src/com/android/settings/homepage/CardDatabaseHelper.java b/src/com/android/settings/homepage/CardDatabaseHelper.java
index 382b71f..b53479e 100644
--- a/src/com/android/settings/homepage/CardDatabaseHelper.java
+++ b/src/com/android/settings/homepage/CardDatabaseHelper.java
@@ -17,6 +17,7 @@
 package com.android.settings.homepage;
 
 import android.content.Context;
+import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteOpenHelper;
 import android.util.Log;
@@ -190,4 +191,12 @@
         }
         return sCardDatabaseHelper;
     }
+
+    Cursor getContextualCards() {
+        final SQLiteDatabase db = this.getReadableDatabase();
+        Cursor cursor = db.query(CARD_TABLE, null /* columns */, null /* selection */,
+                null /* selectionArgs */, null /* groupBy */, null /* having */,
+                null /* orderBy */);
+        return cursor;
+    }
 }
diff --git a/src/com/android/settings/homepage/ContextualCard.java b/src/com/android/settings/homepage/ContextualCard.java
index f5083d8..5bd265b 100644
--- a/src/com/android/settings/homepage/ContextualCard.java
+++ b/src/com/android/settings/homepage/ContextualCard.java
@@ -17,6 +17,7 @@
 package com.android.settings.homepage;
 
 import android.annotation.IntDef;
+import android.database.Cursor;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.text.TextUtils;
@@ -32,10 +33,10 @@
     /**
      * Flags indicating the type of the ContextualCard.
      */
-    @IntDef({CardType.INVALID, CardType.SLICE, CardType.SUGGESTION, CardType.CONDITIONAL})
+    @IntDef({CardType.DEFAULT, CardType.SLICE, CardType.SUGGESTION, CardType.CONDITIONAL})
     @Retention(RetentionPolicy.SOURCE)
     public @interface CardType {
-        int INVALID = -1;
+        int DEFAULT = 0;
         int SLICE = 1;
         int SUGGESTION = 2;
         int CONDITIONAL = 3;
@@ -58,8 +59,8 @@
     private final int mIconResId;
     private final int mCardAction;
     private final long mExpireTimeMS;
-    private final Drawable mIconDrawable;
     private final boolean mIsHalfWidth;
+    private final Drawable mIconDrawable;
 
     String getName() {
         return mName;
@@ -137,6 +138,10 @@
         return mIsHalfWidth;
     }
 
+    boolean isCustomCard() {
+        return TextUtils.isEmpty(mSliceUri);
+    }
+
     public ContextualCard(Builder builder) {
         mName = builder.mName;
         mCardType = builder.mCardType;
@@ -158,6 +163,31 @@
         mIsHalfWidth = builder.mIsHalfWidth;
     }
 
+    ContextualCard(Cursor c) {
+        mName = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.NAME));
+        mCardType = c.getInt(c.getColumnIndex(CardDatabaseHelper.CardColumns.TYPE));
+        mRankingScore = c.getDouble(c.getColumnIndex(CardDatabaseHelper.CardColumns.SCORE));
+        mSliceUri = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.SLICE_URI));
+        mCategory = c.getInt(c.getColumnIndex(CardDatabaseHelper.CardColumns.CATEGORY));
+        mLocalizedToLocale = c.getString(
+                c.getColumnIndex(CardDatabaseHelper.CardColumns.LOCALIZED_TO_LOCALE));
+        mPackageName = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.PACKAGE_NAME));
+        mAppVersion = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.APP_VERSION));
+        mTitleResName = c.getString(
+                c.getColumnIndex(CardDatabaseHelper.CardColumns.TITLE_RES_NAME));
+        mTitleText = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.TITLE_TEXT));
+        mSummaryResName = c.getString(
+                c.getColumnIndex(CardDatabaseHelper.CardColumns.SUMMARY_RES_NAME));
+        mSummaryText = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.SUMMARY_TEXT));
+        mIconResName = c.getString(c.getColumnIndex(CardDatabaseHelper.CardColumns.ICON_RES_NAME));
+        mIconResId = c.getInt(c.getColumnIndex(CardDatabaseHelper.CardColumns.ICON_RES_ID));
+        mCardAction = c.getInt(c.getColumnIndex(CardDatabaseHelper.CardColumns.CARD_ACTION));
+        mExpireTimeMS = c.getLong(c.getColumnIndex(CardDatabaseHelper.CardColumns.EXPIRE_TIME_MS));
+        mIsHalfWidth = (c.getInt(
+                c.getColumnIndex(CardDatabaseHelper.CardColumns.SUPPORT_HALF_WIDTH)) == 1);
+        mIconDrawable = null;
+    }
+
     @Override
     public int hashCode() {
         return mName.hashCode();
diff --git a/src/com/android/settings/homepage/ContextualCardController.java b/src/com/android/settings/homepage/ContextualCardController.java
index 921d72b..e47f70c 100644
--- a/src/com/android/settings/homepage/ContextualCardController.java
+++ b/src/com/android/settings/homepage/ContextualCardController.java
@@ -16,8 +16,6 @@
 
 package com.android.settings.homepage;
 
-import java.util.List;
-
 /**
  * Data controller for {@link ContextualCard}.
  */
@@ -26,12 +24,6 @@
     @ContextualCard.CardType
     int getCardType();
 
-    /**
-     * When data is updated or changed, the new data should be passed to ContextualCardManager for list
-     * updating.
-     */
-    void onDataUpdated(List<ContextualCard> cardList);
-
     void onPrimaryClick(ContextualCard card);
 
     void onActionClick(ContextualCard card);
diff --git a/src/com/android/settings/homepage/ContextualCardManager.java b/src/com/android/settings/homepage/ContextualCardManager.java
index aa2f576..87b048e 100644
--- a/src/com/android/settings/homepage/ContextualCardManager.java
+++ b/src/com/android/settings/homepage/ContextualCardManager.java
@@ -16,14 +16,29 @@
 
 package com.android.settings.homepage;
 
+import static com.android.settings.homepage.CardContentLoader.CARD_CONTENT_LOADER_ID;
+
+import static java.util.stream.Collectors.groupingBy;
+
 import android.content.Context;
+import android.os.Bundle;
+import android.util.ArrayMap;
+import android.util.Log;
 import android.widget.BaseAdapter;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.loader.app.LoaderManager;
+import androidx.loader.content.Loader;
+
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * This is a centralized manager of multiple {@link ContextualCardController}.
@@ -49,88 +64,89 @@
     private final ControllerRendererPool mControllerRendererPool;
     private final Lifecycle mLifecycle;
     private final List<ContextualCard> mContextualCards;
+    private final List<LifecycleObserver> mLifecycleObservers;
 
     private ContextualCardUpdateListener mListener;
 
-
-    public ContextualCardManager(Context context, Lifecycle lifecycle) {
+    public ContextualCardManager(Context context, @NonNull Lifecycle lifecycle) {
         mContext = context;
         mLifecycle = lifecycle;
         mContextualCards = new ArrayList<>();
+        mLifecycleObservers = new ArrayList<>();
         mControllerRendererPool = new ControllerRendererPool();
-    }
-
-    void startCardContentLoading() {
-        final CardContentLoader cardContentLoader = new CardContentLoader();
-        cardContentLoader.setListener(this);
-    }
-
-    private void loadCardControllers() {
-        if (mContextualCards != null) {
-            for (ContextualCard card : mContextualCards) {
-                setupController(card.getCardType());
-            }
-        }
-
         //for data provided by Settings
         for (int cardType : SETTINGS_CARDS) {
             setupController(cardType);
         }
     }
 
+    void loadContextualCards(PersonalSettingsFragment fragment) {
+        final CardContentLoaderCallbacks cardContentLoaderCallbacks =
+                new CardContentLoaderCallbacks(mContext);
+        cardContentLoaderCallbacks.setListener(this);
+        LoaderManager.getInstance(fragment).initLoader(CARD_CONTENT_LOADER_ID, null /* bundle */,
+                cardContentLoaderCallbacks);
+    }
+
+    private void loadCardControllers() {
+        for (ContextualCard card : mContextualCards) {
+            setupController(card.getCardType());
+        }
+    }
+
     private void setupController(int cardType) {
         final ContextualCardController controller = mControllerRendererPool.getController(mContext,
                 cardType);
-        if (controller != null) {
-            controller.setCardUpdateListener(this);
-            if (controller instanceof LifecycleObserver) {
-                if (mLifecycle != null) {
-                    mLifecycle.addObserver((LifecycleObserver) controller);
-                }
-            }
+        if (controller == null) {
+            Log.w(TAG, "Cannot find ContextualCardController for type " + cardType);
+            return;
+        }
+        controller.setCardUpdateListener(this);
+        if (controller instanceof LifecycleObserver && !mLifecycleObservers.contains(controller)) {
+            mLifecycleObservers.add((LifecycleObserver) controller);
+            mLifecycle.addObserver((LifecycleObserver) controller);
         }
     }
 
     //TODO(b/111822376): implement sorting mechanism.
-    private void sortCards() {
+    private void sortCards(List<ContextualCard> cards) {
         //take mContextualCards as the source and do the ranking based on the rule.
     }
 
     @Override
-    public void onContextualCardUpdated(int cardType, List<ContextualCard> updateList) {
+    public void onContextualCardUpdated(Map<Integer, List<ContextualCard>> updateList) {
         //TODO(b/112245748): Should implement a DiffCallback.
         //Keep the old list for comparison.
         final List<ContextualCard> prevCards = mContextualCards;
 
-        //Remove the existing data that matches the certain cardType so as to insert the new data.
-        for (int i = mContextualCards.size() - 1; i >= 0; i--) {
-            if (mContextualCards.get(i).getCardType() == cardType) {
-                mContextualCards.remove(i);
-            }
-        }
+        final Set<Integer> cardTypes = updateList.keySet();
+        //Remove the existing data that matches the certain cardType before inserting new data.
+        final List<ContextualCard> cardsToKeep = mContextualCards
+                .stream()
+                .filter(card -> !cardTypes.contains(card.getCardType()))
+                .collect(Collectors.toList());
+        final List<ContextualCard> allCards = new ArrayList<>();
+        allCards.addAll(cardsToKeep);
+        allCards.addAll(
+                updateList.values().stream().flatMap(List::stream).collect(Collectors.toList()));
 
-        //Append the new data
-        mContextualCards.addAll(updateList);
+        sortCards(allCards);
+        //replace with the new data
+        mContextualCards.clear();
+        mContextualCards.addAll(allCards);
 
-        sortCards();
+        loadCardControllers();
 
         if (mListener != null) {
-            mListener.onContextualCardUpdated(ContextualCard.CardType.INVALID, mContextualCards);
+            final Map<Integer, List<ContextualCard>> cardsToUpdate = new ArrayMap<>();
+            cardsToUpdate.put(ContextualCard.CardType.DEFAULT, mContextualCards);
+            mListener.onContextualCardUpdated(cardsToUpdate);
         }
     }
 
     @Override
-    public void onFinishCardLoading(List<ContextualCard> contextualCards) {
-        mContextualCards.clear();
-        if (contextualCards != null) {
-            mContextualCards.addAll(contextualCards);
-        }
-
-        //Force card sorting here in case CardControllers of custom view have nothing to update
-        // for the first launch.
-        sortCards();
-
-        loadCardControllers();
+    public void onFinishCardLoading(List<ContextualCard> cards) {
+        onContextualCardUpdated(cards.stream().collect(groupingBy(ContextualCard::getCardType)));
     }
 
     void setListener(ContextualCardUpdateListener listener) {
@@ -140,4 +156,42 @@
     public ControllerRendererPool getControllerRendererPool() {
         return mControllerRendererPool;
     }
+
+    static class CardContentLoaderCallbacks implements
+            LoaderManager.LoaderCallbacks<List<ContextualCard>> {
+
+        private Context mContext;
+        private CardContentLoader.CardContentLoaderListener mListener;
+
+        CardContentLoaderCallbacks(Context context) {
+            mContext = context.getApplicationContext();
+        }
+
+        protected void setListener(CardContentLoader.CardContentLoaderListener listener) {
+            mListener = listener;
+        }
+
+        @NonNull
+        @Override
+        public Loader<List<ContextualCard>> onCreateLoader(int id, @Nullable Bundle bundle) {
+            if (id == CARD_CONTENT_LOADER_ID) {
+                return new CardContentLoader(mContext);
+            } else {
+                throw new IllegalArgumentException("Unknown loader id: " + id);
+            }
+        }
+
+        @Override
+        public void onLoadFinished(@NonNull Loader<List<ContextualCard>> loader,
+                List<ContextualCard> contextualCards) {
+            if (mListener != null) {
+                mListener.onFinishCardLoading(contextualCards);
+            }
+        }
+
+        @Override
+        public void onLoaderReset(@NonNull Loader<List<ContextualCard>> loader) {
+
+        }
+    }
 }
diff --git a/src/com/android/settings/homepage/ContextualCardRenderer.java b/src/com/android/settings/homepage/ContextualCardRenderer.java
index 94fdb43..315c09d 100644
--- a/src/com/android/settings/homepage/ContextualCardRenderer.java
+++ b/src/com/android/settings/homepage/ContextualCardRenderer.java
@@ -31,15 +31,15 @@
     int getViewType();
 
     /**
-     * When {@link ContextualCardsAdapter} calls {@link ContextualCardsAdapter#onCreateViewHolder(ViewGroup,
-     * int)}, this method will be called to retrieve the corresponding
+     * When {@link ContextualCardsAdapter} calls {@link ContextualCardsAdapter#onCreateViewHolder},
+     * this method will be called to retrieve the corresponding
      * {@link androidx.recyclerview.widget.RecyclerView.ViewHolder}.
      */
     RecyclerView.ViewHolder createViewHolder(View view);
 
     /**
-     * When {@link ContextualCardsAdapter} calls {@link ContextualCardsAdapter#onBindViewHolder(RecyclerView
-     * .ViewHolder, int)}, this method will be called to bind data to the
+     * When {@link ContextualCardsAdapter} calls {@link ContextualCardsAdapter#onBindViewHolder},
+     * this method will be called to bind data to the
      * {@link androidx.recyclerview.widget.RecyclerView.ViewHolder}.
      */
     void bindView(RecyclerView.ViewHolder holder, ContextualCard card);
diff --git a/src/com/android/settings/homepage/ContextualCardUpdateListener.java b/src/com/android/settings/homepage/ContextualCardUpdateListener.java
index d307a8f..60dd3a7 100644
--- a/src/com/android/settings/homepage/ContextualCardUpdateListener.java
+++ b/src/com/android/settings/homepage/ContextualCardUpdateListener.java
@@ -17,15 +17,19 @@
 package com.android.settings.homepage;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * When {@link ContextualCardController} detects changes, it will notify the listeners registered.
- * In our case, {@link ContextualCardManager} gets noticed.
- *
- * After the list of {@link ContextualCard} gets updated in{@link ContextualCardManager},
- * {@link ContextualCardManager} will notify the listeners registered, {@link
- * ContextualCardsAdapter} in this case.
  */
 public interface ContextualCardUpdateListener {
-    void onContextualCardUpdated(int cardType, List<ContextualCard> updateList);
+
+    /**
+     * Called when a set of cards are updated.
+     *
+     * @param cards A map of updates grouped by {@link ContextualCard.CardType}. Values can be
+     *              null, which means all cards from corresponding {@link
+     *              ContextualCard.CardType} are removed.
+     */
+    void onContextualCardUpdated(Map<Integer, List<ContextualCard>> cards);
 }
\ No newline at end of file
diff --git a/src/com/android/settings/homepage/ContextualCardsAdapter.java b/src/com/android/settings/homepage/ContextualCardsAdapter.java
index e985343..9ab8893 100644
--- a/src/com/android/settings/homepage/ContextualCardsAdapter.java
+++ b/src/com/android/settings/homepage/ContextualCardsAdapter.java
@@ -26,9 +26,10 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
-public class ContextualCardsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements
-        ContextualCardUpdateListener {
+public class ContextualCardsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
+        implements ContextualCardUpdateListener {
     static final int SPAN_COUNT = 2;
 
     private static final String TAG = "ContextualCardsAdapter";
@@ -101,7 +102,8 @@
     }
 
     @Override
-    public void onContextualCardUpdated(int cardType, List<ContextualCard> contextualCards) {
+    public void onContextualCardUpdated(Map<Integer, List<ContextualCard>> cards) {
+        final List<ContextualCard> contextualCards = cards.get(ContextualCard.CardType.DEFAULT);
         //TODO(b/112245748): Should implement a DiffCallback so we can use notifyItemChanged()
         // instead.
         if (contextualCards == null) {
diff --git a/src/com/android/settings/homepage/PersonalSettingsFragment.java b/src/com/android/settings/homepage/PersonalSettingsFragment.java
index 2eb9663..4a0041e 100644
--- a/src/com/android/settings/homepage/PersonalSettingsFragment.java
+++ b/src/com/android/settings/homepage/PersonalSettingsFragment.java
@@ -43,7 +43,7 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         mContextualCardManager = new ContextualCardManager(getContext(), getSettingsLifecycle());
-        mContextualCardManager.startCardContentLoading();
+        mContextualCardManager.loadContextualCards(this);
     }
 
     @Override
diff --git a/src/com/android/settings/homepage/conditional/ConditionContextualCardController.java b/src/com/android/settings/homepage/conditional/ConditionContextualCardController.java
index 6701cfd..fbbab14 100644
--- a/src/com/android/settings/homepage/conditional/ConditionContextualCardController.java
+++ b/src/com/android/settings/homepage/conditional/ConditionContextualCardController.java
@@ -17,6 +17,7 @@
 package com.android.settings.homepage.conditional;
 
 import android.content.Context;
+import android.util.ArrayMap;
 
 import com.android.settings.homepage.ContextualCard;
 import com.android.settings.homepage.ContextualCardController;
@@ -27,6 +28,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 /**
  * This controller triggers the loading of conditional cards and monitors state changes to
@@ -57,11 +59,6 @@
     }
 
     @Override
-    public void onDataUpdated(List<ContextualCard> cardList) {
-        mListener.onContextualCardUpdated(getCardType(), cardList);
-    }
-
-    @Override
     public void onStart() {
         mConditionManager.startMonitoringStateChange();
     }
@@ -96,7 +93,6 @@
                             .setActionText(condition.getActionText())
                             .setName(mContext.getPackageName() + "/"
                                     + condition.getTitle().toString())
-                            .setCardType(ContextualCard.CardType.CONDITIONAL)
                             .setTitleText(condition.getTitle().toString())
                             .setSummaryText(condition.getSummary().toString())
                             .setIconDrawable(condition.getIcon())
@@ -106,7 +102,9 @@
         }
 
         if (mListener != null) {
-            onDataUpdated(conditionCards);
+            final Map<Integer, List<ContextualCard>> conditionalCards = new ArrayMap<>();
+            conditionalCards.put(ContextualCard.CardType.CONDITIONAL, conditionCards);
+            mListener.onContextualCardUpdated(conditionalCards);
         }
     }
 }
diff --git a/src/com/android/settings/homepage/conditional/ConditionalContextualCard.java b/src/com/android/settings/homepage/conditional/ConditionalContextualCard.java
index 62a4956..828f90b 100644
--- a/src/com/android/settings/homepage/conditional/ConditionalContextualCard.java
+++ b/src/com/android/settings/homepage/conditional/ConditionalContextualCard.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.homepage.conditional;
 
+import androidx.annotation.VisibleForTesting;
+
 import com.android.settings.homepage.ContextualCard;
 
 /**
@@ -38,6 +40,11 @@
         mActionText = builder.mActionText;
     }
 
+    @Override
+    public int getCardType() {
+        return CardType.CONDITIONAL;
+    }
+
     public long getConditionId() {
         return mConditionId;
     }
@@ -50,7 +57,7 @@
         return mActionText;
     }
 
-    static class Builder extends ContextualCard.Builder {
+    public static class Builder extends ContextualCard.Builder {
 
         private long mConditionId;
         private int mMetricsConstant;
@@ -71,6 +78,12 @@
             return this;
         }
 
+        @Override
+        public Builder setCardType(int cardType) {
+            throw new IllegalArgumentException(
+                    "Cannot change card type for " + getClass().getName());
+        }
+
         public ConditionalContextualCard build() {
             return new ConditionalContextualCard(this);
         }
diff --git a/src/com/android/settings/network/NetworkDashboardFragment.java b/src/com/android/settings/network/NetworkDashboardFragment.java
index a2a2450..0279cfa 100644
--- a/src/com/android/settings/network/NetworkDashboardFragment.java
+++ b/src/com/android/settings/network/NetworkDashboardFragment.java
@@ -15,12 +15,15 @@
  */
 package com.android.settings.network;
 
+import static android.provider.Settings.ACTION_DATA_USAGE_SETTINGS;
 import static com.android.settings.network.MobilePlanPreferenceController
         .MANAGE_MOBILE_PLAN_DIALOG_ID;
 
 import android.app.Activity;
 import android.app.Dialog;
 import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.icu.text.ListFormatter;
 import android.provider.SearchIndexableResource;
 import android.text.BidiFormatter;
@@ -45,6 +48,7 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.function.BooleanSupplier;
 import java.util.List;
 
 @SearchIndexable
@@ -158,24 +162,32 @@
         private final WifiMasterSwitchPreferenceController mWifiPreferenceController;
         private final MobileNetworkPreferenceController mMobileNetworkPreferenceController;
         private final TetherPreferenceController mTetherPreferenceController;
+        private final BooleanSupplier mHasDataUsageActivity;
 
         public SummaryProvider(Context context, SummaryLoader summaryLoader) {
             this(context, summaryLoader,
                     new WifiMasterSwitchPreferenceController(context, null),
                     new MobileNetworkPreferenceController(context),
-                    new TetherPreferenceController(context, null /* lifecycle */));
+                    new TetherPreferenceController(context, null /* lifecycle */),
+                    () -> {
+                        final Intent intent = new Intent(ACTION_DATA_USAGE_SETTINGS);
+                        final PackageManager pm = context.getPackageManager();
+                        return intent.resolveActivity(pm) != null;
+                    });
         }
 
         @VisibleForTesting(otherwise = VisibleForTesting.NONE)
         SummaryProvider(Context context, SummaryLoader summaryLoader,
                 WifiMasterSwitchPreferenceController wifiPreferenceController,
                 MobileNetworkPreferenceController mobileNetworkPreferenceController,
-                TetherPreferenceController tetherPreferenceController) {
+                TetherPreferenceController tetherPreferenceController,
+                BooleanSupplier hasDataUsageActivity) {
             mContext = context;
             mSummaryLoader = summaryLoader;
             mWifiPreferenceController = wifiPreferenceController;
             mMobileNetworkPreferenceController = mobileNetworkPreferenceController;
             mTetherPreferenceController = tetherPreferenceController;
+            mHasDataUsageActivity = hasDataUsageActivity;
         }
 
 
@@ -198,7 +210,7 @@
                 if (mMobileNetworkPreferenceController.isAvailable() && !TextUtils.isEmpty(mobileSummary)) {
                     summaries.add(mobileSummary);
                 }
-                if (!TextUtils.isEmpty(dataUsageSummary)) {
+                if (!TextUtils.isEmpty(dataUsageSummary) && mHasDataUsageActivity.getAsBoolean()) {
                     summaries.add(dataUsageSummary);
                 }
                 if (mTetherPreferenceController.isAvailable() && !TextUtils.isEmpty(hotspotSummary)) {
diff --git a/src/com/android/settings/notification/NotificationBackend.java b/src/com/android/settings/notification/NotificationBackend.java
index 01f1228..03b4ec3 100644
--- a/src/com/android/settings/notification/NotificationBackend.java
+++ b/src/com/android/settings/notification/NotificationBackend.java
@@ -78,6 +78,12 @@
         return row;
     }
 
+    public boolean isBlockable(Context context, ApplicationInfo info) {
+        final boolean blocked = getNotificationsBanned(info.packageName, info.uid);
+        final boolean systemApp = isSystemApp(context, info);
+        return !systemApp || (systemApp && blocked);
+    }
+
     public AppRow loadAppRow(Context context, PackageManager pm, PackageInfo app) {
         final AppRow row = loadAppRow(context, pm, app.applicationInfo);
         recordCanBeBlocked(context, pm, app, row);
diff --git a/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java b/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java
index a027aec..bbc01f5 100644
--- a/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java
+++ b/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java
@@ -82,17 +82,6 @@
     private Preference mSeeAllPref;
     private Preference mDivider;
 
-    static {
-        SKIP_SYSTEM_PACKAGES.addAll(Arrays.asList(
-                "android",
-                "com.android.phone",
-                "com.android.settings",
-                "com.android.systemui",
-                "com.android.providers.calendar",
-                "com.android.providers.media"
-        ));
-    }
-
     public RecentNotifyingAppsPreferenceController(Context context, NotificationBackend backend,
             Application app, Fragment host) {
         this(context, backend, app == null ? null : ApplicationsState.getInstance(app), host);
@@ -226,6 +215,7 @@
                     .setSourceMetricsCategory(
                             MetricsProto.MetricsEvent.MANAGE_APPLICATIONS_NOTIFICATIONS)
                     .toIntent());
+            pref.setEnabled(mNotificationBackend.isBlockable(mContext, appEntry.info));
             pref.setOnPreferenceChangeListener((preference, newValue) -> {
                 boolean blocked = !(Boolean) newValue;
                 mNotificationBackend.setNotificationsEnabledForPackage(
@@ -272,10 +262,6 @@
      * Whether or not the app should be included in recent list.
      */
     private boolean shouldIncludePkgInRecents(String pkgName) {
-         if (SKIP_SYSTEM_PACKAGES.contains(pkgName)) {
-            Log.d(TAG, "System package, skipping " + pkgName);
-            return false;
-        }
         final Intent launchIntent = new Intent().addCategory(Intent.CATEGORY_LAUNCHER)
                 .setPackage(pkgName);
 
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index 5e961a6..6e3174d 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -964,9 +964,10 @@
                 mAddUserWhenLockedPreferenceController.getPreferenceKey());
         mAddUserWhenLockedPreferenceController.updateState(addUserOnLockScreen);
         mMultiUserFooterPreferenceController.updateState(null /* preference */);
+        mAddUser.setVisible(mUserCaps.mCanAddUser && Utils.isDeviceProvisioned(context)
+                && mUserCaps.mUserSwitcherEnabled);
         mUserListCategory.setVisible(mUserCaps.mUserSwitcherEnabled);
         if (!mUserCaps.mUserSwitcherEnabled) {
-            mAddUser.setVisible(false);
             return;
         }
 
diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java
index de67c10..2e6611f 100644
--- a/src/com/android/settings/wifi/WifiConfigController.java
+++ b/src/com/android/settings/wifi/WifiConfigController.java
@@ -465,8 +465,7 @@
         } else {
             enabled = ipAndProxyFieldsAreValid();
         }
-        if (mEapCaCertSpinner != null
-                && mView.findViewById(R.id.l_ca_cert).getVisibility() != View.GONE) {
+        if (mAccessPointSecurity == AccessPoint.SECURITY_EAP) {
             String caCertSelection = (String) mEapCaCertSpinner.getSelectedItem();
             if (caCertSelection.equals(mUnspecifiedCertString)) {
                 // Disallow submit if the user has not selected a CA certificate for an EAP network
@@ -482,10 +481,8 @@
                 enabled = false;
             }
         }
-        if (mEapUserCertSpinner != null
-                && mView.findViewById(R.id.l_user_cert).getVisibility() != View.GONE
-                && ((String) mEapUserCertSpinner.getSelectedItem())
-                       .equals(mUnspecifiedCertString)) {
+        if (mAccessPointSecurity == AccessPoint.SECURITY_EAP
+                && mEapUserCertSpinner.getSelectedItem().equals(mUnspecifiedCertString)) {
             // Disallow submit if the user has not selected a user certificate for an EAP network
             // configuration.
             enabled = false;
diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceControllerTest.java
index 0ef1cf3..4a482d0 100644
--- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceControllerTest.java
@@ -18,9 +18,9 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
@@ -133,8 +133,11 @@
     @Test
     public void isBrowserDefault_onlyApp_shouldReturnTrue() {
         when(mPackageManager.getDefaultBrowserPackageNameAsUser(anyInt())).thenReturn(null);
+        final List<ResolveInfo> resolveInfos = new ArrayList<>();
+        final String PACKAGE_ONE = "pkg";
+        resolveInfos.add(createResolveInfo(PACKAGE_ONE));
         when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt()))
-                .thenReturn(Collections.singletonList(new ResolveInfo()));
+            .thenReturn(resolveInfos);
 
         assertThat(mController.isBrowserDefault("pkg", 0)).isTrue();
     }
@@ -161,6 +164,15 @@
         assertThat(defaultBrowserInfo.size()).isEqualTo(2);
     }
 
+    @Test
+    public void getCandidates_shouldQueryActivityWithFlagsEquals0() {
+
+        mController.getCandidates(mPackageManager, 0 /* userId */);
+
+        verify(mPackageManager).queryIntentActivitiesAsUser(
+            any(Intent.class), eq(0) /* flags */, eq(0) /* userId */);
+    }
+
     private ResolveInfo createResolveInfo(String packageName) {
         final ResolveInfo info = new ResolveInfo();
         info.handleAllWebDataURI = true;
diff --git a/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java b/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java
index 5321c10..9b138a6 100644
--- a/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java
@@ -124,10 +124,6 @@
         assertEquals(Shadows.shadowOf(textView).innerText(),
                 mActivity.getString(R.string.disabled_by_policy_title_screen_capture));
 
-        mHelper.setAdminSupportTitle(view, DevicePolicyManager.POLICY_MANDATORY_BACKUPS);
-        assertEquals(Shadows.shadowOf(textView).innerText(),
-                mActivity.getString(R.string.disabled_by_policy_title_turn_off_backups));
-
         mHelper.setAdminSupportTitle(view, DevicePolicyManager.POLICY_SUSPEND_PACKAGES);
         assertEquals(Shadows.shadowOf(textView).innerText(),
                 mActivity.getString(R.string.disabled_by_policy_title_suspend_packages));
diff --git a/tests/robotests/src/com/android/settings/enterprise/BackupsEnabledPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/enterprise/BackupsEnabledPreferenceControllerTest.java
deleted file mode 100644
index 4e6db05..0000000
--- a/tests/robotests/src/com/android/settings/enterprise/BackupsEnabledPreferenceControllerTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.enterprise;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-
-import androidx.preference.Preference;
-
-import com.android.settings.testutils.FakeFeatureFactory;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RuntimeEnvironment;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-public class BackupsEnabledPreferenceControllerTest {
-
-    private static final String KEY_BACKUPS_ENABLED = "backups_enabled";
-
-    private Context mContext;
-    private FakeFeatureFactory mFeatureFactory;
-
-    private BackupsEnabledPreferenceController mController;
-
-    @Before
-    public void setUp() {
-        mContext = RuntimeEnvironment.application;
-        mFeatureFactory = FakeFeatureFactory.setupForTest();
-        mController = new BackupsEnabledPreferenceController(mContext);
-    }
-
-    @Test
-    public void testIsAvailable() {
-        when(mFeatureFactory.enterprisePrivacyFeatureProvider.areBackupsMandatory())
-                .thenReturn(false);
-        assertThat(mController.isAvailable()).isFalse();
-
-        when(mFeatureFactory.enterprisePrivacyFeatureProvider.areBackupsMandatory())
-                .thenReturn(true);
-        assertThat(mController.isAvailable()).isTrue();
-    }
-
-    @Test
-    public void testHandlePreferenceTreeClick() {
-        assertThat(mController.handlePreferenceTreeClick(new Preference(mContext, null, 0, 0)))
-                .isFalse();
-    }
-
-    @Test
-    public void testGetPreferenceKey() {
-        assertThat(mController.getPreferenceKey()).isEqualTo(KEY_BACKUPS_ENABLED);
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java
index a7bd329..92c420a 100644
--- a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImplTest.java
@@ -346,15 +346,6 @@
                 .isEqualTo(3);
     }
 
-    @Test
-    public void testAreBackupsMandatory() {
-        assertThat(mProvider.areBackupsMandatory()).isFalse();
-        ComponentName transportComponent = new ComponentName("test", "test");
-        when(mDevicePolicyManager.getMandatoryBackupTransport())
-                .thenReturn(transportComponent);
-        assertThat(mProvider.areBackupsMandatory()).isTrue();
-    }
-
     private void resetAndInitializePackageManager() {
         reset(mPackageManager);
         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN))
diff --git a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacySettingsTest.java b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacySettingsTest.java
index d37738d..f1d03c7 100644
--- a/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacySettingsTest.java
+++ b/tests/robotests/src/com/android/settings/enterprise/EnterprisePrivacySettingsTest.java
@@ -99,7 +99,7 @@
 
     private void verifyPreferenceControllers(List<AbstractPreferenceController> controllers) {
         assertThat(controllers).isNotNull();
-        assertThat(controllers.size()).isEqualTo(18);
+        assertThat(controllers.size()).isEqualTo(17);
         int position = 0;
         assertThat(controllers.get(position++)).isInstanceOf(NetworkLogsPreferenceController.class);
         assertThat(controllers.get(position++)).isInstanceOf(BugReportsPreferenceController.class);
@@ -127,8 +127,6 @@
         assertThat(controllers.get(position++)).isInstanceOf(
                 CaCertsManagedProfilePreferenceController.class);
         assertThat(controllers.get(position++)).isInstanceOf(
-                BackupsEnabledPreferenceController.class);
-        assertThat(controllers.get(position++)).isInstanceOf(
                 PreferenceCategoryController.class);
         assertThat(controllers.get(position++)).isInstanceOf(
                 FailedPasswordWipeCurrentUserPreferenceController.class);
diff --git a/tests/robotests/src/com/android/settings/homepage/ConditionalContextualCardTest.java b/tests/robotests/src/com/android/settings/homepage/ConditionalContextualCardTest.java
new file mode 100644
index 0000000..ced8b06
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/ConditionalContextualCardTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.homepage;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.android.settings.homepage.conditional.ConditionalContextualCard;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class ConditionalContextualCardTest {
+
+    @Test(expected = IllegalArgumentException.class)
+    public void newInstance_changeCardType_shouldCrash() {
+        new ConditionalContextualCard.Builder()
+                .setCardType(ContextualCard.CardType.SUGGESTION)
+                .build();
+    }
+
+    @Test
+    public void getCardType_shouldAlwaysBeConditional() {
+        assertThat(new ConditionalContextualCard.Builder().build().getCardType())
+                .isEqualTo(ContextualCard.CardType.CONDITIONAL);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/homepage/conditional/ConditionContextualCardControllerTest.java b/tests/robotests/src/com/android/settings/homepage/conditional/ConditionContextualCardControllerTest.java
index ed45ce7..a59a3bc 100644
--- a/tests/robotests/src/com/android/settings/homepage/conditional/ConditionContextualCardControllerTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/conditional/ConditionContextualCardControllerTest.java
@@ -82,7 +82,7 @@
 
         mController.onConditionsChanged();
 
-        verify(mController).onDataUpdated(any());
+        verify(mListener).onContextualCardUpdated(any());
     }
 
     @Test
@@ -94,7 +94,7 @@
 
         mController.onConditionsChanged();
 
-        verify(mController, never()).onDataUpdated(any());
+        verify(mListener, never()).onContextualCardUpdated(any());
     }
 
     private class FakeConditionalCard implements ConditionalCard {
diff --git a/tests/robotests/src/com/android/settings/homepage/conditional/ConditionContextualCardRendererTest.java b/tests/robotests/src/com/android/settings/homepage/conditional/ConditionContextualCardRendererTest.java
index 1ee052d..dc56a7f 100644
--- a/tests/robotests/src/com/android/settings/homepage/conditional/ConditionContextualCardRendererTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/conditional/ConditionContextualCardRendererTest.java
@@ -101,7 +101,6 @@
                 .setMetricsConstant(1)
                 .setActionText("test_action")
                 .setName("test_name")
-                .setCardType(ContextualCard.CardType.CONDITIONAL)
                 .setTitleText("test_title")
                 .setSummaryText("test_summary")
                 .setIconDrawable(mContext.getDrawable(R.drawable.ic_do_not_disturb_on_24dp))
diff --git a/tests/robotests/src/com/android/settings/network/NetworkDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/network/NetworkDashboardFragmentTest.java
index d6f86f9..469a537 100644
--- a/tests/robotests/src/com/android/settings/network/NetworkDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/network/NetworkDashboardFragmentTest.java
@@ -79,7 +79,7 @@
         final SummaryLoader.SummaryProvider provider =
                 new NetworkDashboardFragment.SummaryProvider(mContext, summaryLoader,
                         wifiPreferenceController, mobileNetworkPreferenceController,
-                        tetherPreferenceController);
+                        tetherPreferenceController, () -> true);
 
         provider.setListening(false);
 
@@ -107,7 +107,7 @@
         final SummaryLoader.SummaryProvider provider =
                 new NetworkDashboardFragment.SummaryProvider(mContext, summaryLoader,
                         wifiPreferenceController, mobileNetworkPreferenceController,
-                        tetherPreferenceController);
+                        tetherPreferenceController, () -> true);
 
         provider.setListening(false);
 
@@ -121,4 +121,34 @@
 
         verify(summaryLoader).setSummary(provider, "Wi\u2011Fi and data usage");
     }
+
+    @Test
+    public void summaryProviderSetListening_noDataUsageActivity_shouldReturnNoDataUsageSummary() {
+        final WifiMasterSwitchPreferenceController wifiPreferenceController =
+                mock(WifiMasterSwitchPreferenceController.class);
+        final MobileNetworkPreferenceController mobileNetworkPreferenceController =
+                mock(MobileNetworkPreferenceController.class);
+        final TetherPreferenceController tetherPreferenceController =
+                mock(TetherPreferenceController.class);
+
+        final SummaryLoader summaryLoader = mock(SummaryLoader.class);
+        final SummaryLoader.SummaryProvider provider =
+                new NetworkDashboardFragment.SummaryProvider(mContext, summaryLoader,
+                        wifiPreferenceController, mobileNetworkPreferenceController,
+                        tetherPreferenceController, () -> false);
+
+        provider.setListening(false);
+
+        verifyZeroInteractions(summaryLoader);
+
+        when(wifiPreferenceController.isAvailable()).thenReturn(true);
+        when(mobileNetworkPreferenceController.isAvailable()).thenReturn(true);
+        when(tetherPreferenceController.isAvailable()).thenReturn(true);
+
+        provider.setListening(true);
+
+        verify(summaryLoader).setSummary(provider, "Wi\u2011Fi, mobile, and hotspot");
+    }
+
+
 }
diff --git a/tests/robotests/src/com/android/settings/notification/RecentNotifyingAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/RecentNotifyingAppsPreferenceControllerTest.java
index cbc51a9..e222b20 100644
--- a/tests/robotests/src/com/android/settings/notification/RecentNotifyingAppsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/RecentNotifyingAppsPreferenceControllerTest.java
@@ -189,9 +189,8 @@
         mController.displayPreference(mScreen);
 
         verify(mCategory).setTitle(R.string.recent_notifications);
-        // Only add app1. app2 is skipped because of the package name, app3 skipped because
-        // it's invalid app.
-        verify(mCategory, times(1)).addPreference(any(Preference.class));
+        // Only add app1 & app2. app3 skipped because it's invalid app.
+        verify(mCategory, times(2)).addPreference(any(Preference.class));
 
         verify(mSeeAllPref).setSummary(null);
         verify(mSeeAllPref).setIcon(R.drawable.ic_chevron_right_24dp);
@@ -247,35 +246,6 @@
     }
 
     @Test
-    public void display_hasRecentButNoneDisplayable_showAppInfo() {
-        final List<NotifyingApp> apps = new ArrayList<>();
-        final NotifyingApp app1 = new NotifyingApp()
-                .setPackage("com.android.phone")
-                .setLastNotified(System.currentTimeMillis());
-        final NotifyingApp app2 = new NotifyingApp()
-                .setPackage("com.android.settings")
-                .setLastNotified(System.currentTimeMillis());
-        apps.add(app1);
-        apps.add(app2);
-
-        // app1, app2 are not displayable
-        when(mAppState.getEntry(app1.getPackage(), UserHandle.myUserId()))
-                .thenReturn(mock(ApplicationsState.AppEntry.class));
-        when(mAppState.getEntry(app2.getPackage(), UserHandle.myUserId()))
-                .thenReturn(mock(ApplicationsState.AppEntry.class));
-        when(mPackageManager.resolveActivity(any(Intent.class), anyInt())).thenReturn(
-                new ResolveInfo());
-        when(mBackend.getRecentApps()).thenReturn(apps);
-
-        mController.displayPreference(mScreen);
-
-        verify(mCategory, never()).addPreference(any(Preference.class));
-        verify(mCategory).setTitle(null);
-        verify(mSeeAllPref).setTitle(R.string.notifications_title);
-        verify(mSeeAllPref).setIcon(null);
-    }
-
-    @Test
     public void display_showRecents_formatSummary() {
         final List<NotifyingApp> apps = new ArrayList<>();
         final NotifyingApp app1 = new NotifyingApp()
diff --git a/tests/robotests/src/com/android/settings/users/UserSettingsTest.java b/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
index 413d771..02c279e 100644
--- a/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
@@ -212,4 +212,31 @@
 
     }
 
+    @Test
+    public void updateUserList_canAddUserAndSwitchUser_shouldShowAddUser() {
+        Settings.Global.putInt(mContext.getContentResolver(),
+            Settings.Global.DEVICE_PROVISIONED, 1);
+        final RestrictedPreference addUser = mock(RestrictedPreference.class);
+
+        mUserCapabilities.mCanAddUser = true;
+        mUserCapabilities.mDisallowAddUser = false;
+        mUserCapabilities.mUserSwitcherEnabled = true;
+
+        ReflectionHelpers.setField(mFragment, "mUserManager", mUserManager);
+        ReflectionHelpers.setField(mFragment, "mUserCaps", mUserCapabilities);
+        ReflectionHelpers.setField(mFragment, "mDefaultIconDrawable", mDefaultIconDrawable);
+        ReflectionHelpers.setField(mFragment, "mAddingUser", false);
+        mFragment.mMePreference = mMePreference;
+        mFragment.mUserListCategory = mock(PreferenceCategory.class);
+        mFragment.mAddUser = addUser;
+
+        doReturn(mock(PreferenceScreen.class)).when(mFragment).getPreferenceScreen();
+        doReturn("Test summary").when(mFragment).getString(anyInt(), anyInt());
+
+        mFragment.updateUserList();
+
+        verify(addUser).setVisible(true);
+
+    }
+
 }
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java
index 5e8dd28..54be773 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java
@@ -184,6 +184,22 @@
     }
 
     @Test
+    public void isSubmittable_EapToPskWithValidPassword_shouldReturnTrue() {
+        final TextView password = mView.findViewById(R.id.password);
+        final Spinner securitySpinner = mView.findViewById(R.id.security);
+        assertThat(password).isNotNull();
+        assertThat(securitySpinner).isNotNull();
+        when(mAccessPoint.isSaved()).thenReturn(true);
+
+        // Change it from EAP to PSK
+        mController.onItemSelected(securitySpinner, null, AccessPoint.SECURITY_EAP, 0);
+        mController.onItemSelected(securitySpinner, null, AccessPoint.SECURITY_PSK, 0);
+        password.setText(GOOD_PSK);
+
+        assertThat(mController.isSubmittable()).isTrue();
+    }
+
+    @Test
     public void getSignalString_notReachable_shouldHaveNoSignalString() {
         when(mAccessPoint.isReachable()).thenReturn(false);