Merge "Do not include disabled activity in Default Browser."
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index aa3364f..c8d9aff 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -124,7 +124,7 @@
                 android:value="true" />
         </activity>
 
-        <activity android:name=".SettingsHomepageActivity"
+        <activity android:name=".homepage.SettingsHomepageActivity"
                   android:taskAffinity="com.android.settings.root"
                   android:label="@string/settings_label_launcher"
                   android:theme="@style/Theme.Settings.Home"
@@ -136,7 +136,7 @@
                 android:taskAffinity="com.android.settings.root"
                 android:label="@string/settings_label_launcher"
                 android:launchMode="singleTask"
-                android:targetActivity=".SettingsHomepageActivity">
+                android:targetActivity=".homepage.SettingsHomepageActivity">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.DEFAULT" />
diff --git a/res/drawable-nodpi/gesture_ambient_reach b/res/drawable-nodpi/gesture_ambient_reach
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/res/drawable-nodpi/gesture_ambient_reach
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/raw/gesture_ambient_reach.mp4 b/res/raw/gesture_ambient_reach.mp4
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/res/raw/gesture_ambient_reach.mp4
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/bools.xml b/res/values/bools.xml
index f1abe9d..8bd11c7 100644
--- a/res/values/bools.xml
+++ b/res/values/bools.xml
@@ -174,6 +174,9 @@
     <!-- Whether wifi_mac_address should be shown or not. -->
     <bool name="config_show_wifi_mac_address">true</bool>
 
-    <!-- Whether to disable "Uninstall Updates" menu item for System apps or not.. -->
+    <!-- Whether to disable "Uninstall Updates" menu item for System apps or not. -->
     <bool name="config_disable_uninstall_update">false</bool>
+
+    <!-- Whether or not extra preview panels should be used for screen zoom setting. -->
+    <bool name="config_enable_extra_screen_zoom_preview">true</bool>
 </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 6782804..2b37268 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -9581,19 +9581,10 @@
     <!-- Summary text for ambient display (device) [CHAR LIMIT=NONE]-->
     <string name="ambient_display_pickup_summary" product="device">To check time, notifications, and other info, pick up your device.</string>
 
-    <!-- Preference and settings suggestion title text for reach gesture (phone) [CHAR LIMIT=60]-->
-    <string name="ambient_display_reach_title" product="default">Reach to check phone</string>
-    <!-- Preference and settings suggestion title text for reach gesture (tablet) [CHAR LIMIT=60]-->
-    <string name="ambient_display_reach_title" product="tablet">Reach to check tablet</string>
-    <!-- Preference and settings suggestion title text for reach gesture (device) [CHAR LIMIT=60]-->
-    <string name="ambient_display_reach_title" product="device">Reach to check device</string>
-
-    <!-- Summary text for ambient display (phone) [CHAR LIMIT=NONE]-->
-    <string name="ambient_display_reach_summary" product="default">To check time, notifications, and other info, reach for your phone.</string>
-    <!-- Summary text for ambient display (tablet) [CHAR LIMIT=NONE]-->
-    <string name="ambient_display_reach_summary" product="tablet">To check time, notifications, and other info, reach for your tablet.</string>
-    <!-- Summary text for ambient display (device) [CHAR LIMIT=NONE]-->
-    <string name="ambient_display_reach_summary" product="device">To check time, notifications, and other info, reach for your device.</string>
+    <!-- Preference and settings suggestion title text for reach gesture [CHAR LIMIT=60]-->
+    <string name="ambient_display_reach_title">Reach gesture</string>
+    <!-- Summary text for ambient display [CHAR LIMIT=NONE]-->
+    <string name="ambient_display_reach_summary" product="default"></string>
 
     <!-- Title text for swiping downwards on fingerprint sensor for notifications [CHAR LIMIT=80]-->
     <string name="fingerprint_swipe_for_notifications_title">Swipe fingerprint for notifications</string>
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index 95dba41..a76bef7 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -47,7 +47,7 @@
             android:title="@string/display_category_title">
 
         <Preference
-            android:fragment="com.android.settings.accessibility.ToggleFontSizePreferenceFragment"
+            android:fragment="com.android.settings.display.ToggleFontSizePreferenceFragment"
             android:key="font_size_preference_screen"
             android:title="@string/title_font_size"
             settings:searchable="false"/>
diff --git a/res/xml/accessibility_settings_for_setup_wizard.xml b/res/xml/accessibility_settings_for_setup_wizard.xml
index c1141ab..738bb8e 100644
--- a/res/xml/accessibility_settings_for_setup_wizard.xml
+++ b/res/xml/accessibility_settings_for_setup_wizard.xml
@@ -33,7 +33,7 @@
 
     <Preference
         android:fragment=
-                "com.android.settings.accessibility.FontSizePreferenceFragmentForSetupWizard"
+                "com.android.settings.display.FontSizePreferenceFragmentForSetupWizard"
         android:key="font_size_preference"
         android:title="@string/title_font_size"
         android:summary="@string/short_summary_font_size" />
diff --git a/res/xml/display_settings.xml b/res/xml/display_settings.xml
index 54769cf..db4e7d8 100644
--- a/res/xml/display_settings.xml
+++ b/res/xml/display_settings.xml
@@ -83,7 +83,7 @@
     <Preference
         android:key="font_size"
         android:title="@string/title_font_size"
-        android:fragment="com.android.settings.accessibility.ToggleFontSizePreferenceFragment"
+        android:fragment="com.android.settings.display.ToggleFontSizePreferenceFragment"
         settings:controller="com.android.settings.display.FontSizePreferenceController" />
 
     <com.android.settings.display.ScreenZoomPreference
diff --git a/res/xml/gestures.xml b/res/xml/gestures.xml
index 9f69102..aa99446 100644
--- a/res/xml/gestures.xml
+++ b/res/xml/gestures.xml
@@ -28,6 +28,12 @@
         settings:controller="com.android.settings.gestures.AssistGestureSettingsPreferenceController" />
 
     <Preference
+        android:key="gesture_reach_summary"
+        android:title="@string/ambient_display_reach_title"
+        android:fragment="com.android.settings.gestures.ReachGestureSettings"
+        settings:controller="com.android.settings.gestures.ReachGesturePreferenceController" />
+
+    <Preference
         android:key="gesture_swipe_down_fingerprint_input_summary"
         android:title="@string/fingerprint_swipe_for_notifications_title"
         android:fragment="com.android.settings.gestures.SwipeToNotificationSettings"
diff --git a/res/xml/reach_gesture_settings.xml b/res/xml/reach_gesture_settings.xml
index 1acc364..e933e15 100644
--- a/res/xml/reach_gesture_settings.xml
+++ b/res/xml/reach_gesture_settings.xml
@@ -23,8 +23,8 @@
 
     <com.android.settings.widget.VideoPreference
         android:key="gesture_reach_video"
-        app:animation="@raw/gesture_ambient_lift"
-        app:preview="@drawable/gesture_ambient_lift" />
+        app:animation="@raw/gesture_ambient_reach"
+        app:preview="@drawable/gesture_ambient_reach" />
 
     <SwitchPreference
         android:key="gesture_reach"
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index cde2aca..ffce321 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -62,6 +62,7 @@
 import com.android.settings.core.gateway.SettingsGateway;
 import com.android.settings.dashboard.DashboardFeatureProvider;
 import com.android.settings.dashboard.DashboardSummary;
+import com.android.settings.homepage.SettingsHomepageActivity;
 import com.android.settings.homepage.TopLevelSettings;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.DeviceIndexFeatureProvider;
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/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index ce4773d..9a8ef54 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -55,6 +55,7 @@
 import com.android.settings.R;
 import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.Utils;
+import com.android.settings.display.ToggleFontSizePreferenceFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
 import com.android.settingslib.RestrictedLockUtilsInternal;
diff --git a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
index 0696b5e..7b9cc79 100755
--- a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
+++ b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
@@ -185,17 +185,23 @@
         mDpm = (DevicePolicyManager) activity.getSystemService(Context.DEVICE_POLICY_SERVICE);
         mUserManager = (UserManager) activity.getSystemService(Context.USER_SERVICE);
         mPm = activity.getPackageManager();
-
         if (!ensurePackageInfoAvailable(activity)) {
             return;
         }
-
         startListeningToPackageRemove();
 
         setHasOptionsMenu(true);
     }
 
     @Override
+    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+        if (!ensurePackageInfoAvailable(getActivity())) {
+            return;
+        }
+        super.onCreatePreferences(savedInstanceState, rootKey);
+    }
+
+    @Override
     public void onDestroy() {
         stopListeningToPackageRemove();
         super.onDestroy();
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/display/FontSizePreferenceController.java b/src/com/android/settings/display/FontSizePreferenceController.java
index a55d577..680e378 100644
--- a/src/com/android/settings/display/FontSizePreferenceController.java
+++ b/src/com/android/settings/display/FontSizePreferenceController.java
@@ -18,7 +18,6 @@
 import android.provider.Settings;
 
 import com.android.settings.R;
-import com.android.settings.accessibility.ToggleFontSizePreferenceFragment;
 import com.android.settings.core.BasePreferenceController;
 
 public class FontSizePreferenceController extends BasePreferenceController {
diff --git a/src/com/android/settings/accessibility/FontSizePreferenceFragmentForSetupWizard.java b/src/com/android/settings/display/FontSizePreferenceFragmentForSetupWizard.java
similarity index 92%
rename from src/com/android/settings/accessibility/FontSizePreferenceFragmentForSetupWizard.java
rename to src/com/android/settings/display/FontSizePreferenceFragmentForSetupWizard.java
index 8dfb2b4..703ec9c 100644
--- a/src/com/android/settings/accessibility/FontSizePreferenceFragmentForSetupWizard.java
+++ b/src/com/android/settings/display/FontSizePreferenceFragmentForSetupWizard.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.settings.accessibility;
+package com.android.settings.display;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 
diff --git a/src/com/android/settings/PreviewPagerAdapter.java b/src/com/android/settings/display/PreviewPagerAdapter.java
similarity index 82%
rename from src/com/android/settings/PreviewPagerAdapter.java
rename to src/com/android/settings/display/PreviewPagerAdapter.java
index 8d83cb4..4d5b47a 100644
--- a/src/com/android/settings/PreviewPagerAdapter.java
+++ b/src/com/android/settings/display/PreviewPagerAdapter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 The Android Open Source Project
+ * 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.
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.settings;
+package com.android.settings.display;
 
 import android.animation.Animator;
 import android.animation.Animator.AnimatorListener;
@@ -32,6 +32,8 @@
 
 import androidx.viewpager.widget.PagerAdapter;
 
+import com.android.settings.support.actionbar.HelpResourceProvider;
+
 /**
  * A PagerAdapter used by PreviewSeekBarPreferenceFragment that for showing multiple preview screen
  * regarding a single setting and allowing the user to swipe across them.
@@ -76,16 +78,12 @@
                 final Context configContext = context.createConfigurationContext(configurations[j]);
                 configContext.getTheme().setTo(context.getTheme());
 
-                final LayoutInflater configInflater = LayoutInflater.from(configContext);
                 final ViewStub sampleViewStub = new ViewStub(configContext);
                 sampleViewStub.setLayoutResource(previewSampleResIds[i]);
                 final int fi = i, fj = j;
-                sampleViewStub.setOnInflateListener(new OnInflateListener() {
-                    @Override
-                    public void onInflate(ViewStub stub, View inflated) {
-                        inflated.setVisibility(stub.getVisibility());
-                        mViewStubInflated[fi][fj] = true;
-                    }
+                sampleViewStub.setOnInflateListener((stub, inflated) -> {
+                    inflated.setVisibility(stub.getVisibility());
+                    mViewStubInflated[fi][fj] = true;
                 });
 
                 mPreviewFrames[p].addView(sampleViewStub);
@@ -94,7 +92,7 @@
     }
 
     @Override
-    public void destroyItem (ViewGroup container, int position, Object object) {
+    public void destroyItem(ViewGroup container, int position, Object object) {
         container.removeView((View) object);
     }
 
@@ -164,29 +162,29 @@
             if (visibility == View.VISIBLE) {
                 // Fade in animation.
                 view.animate()
-                .alpha(alpha)
-                .setInterpolator(FADE_IN_INTERPOLATOR)
-                .setDuration(CROSS_FADE_DURATION_MS)
-                .setListener(new PreviewFrameAnimatorListener())
-                .withStartAction(new Runnable() {
-                    @Override
-                    public void run() {
-                        view.setVisibility(visibility);
-                    }
-                });
+                        .alpha(alpha)
+                        .setInterpolator(FADE_IN_INTERPOLATOR)
+                        .setDuration(CROSS_FADE_DURATION_MS)
+                        .setListener(new PreviewFrameAnimatorListener())
+                        .withStartAction(new Runnable() {
+                            @Override
+                            public void run() {
+                                view.setVisibility(visibility);
+                            }
+                        });
             } else {
                 // Fade out animation.
                 view.animate()
-                .alpha(alpha)
-                .setInterpolator(FADE_OUT_INTERPOLATOR)
-                .setDuration(CROSS_FADE_DURATION_MS)
-                .setListener(new PreviewFrameAnimatorListener())
-                .withEndAction(new Runnable() {
-                    @Override
-                    public void run() {
-                        view.setVisibility(visibility);
-                    }
-                });
+                        .alpha(alpha)
+                        .setInterpolator(FADE_OUT_INTERPOLATOR)
+                        .setDuration(CROSS_FADE_DURATION_MS)
+                        .setListener(new PreviewFrameAnimatorListener())
+                        .withEndAction(new Runnable() {
+                            @Override
+                            public void run() {
+                                view.setVisibility(visibility);
+                            }
+                        });
             }
         }
     }
diff --git a/src/com/android/settings/PreviewSeekBarPreferenceFragment.java b/src/com/android/settings/display/PreviewSeekBarPreferenceFragment.java
similarity index 79%
rename from src/com/android/settings/PreviewSeekBarPreferenceFragment.java
rename to src/com/android/settings/display/PreviewSeekBarPreferenceFragment.java
index 164648f..bb9e3d7 100644
--- a/src/com/android/settings/PreviewSeekBarPreferenceFragment.java
+++ b/src/com/android/settings/display/PreviewSeekBarPreferenceFragment.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * 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.
@@ -14,14 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.settings;
+package com.android.settings.display;
 
 import android.content.Context;
 import android.content.res.Configuration;
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.SeekBar;
@@ -31,6 +30,8 @@
 import androidx.viewpager.widget.ViewPager;
 import androidx.viewpager.widget.ViewPager.OnPageChangeListener;
 
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.widget.DotsPageIndicator;
 import com.android.settings.widget.LabeledSeekBar;
 
@@ -48,12 +49,6 @@
     /** Index of the entry corresponding to current value of the settings. */
     protected int mCurrentIndex;
 
-    /** Resource id of the layout for this preference fragment. */
-    protected int mActivityLayoutResId;
-
-    /** Resource id of the layout that defines the contents inside preview screen. */
-    protected int[] mPreviewSampleResIds;
-
     private ViewPager mPreviewPager;
     private PreviewPagerAdapter mPreviewPagerAdapter;
     private DotsPageIndicator mPageIndicator;
@@ -82,12 +77,7 @@
         @Override
         public void onStopTrackingTouch(SeekBar seekBar) {
             if (mPreviewPagerAdapter.isAnimating()) {
-                mPreviewPagerAdapter.setAnimationEndAction(new Runnable() {
-                    @Override
-                    public void run() {
-                        commit();
-                    }
-                });
+                mPreviewPagerAdapter.setAnimationEndAction(() -> commit());
             } else {
                 commit();
             }
@@ -102,39 +92,33 @@
         final ViewGroup listContainer = root.findViewById(android.R.id.list_container);
         listContainer.removeAllViews();
 
-        final View content = inflater.inflate(mActivityLayoutResId, listContainer, false);
+        final View content = inflater.inflate(getActivityLayoutResId(), listContainer, false);
         listContainer.addView(content);
 
-        mLabel = (TextView) content.findViewById(R.id.current_label);
+        mLabel = content.findViewById(R.id.current_label);
 
         // The maximum SeekBar value always needs to be non-zero. If there's
         // only one available value, we'll handle this by disabling the
         // seek bar.
         final int max = Math.max(1, mEntries.length - 1);
 
-        mSeekBar = (LabeledSeekBar) content.findViewById(R.id.seek_bar);
+        mSeekBar = content.findViewById(R.id.seek_bar);
         mSeekBar.setLabels(mEntries);
         mSeekBar.setMax(max);
 
         mSmaller = content.findViewById(R.id.smaller);
-        mSmaller.setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                final int progress = mSeekBar.getProgress();
-                if (progress > 0) {
-                    mSeekBar.setProgress(progress - 1, true);
-                }
+        mSmaller.setOnClickListener(v -> {
+            final int progress = mSeekBar.getProgress();
+            if (progress > 0) {
+                mSeekBar.setProgress(progress - 1, true);
             }
         });
 
         mLarger = content.findViewById(R.id.larger);
-        mLarger.setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                final int progress = mSeekBar.getProgress();
-                if (progress < mSeekBar.getMax()) {
-                    mSeekBar.setProgress(progress + 1, true);
-                }
+        mLarger.setOnClickListener(v -> {
+            final int progress = mSeekBar.getProgress();
+            if (progress < mSeekBar.getMax()) {
+                mSeekBar.setProgress(progress + 1, true);
             }
         });
 
@@ -152,15 +136,16 @@
             configurations[i] = createConfig(origConfig, i);
         }
 
-        mPreviewPager = (ViewPager) content.findViewById(R.id.preview_pager);
+        final int[] previews = getPreviewSampleResIds();
+        mPreviewPager = content.findViewById(R.id.preview_pager);
         mPreviewPagerAdapter = new PreviewPagerAdapter(context, isLayoutRtl,
-                mPreviewSampleResIds, configurations);
+                previews, configurations);
         mPreviewPager.setAdapter(mPreviewPagerAdapter);
-        mPreviewPager.setCurrentItem(isLayoutRtl ? mPreviewSampleResIds.length - 1 : 0);
+        mPreviewPager.setCurrentItem(isLayoutRtl ? previews.length - 1 : 0);
         mPreviewPager.addOnPageChangeListener(mPreviewPageChangeListener);
 
-        mPageIndicator = (DotsPageIndicator) content.findViewById(R.id.page_indicator);
-        if (mPreviewSampleResIds.length > 1) {
+        mPageIndicator = content.findViewById(R.id.page_indicator);
+        if (previews.length > 1) {
             mPageIndicator.setViewPager(mPreviewPager);
             mPageIndicator.setVisibility(View.VISIBLE);
             mPageIndicator.setOnPageChangeListener(mPageIndicatorPageChangeListener);
@@ -187,6 +172,12 @@
         mSeekBar.setOnSeekBarChangeListener(null);
     }
 
+    /** Resource id of the layout for this preference fragment. */
+    protected abstract int getActivityLayoutResId();
+
+    /** Resource id of the layout that defines the contents inside preview screen. */
+    protected abstract int[] getPreviewSampleResIds();
+
     /**
      * Creates new configuration based on the current position of the SeekBar.
      */
@@ -210,8 +201,8 @@
 
     private void setPagerIndicatorContentDescription(int position) {
         mPageIndicator.setContentDescription(
-                getPrefContext().getString(R.string.preview_page_indicator_content_description,
-                        position + 1, mPreviewSampleResIds.length));
+                getString(R.string.preview_page_indicator_content_description,
+                        position + 1, getPreviewSampleResIds().length));
     }
 
     private OnPageChangeListener mPreviewPageChangeListener = new OnPageChangeListener() {
diff --git a/src/com/android/settings/display/ScreenZoomPreferenceFragmentForSetupWizard.java b/src/com/android/settings/display/ScreenZoomPreferenceFragmentForSetupWizard.java
index 82cb58d..e02579f 100644
--- a/src/com/android/settings/display/ScreenZoomPreferenceFragmentForSetupWizard.java
+++ b/src/com/android/settings/display/ScreenZoomPreferenceFragmentForSetupWizard.java
@@ -18,8 +18,7 @@
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 
-public class ScreenZoomPreferenceFragmentForSetupWizard
-        extends ScreenZoomSettings {
+public class ScreenZoomPreferenceFragmentForSetupWizard extends ScreenZoomSettings {
 
     @Override
     public int getMetricsCategory() {
diff --git a/src/com/android/settings/display/ScreenZoomSettings.java b/src/com/android/settings/display/ScreenZoomSettings.java
index dbb6353..37ac046 100644
--- a/src/com/android/settings/display/ScreenZoomSettings.java
+++ b/src/com/android/settings/display/ScreenZoomSettings.java
@@ -24,9 +24,9 @@
 import android.view.Display;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.PreviewSeekBarPreferenceFragment;
 import com.android.settings.R;
 import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
 import com.android.settings.search.SearchIndexableRaw;
 import com.android.settingslib.display.DisplayDensityUtils;
 import com.android.settingslib.search.SearchIndexable;
@@ -44,16 +44,25 @@
     private int[] mValues;
 
     @Override
+    protected int getActivityLayoutResId() {
+        return R.layout.screen_zoom_activity;
+    }
+
+    @Override
+    protected int[] getPreviewSampleResIds() {
+        return getContext().getResources().getBoolean(
+                R.bool.config_enable_extra_screen_zoom_preview)
+                ? new int[]{
+                        R.layout.screen_zoom_preview_1,
+                        R.layout.screen_zoom_preview_2,
+                        R.layout.screen_zoom_preview_settings}
+                : new int[]{R.layout.screen_zoom_preview_1};
+    }
+
+    @Override
     public void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        mActivityLayoutResId = R.layout.screen_zoom_activity;
-
-        // This should be replaced once the final preview sample screen is in place.
-        mPreviewSampleResIds = new int[] {R.layout.screen_zoom_preview_1,
-                R.layout.screen_zoom_preview_2,
-                R.layout.screen_zoom_preview_settings};
-
         final DisplayDensityUtils density = new DisplayDensityUtils(getContext());
 
         final int initialIndex = density.getCurrentIndex();
@@ -62,8 +71,8 @@
             // connect to the window manager service. Just use the current
             // density and don't let the user change anything.
             final int densityDpi = getResources().getDisplayMetrics().densityDpi;
-            mValues = new int[] {densityDpi};
-            mEntries = new String[] {getString(DisplayDensityUtils.SUMMARY_DEFAULT)};
+            mValues = new int[]{densityDpi};
+            mEntries = new String[]{getString(DisplayDensityUtils.SUMMARY_DEFAULT)};
             mInitialIndex = 0;
             mDefaultDensity = densityDpi;
         } else {
@@ -108,7 +117,7 @@
     }
 
     /** Index provider used to expose this fragment in search. */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableRaw> getRawDataToIndex(Context context,
diff --git a/src/com/android/settings/accessibility/ToggleFontSizePreferenceFragment.java b/src/com/android/settings/display/ToggleFontSizePreferenceFragment.java
similarity index 91%
rename from src/com/android/settings/accessibility/ToggleFontSizePreferenceFragment.java
rename to src/com/android/settings/display/ToggleFontSizePreferenceFragment.java
index c3100ee..4f118d5 100644
--- a/src/com/android/settings/accessibility/ToggleFontSizePreferenceFragment.java
+++ b/src/com/android/settings/display/ToggleFontSizePreferenceFragment.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.settings.accessibility;
+package com.android.settings.display;
 
 import android.annotation.Nullable;
 import android.content.ContentResolver;
@@ -25,7 +25,6 @@
 import android.provider.Settings;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.PreviewSeekBarPreferenceFragment;
 import com.android.settings.R;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
@@ -44,13 +43,20 @@
     private float[] mValues;
 
     @Override
+    protected int getActivityLayoutResId() {
+        return R.layout.font_size_activity;
+    }
+
+    @Override
+    protected int[] getPreviewSampleResIds() {
+        return new int[]{R.layout.font_size_preview};
+    }
+
+    @Override
     public void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        mActivityLayoutResId = R.layout.font_size_activity;
-        mPreviewSampleResIds = new int[] {R.layout.font_size_preview};
-
-        Resources res = getContext().getResources();
+        final Resources res = getContext().getResources();
         final ContentResolver resolver = getContext().getContentResolver();
         // Mark the appropriate item in the preferences list.
         mEntries = res.getStringArray(R.array.entries_font_size);
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/CardContentProvider.java b/src/com/android/settings/homepage/CardContentProvider.java
index 640a00b..7b08756 100644
--- a/src/com/android/settings/homepage/CardContentProvider.java
+++ b/src/com/android/settings/homepage/CardContentProvider.java
@@ -61,23 +61,38 @@
 
     @Override
     public Uri insert(Uri uri, ContentValues values) {
+        final ContentValues[] cvs = {values};
+        bulkInsert(uri, cvs);
+        return uri;
+    }
+
+    @Override
+    public int bulkInsert(Uri uri, ContentValues[] values) {
         final StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
+        int numInserted = 0;
+        final SQLiteDatabase database = mDBHelper.getWritableDatabase();
+
         try {
             maybeEnableStrictMode();
 
-            final SQLiteDatabase database = mDBHelper.getWritableDatabase();
             final String table = getTableFromMatch(uri);
-            final long ret = database.insert(table, null, values);
-            if (ret != -1) {
-                getContext().getContentResolver().notifyChange(uri, null);
-            } else {
-                Log.e(TAG, "The CardContentProvider insertion failed! Plase check SQLiteDatabase's "
-                        + "message.");
+            database.beginTransaction();
+            for (ContentValues value : values) {
+                long ret = database.insert(table, null, value);
+                if (ret != -1L) {
+                    numInserted++;
+                } else {
+                    Log.e(TAG, "The row " + value.getAsString(CardDatabaseHelper.CardColumns.NAME)
+                            + " insertion failed! Please check your data.");
+                }
             }
+            database.setTransactionSuccessful();
+            getContext().getContentResolver().notifyChange(uri, null);
         } finally {
+            database.endTransaction();
             StrictMode.setThreadPolicy(oldPolicy);
         }
-        return uri;
+        return numInserted;
     }
 
     @Override
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..174a437 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;
@@ -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..4a7a149 100644
--- a/src/com/android/settings/homepage/ContextualCardController.java
+++ b/src/com/android/settings/homepage/ContextualCardController.java
@@ -27,8 +27,8 @@
     int getCardType();
 
     /**
-     * When data is updated or changed, the new data should be passed to ContextualCardManager for list
-     * updating.
+     * When data is updated or changed, the new data should be passed to ContextualCardManager for
+     * list updating.
      */
     void onDataUpdated(List<ContextualCard> cardList);
 
diff --git a/src/com/android/settings/homepage/ContextualCardManager.java b/src/com/android/settings/homepage/ContextualCardManager.java
index 255f7a2..1eec6a7 100644
--- a/src/com/android/settings/homepage/ContextualCardManager.java
+++ b/src/com/android/settings/homepage/ContextualCardManager.java
@@ -16,9 +16,17 @@
 
 package com.android.settings.homepage;
 
+import static com.android.settings.homepage.CardContentLoader.CARD_CONTENT_LOADER_ID;
+
 import android.content.Context;
+import android.os.Bundle;
 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;
 
@@ -28,14 +36,14 @@
 /**
  * This is a centralized manager of multiple {@link ContextualCardController}.
  *
- * {@link ContextualCardManager} first loads data from {@link CardContentLoader} and gets back a list of
- * {@link ContextualCard}. All subclasses of {@link ContextualCardController} are loaded here, which
- * will then trigger the {@link ContextualCardController} to load its data and listen to
+ * {@link ContextualCardManager} first loads data from {@link CardContentLoader} and gets back a
+ * list of {@link ContextualCard}. All subclasses of {@link ContextualCardController} are loaded
+ * here, which will then trigger the {@link ContextualCardController} to load its data and listen to
  * corresponding changes. When every single {@link ContextualCardController} updates its data, the
  * data will be passed here, then going through some sorting mechanisms. The
- * {@link ContextualCardController} will end up building a list of {@link ContextualCard} for {@link
- * ContextualCardsAdapter} and {@link BaseAdapter#notifyDataSetChanged()} will be called to get the page
- * refreshed.
+ * {@link ContextualCardController} will end up building a list of {@link ContextualCard} for
+ * {@link ContextualCardsAdapter} and {@link BaseAdapter#notifyDataSetChanged()} will be called to
+ * get the page refreshed.
  */
 public class ContextualCardManager implements CardContentLoader.CardContentLoaderListener,
         ContextualCardUpdateListener {
@@ -48,8 +56,8 @@
     private final Context mContext;
     private final ControllerRendererPool mControllerRendererPool;
     private final Lifecycle mLifecycle;
+    private final List<ContextualCard> mContextualCards;
 
-    private List<ContextualCard> mContextualCards;
     private ContextualCardUpdateListener mListener;
 
 
@@ -60,9 +68,12 @@
         mControllerRendererPool = new ControllerRendererPool();
     }
 
-    void startCardContentLoading() {
-        final CardContentLoader cardContentLoader = new CardContentLoader();
-        cardContentLoader.setListener(this);
+    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() {
@@ -97,7 +108,7 @@
     }
 
     @Override
-    public void onHomepageCardUpdated(int cardType, List<ContextualCard> updateList) {
+    public void onContextualCardUpdated(int cardType, List<ContextualCard> updateList) {
         //TODO(b/112245748): Should implement a DiffCallback.
         //Keep the old list for comparison.
         final List<ContextualCard> prevCards = mContextualCards;
@@ -115,13 +126,16 @@
         sortCards();
 
         if (mListener != null) {
-            mListener.onHomepageCardUpdated(ContextualCard.CardType.INVALID, mContextualCards);
+            mListener.onContextualCardUpdated(ContextualCard.CardType.INVALID, mContextualCards);
         }
     }
 
     @Override
     public void onFinishCardLoading(List<ContextualCard> contextualCards) {
-        mContextualCards = 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.
@@ -137,4 +151,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 0b45426..d307a8f 100644
--- a/src/com/android/settings/homepage/ContextualCardUpdateListener.java
+++ b/src/com/android/settings/homepage/ContextualCardUpdateListener.java
@@ -19,13 +19,13 @@
 import java.util.List;
 
 /**
- * When {@link ContextualCardController} detects changes, it will notify the listeners registered. In
- * our case, {@link ContextualCardManager} gets noticed.
+ * 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.
+ * {@link ContextualCardManager} will notify the listeners registered, {@link
+ * ContextualCardsAdapter} in this case.
  */
 public interface ContextualCardUpdateListener {
-    void onHomepageCardUpdated(int cardType, List<ContextualCard> updateList);
+    void onContextualCardUpdated(int cardType, List<ContextualCard> updateList);
 }
\ 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 254f4a4..53a47e0 100644
--- a/src/com/android/settings/homepage/ContextualCardsAdapter.java
+++ b/src/com/android/settings/homepage/ContextualCardsAdapter.java
@@ -27,8 +27,8 @@
 import java.util.ArrayList;
 import java.util.List;
 
-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";
@@ -37,8 +37,7 @@
 
     private final Context mContext;
     private final ControllerRendererPool mControllerRendererPool;
-
-    private List<ContextualCard> mContextualCards;
+    private final List<ContextualCard> mContextualCards;
 
     public ContextualCardsAdapter(Context context, ContextualCardManager manager) {
         mContext = context;
@@ -102,13 +101,14 @@
     }
 
     @Override
-    public void onHomepageCardUpdated(int cardType, List<ContextualCard> contextualCards) {
+    public void onContextualCardUpdated(int cardType, List<ContextualCard> contextualCards) {
         //TODO(b/112245748): Should implement a DiffCallback so we can use notifyItemChanged()
         // instead.
         if (contextualCards == null) {
             mContextualCards.clear();
         } else {
-            mContextualCards = contextualCards;
+            mContextualCards.clear();
+            mContextualCards.addAll(contextualCards);
         }
         notifyDataSetChanged();
     }
diff --git a/src/com/android/settings/homepage/PersonalSettingsFragment.java b/src/com/android/settings/homepage/PersonalSettingsFragment.java
index 69af23b..4a0041e 100644
--- a/src/com/android/settings/homepage/PersonalSettingsFragment.java
+++ b/src/com/android/settings/homepage/PersonalSettingsFragment.java
@@ -24,7 +24,6 @@
 import android.view.ViewGroup;
 
 import androidx.recyclerview.widget.GridLayoutManager;
-import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -44,17 +43,16 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         mContextualCardManager = new ContextualCardManager(getContext(), getSettingsLifecycle());
-        mContextualCardManager.startCardContentLoading();
+        mContextualCardManager.loadContextualCards(this);
     }
 
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
             Bundle savedInstanceState) {
-        final View rootView = inflater.inflate(R.layout.settings_homepage,
-                container, false);
+        final View rootView = inflater.inflate(R.layout.settings_homepage, container, false);
         mCardsContainer = rootView.findViewById(R.id.card_container);
         mLayoutManager = new GridLayoutManager(getActivity(), SPAN_COUNT,
-                LinearLayoutManager.VERTICAL, false /* reverseLayout */);
+                GridLayoutManager.VERTICAL, false /* reverseLayout */);
         mCardsContainer.setLayoutManager(mLayoutManager);
         mContextualCardsAdapter = new ContextualCardsAdapter(getContext(), mContextualCardManager);
         mCardsContainer.setAdapter(mContextualCardsAdapter);
diff --git a/src/com/android/settings/SettingsHomepageActivity.java b/src/com/android/settings/homepage/SettingsHomepageActivity.java
similarity index 79%
rename from src/com/android/settings/SettingsHomepageActivity.java
rename to src/com/android/settings/homepage/SettingsHomepageActivity.java
index 77155e0..35b45a4 100644
--- a/src/com/android/settings/SettingsHomepageActivity.java
+++ b/src/com/android/settings/homepage/SettingsHomepageActivity.java
@@ -14,32 +14,31 @@
  * limitations under the License.
  */
 
-package com.android.settings;
+package com.android.settings.homepage;
 
 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
 import android.util.FeatureFlagUtils;
 
+import androidx.annotation.VisibleForTesting;
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentManager;
 import androidx.fragment.app.FragmentTransaction;
 
+import com.android.settings.R;
 import com.android.settings.core.FeatureFlags;
 import com.android.settings.core.SettingsBaseActivity;
-import com.android.settings.dashboard.DashboardSummary;
-import com.android.settings.homepage.PersonalSettingsFragment;
-import com.android.settings.homepage.TopLevelSettings;
 import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.search.SearchFeatureProvider;
 
 import com.google.android.material.bottomnavigation.BottomNavigationView;
 import com.google.android.material.floatingactionbutton.FloatingActionButton;
 
 public class SettingsHomepageActivity extends SettingsBaseActivity {
 
+    @VisibleForTesting
+    static final String PERSONAL_SETTINGS_TAG = "personal_settings";
     private static final String ALL_SETTINGS_TAG = "all_settings";
-    private static final String PERSONAL_SETTINGS_TAG = "personal_settings";
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -63,25 +62,31 @@
         navigation.setOnNavigationItemSelectedListener(item -> {
             switch (item.getItemId()) {
                 case R.id.homepage_personal_settings:
-                    switchFragment(PersonalSettingsFragment.class.getName(), PERSONAL_SETTINGS_TAG,
+                    switchFragment(new PersonalSettingsFragment(), PERSONAL_SETTINGS_TAG,
                             ALL_SETTINGS_TAG);
                     return true;
 
                 case R.id.homepage_all_settings:
-                    switchFragment(TopLevelSettings.class.getName(), ALL_SETTINGS_TAG,
+                    switchFragment(new TopLevelSettings(), ALL_SETTINGS_TAG,
                             PERSONAL_SETTINGS_TAG);
                     return true;
             }
             return false;
         });
+
+        if (savedInstanceState == null) {
+            // savedInstanceState is null, this is first load.
+            // Default to open contextual cards.
+            switchFragment(new PersonalSettingsFragment(), PERSONAL_SETTINGS_TAG,
+                    ALL_SETTINGS_TAG);
+        }
     }
 
     public static boolean isDynamicHomepageEnabled(Context context) {
         return FeatureFlagUtils.isEnabled(context, FeatureFlags.DYNAMIC_HOMEPAGE);
     }
 
-    private void switchFragment(String fragmentName, String showFragmentTag,
-            String hideFragmentTag) {
+    private void switchFragment(Fragment fragment, String showFragmentTag, String hideFragmentTag) {
         final FragmentManager fragmentManager = getSupportFragmentManager();
         final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
 
@@ -92,8 +97,7 @@
 
         Fragment showFragment = fragmentManager.findFragmentByTag(showFragmentTag);
         if (showFragment == null) {
-            showFragment = Fragment.instantiate(this, fragmentName, null /* args */);
-            fragmentTransaction.add(R.id.main_content, showFragment, showFragmentTag);
+            fragmentTransaction.add(R.id.main_content, fragment, showFragmentTag);
         } else {
             fragmentTransaction.show(showFragment);
         }
diff --git a/src/com/android/settings/homepage/conditional/ConditionContextualCardController.java b/src/com/android/settings/homepage/conditional/ConditionContextualCardController.java
index eab6099..6701cfd 100644
--- a/src/com/android/settings/homepage/conditional/ConditionContextualCardController.java
+++ b/src/com/android/settings/homepage/conditional/ConditionContextualCardController.java
@@ -58,7 +58,7 @@
 
     @Override
     public void onDataUpdated(List<ContextualCard> cardList) {
-        mListener.onHomepageCardUpdated(getCardType(), cardList);
+        mListener.onContextualCardUpdated(getCardType(), cardList);
     }
 
     @Override
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/NotificationSettingsBase.java b/src/com/android/settings/notification/NotificationSettingsBase.java
index d06b545..ed0b123 100644
--- a/src/com/android/settings/notification/NotificationSettingsBase.java
+++ b/src/com/android/settings/notification/NotificationSettingsBase.java
@@ -112,19 +112,22 @@
 
         mPkgInfo = findPackageInfo(mPkg, mUid);
 
-        mUserId = UserHandle.getUserId(mUid);
-        mSuspendedAppsAdmin = RestrictedLockUtilsInternal.checkIfApplicationIsSuspended(
-                mContext, mPkg, mUserId);
+        if (mPkgInfo != null) {
+            mUserId = UserHandle.getUserId(mUid);
+            mSuspendedAppsAdmin = RestrictedLockUtilsInternal.checkIfApplicationIsSuspended(
+                    mContext, mPkg, mUserId);
 
-        loadChannel();
-        loadAppRow();
-        loadChannelGroup();
-        collectConfigActivities();
 
-        getSettingsLifecycle().addObserver(use(HeaderPreferenceController.class));
+            loadChannel();
+            loadAppRow();
+            loadChannelGroup();
+            collectConfigActivities();
 
-        for (NotificationPreferenceController controller : mControllers) {
-            controller.onResume(mAppRow, mChannel, mChannelGroup, mSuspendedAppsAdmin);
+            getSettingsLifecycle().addObserver(use(HeaderPreferenceController.class));
+
+            for (NotificationPreferenceController controller : mControllers) {
+                controller.onResume(mAppRow, mChannel, mChannelGroup, mSuspendedAppsAdmin);
+            }
         }
     }
 
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index 181ab9d..6e3174d 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -964,7 +964,8 @@
                 mAddUserWhenLockedPreferenceController.getPreferenceKey());
         mAddUserWhenLockedPreferenceController.updateState(addUserOnLockScreen);
         mMultiUserFooterPreferenceController.updateState(null /* preference */);
-        mAddUser.setVisible(mUserCaps.mUserSwitcherEnabled);
+        mAddUser.setVisible(mUserCaps.mCanAddUser && Utils.isDeviceProvisioned(context)
+                && mUserCaps.mUserSwitcherEnabled);
         mUserListCategory.setVisible(mUserCaps.mUserSwitcherEnabled);
         if (!mUserCaps.mUserSwitcherEnabled) {
             return;
diff --git a/src/com/android/settings/utils/ManagedServiceSettings.java b/src/com/android/settings/utils/ManagedServiceSettings.java
index 6ee5e8e..e5dfb06 100644
--- a/src/com/android/settings/utils/ManagedServiceSettings.java
+++ b/src/com/android/settings/utils/ManagedServiceSettings.java
@@ -32,11 +32,6 @@
 import android.util.Log;
 import android.view.View;
 
-import androidx.appcompat.app.AlertDialog;
-import androidx.fragment.app.Fragment;
-import androidx.preference.PreferenceScreen;
-import androidx.preference.SwitchPreference;
-
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
 import com.android.settings.Utils;
@@ -47,6 +42,11 @@
 
 import java.util.List;
 
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.Fragment;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+
 public abstract class ManagedServiceSettings extends EmptyTextSettings {
     private static final String TAG = "ManagedServiceSettings";
     private final Config mConfig;
@@ -117,12 +117,12 @@
             CharSequence title = null;
             try {
                 title = mPm.getApplicationInfoAsUser(
-                        service.packageName, 0, getCurrentUser(managedProfileId)).loadLabel(mPm);
+                        service.packageName, 0, UserHandle.myUserId()).loadLabel(mPm);
             } catch (PackageManager.NameNotFoundException e) {
                 // unlikely, as we are iterating over live services.
                 Log.e(TAG, "can't find package name", e);
             }
-            final String finalTitle = title.toString();
+            final CharSequence finalTitle = title;
             final String summary = service.loadLabel(mPm).toString();
             final SwitchPreference pref = new AppSwitchPreference(getPrefContext());
             pref.setPersistent(false);
@@ -143,7 +143,11 @@
             }
             pref.setOnPreferenceChangeListener((preference, newValue) -> {
                 final boolean enable = (boolean) newValue;
-                return setEnabled(cn, finalTitle, enable);
+                if (finalTitle != null) {
+                    return setEnabled(cn, finalTitle.toString(), enable);
+                } else {
+                    return setEnabled(cn, null, enable);
+                }
             });
             pref.setKey(cn.flattenToString());
             screen.addPreference(pref);
diff --git a/tests/robotests/assets/grandfather_not_in_search_index_provider_registry b/tests/robotests/assets/grandfather_not_in_search_index_provider_registry
index af663f4..64e0a01 100644
--- a/tests/robotests/assets/grandfather_not_in_search_index_provider_registry
+++ b/tests/robotests/assets/grandfather_not_in_search_index_provider_registry
@@ -1,3 +1,3 @@
-com.android.settings.accessibility.FontSizePreferenceFragmentForSetupWizard
+com.android.settings.display.FontSizePreferenceFragmentForSetupWizard
 com.android.settings.display.ScreenZoomPreferenceFragmentForSetupWizard
 com.android.settings.search.FakeSettingsFragment
diff --git a/tests/robotests/config/robolectric.properties b/tests/robotests/config/robolectric.properties
index d213eec..aae2779 100644
--- a/tests/robotests/config/robolectric.properties
+++ b/tests/robotests/config/robolectric.properties
@@ -1,3 +1,6 @@
 manifest=packages/apps/Settings/AndroidManifest.xml
 sdk=NEWEST_SDK
-shadows=com.android.settings.testutils.shadow.ShadowThreadUtils
\ No newline at end of file
+
+shadows=\
+   com.android.settings.testutils.shadow.ShadowThreadUtils,\
+   com.android.settingslib.testutils.shadow.ShadowXmlUtils
diff --git a/tests/robotests/res/values-mcc999/config.xml b/tests/robotests/res/values-mcc999/config.xml
index 2488882..6347d79 100644
--- a/tests/robotests/res/values-mcc999/config.xml
+++ b/tests/robotests/res/values-mcc999/config.xml
@@ -63,6 +63,9 @@
     <bool name="config_disable_uninstall_update">true</bool>
     <bool name="config_show_device_name">false</bool>
 
+    <!-- Whether or not extra preview panels should be used for screen zoom setting. -->
+    <bool name="config_enable_extra_screen_zoom_preview">false</bool>
+
     <!-- List of a11y components on the device allowed to be enabled by Settings Slices -->
     <string-array name="config_settings_slices_accessibility_components" translatable="false">
         <item>fake_package/fake_service</item>
@@ -72,5 +75,4 @@
     <string-array name="slice_whitelist_package_names" translatable="false">
         <item>com.android.settings.slice_whitelist_package</item>
     </string-array>
-
 </resources>
diff --git a/tests/robotests/res/values/themes.xml b/tests/robotests/res/values/themes.xml
index 9a247f6..d3ba69f 100644
--- a/tests/robotests/res/values/themes.xml
+++ b/tests/robotests/res/values/themes.xml
@@ -6,5 +6,14 @@
 
     <!-- Override the main app's style for ActionPrimaryButton to get around lack of new style
          support in robolectric  -->
-    <style name="ActionPrimaryButton" parent="android:Widget.DeviceDefault.Button" />
+    <style name="ActionPrimaryButton" parent="android:Widget.DeviceDefault.Button"/>
+
+    <!-- Test version of Theme.Settings.Home. Needed to build homepage activity in Robolectric -->
+    <style name="Theme.Settings.Home" parent="Theme.AppCompat.DayNight.NoActionBar">
+        <item name="colorPrimary">#ffffff</item>
+        <item name="colorPrimaryDark">#ffffff</item>
+        <item name="colorAccent">#ffffff</item>
+        <item name="preferenceTheme">@style/PreferenceTheme</item>
+        <item name="android:windowLightStatusBar">true</item>
+    </style>
 </resources>
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java
index b6bb9b5..539e75f 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java
@@ -170,7 +170,7 @@
     }
 
     @Test
-    public void launchFragment_hasNoPackageInfo_shouldFinish() {
+    public void ensurePackageInfoAvailable_hasNoPackageInfo_shouldFinish() {
         ReflectionHelpers.setField(mFragment, "mPackageInfo", null);
 
         assertThat(mFragment.ensurePackageInfoAvailable(mActivity)).isFalse();
@@ -178,7 +178,7 @@
     }
 
     @Test
-    public void launchFragment_hasPackageInfo_shouldReturnTrue() {
+    public void ensurePackageInfoAvailable_hasPackageInfo_shouldReturnTrue() {
         final PackageInfo packageInfo = mock(PackageInfo.class);
         ReflectionHelpers.setField(mFragment, "mPackageInfo", packageInfo);
 
@@ -187,6 +187,16 @@
     }
 
     @Test
+    public void createPreference_hasNoPackageInfo_shouldSkip() {
+        ReflectionHelpers.setField(mFragment, "mPackageInfo", null);
+
+        mFragment.onCreatePreferences(new Bundle(), "root_key");
+
+        verify(mActivity).finishAndRemoveTask();
+        verify(mFragment, never()).getPreferenceScreen();
+    }
+
+    @Test
     public void packageSizeChange_isOtherPackage_shouldNotRefreshUi() {
         ReflectionHelpers.setField(mFragment, "mPackageName", PACKAGE_NAME);
         mFragment.onPackageSizeChanged("Not_" + PACKAGE_NAME);
diff --git a/tests/robotests/src/com/android/settings/display/ScreenZoomSettingsTest.java b/tests/robotests/src/com/android/settings/display/ScreenZoomSettingsTest.java
new file mode 100644
index 0000000..0822076
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/display/ScreenZoomSettingsTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.display;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class ScreenZoomSettingsTest {
+
+    private ScreenZoomSettings mSettings;
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application;
+        mSettings = spy(new ScreenZoomSettings());
+        doReturn(mContext).when(mSettings).getContext();
+    }
+
+    @Test
+    public void getPreviewSampleResIds_default_return3Previews() {
+        assertThat(mSettings.getPreviewSampleResIds()).hasLength(3);
+    }
+
+    @Test
+    @Config(qualifiers = "mcc999")
+    public void getPreviewSampleResIds_extraPreviewDisabled_return1Preview() {
+        assertThat(mSettings.getPreviewSampleResIds()).hasLength(1);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/homepage/CardContentProviderTest.java b/tests/robotests/src/com/android/settings/homepage/CardContentProviderTest.java
index eec87b0..84955e2 100644
--- a/tests/robotests/src/com/android/settings/homepage/CardContentProviderTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/CardContentProviderTest.java
@@ -72,16 +72,25 @@
 
     @Test
     public void cardData_insert() {
-        final int cnt_before_instert = getRowCount();
-        mResolver.insert(mUri, insertOneRow());
-        final int cnt_after_instert = getRowCount();
+        final int rowsBeforeInsert = getRowCount();
+        mResolver.insert(mUri, generateOneRow());
+        final int rowsAfterInsert = getRowCount();
 
-        assertThat(cnt_after_instert - cnt_before_instert).isEqualTo(1);
+        assertThat(rowsAfterInsert - rowsBeforeInsert).isEqualTo(1);
+    }
+
+    @Test
+    public void cardData_bulkInsert_twoRows() {
+        final int rowsBeforeInsert = getRowCount();
+        mResolver.bulkInsert(mUri, generateTwoRows());
+        final int rowsAfterInsert = getRowCount();
+
+        assertThat(rowsAfterInsert - rowsBeforeInsert).isEqualTo(2);
     }
 
     @Test
     public void cardData_query() {
-        mResolver.insert(mUri, insertOneRow());
+        mResolver.insert(mUri, generateOneRow());
         final int count = getRowCount();
 
         assertThat(count).isGreaterThan(0);
@@ -89,24 +98,24 @@
 
     @Test
     public void cardData_delete() {
-        mResolver.insert(mUri, insertOneRow());
-        final int del_count = mResolver.delete(mUri, null, null);
+        mResolver.insert(mUri, generateOneRow());
+        final int delCount = mResolver.delete(mUri, null, null);
 
-        assertThat(del_count).isGreaterThan(0);
+        assertThat(delCount).isGreaterThan(0);
     }
 
     @Test
     public void cardData_update() {
-        mResolver.insert(mUri, insertOneRow());
+        mResolver.insert(mUri, generateOneRow());
 
         final double updatingScore = 0.87;
         final ContentValues values = new ContentValues();
         values.put(CardDatabaseHelper.CardColumns.SCORE, updatingScore);
         final String strWhere = CardDatabaseHelper.CardColumns.NAME + "=?";
         final String[] selectionArgs = {"auto_rotate"};
-        final int update_count = mResolver.update(mUri, values, strWhere, selectionArgs);
+        final int updateCount = mResolver.update(mUri, values, strWhere, selectionArgs);
 
-        assertThat(update_count).isGreaterThan(0);
+        assertThat(updateCount).isGreaterThan(0);
 
         final String[] columns = {CardDatabaseHelper.CardColumns.SCORE};
         final Cursor cr = mResolver.query(mUri, columns, strWhere, selectionArgs, null);
@@ -122,7 +131,7 @@
         ShadowThreadUtils.setIsMainThread(true);
         ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", true);
 
-        mProvider.insert(mUri, insertOneRow());
+        mProvider.insert(mUri, generateOneRow());
 
         verify(mProvider).enableStrictMode();
     }
@@ -164,7 +173,7 @@
         ShadowThreadUtils.setIsMainThread(false);
         ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", true);
 
-        mProvider.insert(mUri, insertOneRow());
+        mProvider.insert(mUri, generateOneRow());
 
         verify(mProvider, never()).enableStrictMode();
     }
@@ -217,10 +226,10 @@
         mProvider.getTableFromMatch(invalid_Uri);
     }
 
-    private ContentValues insertOneRow() {
+    private ContentValues generateOneRow() {
         final ContentValues values = new ContentValues();
         values.put(CardDatabaseHelper.CardColumns.NAME, "auto_rotate");
-        values.put(CardDatabaseHelper.CardColumns.TYPE, 0);
+        values.put(CardDatabaseHelper.CardColumns.TYPE, 1);
         values.put(CardDatabaseHelper.CardColumns.SCORE, 0.9);
         values.put(CardDatabaseHelper.CardColumns.SLICE_URI,
                 "content://com.android.settings.slices/action/auto_rotate");
@@ -231,6 +240,24 @@
         return values;
     }
 
+    private ContentValues[] generateTwoRows() {
+        final ContentValues[] twoRows = new ContentValues[2];
+        twoRows[0] = generateOneRow();
+
+        final ContentValues values = new ContentValues();
+        values.put(CardDatabaseHelper.CardColumns.NAME, "toggle_airplane");
+        values.put(CardDatabaseHelper.CardColumns.TYPE, 1);
+        values.put(CardDatabaseHelper.CardColumns.SCORE, 0.95);
+        values.put(CardDatabaseHelper.CardColumns.SLICE_URI,
+                "content://com.android.settings.slices/action/toggle_airplane");
+        values.put(CardDatabaseHelper.CardColumns.CATEGORY, 2);
+        values.put(CardDatabaseHelper.CardColumns.PACKAGE_NAME, "com.android.settings");
+        values.put(CardDatabaseHelper.CardColumns.APP_VERSION, "1.0.0");
+        twoRows[1] = values;
+
+        return twoRows;
+    }
+
     private int getRowCount() {
         final Cursor cr = mResolver.query(mUri, null, null, null);
         final int count = cr.getCount();
diff --git a/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java b/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
new file mode 100644
index 0000000..4b237a0
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.android.settings.homepage.SettingsHomepageActivity.PERSONAL_SETTINGS_TAG;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.util.FeatureFlagUtils;
+
+import androidx.fragment.app.Fragment;
+
+import com.android.settings.core.FeatureFlags;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class SettingsHomepageActivityTest {
+
+    private Context mContext;
+    private SettingsHomepageActivity mActivity;
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application;
+        FeatureFlagUtils.setEnabled(mContext, FeatureFlags.DYNAMIC_HOMEPAGE, true);
+    }
+
+    @Test
+    public void launchHomepage_shouldOpenPersonalSettings() {
+        mActivity = Robolectric.setupActivity(SettingsHomepageActivity.class);
+        final Fragment fragment = mActivity.getSupportFragmentManager()
+                .findFragmentByTag(PERSONAL_SETTINGS_TAG);
+
+        assertThat(fragment).isInstanceOf(PersonalSettingsFragment.class);
+    }
+}
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/testutils/SettingsRobolectricTestRunner.java b/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java
index ad808fc..87f0a37 100644
--- a/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java
+++ b/tests/robotests/src/com/android/settings/testutils/SettingsRobolectricTestRunner.java
@@ -76,6 +76,8 @@
             paths.add(new ResourcePath(null,
                 Fs.fromURL(new URL("file:frameworks/base/packages/SettingsLib/res")), null));
             paths.add(new ResourcePath(null,
+                    Fs.fromURL(new URL("file:frameworks/base/packages/SettingsLib/HelpUtils/res/")), null));
+            paths.add(new ResourcePath(null,
                 Fs.fromURL(new URL("file:frameworks/base/core/res/res")), null));
             paths.add(new ResourcePath(null,
                 Fs.fromURL(new URL("file:frameworks/opt/setupwizard/library/main/res")), null));
@@ -86,6 +88,8 @@
             paths.add(new ResourcePath(null,
                 Fs.fromURL(new URL("file:out/soong/.intermediates/prebuilts/sdk/current/androidx/androidx.appcompat_appcompat-nodeps/android_common/aar/res/")), null));
             paths.add(new ResourcePath(null,
+                Fs.fromURL(new URL("file:out/soong/.intermediates/prebuilts/sdk/current/extras/material-design-x/com.google.android.material_material-nodeps/android_common/aar/res/")), null));
+            paths.add(new ResourcePath(null,
                 Fs.fromURL(new URL("file:out/soong/.intermediates/prebuilts/sdk/current/androidx/androidx.cardview_cardview-nodeps/android_common/aar/res")), null));
         } catch (MalformedURLException e) {
             throw new RuntimeException("SettingsRobolectricTestRunner failure", e);
diff --git a/tests/robotests/src/com/android/settings/users/UserSettingsTest.java b/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
index 41f48c6..02c279e 100644
--- a/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
@@ -21,6 +21,7 @@
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -184,4 +185,58 @@
 
         assertThat(addUser.isEnabled()).isFalse();
     }
+
+    @Test
+    public void updateUserList_cannotAddUserButCanSwitchUser_shouldNotShowAddUser() {
+        Settings.Global.putInt(mContext.getContentResolver(),
+            Settings.Global.DEVICE_PROVISIONED, 1);
+        final RestrictedPreference addUser = mock(RestrictedPreference.class);
+
+        mUserCapabilities.mCanAddUser = false;
+        mUserCapabilities.mDisallowAddUser = true;
+        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();
+
+        mFragment.updateUserList();
+
+        verify(addUser, never()).setVisible(true);
+
+    }
+
+    @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);
+
+    }
+
 }