Merge "[Settings Telephony] Carrier name API replacement"
diff --git a/res/layout/advanced_bt_entity_sub.xml b/res/layout/advanced_bt_entity_sub.xml
index 0f30583..359d68b 100644
--- a/res/layout/advanced_bt_entity_sub.xml
+++ b/res/layout/advanced_bt_entity_sub.xml
@@ -38,10 +38,12 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center_horizontal"
+        android:gravity="center"
         android:singleLine="false"
         android:ellipsize="marquee"
         android:textDirection="locale"
-        android:layout_marginTop="24dp"/>
+        android:layout_marginTop="24dp"
+        android:textSize="@dimen/advanced_bluetooth_header_title_text_size"/>
 
     <LinearLayout
         android:layout_width="wrap_content"
diff --git a/res/layout/disable_accessibility_service_dialog_content.xml b/res/layout/disable_accessibility_service_dialog_content.xml
deleted file mode 100644
index 680de4a..0000000
--- a/res/layout/disable_accessibility_service_dialog_content.xml
+++ /dev/null
@@ -1,71 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2019 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
-  -->
-
-<ScrollView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
-    android:textDirection="locale"
-    android:scrollbarStyle="outsideOverlay"
-    android:gravity="top">
-
-    <LinearLayout
-        android:theme="@style/Theme.AlertDialog"
-        style="@style/AccessibilityDialog">
-
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="vertical"
-            android:gravity="center_horizontal"
-            android:paddingTop="32dp"
-            android:paddingLeft="24dp"
-            android:paddingRight="24dp">
-
-            <TextView
-                android:id="@+id/permissionDialog_disable_title"
-                style="@style/AccessibilityDialogTitle" />
-
-            <TextView
-                android:id="@+id/permissionDialog_disable_message"
-                android:gravity="center"
-                android:text="@string/accessibility_service_warning_description"
-                style="@style/AccessibilityDialogDescription" />
-
-        </LinearLayout>
-            <!-- Buttons on bottom of dialog -->
-            <LinearLayout
-                style="@style/AccessibilityDialogButtonList">
-
-                <Space
-                    style="@style/AccessibilityDialogButtonBarSpace"/>
-
-                <Button
-                    android:id="@+id/permission_disable_stop_button"
-                    android:text="@string/accessibility_dialog_button_stop"
-                    style="@style/AccessibilityDialogButton" />
-
-                <Button
-                    android:id="@+id/permission_disable_cancel_button"
-                    android:text="@string/accessibility_dialog_button_cancel"
-                    style="@style/AccessibilityDialogButton" />
-
-            </LinearLayout>
-
-    </LinearLayout>
-
-</ScrollView>
diff --git a/res/layout/legacy_suggestion_tile.xml b/res/layout/legacy_suggestion_tile.xml
index 9af5b6b..2a18403 100644
--- a/res/layout/legacy_suggestion_tile.xml
+++ b/res/layout/legacy_suggestion_tile.xml
@@ -42,6 +42,23 @@
                 android:layout_marginTop="16dp"
                 android:layout_marginBottom="6dp"/>
 
+            <FrameLayout
+                android:id="@+id/close_button"
+                android:layout_width="48dp"
+                android:layout_height="48dp"
+                android:layout_alignParentEnd="true"
+                android:paddingTop="8dp"
+                android:paddingEnd="8dp"
+                android:orientation="horizontal"
+                android:contentDescription="@string/suggestion_button_close">
+                <ImageView
+                    android:layout_width="18dp"
+                    android:layout_height="18dp"
+                    android:layout_gravity="end|top"
+                    android:alpha="0.54"
+                    android:src="@drawable/ic_suggestion_close_button"/>
+            </FrameLayout>
+
         </RelativeLayout>
 
         <TextView
diff --git a/res/layout/notification_log_row.xml b/res/layout/notification_log_row.xml
index e76835e..4d44f9f 100644
--- a/res/layout/notification_log_row.xml
+++ b/res/layout/notification_log_row.xml
@@ -26,8 +26,7 @@
 
     <RelativeLayout
         android:layout_width="match_parent"
-        android:layout_height="@*android:dimen/status_bar_icon_size"
-        android:layout_marginBottom="6dp"
+        android:layout_height="wrap_content"
         >
 
         <ImageView
@@ -46,24 +45,38 @@
             android:scaleType="fitCenter" />
 
         <TextView
-            android:id="@+id/title"
-            android:layout_width="match_parent"
+            android:id="@+id/pkgname"
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_centerVertical="true"
-            android:layout_toStartOf="@+id/timestamp"
             android:layout_toEndOf="@id/icon"
             android:ellipsize="end"
             android:singleLine="true"
             android:textColor="?android:attr/textColorPrimary"
             android:textAppearance="?android:attr/textAppearanceSmall"
             android:textStyle="bold"
-            android:textAlignment="viewStart"
-            android:labelFor="@android:id/button2" />
+            android:textAlignment="viewStart" />
+
+        <ImageView
+            android:id="@+id/alerted_icon"
+            android:layout_width="@*android:dimen/status_bar_icon_size"
+            android:layout_height="@*android:dimen/status_bar_icon_size"
+            android:layout_centerVertical="true"
+            android:layout_marginStart="6dp"
+            android:paddingTop="1dp"
+            android:scaleType="fitCenter"
+            android:visibility="gone"
+            android:layout_toEndOf="@id/pkgname"
+            android:tint="?android:attr/textColorSecondary"
+            android:src="@drawable/ic_notifications_alert"
+        />
 
         <DateTimeView
             android:id="@+id/timestamp"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:paddingTop="13dp"
+            android:paddingBottom="13dp"
             android:layout_alignBottom="@android:id/widget_frame"
             android:layout_alignParentEnd="true"
             android:layout_alignTop="@android:id/widget_frame"
@@ -78,26 +91,25 @@
 
     <LinearLayout
         android:layout_width="match_parent"
-        android:layout_height="@*android:dimen/status_bar_icon_size"
-        android:orientation="horizontal"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
         android:layout_marginStart="30dp"
         android:layout_marginBottom="6dp"
         >
 
-        <ImageView
-            android:id="@+id/pkgicon"
-            android:layout_width="@*android:dimen/status_bar_icon_size"
-            android:layout_height="@*android:dimen/status_bar_icon_size"
-            android:layout_marginStart="0dp"
-            android:layout_marginEnd="6dp"
-            android:contentDescription="@null"
-            android:adjustViewBounds="true"
-            android:maxHeight="@*android:dimen/status_bar_icon_size"
-            android:maxWidth="@*android:dimen/status_bar_icon_size"
-            android:scaleType="fitCenter" />
+        <TextView
+            android:id="@+id/title"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="left|center_vertical"
+            android:ellipsize="end"
+            android:singleLine="true"
+            android:textColor="?android:attr/textColorPrimary"
+            android:textAlignment="viewStart"
+        />
 
         <TextView
-            android:id="@+id/pkgname"
+            android:id="@+id/text"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_gravity="left|center_vertical"
@@ -106,12 +118,30 @@
             android:textColor="?android:attr/textColorPrimary"
             android:textAppearance="?android:attr/textAppearanceSmall"
             android:textAlignment="viewStart"
-            />
+        />
 
     </LinearLayout>
 
-    <TextView
-            android:id="@+id/extra"
+    <LinearLayout
+        android:id="@+id/extra"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+    >
+        <TextView
+                android:id="@+id/notification_extra"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+                android:layout_marginStart="30dp"
+                android:singleLine="false"
+                android:textColor="?android:attr/textColorPrimary"
+                android:textSize="10sp"
+                android:fontFamily="monospace"
+                android:textAlignment="viewStart"
+        />
+        <TextView
+            android:id="@+id/ranking_extra"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:orientation="horizontal"
@@ -122,6 +152,7 @@
             android:textSize="10sp"
             android:fontFamily="monospace"
             android:textAlignment="viewStart"
-    />
+        />
+    </LinearLayout>
 
 </LinearLayout>
diff --git a/res/layout/wifi_dialog.xml b/res/layout/wifi_dialog.xml
index a7c1690..e205157 100644
--- a/res/layout/wifi_dialog.xml
+++ b/res/layout/wifi_dialog.xml
@@ -373,6 +373,34 @@
                     android:orientation="vertical"
                     android:visibility="gone">
 
+            <LinearLayout android:id="@+id/hidden_settings_field"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:visibility="gone"
+                style="@style/wifi_item">
+
+                <TextView android:id="@+id/hidden_settings_title"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    style="@style/wifi_item_label"
+                    android:text="@string/wifi_hidden_network" />
+
+                <Spinner android:id="@+id/hidden_settings"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    style="@style/wifi_item_spinner"
+                    android:prompt="@string/wifi_hidden_network"
+                    android:entries="@array/wifi_hidden_entries"/>
+
+                <TextView android:id="@+id/hidden_settings_warning"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:padding="8dp"
+                    android:text="@string/wifi_hidden_network_warning"
+                    android:textAppearance="?android:attr/textAppearanceSmall"
+                    android:visibility="gone"/>
+            </LinearLayout>
+
             <LinearLayout android:id="@+id/metered_settings_fields"
                           android:layout_width="match_parent"
                           android:layout_height="wrap_content"
@@ -677,34 +705,6 @@
                             android:checked="true" />
                 </LinearLayout>
             </LinearLayout>
-
-            <LinearLayout android:id="@+id/hidden_settings_field"
-                          android:layout_width="match_parent"
-                          android:layout_height="wrap_content"
-                          android:visibility="gone"
-                          style="@style/wifi_item">
-
-                <TextView android:id="@+id/hidden_settings_title"
-                          android:layout_width="wrap_content"
-                          android:layout_height="wrap_content"
-                          style="@style/wifi_item_label"
-                          android:text="@string/wifi_hidden_network" />
-
-                <Spinner android:id="@+id/hidden_settings"
-                         android:layout_width="match_parent"
-                         android:layout_height="wrap_content"
-                         style="@style/wifi_item_spinner"
-                         android:prompt="@string/wifi_hidden_network"
-                         android:entries="@array/wifi_hidden_entries"/>
-
-                <TextView android:id="@+id/hidden_settings_warning"
-                          android:layout_width="wrap_content"
-                          android:layout_height="wrap_content"
-                          android:padding="8dp"
-                          android:text="@string/wifi_hidden_network_warning"
-                          android:textAppearance="?android:attr/textAppearanceSmall"
-                          android:visibility="gone"/>
-            </LinearLayout>
         </LinearLayout>
     </LinearLayout>
 </ScrollView>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 4d0affb..f97da1f 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -412,4 +412,7 @@
 
     <!-- System navigation settings illustration height -->
     <dimen name="system_navigation_illustration_height">320dp</dimen>
+
+    <!-- Header title size of advanced bluetooth device -->
+    <dimen name="advanced_bluetooth_header_title_text_size">16sp</dimen>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 430819f..b545045 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -8716,6 +8716,9 @@
     <!-- Generic label for suggestion card's ok button [CHAR LIMIT=20] -->
     <string name="suggestion_button_text">Ok</string>
 
+    <!-- Strings for suggestion card's close button [CHAR LIMIT=20] -->
+    <string name="suggestion_button_close">Close</string>
+
     <!-- [CHAR LIMIT=35] Feedback on the device -->
     <string name="device_feedback">Send feedback about this device</string>
 
@@ -9997,14 +10000,7 @@
     <string name="notification_log_details_ashmem">ashmem</string>
     <!-- Notification log debug tool: header: notification alert info -->
     <string name="notification_log_details_alerted">notification alerted</string>
-    <!-- Notification log debug tool: header: notification sound info -->
-    <string name="notification_log_details_sound">sound</string>
-    <!-- Notification log debug tool: header: notification vibration info -->
-    <string name="notification_log_details_vibrate">vibrate</string>
-    <!-- Notification log debug tool: header: notification vibration info -->
-    <string name="notification_log_details_vibrate_pattern">pattern</string>
-    <!-- Notification log debug tool: the word 'default' -->
-    <string name="notification_log_details_default">default</string>
+    <string name="notification_log_channel">channel</string>
     <!-- Notification log debug tool: the word 'none' -->
     <string name="notification_log_details_none">none</string>
     <!-- Notification log debug tool: missing ranking information -->
@@ -11327,4 +11323,7 @@
     <!-- Summary for Enterprise Privacy settings, explaining what the user can expect to find under it [CHAR LIMIT=NONE]-->
     <string name="work_policy_privacy_settings_summary">Settings managed by your IT admin</string>
 
+    <!-- Developer Settings: Search keywords for the Profile HWUI rendering. [CHAR_LIMIT=NONE] -->
+    <string name="track_frame_time_keywords">GPU</string>
+
 </resources>
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index 68307fc..a89997a 100644
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -471,7 +471,8 @@
             android:key="track_frame_time"
             android:title="@string/track_frame_time"
             android:entries="@array/track_frame_time_entries"
-            android:entryValues="@array/track_frame_time_values" />
+            android:entryValues="@array/track_frame_time_values"
+            settings:keywords="@string/track_frame_time_keywords" />
 
     </PreferenceCategory>
 
diff --git a/res/xml/enterprise_privacy_settings.xml b/res/xml/enterprise_privacy_settings.xml
index e8b26b0..e0631df 100644
--- a/res/xml/enterprise_privacy_settings.xml
+++ b/res/xml/enterprise_privacy_settings.xml
@@ -19,13 +19,6 @@
                   android:key="enterprise_privacy_settings"
                   android:title="@string/enterprise_privacy_settings">
 
-    <!-- Header -->
-    <Preference android:key="enterprise_privacy_header"
-                android:order="100"
-                android:icon="@drawable/ic_info_outline_24dp"
-                android:summary="@string/enterprise_privacy_header"
-                android:selectable="false"/>
-
     <PreferenceCategory android:key="exposure_category"
                         android:order="200"
                         android:title="@string/enterprise_privacy_exposure_category"
@@ -125,4 +118,10 @@
                     android:title="@string/enterprise_privacy_failed_password_wipe_work"
                     android:selectable="false"/>
     </PreferenceCategory>
+
+    <com.android.settingslib.widget.FooterPreference
+        android:key="enterprise_privacy_footer"
+        android:title="@string/enterprise_privacy_header"
+        android:selectable="false"
+        settings:searchable="false"/>
 </PreferenceScreen>
diff --git a/res/xml/mobile_network_settings.xml b/res/xml/mobile_network_settings.xml
index ae7c903..ea31b1c 100644
--- a/res/xml/mobile_network_settings.xml
+++ b/res/xml/mobile_network_settings.xml
@@ -53,6 +53,22 @@
         settings:keywords="@string/keywords_enhance_4g_lte"
         settings:controller="com.android.settings.network.telephony.Enhanced4gLtePreferenceController"/>
 
+    <SwitchPreference
+        android:key="4g_calling"
+        android:title="@string/enhanced_4g_lte_mode_title_4g_calling"
+        android:persistent="false"
+        android:summary="@string/enhanced_4g_lte_mode_summary_4g_calling"
+        settings:keywords="@string/keywords_enhance_4g_lte"
+        settings:controller="com.android.settings.network.telephony.Enhanced4gCallingPreferenceController"/>
+
+    <SwitchPreference
+        android:key="advance_call"
+        android:title="@string/enhanced_4g_lte_mode_title_advanced_calling"
+        android:persistent="false"
+        android:summary="@string/enhanced_4g_lte_mode_summary"
+        settings:keywords="@string/keywords_enhance_4g_lte"
+        settings:controller="com.android.settings.network.telephony.Enhanced4gAdvancedCallingPreferenceController"/>
+
     <ListPreference
         android:key="preferred_network_mode_key"
         android:title="@string/preferred_network_mode_title"
diff --git a/res/xml/mobile_network_settings_v2.xml b/res/xml/mobile_network_settings_v2.xml
index 31a5ef7..af1fe20 100644
--- a/res/xml/mobile_network_settings_v2.xml
+++ b/res/xml/mobile_network_settings_v2.xml
@@ -100,6 +100,22 @@
             settings:keywords="@string/keywords_enhance_4g_lte"
             settings:controller="com.android.settings.network.telephony.Enhanced4gLtePreferenceController"/>
 
+        <SwitchPreference
+            android:key="4g_calling"
+            android:title="@string/enhanced_4g_lte_mode_title_4g_calling"
+            android:persistent="false"
+            android:summary="@string/enhanced_4g_lte_mode_summary_4g_calling"
+            settings:keywords="@string/keywords_enhance_4g_lte"
+            settings:controller="com.android.settings.network.telephony.Enhanced4gCallingPreferenceController"/>
+
+        <SwitchPreference
+            android:key="advance_call"
+            android:title="@string/enhanced_4g_lte_mode_title_advanced_calling"
+            android:persistent="false"
+            android:summary="@string/enhanced_4g_lte_mode_summary"
+            settings:keywords="@string/keywords_enhance_4g_lte"
+            settings:controller="com.android.settings.network.telephony.Enhanced4gAdvancedCallingPreferenceController"/>
+
         <ListPreference
             android:key="preferred_network_mode_key"
             android:title="@string/preferred_network_mode_title"
diff --git a/res/xml/special_access.xml b/res/xml/special_access.xml
index e07ede7..b0d962a 100644
--- a/res/xml/special_access.xml
+++ b/res/xml/special_access.xml
@@ -39,7 +39,7 @@
         settings:controller="com.android.settings.enterprise.ManageDeviceAdminPreferenceController" />
 
     <Preference
-        android:key="system_alert_window"
+        android:key="system_alert_window_app_list"
         android:title="@string/system_alert_window_settings"
         android:fragment="com.android.settings.applications.manageapplications.ManageApplications"
         settings:keywords="@string/keywords_draw_overlay"
diff --git a/src/com/android/settings/BugreportPreference.java b/src/com/android/settings/BugreportPreference.java
index dfefe5a..598399a 100644
--- a/src/com/android/settings/BugreportPreference.java
+++ b/src/com/android/settings/BugreportPreference.java
@@ -21,30 +21,20 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.os.RemoteException;
-import android.os.BugreportParams;
-import android.os.SystemProperties;
 import android.util.AttributeSet;
-import android.util.FeatureFlagUtils;
 import android.util.Log;
 import android.view.View;
 import android.widget.CheckedTextView;
 import android.widget.TextView;
-import android.content.Intent;
 
 import androidx.appcompat.app.AlertDialog.Builder;
 
-import com.android.settings.core.FeatureFlags;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.CustomDialogPreferenceCompat;
 
 public class BugreportPreference extends CustomDialogPreferenceCompat {
 
     private static final String TAG = "BugreportPreference";
-    private static final String INTENT_BUGREPORT_REQUESTED =
-            "com.android.internal.intent.action.BUGREPORT_REQUESTED";
-    private static final String EXTRA_ORIGINAL_INTENT = "android.intent.extra.ORIGINAL_INTENT";
-    private static final String EXTRA_BUGREPORT_TYPE = "android.intent.extra.BUGREPORT_TYPE";
-    private static final String SHELL_APP_PACKAGE = "com.android.shell";
 
     private CheckedTextView mInteractiveTitle;
     private TextView mInteractiveSummary;
@@ -56,12 +46,15 @@
     }
 
     @Override
-    protected void onPrepareDialogBuilder(Builder builder, DialogInterface.OnClickListener listener) {
+    protected void onPrepareDialogBuilder(Builder builder,
+            DialogInterface.OnClickListener listener) {
         super.onPrepareDialogBuilder(builder, listener);
 
         final View dialogView = View.inflate(getContext(), R.layout.bugreport_options_dialog, null);
-        mInteractiveTitle = (CheckedTextView) dialogView.findViewById(R.id.bugreport_option_interactive_title);
-        mInteractiveSummary = (TextView) dialogView.findViewById(R.id.bugreport_option_interactive_summary);
+        mInteractiveTitle = (CheckedTextView) dialogView
+                .findViewById(R.id.bugreport_option_interactive_title);
+        mInteractiveSummary = (TextView) dialogView
+                .findViewById(R.id.bugreport_option_interactive_summary);
         mFullTitle = (CheckedTextView) dialogView.findViewById(R.id.bugreport_option_full_title);
         mFullSummary = (TextView) dialogView.findViewById(R.id.bugreport_option_full_summary);
         final View.OnClickListener l = new View.OnClickListener() {
@@ -96,38 +89,21 @@
                 Log.v(TAG, "Taking full bugreport right away");
                 FeatureFactory.getFactory(context).getMetricsFeatureProvider().action(context,
                         SettingsEnums.ACTION_BUGREPORT_FROM_SETTINGS_FULL);
-                takeBugreport(ActivityManager.BUGREPORT_OPTION_FULL);
+                try {
+                    ActivityManager.getService().requestFullBugReport();
+                } catch (RemoteException e) {
+                    Log.e(TAG, "error taking bugreport (bugreportType=Full)", e);
+                }
             } else {
                 Log.v(TAG, "Taking interactive bugreport right away");
                 FeatureFactory.getFactory(context).getMetricsFeatureProvider().action(context,
                         SettingsEnums.ACTION_BUGREPORT_FROM_SETTINGS_INTERACTIVE);
-                takeBugreport(ActivityManager.BUGREPORT_OPTION_INTERACTIVE);
+                try {
+                    ActivityManager.getService().requestInteractiveBugReport();
+                } catch (RemoteException e) {
+                    Log.e(TAG, "error taking bugreport (bugreportType=Interactive)", e);
+                }
             }
         }
     }
-
-    private void takeBugreport(int bugreportType) {
-        try {
-            final Context context = getContext();
-            // USE_BUGREPORT_API is a system property flag used to switch back to the old workflow
-            // using dumpstate. By using the default value as true, new workflow using Bugreport
-            // API is triggered. To switch to the old workflow directly using dumpstate run the
-            // following commands on the terminal:
-            // * adb root
-            // * adb shell setprop settings_use_bugreport_api false
-            if (FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.USE_BUGREPORT_API)) {
-                Intent triggerShellBugreport = new Intent();
-                triggerShellBugreport.setAction(INTENT_BUGREPORT_REQUESTED);
-                triggerShellBugreport.setPackage(SHELL_APP_PACKAGE);
-                triggerShellBugreport.putExtra(EXTRA_BUGREPORT_TYPE, bugreportType);
-
-                // Send broadcast to shell to trigger bugreport using Bugreport API
-                context.sendBroadcast(triggerShellBugreport);
-            } else {
-                ActivityManager.getService().requestBugReport(bugreportType);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "error taking bugreport (bugreportType=" + bugreportType + ")", e);
-        }
-    }
 }
diff --git a/src/com/android/settings/DateTimeSettings.java b/src/com/android/settings/DateTimeSettings.java
index 40b2005..e6e3732 100644
--- a/src/com/android/settings/DateTimeSettings.java
+++ b/src/com/android/settings/DateTimeSettings.java
@@ -21,7 +21,6 @@
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.content.Intent;
-import android.provider.SearchIndexableResource;
 
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.dashboard.SummaryLoader;
@@ -34,7 +33,6 @@
 import com.android.settings.datetime.TimePreferenceController;
 import com.android.settings.datetime.TimeZonePreferenceController;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.datetime.ZoneGetter;
 import com.android.settingslib.search.SearchIndexable;
@@ -64,7 +62,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.date_time_prefs;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -176,21 +174,6 @@
     };
 
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new DateTimeSearchIndexProvider();
-
-    private static class DateTimeSearchIndexProvider extends BaseSearchIndexProvider {
-
-        @Override
-        public List<SearchIndexableResource> getXmlResourcesToIndex(
-                Context context, boolean enabled) {
-            List<SearchIndexableResource> result = new ArrayList<>();
-
-            SearchIndexableResource sir = new SearchIndexableResource(context);
-            sir.xmlResId = R.xml.date_time_prefs;
-            result.add(sir);
-
-            return result;
-        }
-    }
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider(R.xml.date_time_prefs);
 }
diff --git a/src/com/android/settings/DisplaySettings.java b/src/com/android/settings/DisplaySettings.java
index d79d401..9ad4e25 100644
--- a/src/com/android/settings/DisplaySettings.java
+++ b/src/com/android/settings/DisplaySettings.java
@@ -19,7 +19,6 @@
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.os.Bundle;
-import android.provider.SearchIndexableResource;
 
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.display.BrightnessLevelPreferenceController;
@@ -35,7 +34,6 @@
 import com.android.settings.display.TimeoutPreferenceController;
 import com.android.settings.display.VrDisplayPreferenceController;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.search.SearchIndexable;
@@ -61,7 +59,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.display_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -97,7 +95,7 @@
         return controllers;
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.display_settings) {
 
                 @Override
diff --git a/src/com/android/settings/LegalSettings.java b/src/com/android/settings/LegalSettings.java
index e6f0c2c..f6e13ea 100644
--- a/src/com/android/settings/LegalSettings.java
+++ b/src/com/android/settings/LegalSettings.java
@@ -17,17 +17,11 @@
 package com.android.settings;
 
 import android.app.settings.SettingsEnums;
-import android.content.Context;
-import android.provider.SearchIndexableResource;
 
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settingslib.search.SearchIndexable;
 
-import java.util.Arrays;
-import java.util.List;
-
 @SearchIndexable
 public class LegalSettings extends DashboardFragment {
 
@@ -45,18 +39,9 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.about_legal;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider() {
-
-                @Override
-                public List<SearchIndexableResource> getXmlResourcesToIndex(
-                        Context context, boolean enabled) {
-                    final SearchIndexableResource sir = new SearchIndexableResource(context);
-                    sir.xmlResId = R.xml.about_legal;
-                    return Arrays.asList(sir);
-                }
-            };
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider(R.xml.about_legal);
 }
diff --git a/src/com/android/settings/TetherSettings.java b/src/com/android/settings/TetherSettings.java
index a6cbcb0..9ddda1d 100644
--- a/src/com/android/settings/TetherSettings.java
+++ b/src/com/android/settings/TetherSettings.java
@@ -441,7 +441,7 @@
         }
     };
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableResource> getXmlResourcesToIndex(
diff --git a/src/com/android/settings/accessibility/AccessibilityControlTimeoutPreferenceFragment.java b/src/com/android/settings/accessibility/AccessibilityControlTimeoutPreferenceFragment.java
index de444f2..b37fdfb 100644
--- a/src/com/android/settings/accessibility/AccessibilityControlTimeoutPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/AccessibilityControlTimeoutPreferenceFragment.java
@@ -104,7 +104,7 @@
         return sControllers;
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.accessibility_control_timeout_settings) {
 
                 @Override
diff --git a/src/com/android/settings/accessibility/AccessibilityServiceWarning.java b/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
index 40ac641..1203e11 100644
--- a/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
+++ b/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
@@ -22,6 +22,7 @@
 import android.app.Activity;
 import android.app.Dialog;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.graphics.drawable.Drawable;
 import android.os.storage.StorageManager;
 import android.text.BidiFormatter;
@@ -77,10 +78,16 @@
     }
 
     public static Dialog createDisableDialog(Activity parentActivity,
-            AccessibilityServiceInfo info, View.OnClickListener listener) {
+            AccessibilityServiceInfo info, DialogInterface.OnClickListener listener) {
         final AlertDialog ad = new AlertDialog.Builder(parentActivity)
-                .setView(createDisableDialogContentView(parentActivity, info, listener))
+                .setTitle(parentActivity.getString(R.string.disable_service_title,
+                        info.getResolveInfo().loadLabel(parentActivity.getPackageManager())))
+                .setMessage(parentActivity.getString(R.string.disable_service_message,
+                        parentActivity.getString(R.string.accessibility_dialog_button_stop),
+                        getServiceName(parentActivity, info)))
                 .setCancelable(true)
+                .setPositiveButton(R.string.accessibility_dialog_button_stop, listener)
+                .setNegativeButton(R.string.accessibility_dialog_button_cancel, listener)
                 .create();
 
         return ad;
@@ -148,33 +155,6 @@
         return content;
     }
 
-    private static View createDisableDialogContentView(Context context,
-            AccessibilityServiceInfo info, View.OnClickListener listener) {
-        LayoutInflater inflater = (LayoutInflater) context.getSystemService(
-                Context.LAYOUT_INFLATER_SERVICE);
-
-        View content = inflater.inflate(R.layout.disable_accessibility_service_dialog_content,
-                null);
-
-        TextView permissionDialogTitle = content.findViewById(R.id.permissionDialog_disable_title);
-        permissionDialogTitle.setText(context.getString(R.string.disable_service_title,
-                getServiceName(context, info)));
-        TextView permissionDialogMessage = content
-                .findViewById(R.id.permissionDialog_disable_message);
-        permissionDialogMessage.setText(context.getString(R.string.disable_service_message,
-                context.getString(R.string.accessibility_dialog_button_stop),
-                getServiceName(context, info)));
-
-        Button permissionAllowButton = content.findViewById(
-                R.id.permission_disable_stop_button);
-        Button permissionDenyButton = content.findViewById(
-                R.id.permission_disable_cancel_button);
-        permissionAllowButton.setOnClickListener(listener);
-        permissionDenyButton.setOnClickListener(listener);
-
-        return content;
-    }
-
     // Get the service name and bidi wrap it to protect from bidi side effects.
     private static CharSequence getServiceName(Context context, AccessibilityServiceInfo info) {
         final Locale locale = context.getResources().getConfiguration().getLocales().get(0);
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index 4f9d965..b985cd1 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -32,7 +32,6 @@
 import android.os.Handler;
 import android.os.UserHandle;
 import android.provider.DeviceConfig;
-import android.provider.SearchIndexableResource;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.ArrayMap;
@@ -246,7 +245,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.accessibility_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -506,6 +505,6 @@
         }
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.accessibility_settings);
 }
diff --git a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
index cd13875..d686025 100644
--- a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
@@ -192,7 +192,7 @@
         return ComponentName.unflattenFromString(componentNameString);
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 // This fragment is for details of the shortcut. Only the shortcut itself needs
                 // to be indexed.
diff --git a/src/com/android/settings/accessibility/MagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/MagnificationPreferenceFragment.java
index 87b3de7..c84d3ac 100644
--- a/src/com/android/settings/accessibility/MagnificationPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/MagnificationPreferenceFragment.java
@@ -167,7 +167,7 @@
                 == NAV_BAR_MODE_GESTURAL;
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.accessibility_magnification_settings) {
 
                 @Override
diff --git a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
index ec8df88..1556bec 100644
--- a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
@@ -25,6 +25,7 @@
 import android.app.settings.SettingsEnums;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
@@ -49,8 +50,7 @@
 
 import java.util.List;
 
-public class ToggleAccessibilityServicePreferenceFragment
-        extends ToggleFeaturePreferenceFragment implements View.OnClickListener {
+public class ToggleAccessibilityServicePreferenceFragment extends ToggleFeaturePreferenceFragment {
 
     private static final int DIALOG_ID_ENABLE_WARNING = 1;
     private static final int DIALOG_ID_DISABLE_WARNING = 2;
@@ -72,6 +72,42 @@
 
     private Dialog mDialog;
 
+    private final View.OnClickListener mViewOnClickListener =
+            (View view) -> {
+                if (view.getId() == R.id.permission_enable_allow_button) {
+                    if (isFullDiskEncrypted()) {
+                        String title = createConfirmCredentialReasonMessage();
+                        Intent intent = ConfirmDeviceCredentialActivity.createIntent(title, null);
+                        startActivityForResult(intent,
+                                ACTIVITY_REQUEST_CONFIRM_CREDENTIAL_FOR_WEAKER_ENCRYPTION);
+                    } else {
+                        handleConfirmServiceEnabled(true);
+                        if (isServiceSupportAccessibilityButton()) {
+                            showDialog(DIALOG_ID_LAUNCH_ACCESSIBILITY_TUTORIAL);
+                        }
+                    }
+                } else if (view.getId() == R.id.permission_enable_deny_button) {
+                    handleConfirmServiceEnabled(false);
+                } else {
+                    throw new IllegalArgumentException();
+                }
+                mDialog.dismiss();
+            };
+
+    private final DialogInterface.OnClickListener mDialogInterfaceOnClickListener =
+            (DialogInterface dialog, int which) -> {
+                switch (which) {
+                    case DialogInterface.BUTTON_POSITIVE:
+                        handleConfirmServiceEnabled(false);
+                        break;
+                    case DialogInterface.BUTTON_NEGATIVE:
+                        handleConfirmServiceEnabled(true);
+                        break;
+                    default:
+                        throw new IllegalArgumentException();
+                }
+            };
+
     @Override
     public int getMetricsCategory() {
         return SettingsEnums.ACCESSIBILITY_SERVICE;
@@ -137,7 +173,7 @@
                     return null;
                 }
                 mDialog = AccessibilityServiceWarning
-                        .createCapabilitiesDialog(getActivity(), info, this);
+                        .createCapabilitiesDialog(getActivity(), info, mViewOnClickListener);
                 break;
             }
             case DIALOG_ID_DISABLE_WARNING: {
@@ -146,7 +182,7 @@
                     return null;
                 }
                 mDialog = AccessibilityServiceWarning
-                        .createDisableDialog(getActivity(), info, this);
+                        .createDisableDialog(getActivity(), info, mDialogInterfaceOnClickListener);
                 break;
             }
             case DIALOG_ID_LAUNCH_ACCESSIBILITY_TUTORIAL: {
@@ -210,32 +246,6 @@
         }
     }
 
-    @Override
-    public void onClick(View view) {
-        if (view.getId() == R.id.permission_enable_allow_button) {
-            if (isFullDiskEncrypted()) {
-                String title = createConfirmCredentialReasonMessage();
-                Intent intent = ConfirmDeviceCredentialActivity.createIntent(title, null);
-                startActivityForResult(intent,
-                        ACTIVITY_REQUEST_CONFIRM_CREDENTIAL_FOR_WEAKER_ENCRYPTION);
-            } else {
-                handleConfirmServiceEnabled(true);
-                if (isServiceSupportAccessibilityButton()) {
-                    showDialog(DIALOG_ID_LAUNCH_ACCESSIBILITY_TUTORIAL);
-                }
-            }
-        } else if (view.getId() == R.id.permission_enable_deny_button) {
-            handleConfirmServiceEnabled(false);
-        } else if (view.getId() == R.id.permission_disable_stop_button) {
-            handleConfirmServiceEnabled(false);
-        } else if (view.getId() == R.id.permission_disable_cancel_button) {
-            handleConfirmServiceEnabled(true);
-        } else {
-            throw new IllegalArgumentException();
-        }
-        mDialog.dismiss();
-    }
-
     private boolean isGestureNavigateEnabled() {
         return getContext().getResources().getInteger(
                 com.android.internal.R.integer.config_navBarInteractionMode)
diff --git a/src/com/android/settings/accessibility/ToggleAutoclickPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleAutoclickPreferenceFragment.java
index 13a0ed1..bb1dbee 100644
--- a/src/com/android/settings/accessibility/ToggleAutoclickPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleAutoclickPreferenceFragment.java
@@ -187,6 +187,6 @@
         return (delay - MIN_AUTOCLICK_DELAY) / AUTOCLICK_DELAY_STEP;
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.accessibility_autoclick_settings);
 }
diff --git a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
index ca52e29..3a441c7 100644
--- a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
@@ -127,7 +127,7 @@
         onPreferenceToggled(mPreferenceKey, isChecked);
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.accessibility_daltonizer_settings);
 
 }
diff --git a/src/com/android/settings/accessibility/VibrationSettings.java b/src/com/android/settings/accessibility/VibrationSettings.java
index 88d07a2..32256f4 100644
--- a/src/com/android/settings/accessibility/VibrationSettings.java
+++ b/src/com/android/settings/accessibility/VibrationSettings.java
@@ -51,6 +51,6 @@
         return TAG;
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.accessibility_vibration_settings);
 }
diff --git a/src/com/android/settings/accounts/AccountDashboardFragment.java b/src/com/android/settings/accounts/AccountDashboardFragment.java
index 515008a..04a9701 100644
--- a/src/com/android/settings/accounts/AccountDashboardFragment.java
+++ b/src/com/android/settings/accounts/AccountDashboardFragment.java
@@ -19,7 +19,6 @@
 
 import android.app.settings.SettingsEnums;
 import android.content.Context;
-import android.provider.SearchIndexableResource;
 
 import com.android.settings.R;
 import com.android.settings.SettingsPreferenceFragment;
@@ -32,7 +31,6 @@
 import com.android.settingslib.search.SearchIndexable;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
 @SearchIndexable
@@ -53,7 +51,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.accounts_dashboard_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -83,15 +81,8 @@
         return controllers;
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider() {
-                @Override
-                public List<SearchIndexableResource> getXmlResourcesToIndex(
-                        Context context, boolean enabled) {
-                    final SearchIndexableResource sir = new SearchIndexableResource(context);
-                    sir.xmlResId = R.xml.accounts_dashboard_settings;
-                    return Arrays.asList(sir);
-                }
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider(R.xml.accounts_dashboard_settings) {
 
                 @Override
                 public List<AbstractPreferenceController> createPreferenceControllers(
diff --git a/src/com/android/settings/accounts/ManagedProfileSettings.java b/src/com/android/settings/accounts/ManagedProfileSettings.java
index 1f18d07..e82b72b 100644
--- a/src/com/android/settings/accounts/ManagedProfileSettings.java
+++ b/src/com/android/settings/accounts/ManagedProfileSettings.java
@@ -116,7 +116,7 @@
         return SettingsEnums.ACCOUNTS_WORK_PROFILE_SETTINGS;
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
diff --git a/src/com/android/settings/applications/AppAndNotificationDashboardFragment.java b/src/com/android/settings/applications/AppAndNotificationDashboardFragment.java
index 876c999..8b0f851 100644
--- a/src/com/android/settings/applications/AppAndNotificationDashboardFragment.java
+++ b/src/com/android/settings/applications/AppAndNotificationDashboardFragment.java
@@ -121,7 +121,7 @@
         return controllers;
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableResource> getXmlResourcesToIndex(
diff --git a/src/com/android/settings/applications/assist/ManageAssist.java b/src/com/android/settings/applications/assist/ManageAssist.java
index ae2728d..c3dac26 100644
--- a/src/com/android/settings/applications/assist/ManageAssist.java
+++ b/src/com/android/settings/applications/assist/ManageAssist.java
@@ -18,19 +18,16 @@
 
 import android.app.settings.SettingsEnums;
 import android.content.Context;
-import android.provider.SearchIndexableResource;
 
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.gestures.AssistGestureSettingsPreferenceController;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.search.SearchIndexable;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -49,7 +46,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.manage_assist;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -80,15 +77,8 @@
         return controllers;
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider() {
-                @Override
-                public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
-                        boolean enabled) {
-                    final SearchIndexableResource sir = new SearchIndexableResource(context);
-                    sir.xmlResId = R.xml.manage_assist;
-                    return Arrays.asList(sir);
-                }
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider(R.xml.manage_assist) {
 
                 @Override
                 public List<AbstractPreferenceController> createPreferenceControllers(
diff --git a/src/com/android/settings/applications/defaultapps/AutofillPicker.java b/src/com/android/settings/applications/defaultapps/AutofillPicker.java
index e443f4f..3279031 100644
--- a/src/com/android/settings/applications/defaultapps/AutofillPicker.java
+++ b/src/com/android/settings/applications/defaultapps/AutofillPicker.java
@@ -54,7 +54,7 @@
         return buildPreferenceControllers(context);
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.default_autofill_picker_settings) {
 
                 @Override
diff --git a/src/com/android/settings/applications/managedomainurls/ManageDomainUrls.java b/src/com/android/settings/applications/managedomainurls/ManageDomainUrls.java
index 8b133c7..1176a1b 100644
--- a/src/com/android/settings/applications/managedomainurls/ManageDomainUrls.java
+++ b/src/com/android/settings/applications/managedomainurls/ManageDomainUrls.java
@@ -20,17 +20,12 @@
 
 import android.app.settings.SettingsEnums;
 import android.content.Context;
-import android.provider.SearchIndexableResource;
 
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settingslib.search.SearchIndexable;
 
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * Activity to manage how Android handles URL resolution. Includes both per-app
  * handling as well as system handling for Web Actions.
@@ -53,7 +48,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.manage_domain_url_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -61,6 +56,6 @@
         return SettingsEnums.MANAGE_DOMAIN_URLS;
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.manage_domain_url_settings);
 }
diff --git a/src/com/android/settings/applications/specialaccess/SpecialAccessSettings.java b/src/com/android/settings/applications/specialaccess/SpecialAccessSettings.java
index 6e8ed5a..26f54c9 100644
--- a/src/com/android/settings/applications/specialaccess/SpecialAccessSettings.java
+++ b/src/com/android/settings/applications/specialaccess/SpecialAccessSettings.java
@@ -17,18 +17,12 @@
 package com.android.settings.applications.specialaccess;
 
 import android.app.settings.SettingsEnums;
-import android.content.Context;
-import android.provider.SearchIndexableResource;
 
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settingslib.search.SearchIndexable;
 
-import java.util.ArrayList;
-import java.util.List;
-
 @SearchIndexable
 public class SpecialAccessSettings extends DashboardFragment {
 
@@ -41,7 +35,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.special_access;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -49,6 +43,6 @@
         return SettingsEnums.SPECIAL_ACCESS;
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.special_access);
 }
diff --git a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminSettings.java b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminSettings.java
index 1549ba2..67b10ff 100644
--- a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminSettings.java
+++ b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminSettings.java
@@ -17,18 +17,12 @@
 package com.android.settings.applications.specialaccess.deviceadmin;
 
 import android.app.settings.SettingsEnums;
-import android.content.Context;
-import android.provider.SearchIndexableResource;
 
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settingslib.search.SearchIndexable;
 
-import java.util.ArrayList;
-import java.util.List;
-
 @SearchIndexable
 public class DeviceAdminSettings extends DashboardFragment {
     static final String TAG = "DeviceAdminSettings";
@@ -39,7 +33,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.device_admin_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -47,6 +41,6 @@
         return TAG;
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.device_admin_settings);
 }
diff --git a/src/com/android/settings/applications/specialaccess/pictureinpicture/PictureInPictureSettings.java b/src/com/android/settings/applications/specialaccess/pictureinpicture/PictureInPictureSettings.java
index 3671f05..f90e4e1 100644
--- a/src/com/android/settings/applications/specialaccess/pictureinpicture/PictureInPictureSettings.java
+++ b/src/com/android/settings/applications/specialaccess/pictureinpicture/PictureInPictureSettings.java
@@ -28,7 +28,6 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.provider.SearchIndexableResource;
 import android.util.IconDrawableFactory;
 import android.util.Pair;
 import android.view.View;
@@ -41,7 +40,6 @@
 import com.android.settings.R;
 import com.android.settings.applications.AppInfoBase;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settings.widget.EmptyTextSettings;
 import com.android.settingslib.search.SearchIndexable;
 import com.android.settingslib.widget.apppreference.AppPreference;
@@ -187,7 +185,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.picture_in_picture_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -219,6 +217,6 @@
         return pipApps;
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.picture_in_picture_settings);
 }
diff --git a/src/com/android/settings/applications/specialaccess/premiumsms/PremiumSmsAccess.java b/src/com/android/settings/applications/specialaccess/premiumsms/PremiumSmsAccess.java
index 00c60d5..420dcef 100644
--- a/src/com/android/settings/applications/specialaccess/premiumsms/PremiumSmsAccess.java
+++ b/src/com/android/settings/applications/specialaccess/premiumsms/PremiumSmsAccess.java
@@ -21,7 +21,6 @@
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.os.Bundle;
-import android.provider.SearchIndexableResource;
 import android.view.View;
 
 import androidx.annotation.VisibleForTesting;
@@ -38,7 +37,6 @@
 import com.android.settings.applications.AppStateSmsPremBridge.SmsState;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settings.widget.EmptyTextSettings;
 import com.android.settingslib.applications.ApplicationsState;
 import com.android.settingslib.applications.ApplicationsState.AppEntry;
@@ -49,7 +47,6 @@
 import com.android.settingslib.widget.FooterPreference;
 
 import java.util.ArrayList;
-import java.util.List;
 
 @SearchIndexable
 public class PremiumSmsAccess extends EmptyTextSettings
@@ -94,7 +91,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.premium_sms_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -252,6 +249,6 @@
         }
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.premium_sms_settings);
 }
diff --git a/src/com/android/settings/applications/specialaccess/vrlistener/VrListenerSettings.java b/src/com/android/settings/applications/specialaccess/vrlistener/VrListenerSettings.java
index 38240fc..ce6abc1 100644
--- a/src/com/android/settings/applications/specialaccess/vrlistener/VrListenerSettings.java
+++ b/src/com/android/settings/applications/specialaccess/vrlistener/VrListenerSettings.java
@@ -17,8 +17,6 @@
 
 import android.app.settings.SettingsEnums;
 import android.content.ComponentName;
-import android.content.Context;
-import android.provider.SearchIndexableResource;
 import android.provider.Settings;
 import android.service.vr.VrListenerService;
 
@@ -27,14 +25,10 @@
 import com.android.settings.R;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settings.utils.ManagedServiceSettings;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.search.SearchIndexable;
 
-import java.util.ArrayList;
-import java.util.List;
-
 @SearchIndexable
 public class VrListenerSettings extends ManagedServiceSettings {
     private static final String TAG = VrListenerSettings.class.getSimpleName();
@@ -67,7 +61,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.vr_listeners_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @VisibleForTesting
@@ -84,7 +78,7 @@
                 0);
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.vr_listeners_settings);
 
 }
diff --git a/src/com/android/settings/backup/BackupSettingsFragment.java b/src/com/android/settings/backup/BackupSettingsFragment.java
index 58bfef0..b1f639a 100644
--- a/src/com/android/settings/backup/BackupSettingsFragment.java
+++ b/src/com/android/settings/backup/BackupSettingsFragment.java
@@ -70,7 +70,7 @@
 
     // The intention is to index {@link UserBackupSettingsActivity} instead of the fragments,
     // therefore leaving this index provider empty.
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider();
 
     @Override
diff --git a/src/com/android/settings/backup/PrivacySettings.java b/src/com/android/settings/backup/PrivacySettings.java
index c07fdee..5509c2f 100644
--- a/src/com/android/settings/backup/PrivacySettings.java
+++ b/src/com/android/settings/backup/PrivacySettings.java
@@ -18,16 +18,12 @@
 
 import android.app.settings.SettingsEnums;
 import android.content.Context;
-import android.provider.SearchIndexableResource;
 
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.search.SearchIndexable;
 
-import java.util.Arrays;
-import java.util.List;
-
 @SearchIndexable
 public class PrivacySettings extends DashboardFragment {
     private static final String TAG = "PrivacySettings";
@@ -44,7 +40,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.privacy_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -71,7 +67,7 @@
         }
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.privacy_settings) {
 
                 @Override
diff --git a/src/com/android/settings/backup/UserBackupSettingsActivity.java b/src/com/android/settings/backup/UserBackupSettingsActivity.java
index c2bcd07..31e86e4 100644
--- a/src/com/android/settings/backup/UserBackupSettingsActivity.java
+++ b/src/com/android/settings/backup/UserBackupSettingsActivity.java
@@ -96,7 +96,7 @@
     /**
      * For Search.
      */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 private static final String BACKUP_SEARCH_INDEX_KEY = "Backup";
 
diff --git a/src/com/android/settings/biometrics/face/FaceSettings.java b/src/com/android/settings/biometrics/face/FaceSettings.java
index c55a252..20ab6b8 100644
--- a/src/com/android/settings/biometrics/face/FaceSettings.java
+++ b/src/com/android/settings/biometrics/face/FaceSettings.java
@@ -28,7 +28,6 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.provider.SearchIndexableResource;
 import android.util.Log;
 
 import androidx.preference.Preference;
@@ -94,7 +93,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.security_settings_face;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -270,7 +269,7 @@
         return controllers;
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.security_settings_face) {
 
                 @Override
diff --git a/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java b/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java
index 0d130d9..8509ca0 100644
--- a/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java
+++ b/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceDashboardFragment.java
@@ -89,7 +89,7 @@
     /**
      * For Search.
      */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableResource> getXmlResourcesToIndex(
diff --git a/src/com/android/settings/connecteddevice/BluetoothDashboardFragment.java b/src/com/android/settings/connecteddevice/BluetoothDashboardFragment.java
index 36b2ae8..996e279 100644
--- a/src/com/android/settings/connecteddevice/BluetoothDashboardFragment.java
+++ b/src/com/android/settings/connecteddevice/BluetoothDashboardFragment.java
@@ -101,7 +101,7 @@
     /**
      * For Search.
      */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableRaw> getRawDataToIndex(Context context,
diff --git a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java
index 4cadae9..1452a26 100644
--- a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java
+++ b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.net.Uri;
 import android.provider.DeviceConfig;
-import android.provider.SearchIndexableResource;
 
 import androidx.annotation.VisibleForTesting;
 
@@ -30,9 +29,6 @@
 import com.android.settings.slices.SlicePreferenceController;
 import com.android.settingslib.search.SearchIndexable;
 
-import java.util.Arrays;
-import java.util.List;
-
 @SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
 public class ConnectedDeviceDashboardFragment extends DashboardFragment {
 
@@ -60,7 +56,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.connected_devices;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -79,6 +75,6 @@
     /**
      * For Search.
      */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.connected_devices);
 }
diff --git a/src/com/android/settings/connecteddevice/PreviouslyConnectedDeviceDashboardFragment.java b/src/com/android/settings/connecteddevice/PreviouslyConnectedDeviceDashboardFragment.java
index 709e1dc..b6d2bdd 100644
--- a/src/com/android/settings/connecteddevice/PreviouslyConnectedDeviceDashboardFragment.java
+++ b/src/com/android/settings/connecteddevice/PreviouslyConnectedDeviceDashboardFragment.java
@@ -66,7 +66,7 @@
     /**
      * For Search.
      */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
         @Override
         public List<SearchIndexableRaw> getRawDataToIndex(
diff --git a/src/com/android/settings/connecteddevice/usb/UsbDetailsFragment.java b/src/com/android/settings/connecteddevice/usb/UsbDetailsFragment.java
index bf760f0..4d5c1bc 100644
--- a/src/com/android/settings/connecteddevice/usb/UsbDetailsFragment.java
+++ b/src/com/android/settings/connecteddevice/usb/UsbDetailsFragment.java
@@ -18,19 +18,15 @@
 
 import android.app.settings.SettingsEnums;
 import android.content.Context;
-import android.provider.SearchIndexableResource;
 
 import androidx.annotation.VisibleForTesting;
 
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.search.SearchIndexable;
 
-import com.google.android.collect.Lists;
-
 import java.util.ArrayList;
 import java.util.List;
 
@@ -66,7 +62,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.usb_details_fragment;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -93,7 +89,7 @@
     /**
      * For Search.
      */
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.usb_details_fragment) {
 
                 @Override
diff --git a/src/com/android/settings/dashboard/DashboardFragment.java b/src/com/android/settings/dashboard/DashboardFragment.java
index f2e3d73..178c5a2 100644
--- a/src/com/android/settings/dashboard/DashboardFragment.java
+++ b/src/com/android/settings/dashboard/DashboardFragment.java
@@ -63,6 +63,7 @@
     private final Map<Class, List<AbstractPreferenceController>> mPreferenceControllers =
             new ArrayMap<>();
     private final Set<String> mDashboardTilePrefKeys = new ArraySet<>();
+    private final List<AbstractPreferenceController> mControllers = new ArrayList<>();
 
     private DashboardFeatureProvider mDashboardFeatureProvider;
     private DashboardTilePlaceholderPreferenceController mPlaceholderPreferenceController;
@@ -79,7 +80,6 @@
                 R.array.config_suppress_injected_tile_keys));
         mDashboardFeatureProvider = FeatureFactory.getFactory(context).
                 getDashboardFeatureProvider(context);
-        final List<AbstractPreferenceController> controllers = new ArrayList<>();
         // Load preference controllers from code
         final List<AbstractPreferenceController> controllersFromCode =
                 createPreferenceControllers(context);
@@ -93,9 +93,9 @@
 
         // Add unique controllers to list.
         if (controllersFromCode != null) {
-            controllers.addAll(controllersFromCode);
+            mControllers.addAll(controllersFromCode);
         }
-        controllers.addAll(uniqueControllerFromXml);
+        mControllers.addAll(uniqueControllerFromXml);
 
         // And wire up with lifecycle.
         final Lifecycle lifecycle = getSettingsLifecycle();
@@ -107,12 +107,10 @@
 
         mPlaceholderPreferenceController =
                 new DashboardTilePlaceholderPreferenceController(context);
-        controllers.add(mPlaceholderPreferenceController);
-        for (AbstractPreferenceController controller : controllers) {
+        mControllers.add(mPlaceholderPreferenceController);
+        for (AbstractPreferenceController controller : mControllers) {
             addPreferenceController(controller);
         }
-
-        checkUiBlocker(controllers);
     }
 
     @VisibleForTesting
@@ -122,8 +120,10 @@
                 .stream()
                 .filter(controller -> controller instanceof BasePreferenceController.UiBlocker)
                 .forEach(controller -> {
-                    ((BasePreferenceController) controller).setUiBlockListener(this);
-                    keys.add(controller.getPreferenceKey());
+                    if (controller.isAvailable()) {
+                        ((BasePreferenceController) controller).setUiBlockListener(this);
+                        keys.add(controller.getPreferenceKey());
+                    }
                 });
 
         if (!keys.isEmpty()) {
@@ -157,6 +157,7 @@
 
     @Override
     public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+        checkUiBlocker(mControllers);
         refreshAllPreferences(getLogTag());
     }
 
diff --git a/src/com/android/settings/datausage/BillingCycleSettings.java b/src/com/android/settings/datausage/BillingCycleSettings.java
index e203456..74f06d7 100644
--- a/src/com/android/settings/datausage/BillingCycleSettings.java
+++ b/src/com/android/settings/datausage/BillingCycleSettings.java
@@ -25,7 +25,6 @@
 import android.net.NetworkPolicy;
 import android.net.NetworkTemplate;
 import android.os.Bundle;
-import android.provider.SearchIndexableResource;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -42,13 +41,10 @@
 import com.android.settings.R;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settingslib.NetworkPolicyEditor;
 import com.android.settingslib.net.DataUsageController;
 import com.android.settingslib.search.SearchIndexable;
 
-import java.util.ArrayList;
-import java.util.List;
 import java.util.TimeZone;
 
 @SearchIndexable
@@ -196,7 +192,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.billing_cycle;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -472,7 +468,7 @@
         }
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.billing_cycle) {
 
                 @Override
diff --git a/src/com/android/settings/datausage/DataSaverSummary.java b/src/com/android/settings/datausage/DataSaverSummary.java
index b3a63d7..622fd13 100644
--- a/src/com/android/settings/datausage/DataSaverSummary.java
+++ b/src/com/android/settings/datausage/DataSaverSummary.java
@@ -197,7 +197,7 @@
 
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.data_saver) {
 
                 @Override
diff --git a/src/com/android/settings/datausage/UnrestrictedDataAccess.java b/src/com/android/settings/datausage/UnrestrictedDataAccess.java
index cbc148c..e8da102 100644
--- a/src/com/android/settings/datausage/UnrestrictedDataAccess.java
+++ b/src/com/android/settings/datausage/UnrestrictedDataAccess.java
@@ -17,7 +17,6 @@
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.os.Bundle;
-import android.provider.SearchIndexableResource;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
@@ -26,14 +25,10 @@
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settingslib.applications.ApplicationsState;
 import com.android.settingslib.applications.ApplicationsState.AppFilter;
 import com.android.settingslib.search.SearchIndexable;
 
-import java.util.ArrayList;
-import java.util.List;
-
 @SearchIndexable
 public class UnrestrictedDataAccess extends DashboardFragment {
 
@@ -114,9 +109,9 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.unrestricted_data_access_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.unrestricted_data_access_settings);
 }
diff --git a/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java b/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java
index 0bc9dc9..e947f5f 100644
--- a/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java
+++ b/src/com/android/settings/deletionhelper/AutomaticStorageManagerSettings.java
@@ -163,7 +163,7 @@
     }
 
     /** For Search. */
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 protected boolean isPageSearchEnabled(Context context) {
diff --git a/src/com/android/settings/development/CameraLaserSensorPreferenceController.java b/src/com/android/settings/development/CameraLaserSensorPreferenceController.java
index ec0ca24..6717280 100644
--- a/src/com/android/settings/development/CameraLaserSensorPreferenceController.java
+++ b/src/com/android/settings/development/CameraLaserSensorPreferenceController.java
@@ -75,12 +75,9 @@
         ((SwitchPreference) mPreference).setChecked(enabled);
     }
 
-    @Override
-    protected void onDeveloperOptionsSwitchDisabled() {
-        super.onDeveloperOptionsSwitchDisabled();
-        SystemProperties.set(PROPERTY_CAMERA_LASER_SENSOR, Integer.toString(DISABLED));
-        ((SwitchPreference) mPreference).setChecked(false);
-    }
+    // There should be no impact on the current
+    // laser sensor settings in case the developer
+    // settings switch is turned on or off!
 
     private boolean isLaserSensorEnabled() {
         final String prop = SystemProperties.get(PROPERTY_CAMERA_LASER_SENSOR,
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
index 0e7873c..4be90d5 100644
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -521,7 +521,7 @@
     /**
      * For Search.
      */
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.development_settings) {
 
                 @Override
diff --git a/src/com/android/settings/development/featureflags/FeatureFlagsDashboard.java b/src/com/android/settings/development/featureflags/FeatureFlagsDashboard.java
index f0d7f1c..d5f1106 100644
--- a/src/com/android/settings/development/featureflags/FeatureFlagsDashboard.java
+++ b/src/com/android/settings/development/featureflags/FeatureFlagsDashboard.java
@@ -60,7 +60,7 @@
         return 0;
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
diff --git a/src/com/android/settings/development/gamedriver/GameDriverDashboard.java b/src/com/android/settings/development/gamedriver/GameDriverDashboard.java
index e1f7908..91057e8 100644
--- a/src/com/android/settings/development/gamedriver/GameDriverDashboard.java
+++ b/src/com/android/settings/development/gamedriver/GameDriverDashboard.java
@@ -75,7 +75,7 @@
         switchBar.show();
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.game_driver_settings) {
 
                 @Override
diff --git a/src/com/android/settings/development/qstile/DevelopmentTileConfigFragment.java b/src/com/android/settings/development/qstile/DevelopmentTileConfigFragment.java
index 82d01ac..e266d9c 100644
--- a/src/com/android/settings/development/qstile/DevelopmentTileConfigFragment.java
+++ b/src/com/android/settings/development/qstile/DevelopmentTileConfigFragment.java
@@ -49,7 +49,7 @@
         return SettingsEnums.DEVELOPMENT_QS_TILE_CONFIG;
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.development_tile_settings) {
 
                 @Override
diff --git a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
index 9dab2bd..e11c786 100644
--- a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
+++ b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
@@ -226,7 +226,7 @@
     /**
      * For Search.
      */
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableResource> getXmlResourcesToIndex(
diff --git a/src/com/android/settings/deviceinfo/StorageSettings.java b/src/com/android/settings/deviceinfo/StorageSettings.java
index e791168..1bafd51 100644
--- a/src/com/android/settings/deviceinfo/StorageSettings.java
+++ b/src/com/android/settings/deviceinfo/StorageSettings.java
@@ -542,7 +542,7 @@
     }
 
     /** Enable indexing of searchable data */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableRaw> getRawDataToIndex(
diff --git a/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java b/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java
index 8cbe05f..b2e2980 100644
--- a/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java
+++ b/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java
@@ -173,7 +173,7 @@
     /**
      * For Search.
      */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.my_device_info) {
 
                 @Override
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionSettings.java b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionSettings.java
index 0971ba8..7a722f9 100644
--- a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionSettings.java
+++ b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionSettings.java
@@ -47,6 +47,6 @@
         return SettingsEnums.DIALOG_FIRMWARE_VERSION;
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.firmware_version);
 }
diff --git a/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoFragment.java b/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoFragment.java
index aadb0d5..fd2dcc5 100644
--- a/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoFragment.java
+++ b/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoFragment.java
@@ -50,7 +50,7 @@
         return TAG;
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.hardware_info) {
 
                 @Override
diff --git a/src/com/android/settings/display/AdaptiveSleepSettings.java b/src/com/android/settings/display/AdaptiveSleepSettings.java
index ff955c7..7937480 100644
--- a/src/com/android/settings/display/AdaptiveSleepSettings.java
+++ b/src/com/android/settings/display/AdaptiveSleepSettings.java
@@ -22,7 +22,6 @@
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.os.Bundle;
-import android.provider.SearchIndexableResource;
 
 import androidx.preference.Preference;
 
@@ -30,10 +29,6 @@
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.search.SearchIndexable;
-import com.android.settingslib.widget.FooterPreference;
-
-import java.util.Arrays;
-import java.util.List;
 
 @SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
 public class AdaptiveSleepSettings extends DashboardFragment {
@@ -59,7 +54,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.adaptive_sleep_detail;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -77,6 +72,6 @@
         return R.string.help_url_adaptive_sleep;
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.adaptive_sleep_detail);
 }
diff --git a/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java b/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java
index 6a9e9fc..a0b1f44 100644
--- a/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java
+++ b/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java
@@ -17,6 +17,7 @@
 
 import android.content.Context;
 import android.hardware.display.AmbientDisplayConfiguration;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.TextUtils;
@@ -29,6 +30,7 @@
     private final int OFF = 0;
 
     private static final int MY_USER = UserHandle.myUserId();
+    private static final String PROP_AWARE_AVAILABLE = "ro.vendor.aware_available";
 
     private AmbientDisplayConfiguration mConfig;
     private OnPreferenceChangedCallback mCallback;
@@ -43,7 +45,9 @@
 
     @Override
     public int getAvailabilityStatus() {
-        return isAvailable(getConfig()) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+        return isAvailable(getConfig())
+                && !SystemProperties.getBoolean(PROP_AWARE_AVAILABLE, false) ?
+                AVAILABLE : UNSUPPORTED_ON_DEVICE;
     }
 
     @Override
diff --git a/src/com/android/settings/display/AutoBrightnessSettings.java b/src/com/android/settings/display/AutoBrightnessSettings.java
index 1dd1d62..38de253 100644
--- a/src/com/android/settings/display/AutoBrightnessSettings.java
+++ b/src/com/android/settings/display/AutoBrightnessSettings.java
@@ -17,18 +17,13 @@
 package com.android.settings.display;
 
 import android.app.settings.SettingsEnums;
-import android.content.Context;
 import android.os.Bundle;
-import android.provider.SearchIndexableResource;
 
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.search.SearchIndexable;
 
-import java.util.Arrays;
-import java.util.List;
-
 @SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
 public class AutoBrightnessSettings extends DashboardFragment {
 
@@ -41,7 +36,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.auto_brightness_detail;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -59,14 +54,6 @@
         return R.string.help_url_auto_brightness;
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider() {
-                @Override
-                public List<SearchIndexableResource> getXmlResourcesToIndex(
-                        Context context, boolean enabled) {
-                    final SearchIndexableResource sir = new SearchIndexableResource(context);
-                    sir.xmlResId = R.xml.auto_brightness_detail;
-                    return Arrays.asList(sir);
-                }
-            };
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider(R.xml.auto_brightness_detail);
 }
diff --git a/src/com/android/settings/display/ColorModePreferenceFragment.java b/src/com/android/settings/display/ColorModePreferenceFragment.java
index 598d9c1..a977bc7 100644
--- a/src/com/android/settings/display/ColorModePreferenceFragment.java
+++ b/src/com/android/settings/display/ColorModePreferenceFragment.java
@@ -22,22 +22,19 @@
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Looper;
-import android.provider.SearchIndexableResource;
-
 import android.provider.Settings.Secure;
+
 import androidx.annotation.VisibleForTesting;
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settings.widget.RadioButtonPickerFragment;
 import com.android.settingslib.search.SearchIndexable;
 import com.android.settingslib.widget.CandidateInfo;
 import com.android.settingslib.widget.LayoutPreference;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
 @SuppressWarnings("WeakerAccess")
@@ -93,7 +90,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.color_mode_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @VisibleForTesting
@@ -204,15 +201,8 @@
         }
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider() {
-                @Override
-                public List<SearchIndexableResource> getXmlResourcesToIndex(
-                        Context context, boolean enabled) {
-                    final SearchIndexableResource sir = new SearchIndexableResource(context);
-                    sir.xmlResId = R.xml.color_mode_settings;
-                    return Arrays.asList(sir);
-                }
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider(R.xml.color_mode_settings) {
 
                 @Override
                 protected boolean isPageSearchEnabled(Context context) {
diff --git a/src/com/android/settings/display/NightDisplaySettings.java b/src/com/android/settings/display/NightDisplaySettings.java
index 490e4fa..fa69d70 100644
--- a/src/com/android/settings/display/NightDisplaySettings.java
+++ b/src/com/android/settings/display/NightDisplaySettings.java
@@ -23,19 +23,15 @@
 import android.hardware.display.ColorDisplayManager;
 import android.hardware.display.NightDisplayListener;
 import android.os.Bundle;
-import android.provider.SearchIndexableResource;
 
 import androidx.preference.Preference;
 
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settingslib.search.SearchIndexable;
 
 import java.time.LocalTime;
-import java.util.ArrayList;
-import java.util.List;
 
 /**
  * Settings screen for Night display.
@@ -157,7 +153,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.night_display_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -175,7 +171,7 @@
         return TAG;
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.night_display_settings) {
 
                 @Override
diff --git a/src/com/android/settings/display/ScreenZoomSettings.java b/src/com/android/settings/display/ScreenZoomSettings.java
index 13c76ce..d0a19ee 100644
--- a/src/com/android/settings/display/ScreenZoomSettings.java
+++ b/src/com/android/settings/display/ScreenZoomSettings.java
@@ -118,7 +118,7 @@
     }
 
     /** Index provider used to expose this fragment in search. */
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableRaw> getRawDataToIndex(Context context,
diff --git a/src/com/android/settings/display/ToggleFontSizePreferenceFragment.java b/src/com/android/settings/display/ToggleFontSizePreferenceFragment.java
index 49177a0..98d6432 100644
--- a/src/com/android/settings/display/ToggleFontSizePreferenceFragment.java
+++ b/src/com/android/settings/display/ToggleFontSizePreferenceFragment.java
@@ -115,7 +115,7 @@
         return indices.length - 1;
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableRaw> getRawDataToIndex(Context context,
diff --git a/src/com/android/settings/dream/DreamSettings.java b/src/com/android/settings/dream/DreamSettings.java
index 5b1a843..5bbf910 100644
--- a/src/com/android/settings/dream/DreamSettings.java
+++ b/src/com/android/settings/dream/DreamSettings.java
@@ -23,7 +23,6 @@
 
 import android.app.settings.SettingsEnums;
 import android.content.Context;
-import android.provider.SearchIndexableResource;
 
 import androidx.annotation.VisibleForTesting;
 
@@ -36,7 +35,6 @@
 import com.android.settingslib.search.SearchIndexable;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
 @SearchIndexable
@@ -98,7 +96,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.dream_fragment_overview;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -137,7 +135,7 @@
         return controllers;
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER
             = new BaseSearchIndexProvider(R.xml.dream_fragment_overview) {
 
         @Override
diff --git a/src/com/android/settings/enterprise/EnterprisePrivacySettings.java b/src/com/android/settings/enterprise/EnterprisePrivacySettings.java
index 1490feb..dd0a9ce 100644
--- a/src/com/android/settings/enterprise/EnterprisePrivacySettings.java
+++ b/src/com/android/settings/enterprise/EnterprisePrivacySettings.java
@@ -98,7 +98,7 @@
                 .hasDeviceOwner();
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.enterprise_privacy_settings) {
                 @Override
                 protected boolean isPageSearchEnabled(Context context) {
diff --git a/src/com/android/settings/flashlight/FlashlightHandleActivity.java b/src/com/android/settings/flashlight/FlashlightHandleActivity.java
index 0c50f91..075c39b 100644
--- a/src/com/android/settings/flashlight/FlashlightHandleActivity.java
+++ b/src/com/android/settings/flashlight/FlashlightHandleActivity.java
@@ -53,7 +53,7 @@
         finish();
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
 
                 @Override
diff --git a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java
index 669d7ed..befede4 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java
@@ -166,7 +166,7 @@
         }
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableResource> getXmlResourcesToIndex(
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index 42ea52b..08d70aa 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -24,7 +24,6 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
-import android.provider.SearchIndexableResource;
 import android.provider.Settings.Global;
 import android.text.format.Formatter;
 import android.view.Menu;
@@ -54,7 +53,6 @@
 import com.android.settingslib.utils.StringUtil;
 import com.android.settingslib.widget.LayoutPreference;
 
-import java.util.Collections;
 import java.util.List;
 
 /**
@@ -254,7 +252,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.power_usage_summary;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -395,6 +393,6 @@
     }
 
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.power_usage_summary);
 }
diff --git a/src/com/android/settings/fuelgauge/SmartBatterySettings.java b/src/com/android/settings/fuelgauge/SmartBatterySettings.java
index 130c1f2..e9d637c 100644
--- a/src/com/android/settings/fuelgauge/SmartBatterySettings.java
+++ b/src/com/android/settings/fuelgauge/SmartBatterySettings.java
@@ -78,7 +78,7 @@
         return controllers;
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableResource> getXmlResourcesToIndex(
diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettings.java b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettings.java
index 6216917..2b28391 100644
--- a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettings.java
+++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettings.java
@@ -17,8 +17,6 @@
 package com.android.settings.fuelgauge.batterysaver;
 
 import android.app.settings.SettingsEnums;
-import android.content.Context;
-import android.provider.SearchIndexableResource;
 import android.text.Annotation;
 import android.text.Spannable;
 import android.text.SpannableStringBuilder;
@@ -34,14 +32,10 @@
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settingslib.HelpUtils;
 import com.android.settingslib.search.SearchIndexable;
 import com.android.settingslib.widget.FooterPreference;
 
-import java.util.Arrays;
-import java.util.List;
-
 /**
  * Battery saver settings page
  */
@@ -65,7 +59,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.battery_saver_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -81,16 +75,8 @@
     /**
      * For Search.
      */
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider() {
-                @Override
-                public List<SearchIndexableResource> getXmlResourcesToIndex(
-                        Context context, boolean enabled) {
-                    final SearchIndexableResource sir = new SearchIndexableResource(context);
-                    sir.xmlResId = R.xml.battery_saver_settings;
-                    return Arrays.asList(sir);
-                }
-            };
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider(R.xml.battery_saver_settings);
 
     // Updates the footer for this page.
     @VisibleForTesting
diff --git a/src/com/android/settings/gestures/AssistGestureSettings.java b/src/com/android/settings/gestures/AssistGestureSettings.java
index b67fd65..f56416c 100644
--- a/src/com/android/settings/gestures/AssistGestureSettings.java
+++ b/src/com/android/settings/gestures/AssistGestureSettings.java
@@ -66,7 +66,7 @@
         return controllers;
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableResource> getXmlResourcesToIndex(
diff --git a/src/com/android/settings/gestures/DoubleTapPowerSettings.java b/src/com/android/settings/gestures/DoubleTapPowerSettings.java
index 628a213..466fe91 100644
--- a/src/com/android/settings/gestures/DoubleTapPowerSettings.java
+++ b/src/com/android/settings/gestures/DoubleTapPowerSettings.java
@@ -63,6 +63,6 @@
         return R.xml.double_tap_power_settings;
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.double_tap_power_settings);
 }
diff --git a/src/com/android/settings/gestures/DoubleTapScreenSettings.java b/src/com/android/settings/gestures/DoubleTapScreenSettings.java
index 9a21fed..7c7a02f 100644
--- a/src/com/android/settings/gestures/DoubleTapScreenSettings.java
+++ b/src/com/android/settings/gestures/DoubleTapScreenSettings.java
@@ -72,6 +72,6 @@
         return R.string.help_url_double_tap_screen;
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.double_tap_screen_settings);
 }
diff --git a/src/com/android/settings/gestures/DoubleTwistGestureSettings.java b/src/com/android/settings/gestures/DoubleTwistGestureSettings.java
index 3481929..9ea7180 100644
--- a/src/com/android/settings/gestures/DoubleTwistGestureSettings.java
+++ b/src/com/android/settings/gestures/DoubleTwistGestureSettings.java
@@ -63,7 +63,7 @@
         return R.xml.double_twist_gesture_settings;
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableResource> getXmlResourcesToIndex(
diff --git a/src/com/android/settings/gestures/GestureSettings.java b/src/com/android/settings/gestures/GestureSettings.java
index db402cc..763efaf 100644
--- a/src/com/android/settings/gestures/GestureSettings.java
+++ b/src/com/android/settings/gestures/GestureSettings.java
@@ -66,7 +66,7 @@
         return mAmbientDisplayConfig;
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableResource> getXmlResourcesToIndex(
diff --git a/src/com/android/settings/gestures/GlobalActionsPanelSettings.java b/src/com/android/settings/gestures/GlobalActionsPanelSettings.java
index fee793f..34db20e 100644
--- a/src/com/android/settings/gestures/GlobalActionsPanelSettings.java
+++ b/src/com/android/settings/gestures/GlobalActionsPanelSettings.java
@@ -17,17 +17,12 @@
 package com.android.settings.gestures;
 
 import android.app.settings.SettingsEnums;
-import android.content.Context;
-import android.provider.SearchIndexableResource;
 
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.search.SearchIndexable;
 
-import java.util.Arrays;
-import java.util.List;
-
 @SearchIndexable
 public class GlobalActionsPanelSettings extends DashboardFragment {
 
@@ -45,9 +40,9 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.global_actions_panel_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
         new BaseSearchIndexProvider(R.xml.global_actions_panel_settings);
 }
diff --git a/src/com/android/settings/gestures/PickupGestureSettings.java b/src/com/android/settings/gestures/PickupGestureSettings.java
index caf0d7d..6c7c587 100644
--- a/src/com/android/settings/gestures/PickupGestureSettings.java
+++ b/src/com/android/settings/gestures/PickupGestureSettings.java
@@ -20,7 +20,6 @@
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.hardware.display.AmbientDisplayConfiguration;
-import android.provider.SearchIndexableResource;
 
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
@@ -29,9 +28,6 @@
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.search.SearchIndexable;
 
-import java.util.Arrays;
-import java.util.List;
-
 @SearchIndexable
 public class PickupGestureSettings extends DashboardFragment {
 
@@ -64,7 +60,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.pick_up_gesture_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -72,7 +68,7 @@
         return R.string.help_url_pickup_gesture;
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.pick_up_gesture_settings);
 
 }
diff --git a/src/com/android/settings/gestures/PreventRingingGestureSettings.java b/src/com/android/settings/gestures/PreventRingingGestureSettings.java
index 9740a3f..d327b71 100644
--- a/src/com/android/settings/gestures/PreventRingingGestureSettings.java
+++ b/src/com/android/settings/gestures/PreventRingingGestureSettings.java
@@ -74,7 +74,7 @@
         return R.string.help_uri_prevent_ringing_gesture;
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.prevent_ringing_gesture_settings) {
 
                 @Override
diff --git a/src/com/android/settings/gestures/SwipeToNotificationSettings.java b/src/com/android/settings/gestures/SwipeToNotificationSettings.java
index 90ac4e6..caa760a 100644
--- a/src/com/android/settings/gestures/SwipeToNotificationSettings.java
+++ b/src/com/android/settings/gestures/SwipeToNotificationSettings.java
@@ -19,7 +19,6 @@
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.content.SharedPreferences;
-import android.provider.SearchIndexableResource;
 
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
@@ -28,9 +27,6 @@
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.search.SearchIndexable;
 
-import java.util.Arrays;
-import java.util.List;
-
 @SearchIndexable
 public class SwipeToNotificationSettings extends DashboardFragment {
 
@@ -60,10 +56,10 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.swipe_to_notification_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.swipe_to_notification_settings) {
 
                 @Override
diff --git a/src/com/android/settings/gestures/SystemNavigationGestureSettings.java b/src/com/android/settings/gestures/SystemNavigationGestureSettings.java
index 54064ad..79379ef 100644
--- a/src/com/android/settings/gestures/SystemNavigationGestureSettings.java
+++ b/src/com/android/settings/gestures/SystemNavigationGestureSettings.java
@@ -31,7 +31,6 @@
 import android.content.SharedPreferences;
 import android.content.om.IOverlayManager;
 import android.content.om.OverlayInfo;
-import android.graphics.drawable.Drawable;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.provider.SearchIndexableResource;
@@ -48,6 +47,7 @@
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
+import com.android.settings.utils.CandidateInfoExtra;
 import com.android.settings.widget.RadioButtonPickerFragment;
 import com.android.settings.widget.RadioButtonPreferenceWithExtraWidget;
 import com.android.settings.widget.VideoPreference;
@@ -150,12 +150,12 @@
     @Override
     public void bindPreferenceExtra(RadioButtonPreference pref,
             String key, CandidateInfo info, String defaultKey, String systemDefaultKey) {
-        if (!(info instanceof NavModeCandidateInfo)
+        if (!(info instanceof CandidateInfoExtra)
                 || !(pref instanceof RadioButtonPreferenceWithExtraWidget)) {
             return;
         }
 
-        pref.setSummary(((NavModeCandidateInfo) info).loadSummary());
+        pref.setSummary(((CandidateInfoExtra) info).loadSummary());
 
         RadioButtonPreferenceWithExtraWidget p = (RadioButtonPreferenceWithExtraWidget) pref;
         if (info.getKey() == KEY_SYSTEM_NAV_GESTURAL) {
@@ -175,25 +175,25 @@
     @Override
     protected List<? extends CandidateInfo> getCandidates() {
         final Context c = getContext();
-        List<NavModeCandidateInfo> candidates = new ArrayList<>();
+        List<CandidateInfoExtra> candidates = new ArrayList<>();
 
         if (SystemNavigationPreferenceController.isOverlayPackageAvailable(c,
                 NAV_BAR_MODE_GESTURAL_OVERLAY)) {
-            candidates.add(new NavModeCandidateInfo(
+            candidates.add(new CandidateInfoExtra(
                     c.getText(R.string.edge_to_edge_navigation_title),
                     c.getText(R.string.edge_to_edge_navigation_summary),
                     KEY_SYSTEM_NAV_GESTURAL, true /* enabled */));
         }
         if (SystemNavigationPreferenceController.isOverlayPackageAvailable(c,
                 NAV_BAR_MODE_2BUTTON_OVERLAY)) {
-            candidates.add(new NavModeCandidateInfo(
+            candidates.add(new CandidateInfoExtra(
                     c.getText(R.string.swipe_up_to_switch_apps_title),
                     c.getText(R.string.swipe_up_to_switch_apps_summary),
                     KEY_SYSTEM_NAV_2BUTTONS, true /* enabled */));
         }
         if (SystemNavigationPreferenceController.isOverlayPackageAvailable(c,
                 NAV_BAR_MODE_3BUTTON_OVERLAY)) {
-            candidates.add(new NavModeCandidateInfo(
+            candidates.add(new CandidateInfoExtra(
                     c.getText(R.string.legacy_navigation_title),
                     c.getText(R.string.legacy_navigation_summary),
                     KEY_SYSTEM_NAV_3BUTTONS, true /* enabled */));
@@ -325,40 +325,7 @@
                 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, 0) == 1;
     }
 
-    static class NavModeCandidateInfo extends CandidateInfo {
-        private final CharSequence mLabel;
-        private final CharSequence mSummary;
-        private final String mKey;
-
-        NavModeCandidateInfo(CharSequence label, CharSequence summary, String key,
-                boolean enabled) {
-            super(enabled);
-            mLabel = label;
-            mSummary = summary;
-            mKey = key;
-        }
-
-        @Override
-        public CharSequence loadLabel() {
-            return mLabel;
-        }
-
-        public CharSequence loadSummary() {
-            return mSummary;
-        }
-
-        @Override
-        public Drawable loadIcon() {
-            return null;
-        }
-
-        @Override
-        public String getKey() {
-            return mKey;
-        }
-    }
-
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.system_navigation_gesture_settings) {
 
                 @Override
diff --git a/src/com/android/settings/gestures/TapScreenGestureSettings.java b/src/com/android/settings/gestures/TapScreenGestureSettings.java
index bd09d55..a1a8e42 100644
--- a/src/com/android/settings/gestures/TapScreenGestureSettings.java
+++ b/src/com/android/settings/gestures/TapScreenGestureSettings.java
@@ -67,6 +67,6 @@
         return R.xml.tap_screen_gesture_settings;
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.tap_screen_gesture_settings);
 }
diff --git a/src/com/android/settings/homepage/TopLevelSettings.java b/src/com/android/settings/homepage/TopLevelSettings.java
index ce53e52..cbae863 100644
--- a/src/com/android/settings/homepage/TopLevelSettings.java
+++ b/src/com/android/settings/homepage/TopLevelSettings.java
@@ -22,7 +22,6 @@
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.os.Bundle;
-import android.provider.SearchIndexableResource;
 
 import androidx.fragment.app.Fragment;
 import androidx.preference.Preference;
@@ -36,9 +35,6 @@
 import com.android.settingslib.core.instrumentation.Instrumentable;
 import com.android.settingslib.search.SearchIndexable;
 
-import java.util.Arrays;
-import java.util.List;
-
 @SearchIndexable(forTarget = MOBILE)
 public class TopLevelSettings extends DashboardFragment implements
         PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
@@ -54,7 +50,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.top_level_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -103,7 +99,7 @@
                 .getBoolean(R.bool.config_force_rounded_icon_TopLevelSettings);
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.top_level_settings) {
 
                 @Override
diff --git a/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCard.java b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCard.java
index d11f771..facfcde 100644
--- a/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCard.java
+++ b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCard.java
@@ -17,16 +17,19 @@
 package com.android.settings.homepage.contextualcards.legacysuggestion;
 
 import android.app.PendingIntent;
+import android.service.settings.suggestions.Suggestion;
 
 import com.android.settings.homepage.contextualcards.ContextualCard;
 
 public class LegacySuggestionContextualCard extends ContextualCard {
 
     private final PendingIntent mPendingIntent;
+    private final Suggestion mSuggestion;
 
     public LegacySuggestionContextualCard(Builder builder) {
         super(builder);
         mPendingIntent = builder.mPendingIntent;
+        mSuggestion = builder.mSuggestion;
     }
 
     @Override
@@ -38,15 +41,25 @@
         return mPendingIntent;
     }
 
+    public Suggestion getSuggestion() {
+        return mSuggestion;
+    }
+
     public static class Builder extends ContextualCard.Builder {
 
         private PendingIntent mPendingIntent;
+        private Suggestion mSuggestion;
 
         public Builder setPendingIntent(PendingIntent pendingIntent) {
             mPendingIntent = pendingIntent;
             return this;
         }
 
+        public Builder setSuggestion(Suggestion suggestion) {
+            mSuggestion = suggestion;
+            return this;
+        }
+
         @Override
         public Builder setCardType(int cardType) {
             throw new IllegalArgumentException(
diff --git a/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardController.java b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardController.java
index 3b0b46d..834aa8e 100644
--- a/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardController.java
+++ b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardController.java
@@ -47,6 +47,9 @@
     private static final String TAG = "LegacySuggestCardCtrl";
 
     @VisibleForTesting
+    final List<ContextualCard> mSuggestions;
+
+    @VisibleForTesting
     SuggestionController mSuggestionController;
 
     private ContextualCardUpdateListener mCardUpdateListener;
@@ -55,6 +58,7 @@
 
     public LegacySuggestionContextualCardController(Context context) {
         mContext = context;
+        mSuggestions = new ArrayList<>();
         if (!mContext.getResources().getBoolean(R.bool.config_use_legacy_suggestion)) {
             Log.w(TAG, "Legacy suggestion contextual card disabled, skipping.");
             return;
@@ -88,7 +92,10 @@
 
     @Override
     public void onDismissed(ContextualCard card) {
-
+        mSuggestionController
+                .dismissSuggestions(((LegacySuggestionContextualCard)card).getSuggestion());
+        mSuggestions.remove(card);
+        updateAdapter();
     }
 
     @Override
@@ -144,6 +151,7 @@
                     }
                     cardBuilder
                             .setPendingIntent(suggestion.getPendingIntent())
+                            .setSuggestion(suggestion)
                             .setName(suggestion.getId())
                             .setTitleText(suggestion.getTitle().toString())
                             .setSummaryText(suggestion.getSummary().toString())
@@ -153,12 +161,16 @@
                 }
             }
 
-            // Update adapter
-            final Map<Integer, List<ContextualCard>> suggestionCards = new ArrayMap<>();
-            suggestionCards.put(ContextualCard.CardType.LEGACY_SUGGESTION, cards);
-            ThreadUtils.postOnMainThread(
-                    () -> mCardUpdateListener.onContextualCardUpdated(suggestionCards));
-
+            mSuggestions.clear();
+            mSuggestions.addAll(cards);
+            updateAdapter();
         });
     }
+
+    private void updateAdapter() {
+        final Map<Integer, List<ContextualCard>> suggestionCards = new ArrayMap<>();
+        suggestionCards.put(ContextualCard.CardType.LEGACY_SUGGESTION, mSuggestions);
+        ThreadUtils.postOnMainThread(
+                () -> mCardUpdateListener.onContextualCardUpdated(suggestionCards));
+    }
 }
diff --git a/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRenderer.java b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRenderer.java
index 3bccabc..395e814 100644
--- a/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRenderer.java
+++ b/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRenderer.java
@@ -26,6 +26,7 @@
 
 import com.android.settings.R;
 import com.android.settings.homepage.contextualcards.ContextualCard;
+import com.android.settings.homepage.contextualcards.ContextualCardController;
 import com.android.settings.homepage.contextualcards.ContextualCardRenderer;
 import com.android.settings.homepage.contextualcards.ControllerRendererPool;
 
@@ -51,12 +52,13 @@
     @Override
     public void bindView(RecyclerView.ViewHolder holder, ContextualCard card) {
         final LegacySuggestionViewHolder vh = (LegacySuggestionViewHolder) holder;
+        final ContextualCardController controller = mControllerRendererPool
+                .getController(mContext, card.getCardType());
         vh.icon.setImageDrawable(card.getIconDrawable());
         vh.title.setText(card.getTitleText());
         vh.summary.setText(card.getSummaryText());
-        vh.itemView.setOnClickListener(v ->
-                mControllerRendererPool.getController(mContext,
-                        card.getCardType()).onPrimaryClick(card));
+        vh.itemView.setOnClickListener(v -> controller.onPrimaryClick(card));
+        vh.closeButton.setOnClickListener(v -> controller.onDismissed(card));
     }
 
     private static class LegacySuggestionViewHolder extends RecyclerView.ViewHolder {
@@ -64,12 +66,14 @@
         public final ImageView icon;
         public final TextView title;
         public final TextView summary;
+        public final View closeButton;
 
         public LegacySuggestionViewHolder(View itemView) {
             super(itemView);
             icon = itemView.findViewById(android.R.id.icon);
             title = itemView.findViewById(android.R.id.title);
             summary = itemView.findViewById(android.R.id.summary);
+            closeButton = itemView.findViewById(R.id.close_button);
         }
     }
 }
diff --git a/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java b/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java
index c37d2b5..686558c 100644
--- a/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java
+++ b/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java
@@ -113,7 +113,7 @@
         }
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
diff --git a/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java b/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java
index 119571d..c154f61 100644
--- a/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java
+++ b/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java
@@ -332,7 +332,7 @@
         }
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableResource> getXmlResourcesToIndex(
diff --git a/src/com/android/settings/inputmethod/UserDictionaryList.java b/src/com/android/settings/inputmethod/UserDictionaryList.java
index 497b380..310c1e8 100644
--- a/src/com/android/settings/inputmethod/UserDictionaryList.java
+++ b/src/com/android/settings/inputmethod/UserDictionaryList.java
@@ -75,7 +75,7 @@
         return TAG;
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
diff --git a/src/com/android/settings/inputmethod/VirtualKeyboardFragment.java b/src/com/android/settings/inputmethod/VirtualKeyboardFragment.java
index 61dbd31..dfdb50a 100644
--- a/src/com/android/settings/inputmethod/VirtualKeyboardFragment.java
+++ b/src/com/android/settings/inputmethod/VirtualKeyboardFragment.java
@@ -49,7 +49,7 @@
         return SettingsEnums.VIRTUAL_KEYBOARDS;
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableResource> getXmlResourcesToIndex(
diff --git a/src/com/android/settings/language/LanguageAndInputSettings.java b/src/com/android/settings/language/LanguageAndInputSettings.java
index 771d718..45caeb5 100644
--- a/src/com/android/settings/language/LanguageAndInputSettings.java
+++ b/src/com/android/settings/language/LanguageAndInputSettings.java
@@ -22,7 +22,6 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.pm.PackageManager;
-import android.provider.SearchIndexableResource;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.view.inputmethod.InputMethodInfo;
@@ -81,7 +80,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.language_and_input;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -161,7 +160,7 @@
     public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
             = (activity, summaryLoader) -> new SummaryProvider(activity, summaryLoader);
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.language_and_input) {
 
                 @Override
diff --git a/src/com/android/settings/location/LocationSettings.java b/src/com/android/settings/location/LocationSettings.java
index d36eaad..d455a92 100644
--- a/src/com/android/settings/location/LocationSettings.java
+++ b/src/com/android/settings/location/LocationSettings.java
@@ -20,7 +20,6 @@
 import android.content.Context;
 import android.location.SettingInjectorService;
 import android.os.Bundle;
-import android.provider.SearchIndexableResource;
 
 import androidx.preference.Preference;
 import androidx.preference.PreferenceGroup;
@@ -29,7 +28,6 @@
 import com.android.settings.SettingsActivity;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settings.widget.SwitchBar;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -37,7 +35,6 @@
 import com.android.settingslib.search.SearchIndexable;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
@@ -86,7 +83,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.location_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -128,7 +125,7 @@
     /**
      * For Search.
      */
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.location_settings) {
 
                 @Override
diff --git a/src/com/android/settings/location/RecentLocationRequestSeeAllFragment.java b/src/com/android/settings/location/RecentLocationRequestSeeAllFragment.java
index b704cb4..c31a783 100644
--- a/src/com/android/settings/location/RecentLocationRequestSeeAllFragment.java
+++ b/src/com/android/settings/location/RecentLocationRequestSeeAllFragment.java
@@ -16,7 +16,6 @@
 package com.android.settings.location;
 
 import android.content.Context;
-import android.provider.SearchIndexableResource;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
@@ -25,13 +24,11 @@
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.search.SearchIndexable;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
 /** Dashboard Fragment to display all recent location requests, sorted by recency. */
@@ -56,7 +53,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.location_recent_requests_see_all;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -105,7 +102,7 @@
     /**
      * For Search.
      */
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.location_recent_requests_see_all) {
 
                 @Override
diff --git a/src/com/android/settings/location/ScanningSettings.java b/src/com/android/settings/location/ScanningSettings.java
index c031f4d..b95f976 100644
--- a/src/com/android/settings/location/ScanningSettings.java
+++ b/src/com/android/settings/location/ScanningSettings.java
@@ -18,17 +18,14 @@
 
 import android.app.settings.SettingsEnums;
 import android.content.Context;
-import android.provider.SearchIndexableResource;
 
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.search.SearchIndexable;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -45,7 +42,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.location_scanning;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -68,7 +65,7 @@
     /**
      * For Search.
      */
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.location_scanning) {
 
                 @Override
diff --git a/src/com/android/settings/network/ApnSettings.java b/src/com/android/settings/network/ApnSettings.java
index f0603bb..137abadf 100755
--- a/src/com/android/settings/network/ApnSettings.java
+++ b/src/com/android/settings/network/ApnSettings.java
@@ -113,6 +113,7 @@
     private HandlerThread mRestoreDefaultApnThread;
     private SubscriptionInfo mSubscriptionInfo;
     private int mSubId;
+    private int mPhoneId;
     private UiccController mUiccController;
     private String mMvnoType;
     private String mMvnoMatchData;
@@ -151,7 +152,9 @@
                 if (!mRestoreDefaultApnMode) {
                     int extraSubId = intent.getIntExtra(TelephonyManager.EXTRA_SUBSCRIPTION_ID,
                             SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-                    if (extraSubId != mSubId) {
+                    if (SubscriptionManager.isValidSubscriptionId(extraSubId) &&
+                            mPhoneId == SubscriptionManager.getPhoneId(extraSubId) &&
+                            extraSubId != mSubId) {
                         // subscription has changed
                         mSubId = extraSubId;
                         mSubscriptionInfo = getSubscriptionInfo(mSubId);
@@ -182,7 +185,7 @@
         final Activity activity = getActivity();
         mSubId = activity.getIntent().getIntExtra(SUB_ID,
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-
+        mPhoneId = SubscriptionManager.getPhoneId(mSubId);
         mIntentFilter = new IntentFilter(
                 TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
         mIntentFilter.addAction(TelephonyManager.ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED);
diff --git a/src/com/android/settings/network/MobileNetworkListFragment.java b/src/com/android/settings/network/MobileNetworkListFragment.java
index 5afa994..cae02f9 100644
--- a/src/com/android/settings/network/MobileNetworkListFragment.java
+++ b/src/com/android/settings/network/MobileNetworkListFragment.java
@@ -19,7 +19,6 @@
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.os.UserManager;
-import android.provider.SearchIndexableResource;
 
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
@@ -36,7 +35,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.mobile_network_list;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -56,7 +55,7 @@
         return controllers;
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.mobile_network_list) {
 
                 @Override
diff --git a/src/com/android/settings/network/NetworkDashboardFragment.java b/src/com/android/settings/network/NetworkDashboardFragment.java
index 8c686a5..92c55cb 100644
--- a/src/com/android/settings/network/NetworkDashboardFragment.java
+++ b/src/com/android/settings/network/NetworkDashboardFragment.java
@@ -162,7 +162,7 @@
         return 0;
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableResource> getXmlResourcesToIndex(
diff --git a/src/com/android/settings/network/telephony/Enhanced4gAdvancedCallingPreferenceController.java b/src/com/android/settings/network/telephony/Enhanced4gAdvancedCallingPreferenceController.java
new file mode 100644
index 0000000..96e43b7
--- /dev/null
+++ b/src/com/android/settings/network/telephony/Enhanced4gAdvancedCallingPreferenceController.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2019 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.network.telephony;
+
+import android.content.Context;
+
+/**
+ * Preference controller for "Advance Calling"
+ */
+public class Enhanced4gAdvancedCallingPreferenceController extends
+        Enhanced4gBasePreferenceController {
+
+    public Enhanced4gAdvancedCallingPreferenceController(Context context, String key) {
+        super(context, key);
+    }
+
+    @Override
+    protected int getMode() {
+        return MODE_ADVANCED_CALL;
+    }
+}
diff --git a/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java b/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java
new file mode 100644
index 0000000..25eefdf
--- /dev/null
+++ b/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceController.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2019 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.network.telephony;
+
+import android.content.Context;
+import android.os.Looper;
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
+import android.telephony.PhoneStateListener;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+
+import com.android.ims.ImsManager;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Preference controller for "Enhanced 4G LTE"
+ */
+public class Enhanced4gBasePreferenceController extends TelephonyTogglePreferenceController
+        implements LifecycleObserver, OnStart, OnStop {
+
+    private Preference mPreference;
+    private TelephonyManager mTelephonyManager;
+    private CarrierConfigManager mCarrierConfigManager;
+    private PersistableBundle mCarrierConfig;
+    @VisibleForTesting
+    ImsManager mImsManager;
+    private PhoneCallStateListener mPhoneStateListener;
+    private final List<On4gLteUpdateListener> m4gLteListeners;
+
+    protected static final int MODE_NONE = -1;
+    protected static final int MODE_VOLTE = 0;
+    protected static final int MODE_ADVANCED_CALL = 1;
+    protected static final int MODE_4G_CALLING = 2;
+    private int m4gCurrentMode = MODE_NONE;
+
+    public Enhanced4gBasePreferenceController(Context context, String key) {
+        super(context, key);
+        mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);
+        m4gLteListeners = new ArrayList<>();
+        mPhoneStateListener = new PhoneCallStateListener(Looper.getMainLooper());
+    }
+
+    public Enhanced4gBasePreferenceController init(int subId) {
+        if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID && mSubId == subId) {
+            return this;
+        }
+        mSubId = subId;
+        mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId);
+        mCarrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
+        if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            mImsManager = ImsManager.getInstance(mContext, SubscriptionManager.getPhoneId(mSubId));
+        }
+
+        final boolean show4GForLTE = mCarrierConfig.getBoolean(
+                CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL);
+        m4gCurrentMode = mCarrierConfig.getInt(
+                CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT);
+        if (m4gCurrentMode != MODE_ADVANCED_CALL) {
+            m4gCurrentMode = show4GForLTE ? MODE_4G_CALLING : MODE_VOLTE;
+        }
+        return this;
+    }
+
+    @Override
+    public int getAvailabilityStatus(int subId) {
+        init(subId);
+        if (!isModeMatched()) {
+            return CONDITIONALLY_UNAVAILABLE;
+        }
+        final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId);
+        final boolean isVisible = subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
+                && mImsManager != null && carrierConfig != null
+                && mImsManager.isVolteEnabledByPlatform()
+                && mImsManager.isVolteProvisionedOnDevice()
+                && MobileNetworkUtils.isImsServiceStateReady(mImsManager)
+                && !carrierConfig.getBoolean(CarrierConfigManager.KEY_HIDE_ENHANCED_4G_LTE_BOOL);
+        return isVisible
+                ? (isPrefEnabled() ? AVAILABLE : AVAILABLE_UNSEARCHABLE)
+                : CONDITIONALLY_UNAVAILABLE;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreference = screen.findPreference(getPreferenceKey());
+    }
+
+    @Override
+    public void onStart() {
+        mPhoneStateListener.register(mSubId);
+    }
+
+    @Override
+    public void onStop() {
+        mPhoneStateListener.unregister();
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        super.updateState(preference);
+        final SwitchPreference switchPreference = (SwitchPreference) preference;
+
+        switchPreference.setEnabled(isPrefEnabled());
+        switchPreference.setChecked(mImsManager.isEnhanced4gLteModeSettingEnabledByUser()
+                && mImsManager.isNonTtyOrTtyOnVolteEnabled());
+    }
+
+    @Override
+    public boolean setChecked(boolean isChecked) {
+        mImsManager.setEnhanced4gLteModeSetting(isChecked);
+        for (final On4gLteUpdateListener lsn : m4gLteListeners) {
+            lsn.on4gLteUpdated();
+        }
+        return true;
+    }
+
+    @Override
+    public boolean isChecked() {
+        return mImsManager.isEnhanced4gLteModeSettingEnabledByUser();
+    }
+
+    public Enhanced4gBasePreferenceController addListener(On4gLteUpdateListener lsn) {
+        m4gLteListeners.add(lsn);
+        return this;
+    }
+
+    protected int getMode() {
+        return MODE_NONE;
+    }
+
+    private boolean isModeMatched() {
+        return m4gCurrentMode == getMode();
+    }
+
+    private boolean isPrefEnabled() {
+        return mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
+                && mTelephonyManager.getCallState(mSubId) == TelephonyManager.CALL_STATE_IDLE
+                && mImsManager != null
+                && mImsManager.isNonTtyOrTtyOnVolteEnabled()
+                && mCarrierConfig.getBoolean(
+                CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL);
+    }
+
+    private class PhoneCallStateListener extends PhoneStateListener {
+
+        public PhoneCallStateListener(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void onCallStateChanged(int state, String incomingNumber) {
+            updateState(mPreference);
+        }
+
+        public void register(int subId) {
+            mSubId = subId;
+            mTelephonyManager.listen(this, PhoneStateListener.LISTEN_CALL_STATE);
+        }
+
+        public void unregister() {
+            mTelephonyManager.listen(this, PhoneStateListener.LISTEN_NONE);
+        }
+    }
+
+    /**
+     * Update other preferences when 4gLte state is changed
+     */
+    public interface On4gLteUpdateListener {
+        void on4gLteUpdated();
+    }
+}
diff --git a/src/com/android/settings/network/telephony/Enhanced4gCallingPreferenceController.java b/src/com/android/settings/network/telephony/Enhanced4gCallingPreferenceController.java
new file mode 100644
index 0000000..a0d2e34
--- /dev/null
+++ b/src/com/android/settings/network/telephony/Enhanced4gCallingPreferenceController.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2019 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.network.telephony;
+
+import android.content.Context;
+
+/**
+ * Preference controller for "4G Calling"
+ */
+public class Enhanced4gCallingPreferenceController extends Enhanced4gBasePreferenceController {
+
+    public Enhanced4gCallingPreferenceController(Context context, String key) {
+        super(context, key);
+    }
+
+    @Override
+    protected int getMode() {
+        return MODE_4G_CALLING;
+    }
+}
diff --git a/src/com/android/settings/network/telephony/Enhanced4gLtePreferenceController.java b/src/com/android/settings/network/telephony/Enhanced4gLtePreferenceController.java
index 9069c35..22cbd97 100644
--- a/src/com/android/settings/network/telephony/Enhanced4gLtePreferenceController.java
+++ b/src/com/android/settings/network/telephony/Enhanced4gLtePreferenceController.java
@@ -17,177 +17,18 @@
 package com.android.settings.network.telephony;
 
 import android.content.Context;
-import android.os.Looper;
-import android.os.PersistableBundle;
-import android.telephony.CarrierConfigManager;
-import android.telephony.PhoneStateListener;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-
-import androidx.annotation.VisibleForTesting;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-import androidx.preference.SwitchPreference;
-
-import com.android.ims.ImsManager;
-import com.android.settings.R;
-import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.core.lifecycle.events.OnStart;
-import com.android.settingslib.core.lifecycle.events.OnStop;
-
-import java.util.ArrayList;
-import java.util.List;
 
 /**
  * Preference controller for "Enhanced 4G LTE"
  */
-public class Enhanced4gLtePreferenceController extends TelephonyTogglePreferenceController
-        implements LifecycleObserver, OnStart, OnStop {
-
-    private Preference mPreference;
-    private TelephonyManager mTelephonyManager;
-    private CarrierConfigManager mCarrierConfigManager;
-    private PersistableBundle mCarrierConfig;
-    @VisibleForTesting
-    ImsManager mImsManager;
-    private PhoneCallStateListener mPhoneStateListener;
-    private final List<On4gLteUpdateListener> m4gLteListeners;
-    private final CharSequence[] mVariantTitles;
-    private final CharSequence[] mVariantSumaries;
-
-    private final int VARIANT_TITLE_VOLTE = 0;
-    private final int VARIANT_TITLE_ADVANCED_CALL = 1;
-    private final int VARIANT_TITLE_4G_CALLING = 2;
+public class Enhanced4gLtePreferenceController extends Enhanced4gBasePreferenceController {
 
     public Enhanced4gLtePreferenceController(Context context, String key) {
         super(context, key);
-        mCarrierConfigManager = context.getSystemService(CarrierConfigManager.class);
-        m4gLteListeners = new ArrayList<>();
-        mPhoneStateListener = new PhoneCallStateListener(Looper.getMainLooper());
-        mVariantTitles = context.getResources()
-                .getTextArray(R.array.enhanced_4g_lte_mode_title_variant);
-        mVariantSumaries = context.getResources()
-                .getTextArray(R.array.enhanced_4g_lte_mode_sumary_variant);
     }
 
     @Override
-    public int getAvailabilityStatus(int subId) {
-        init(subId);
-        final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId);
-        final boolean isVisible = subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
-                && mImsManager != null && carrierConfig != null
-                && mImsManager.isVolteEnabledByPlatform()
-                && mImsManager.isVolteProvisionedOnDevice()
-                && MobileNetworkUtils.isImsServiceStateReady(mImsManager)
-                && !carrierConfig.getBoolean(CarrierConfigManager.KEY_HIDE_ENHANCED_4G_LTE_BOOL);
-        return isVisible
-                ? (is4gLtePrefEnabled() ? AVAILABLE : AVAILABLE_UNSEARCHABLE)
-                : CONDITIONALLY_UNAVAILABLE;
-    }
-
-    @Override
-    public void displayPreference(PreferenceScreen screen) {
-        super.displayPreference(screen);
-        mPreference = screen.findPreference(getPreferenceKey());
-    }
-
-    @Override
-    public void onStart() {
-        mPhoneStateListener.register(mSubId);
-    }
-
-    @Override
-    public void onStop() {
-        mPhoneStateListener.unregister();
-    }
-
-    @Override
-    public void updateState(Preference preference) {
-        super.updateState(preference);
-        final SwitchPreference switchPreference = (SwitchPreference) preference;
-        final boolean show4GForLTE = mCarrierConfig.getBoolean(
-                CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL);
-        int variant4glteTitleIndex = mCarrierConfig.getInt(
-                CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT);
-
-        if (variant4glteTitleIndex != VARIANT_TITLE_ADVANCED_CALL) {
-            variant4glteTitleIndex = show4GForLTE ? VARIANT_TITLE_4G_CALLING : VARIANT_TITLE_VOLTE;
-        }
-
-        switchPreference.setTitle(mVariantTitles[variant4glteTitleIndex]);
-        switchPreference.setSummary(mVariantSumaries[variant4glteTitleIndex]);
-        switchPreference.setEnabled(is4gLtePrefEnabled());
-        switchPreference.setChecked(mImsManager.isEnhanced4gLteModeSettingEnabledByUser()
-                && mImsManager.isNonTtyOrTtyOnVolteEnabled());
-    }
-
-    @Override
-    public boolean setChecked(boolean isChecked) {
-        mImsManager.setEnhanced4gLteModeSetting(isChecked);
-        for (final On4gLteUpdateListener lsn : m4gLteListeners) {
-            lsn.on4gLteUpdated();
-        }
-        return true;
-    }
-
-    @Override
-    public boolean isChecked() {
-        return mImsManager.isEnhanced4gLteModeSettingEnabledByUser();
-    }
-
-    public Enhanced4gLtePreferenceController init(int subId) {
-        if (mSubId == subId) {
-            return this;
-        }
-        mSubId = subId;
-        mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId);
-        mCarrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
-        if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            mImsManager = ImsManager.getInstance(mContext, SubscriptionManager.getPhoneId(mSubId));
-        }
-
-        return this;
-    }
-
-    public Enhanced4gLtePreferenceController addListener(On4gLteUpdateListener lsn) {
-        m4gLteListeners.add(lsn);
-        return this;
-    }
-
-    private boolean is4gLtePrefEnabled() {
-        return mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
-                && mTelephonyManager.getCallState(mSubId) == TelephonyManager.CALL_STATE_IDLE
-                && mImsManager != null
-                && mImsManager.isNonTtyOrTtyOnVolteEnabled()
-                && mCarrierConfig.getBoolean(
-                CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL);
-    }
-
-    private class PhoneCallStateListener extends PhoneStateListener {
-
-        public PhoneCallStateListener(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void onCallStateChanged(int state, String incomingNumber) {
-            updateState(mPreference);
-        }
-
-        public void register(int subId) {
-            mSubId = subId;
-            mTelephonyManager.listen(this, PhoneStateListener.LISTEN_CALL_STATE);
-        }
-
-        public void unregister() {
-            mTelephonyManager.listen(this, PhoneStateListener.LISTEN_NONE);
-        }
-    }
-
-    /**
-     * Update other preferences when 4gLte state is changed
-     */
-    public interface On4gLteUpdateListener {
-        void on4gLteUpdated();
+    protected int getMode() {
+        return MODE_VOLTE;
     }
 }
diff --git a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
index c06b78b..bdcc736 100644
--- a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
+++ b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
@@ -65,7 +65,7 @@
     public int getAvailabilityStatus(int subId) {
         return subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
                 ? AVAILABLE
-                : DISABLED_DEPENDENT_SETTING;
+                : AVAILABLE_UNSEARCHABLE;
     }
 
     @Override
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
index 0a63e73..d770e02 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
@@ -32,6 +32,9 @@
 import android.view.MenuInflater;
 import android.view.MenuItem;
 
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.settings.R;
 import com.android.settings.core.FeatureFlags;
@@ -53,9 +56,6 @@
 import java.util.Arrays;
 import java.util.List;
 
-import androidx.annotation.VisibleForTesting;
-import androidx.preference.Preference;
-
 @SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
 public class MobileNetworkSettings extends RestrictedDashboardFragment {
 
@@ -175,6 +175,10 @@
                 use(VideoCallingPreferenceController.class).init(mSubId);
         use(Enhanced4gLtePreferenceController.class).init(mSubId)
                 .addListener(videoCallingPreferenceController);
+        use(Enhanced4gCallingPreferenceController.class).init(mSubId)
+                .addListener(videoCallingPreferenceController);
+        use(Enhanced4gAdvancedCallingPreferenceController.class).init(mSubId)
+                .addListener(videoCallingPreferenceController);
     }
 
     @Override
@@ -267,7 +271,7 @@
         return super.onOptionsItemSelected(menuItem);
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
diff --git a/src/com/android/settings/network/telephony/NetworkScanHelper.java b/src/com/android/settings/network/telephony/NetworkScanHelper.java
index c4839b6..0ec61e7 100644
--- a/src/com/android/settings/network/telephony/NetworkScanHelper.java
+++ b/src/com/android/settings/network/telephony/NetworkScanHelper.java
@@ -37,6 +37,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.List;
+import java.util.concurrent.CancellationException;
 import java.util.concurrent.Executor;
 import java.util.stream.Collectors;
 
@@ -177,6 +178,9 @@
 
                 @Override
                 public void onFailure(Throwable t) {
+                    if (t instanceof CancellationException) {
+                        return;
+                    }
                     int errCode = Integer.parseInt(t.getMessage());
                     onError(errCode);
                 }
@@ -184,10 +188,16 @@
             mExecutor.execute(new NetworkScanSyncTask(
                     mTelephonyManager, (SettableFuture) mNetworkScanFuture));
         } else if (type == NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS) {
+            if (mNetworkScanRequester != null) {
+                return;
+            }
             mNetworkScanRequester = mTelephonyManager.requestNetworkScan(
                     NETWORK_SCAN_REQUEST,
                     mExecutor,
                     mInternalNetworkScanCallback);
+            if (mNetworkScanRequester == null) {
+                onError(NetworkScan.ERROR_RADIO_INTERFACE_ERROR);
+            }
         }
     }
 
@@ -199,7 +209,7 @@
     public void stopNetworkQuery() {
         if (mNetworkScanRequester != null) {
             mNetworkScanRequester.stopScan();
-            mNetworkScanFuture = null;
+            mNetworkScanRequester = null;
         }
 
         if (mNetworkScanFuture != null) {
diff --git a/src/com/android/settings/network/telephony/VideoCallingPreferenceController.java b/src/com/android/settings/network/telephony/VideoCallingPreferenceController.java
index 1c78863..a16dc24 100644
--- a/src/com/android/settings/network/telephony/VideoCallingPreferenceController.java
+++ b/src/com/android/settings/network/telephony/VideoCallingPreferenceController.java
@@ -43,7 +43,7 @@
  */
 public class VideoCallingPreferenceController extends TelephonyTogglePreferenceController implements
         LifecycleObserver, OnStart, OnStop,
-        Enhanced4gLtePreferenceController.On4gLteUpdateListener {
+        Enhanced4gBasePreferenceController.On4gLteUpdateListener {
 
     private Preference mPreference;
     private TelephonyManager mTelephonyManager;
diff --git a/src/com/android/settings/nfc/PaymentSettings.java b/src/com/android/settings/nfc/PaymentSettings.java
index 62a3d54..600f92b 100644
--- a/src/com/android/settings/nfc/PaymentSettings.java
+++ b/src/com/android/settings/nfc/PaymentSettings.java
@@ -24,7 +24,6 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.provider.SearchIndexableResource;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
@@ -36,9 +35,6 @@
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settingslib.search.SearchIndexable;
 
-import java.util.Arrays;
-import java.util.List;
-
 
 @SearchIndexable
 public class PaymentSettings extends DashboardFragment {
@@ -58,7 +54,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.nfc_payment_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -101,7 +97,7 @@
         menuItem.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_NEVER);
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.nfc_payment_settings) {
 
                 @Override
diff --git a/src/com/android/settings/notification/AppBubbleNotificationSettings.java b/src/com/android/settings/notification/AppBubbleNotificationSettings.java
index 2517573..82bab24 100644
--- a/src/com/android/settings/notification/AppBubbleNotificationSettings.java
+++ b/src/com/android/settings/notification/AppBubbleNotificationSettings.java
@@ -23,7 +23,6 @@
 
 import com.android.settings.R;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.search.SearchIndexable;
 
@@ -99,7 +98,7 @@
         super.onPause();
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
 
                 @Override
diff --git a/src/com/android/settings/notification/ConfigureNotificationSettings.java b/src/com/android/settings/notification/ConfigureNotificationSettings.java
index 7174b9d..f5765d7 100644
--- a/src/com/android/settings/notification/ConfigureNotificationSettings.java
+++ b/src/com/android/settings/notification/ConfigureNotificationSettings.java
@@ -28,7 +28,6 @@
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.provider.SearchIndexableResource;
 import android.text.TextUtils;
 
 import androidx.annotation.VisibleForTesting;
@@ -43,13 +42,10 @@
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.dashboard.SummaryLoader;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.search.SearchIndexable;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
 @SearchIndexable
@@ -80,7 +76,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.configure_notification_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -217,7 +213,7 @@
     /**
      * For Search.
      */
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.configure_notification_settings) {
 
                 @Override
diff --git a/src/com/android/settings/notification/NotificationAccessSettings.java b/src/com/android/settings/notification/NotificationAccessSettings.java
index a8533fa..82e3dee 100644
--- a/src/com/android/settings/notification/NotificationAccessSettings.java
+++ b/src/com/android/settings/notification/NotificationAccessSettings.java
@@ -190,6 +190,6 @@
         }
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.notification_access_settings);
 }
diff --git a/src/com/android/settings/notification/NotificationAssistantPicker.java b/src/com/android/settings/notification/NotificationAssistantPicker.java
index 41fc7c1..4cfc7da 100644
--- a/src/com/android/settings/notification/NotificationAssistantPicker.java
+++ b/src/com/android/settings/notification/NotificationAssistantPicker.java
@@ -23,18 +23,14 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
 import android.graphics.drawable.Drawable;
-import android.os.RemoteException;
-import android.provider.SearchIndexableResource;
 import android.provider.Settings;
 import android.service.notification.NotificationAssistantService;
 import android.text.TextUtils;
-import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
 import com.android.settings.applications.defaultapps.DefaultAppPickerFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settingslib.applications.DefaultAppInfo;
 import com.android.settingslib.applications.ServiceListing;
 import com.android.settingslib.widget.CandidateInfo;
@@ -78,7 +74,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.notification_assistant_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -128,7 +124,7 @@
         mCandidateInfos = list;
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.notification_assistant_settings);
 
     public static class CandidateNone extends CandidateInfo {
diff --git a/src/com/android/settings/notification/NotificationStation.java b/src/com/android/settings/notification/NotificationStation.java
index 80b2d45..e5db3ee 100644
--- a/src/com/android/settings/notification/NotificationStation.java
+++ b/src/com/android/settings/notification/NotificationStation.java
@@ -16,7 +16,8 @@
 
 package com.android.settings.notification;
 
-import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+import static android.provider.Settings.EXTRA_APP_PACKAGE;
+import static android.provider.Settings.EXTRA_CHANNEL_ID;
 
 import android.app.Activity;
 import android.app.ActivityManager;
@@ -27,18 +28,19 @@
 import android.app.settings.SettingsEnums;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
 import android.content.IntentSender;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
-import android.content.res.Resources;
+import android.graphics.PorterDuff;
 import android.graphics.Typeface;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
-import android.os.Handler;
 import android.os.Parcel;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.provider.Settings;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.NotificationListenerService.Ranking;
 import android.service.notification.NotificationListenerService.RankingMap;
@@ -49,6 +51,7 @@
 import android.text.style.StyleSpan;
 import android.util.Log;
 import android.view.View;
+import android.view.ViewGroup;
 import android.widget.DateTimeView;
 import android.widget.ImageView;
 import android.widget.TextView;
@@ -62,8 +65,8 @@
 import com.android.settings.Utils;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Comparator;
+import java.util.LinkedList;
 import java.util.List;
 
 public class NotificationStation extends SettingsPreferenceFragment {
@@ -72,33 +75,44 @@
     private static final boolean DEBUG = false;
     private static final boolean DUMP_EXTRAS = true;
     private static final boolean DUMP_PARCEL = true;
-    private Handler mHandler;
 
     private static class HistoricalNotificationInfo {
         public String key;
-        public String channel;
+        public NotificationChannel channel;
         public String pkg;
         public Drawable pkgicon;
         public CharSequence pkgname;
         public Drawable icon;
         public CharSequence title;
+        public CharSequence text;
         public int priority;
         public int user;
         public long timestamp;
         public boolean active;
-        public CharSequence extra;
+        public CharSequence notificationExtra;
+        public CharSequence rankingExtra;
+        public boolean alerted;
+        public boolean visuallyInterruptive;
+
+        public void updateFrom(HistoricalNotificationInfo updatedInfo) {
+            this.channel = updatedInfo.channel;
+            this.icon = updatedInfo.icon;
+            this.title = updatedInfo.title;
+            this.text = updatedInfo.text;
+            this.priority = updatedInfo.priority;
+            this.timestamp = updatedInfo.timestamp;
+            this.active = updatedInfo.active;
+            this.alerted = updatedInfo.alerted;
+            this.visuallyInterruptive = updatedInfo.visuallyInterruptive;
+            this.notificationExtra = updatedInfo.notificationExtra;
+            this.rankingExtra = updatedInfo.rankingExtra;
+        }
     }
 
     private PackageManager mPm;
     private INotificationManager mNoMan;
     private RankingMap mRanking;
-
-    private Runnable mRefreshListRunnable = new Runnable() {
-        @Override
-        public void run() {
-            refreshList();
-        }
-    };
+    private LinkedList<HistoricalNotificationInfo> mNotificationInfos;
 
     private final NotificationListenerService mListener = new NotificationListenerService() {
         @Override
@@ -106,15 +120,21 @@
             logd("onNotificationPosted: %s, with update for %d", sbn.getNotification(),
                     ranking == null ? 0 : ranking.getOrderedKeys().length);
             mRanking = ranking;
-            scheduleRefreshList();
+            if (sbn.getNotification().isGroupSummary()) {
+                return;
+            }
+            addOrUpdateNotification(sbn);
         }
 
         @Override
-        public void onNotificationRemoved(StatusBarNotification notification, RankingMap ranking) {
+        public void onNotificationRemoved(StatusBarNotification sbn, RankingMap ranking) {
             logd("onNotificationRankingUpdate with update for %d",
                     ranking == null ? 0 : ranking.getOrderedKeys().length);
             mRanking = ranking;
-            scheduleRefreshList();
+            if (sbn.getNotification().isGroupSummary()) {
+                return;
+            }
+            markNotificationAsDismissed(sbn);
         }
 
         @Override
@@ -122,7 +142,7 @@
             logd("onNotificationRankingUpdate with update for %d",
                     ranking == null ? 0 : ranking.getOrderedKeys().length);
             mRanking = ranking;
-            scheduleRefreshList();
+            updateNotificationsFromRanking();
         }
 
         @Override
@@ -130,44 +150,29 @@
             mRanking = getCurrentRanking();
             logd("onListenerConnected with update for %d",
                     mRanking == null ? 0 : mRanking.getOrderedKeys().length);
-            scheduleRefreshList();
+            populateNotifications();
         }
     };
 
-    private void scheduleRefreshList() {
-        if (mHandler != null) {
-            mHandler.removeCallbacks(mRefreshListRunnable);
-            mHandler.postDelayed(mRefreshListRunnable, 100);
-        }
-    }
-
     private Context mContext;
 
     private final Comparator<HistoricalNotificationInfo> mNotificationSorter
-            = new Comparator<HistoricalNotificationInfo>() {
-                @Override
-                public int compare(HistoricalNotificationInfo lhs,
-                                   HistoricalNotificationInfo rhs) {
-                    return Long.compare(rhs.timestamp, lhs.timestamp);
-                }
-            };
+            = (lhs, rhs) -> Long.compare(rhs.timestamp, lhs.timestamp);
 
     @Override
     public void onAttach(Activity activity) {
         logd("onAttach(%s)", activity.getClass().getSimpleName());
         super.onAttach(activity);
-        mHandler = new Handler(activity.getMainLooper());
         mContext = activity;
         mPm = mContext.getPackageManager();
         mNoMan = INotificationManager.Stub.asInterface(
                 ServiceManager.getService(Context.NOTIFICATION_SERVICE));
+        mNotificationInfos = new LinkedList<>();
     }
 
     @Override
     public void onDetach() {
         logd("onDetach()");
-        mHandler.removeCallbacks(mRefreshListRunnable);
-        mHandler = null;
         super.onDetach();
     }
 
@@ -205,24 +210,84 @@
         } catch (RemoteException e) {
             Log.e(TAG, "Cannot register listener", e);
         }
-        refreshList();
     }
 
-    private void refreshList() {
-        List<HistoricalNotificationInfo> infos = loadNotifications();
-        if (infos != null) {
-            final int N = infos.size();
-            logd("adding %d infos", N);
-            Collections.sort(infos, mNotificationSorter);
-            if (getPreferenceScreen() == null) {
-                setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getContext()));
+    /**
+     * Adds all current and historical notifications when the NLS connects.
+     */
+    private void populateNotifications() {
+        loadNotifications();
+        final int N = mNotificationInfos.size();
+        logd("adding %d infos", N);
+        if (getPreferenceScreen() == null) {
+            setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getContext()));
+        }
+        getPreferenceScreen().removeAll();
+        for (int i = 0; i < N; i++) {
+            getPreferenceScreen().addPreference(new HistoricalNotificationPreference(
+                    getPrefContext(), mNotificationInfos.get(i), i));
+        }
+    }
+
+    /**
+     * Finds and dims the given notification in the preferences list.
+     */
+    private void markNotificationAsDismissed(StatusBarNotification sbn) {
+        final int N = mNotificationInfos.size();
+        for (int i = 0; i < N; i++) {
+            final HistoricalNotificationInfo info = mNotificationInfos.get(i);
+            if (TextUtils.equals(info.key, sbn.getKey())) {
+                info.active = false;
+                ((HistoricalNotificationPreference) getPreferenceScreen().findPreference(
+                        sbn.getKey())).updatePreference(info);
+               break;
             }
-            getPreferenceScreen().removeAll();
-            for (int i = 0; i < N; i++) {
-                getPreferenceScreen().addPreference(
-                        new HistoricalNotificationPreference(getPrefContext(), infos.get(i)));
+        }
+    }
+
+    /**
+     * Either updates a notification with its latest information or (if it's something the user
+     * would consider a new notification) adds a new entry at the start of the list.
+     */
+    private void addOrUpdateNotification(StatusBarNotification sbn) {
+        HistoricalNotificationInfo newInfo = createFromSbn(sbn, true);
+        boolean needsAdd = true;
+        final int N = mNotificationInfos.size();
+        for (int i = 0; i < N; i++) {
+            final HistoricalNotificationInfo info = mNotificationInfos.get(i);
+            if (TextUtils.equals(info.key, sbn.getKey()) && info.active
+                    && !newInfo.alerted && !newInfo.visuallyInterruptive) {
+                info.updateFrom(newInfo);
+
+                ((HistoricalNotificationPreference) getPreferenceScreen().findPreference(
+                        sbn.getKey())).updatePreference(info);
+                needsAdd = false;
+                break;
             }
         }
+        if (needsAdd) {
+            mNotificationInfos.addFirst(newInfo);
+            getPreferenceScreen().addPreference(new HistoricalNotificationPreference(
+                    getPrefContext(),
+                    mNotificationInfos.peekFirst(), -1 * mNotificationInfos.size()));
+        }
+    }
+
+    /**
+     * Updates all notifications in the list based on new information in the ranking.
+     */
+    private void updateNotificationsFromRanking() {
+        Ranking rank = new Ranking();
+        for (int i = 0; i < getPreferenceScreen().getPreferenceCount(); i++) {
+            final HistoricalNotificationPreference p =
+                    (HistoricalNotificationPreference) getPreferenceScreen().getPreference(i);
+            final HistoricalNotificationInfo info = mNotificationInfos.get(i);
+            mRanking.getRanking(p.getKey(), rank);
+
+            updateFromRanking(info);
+            ((HistoricalNotificationPreference) getPreferenceScreen().findPreference(
+                    info.key)).updatePreference(info);
+        }
     }
 
     private static void logd(String msg, Object... args) {
@@ -242,14 +307,46 @@
         CharSequence title = null;
         if (n.extras != null) {
             title = n.extras.getCharSequence(Notification.EXTRA_TITLE);
-            if (TextUtils.isEmpty(title)) {
-                title = n.extras.getCharSequence(Notification.EXTRA_TEXT);
+        }
+        return title == null? null : String.valueOf(title);
+    }
+
+    /**
+     * Returns the appropriate substring for this notification based on the style of notification.
+     */
+    private static String getTextString(Context appContext, Notification n) {
+        CharSequence text = null;
+        if (n.extras != null) {
+            text = n.extras.getCharSequence(Notification.EXTRA_TEXT);
+
+            Notification.Builder nb = Notification.Builder.recoverBuilder(appContext, n);
+
+            if (nb.getStyle() instanceof Notification.BigTextStyle) {
+                text = ((Notification.BigTextStyle) nb.getStyle()).getBigText();
+            } else if (nb.getStyle() instanceof Notification.MessagingStyle) {
+                Notification.MessagingStyle ms = (Notification.MessagingStyle) nb.getStyle();
+                final List<Notification.MessagingStyle.Message> messages = ms.getMessages();
+                if (messages != null && messages.size() > 0) {
+                    text = messages.get(messages.size() - 1).getText();
+                }
+            }
+
+            if (TextUtils.isEmpty(text)) {
+                text = n.extras.getCharSequence(Notification.EXTRA_TEXT);
             }
         }
-        if (TextUtils.isEmpty(title) && !TextUtils.isEmpty(n.tickerText)) {
-            title = n.tickerText;
+        return text == null ? null : String.valueOf(text);
+    }
+
+    private static Drawable loadIcon(Context context, StatusBarNotification sbn) {
+        Drawable draw = sbn.getNotification().getSmallIcon().loadDrawableAsUser(
+                sbn.getPackageContext(context), sbn.getUserId());
+        if (draw == null) {
+            return null;
         }
-        return String.valueOf(title);
+        draw.mutate();
+        draw.setColorFilter(sbn.getNotification().color, PorterDuff.Mode.SRC_ATOP);
+        return draw;
     }
 
     private static String formatPendingIntent(PendingIntent pi) {
@@ -265,7 +362,11 @@
         return sb.toString();
     }
 
-    private List<HistoricalNotificationInfo> loadNotifications() {
+    /**
+     * Reads all current and past notifications (up to the system limit, since the device was
+     * booted), stores the data we need to present them, and sorts them chronologically for display.
+     */
+    private void loadNotifications() {
         final int currentUserId = ActivityManager.getCurrentUser();
         try {
             StatusBarNotification[] active = mNoMan.getActiveNotifications(
@@ -274,51 +375,125 @@
                     mContext.getPackageName(), 50);
 
             List<HistoricalNotificationInfo> list
-                    = new ArrayList<HistoricalNotificationInfo>(active.length + dismissed.length);
+                    = new ArrayList<>(active.length + dismissed.length);
 
-            for (StatusBarNotification[] resultset
+            for (StatusBarNotification[] resultSet
                     : new StatusBarNotification[][] { active, dismissed }) {
-                for (StatusBarNotification sbn : resultset) {
+                for (StatusBarNotification sbn : resultSet) {
                     if (sbn.getUserId() != UserHandle.USER_ALL & sbn.getUserId() != currentUserId) {
                         continue;
                     }
-
-                    final Notification n = sbn.getNotification();
-                    final HistoricalNotificationInfo info = new HistoricalNotificationInfo();
-                    info.pkg = sbn.getPackageName();
-                    info.user = sbn.getUserId();
-                    info.icon = loadIconDrawable(info.pkg, info.user, n.icon);
-                    info.pkgicon = loadPackageIconDrawable(info.pkg, info.user);
-                    info.pkgname = loadPackageName(info.pkg);
-                    info.title = getTitleString(n);
-                    if (TextUtils.isEmpty(info.title)) {
-                        info.title = getString(R.string.notification_log_no_title);
+                    if (sbn.getNotification().isGroupSummary()) {
+                        continue;
                     }
-                    info.timestamp = sbn.getPostTime();
-                    info.priority = n.priority;
-                    info.channel = n.getChannelId();
-                    info.key = sbn.getKey();
-
-                    info.active = (resultset == active);
-
-                    info.extra = generateExtraText(sbn, info);
-
+                    final HistoricalNotificationInfo info = createFromSbn(sbn, resultSet == active);
                     logd("   [%d] %s: %s", info.timestamp, info.pkg, info.title);
                     list.add(info);
                 }
             }
 
-            return list;
+            // notifications are given to us in the same order as the shade; sorted by inferred
+            // priority. Resort chronologically for our display.
+            list.sort(mNotificationSorter);
+            mNotificationInfos = new LinkedList<>(list);
+
         } catch (RemoteException e) {
             Log.e(TAG, "Cannot load Notifications: ", e);
         }
-        return null;
     }
 
+    private HistoricalNotificationInfo createFromSbn(StatusBarNotification sbn, boolean active) {
+        final Notification n = sbn.getNotification();
+        final HistoricalNotificationInfo info = new HistoricalNotificationInfo();
+        info.pkg = sbn.getPackageName();
+        info.user = sbn.getUserId();
+        info.icon = loadIcon(mContext, sbn);
+        if (info.icon == null) {
+            info.icon = loadPackageIconDrawable(info.pkg, info.user);
+        }
+        info.pkgname = loadPackageName(info.pkg);
+        info.title = getTitleString(n);
+        info.text = getTextString(sbn.getPackageContext(mContext), n);
+        info.timestamp = sbn.getPostTime();
+        info.priority = n.priority;
+        info.key = sbn.getKey();
+
+        info.active = active;
+        info.notificationExtra = generateExtraText(sbn, info);
+
+        updateFromRanking(info);
+
+        return info;
+    }
+
+    private void updateFromRanking(HistoricalNotificationInfo info) {
+        Ranking rank = new Ranking();
+        if (mRanking == null) {
+            return;
+        }
+        mRanking.getRanking(info.key, rank);
+        info.alerted = rank.getLastAudiblyAlertedMillis() > 0;
+        info.visuallyInterruptive = rank.visuallyInterruptive();
+        info.channel = rank.getChannel();
+        info.rankingExtra = generateRankingExtraText(info);
+    }
+
+    /**
+     * Generates a string of debug information for this notification based on the RankingMap
+     */
+    private CharSequence generateRankingExtraText(HistoricalNotificationInfo info) {
+        final SpannableStringBuilder sb = new SpannableStringBuilder();
+        final String delim = getString(R.string.notification_log_details_delimiter);
+
+        Ranking rank = new Ranking();
+        if (mRanking != null && mRanking.getRanking(info.key, rank)) {
+            if (info.active && info.alerted) {
+                sb.append("\n")
+                        .append(bold(getString(R.string.notification_log_details_alerted)));
+            }
+            sb.append("\n")
+                    .append(bold(getString(R.string.notification_log_channel)))
+                    .append(delim)
+                    .append(info.channel.toString());
+            if (info.active) {
+                sb.append("\n")
+                        .append(bold(getString(
+                                R.string.notification_log_details_importance)))
+                        .append(delim)
+                        .append(Ranking.importanceToString(rank.getImportance()));
+                if (rank.getImportanceExplanation() != null) {
+                    sb.append("\n")
+                            .append(bold(getString(
+                                    R.string.notification_log_details_explanation)))
+                            .append(delim)
+                            .append(rank.getImportanceExplanation());
+                }
+                sb.append("\n")
+                        .append(bold(getString(
+                                R.string.notification_log_details_badge)))
+                        .append(delim)
+                        .append(Boolean.toString(rank.canShowBadge()));
+            }
+        } else {
+            if (mRanking == null) {
+                sb.append("\n")
+                        .append(bold(getString(
+                                R.string.notification_log_details_ranking_null)));
+            } else {
+                sb.append("\n")
+                        .append(bold(getString(
+                                R.string.notification_log_details_ranking_none)));
+            }
+        }
+
+        return sb;
+    }
+
+    /**
+     * Generates a string of debug information for this notification
+     */
     private CharSequence generateExtraText(StatusBarNotification sbn,
                                            HistoricalNotificationInfo info) {
-        final Ranking rank = new Ranking();
-
         final Notification n = sbn.getNotification();
         final SpannableStringBuilder sb = new SpannableStringBuilder();
         final String delim = getString(R.string.notification_log_details_delimiter);
@@ -334,10 +509,6 @@
                 .append(delim)
                 .append(String.valueOf(n.getSmallIcon()));
         sb.append("\n")
-                .append(bold("channelId"))
-                .append(delim)
-                .append(String.valueOf(n.getChannelId()));
-        sb.append("\n")
                 .append(bold("postTime"))
                 .append(delim)
                 .append(String.valueOf(sbn.getPostTime()));
@@ -357,58 +528,6 @@
                         getString(R.string.notification_log_details_group_summary)));
             }
         }
-        if (info.active) {
-            // mRanking only applies to active notifications
-            if (mRanking != null && mRanking.getRanking(sbn.getKey(), rank)) {
-                if (rank.getLastAudiblyAlertedMillis() > 0) {
-                    sb.append("\n")
-                            .append(bold(getString(R.string.notification_log_details_alerted)));
-                }
-            }
-        }
-        try {
-            NotificationChannel channel = mNoMan.getNotificationChannelForPackage(
-                    sbn.getPackageName(), sbn.getUid(), n.getChannelId(), false);
-            sb.append("\n")
-                    .append(bold(getString(R.string.notification_log_details_sound)))
-                    .append(delim);
-            if (channel == null || channel.getImportance() == IMPORTANCE_UNSPECIFIED) {
-
-                if (0 != (n.defaults & Notification.DEFAULT_SOUND)) {
-                    sb.append(getString(R.string.notification_log_details_default));
-                } else if (n.sound != null) {
-                    sb.append(n.sound.toString());
-                } else {
-                    sb.append(getString(R.string.notification_log_details_none));
-                }
-            } else {
-                sb.append(String.valueOf(channel.getSound()));
-            }
-            sb.append("\n")
-                    .append(bold(getString(R.string.notification_log_details_vibrate)))
-                    .append(delim);
-            if (channel == null || channel.getImportance() == IMPORTANCE_UNSPECIFIED) {
-                if (0 != (n.defaults & Notification.DEFAULT_VIBRATE)) {
-                    sb.append(getString(R.string.notification_log_details_default));
-                } else if (n.vibrate != null) {
-                    sb.append(getString(R.string.notification_log_details_vibrate_pattern));
-                } else {
-                    sb.append(getString(R.string.notification_log_details_none));
-                }
-            } else {
-                if (channel.getVibrationPattern() != null) {
-                    sb.append(getString(R.string.notification_log_details_vibrate_pattern));
-                } else {
-                    sb.append(getString(R.string.notification_log_details_none));
-                }
-            }
-        } catch (RemoteException e) {
-            Log.d(TAG, "cannot read channel info", e);
-        }
-        sb.append("\n")
-                .append(bold(getString(R.string.notification_log_details_visibility)))
-                .append(delim)
-                .append(Notification.visibilityToString(n.visibility));
         if (n.publicVersion != null) {
             sb.append("\n")
                     .append(bold(getString(
@@ -416,42 +535,7 @@
                     .append(delim)
                     .append(getTitleString(n.publicVersion));
         }
-        sb.append("\n")
-                .append(bold(getString(R.string.notification_log_details_priority)))
-                .append(delim)
-                .append(Notification.priorityToString(n.priority));
-        if (info.active) {
-            // mRanking only applies to active notifications
-            if (mRanking != null && mRanking.getRanking(sbn.getKey(), rank)) {
-                sb.append("\n")
-                        .append(bold(getString(
-                                R.string.notification_log_details_importance)))
-                        .append(delim)
-                        .append(Ranking.importanceToString(rank.getImportance()));
-                if (rank.getImportanceExplanation() != null) {
-                    sb.append("\n")
-                            .append(bold(getString(
-                                    R.string.notification_log_details_explanation)))
-                            .append(delim)
-                            .append(rank.getImportanceExplanation());
-                }
-                sb.append("\n")
-                        .append(bold(getString(
-                                R.string.notification_log_details_badge)))
-                        .append(delim)
-                        .append(Boolean.toString(rank.canShowBadge()));
-            } else {
-                if (mRanking == null) {
-                    sb.append("\n")
-                            .append(bold(getString(
-                                    R.string.notification_log_details_ranking_null)));
-                } else {
-                    sb.append("\n")
-                            .append(bold(getString(
-                                    R.string.notification_log_details_ranking_none)));
-                }
-            }
-        }
+
         if (n.contentIntent != null) {
             sb.append("\n")
                     .append(bold(getString(
@@ -535,25 +619,6 @@
         return sb;
     }
 
-    private Resources getResourcesForUserPackage(String pkg, int userId) {
-        Resources r = null;
-
-        if (pkg != null) {
-            try {
-                if (userId == UserHandle.USER_ALL) {
-                    userId = UserHandle.USER_SYSTEM;
-                }
-                r = mPm.getResourcesForApplicationAsUser(pkg, userId);
-            } catch (PackageManager.NameNotFoundException ex) {
-                Log.e(TAG, "Icon package not found: " + pkg, ex);
-                return null;
-            }
-        } else {
-            r = mContext.getResources();
-        }
-        return r;
-    }
-
     private Drawable loadPackageIconDrawable(String pkg, int userId) {
         Drawable icon = null;
         try {
@@ -576,31 +641,17 @@
         return pkg;
     }
 
-    private Drawable loadIconDrawable(String pkg, int userId, int resId) {
-        Resources r = getResourcesForUserPackage(pkg, userId);
-
-        if (resId == 0) {
-            return null;
-        }
-
-        try {
-            return r.getDrawable(resId, null);
-        } catch (RuntimeException e) {
-            Log.w(TAG, "Icon not found in "
-                    + (pkg != null ? resId : "<system>")
-                    + ": " + Integer.toHexString(resId), e);
-        }
-
-        return null;
-    }
-
     private static class HistoricalNotificationPreference extends Preference {
         private final HistoricalNotificationInfo mInfo;
         private static long sLastExpandedTimestamp; // quick hack to keep things from collapsing
+        public ViewGroup mItemView; // hack to update prefs fast;
 
-        public HistoricalNotificationPreference(Context context, HistoricalNotificationInfo info) {
+        public HistoricalNotificationPreference(Context context, HistoricalNotificationInfo info,
+                int order) {
             super(context);
             setLayoutResource(R.layout.notification_log_row);
+            setOrder(order);
+            setKey(info.key);
             mInfo = info;
         }
 
@@ -608,41 +659,67 @@
         public void onBindViewHolder(PreferenceViewHolder row) {
             super.onBindViewHolder(row);
 
-            if (mInfo.icon != null) {
-                ((ImageView) row.findViewById(R.id.icon)).setImageDrawable(mInfo.icon);
+            mItemView = (ViewGroup) row.itemView;
+
+            updatePreference(mInfo);
+
+            row.findViewById(R.id.timestamp).setOnLongClickListener(v -> {
+                final View extras = row.findViewById(R.id.extra);
+                extras.setVisibility(extras.getVisibility() == View.VISIBLE
+                        ? View.GONE : View.VISIBLE);
+                sLastExpandedTimestamp = mInfo.timestamp;
+                return false;
+            });
+        }
+
+        public void updatePreference(HistoricalNotificationInfo info) {
+            if (mItemView == null) {
+                return;
             }
-            if (mInfo.pkgicon != null) {
-                ((ImageView) row.findViewById(R.id.pkgicon)).setImageDrawable(mInfo.pkgicon);
+            if (info.icon != null) {
+                ((ImageView) mItemView.findViewById(R.id.icon)).setImageDrawable(mInfo.icon);
+            }
+            ((TextView) mItemView.findViewById(R.id.pkgname)).setText(mInfo.pkgname);
+            ((DateTimeView) mItemView.findViewById(R.id.timestamp)).setTime(info.timestamp);
+            if (!TextUtils.isEmpty(info.title)) {
+                ((TextView) mItemView.findViewById(R.id.title)).setText(info.title);
+                mItemView.findViewById(R.id.title).setVisibility(View.VISIBLE);
+            } else {
+                mItemView.findViewById(R.id.title).setVisibility(View.GONE);
+            }
+            if (!TextUtils.isEmpty(info.text)) {
+                ((TextView) mItemView.findViewById(R.id.text)).setText(info.text);
+                mItemView.findViewById(R.id.text).setVisibility(View.VISIBLE);
+            } else {
+                mItemView.findViewById(R.id.text).setVisibility(View.GONE);
+            }
+            if (info.icon != null) {
+                ((ImageView) mItemView.findViewById(R.id.icon)).setImageDrawable(info.icon);
             }
 
-            ((DateTimeView) row.findViewById(R.id.timestamp)).setTime(mInfo.timestamp);
-            ((TextView) row.findViewById(R.id.title)).setText(mInfo.title);
-            ((TextView) row.findViewById(R.id.pkgname)).setText(mInfo.pkgname);
+            ((DateTimeView) mItemView.findViewById(R.id.timestamp)).setTime(mInfo.timestamp);
 
-            final TextView extra = (TextView) row.findViewById(R.id.extra);
-            extra.setText(mInfo.extra);
-            extra.setVisibility(mInfo.timestamp == sLastExpandedTimestamp
-                    ? View.VISIBLE : View.GONE);
+            ((TextView) mItemView.findViewById(R.id.notification_extra))
+                    .setText(mInfo.notificationExtra);
+            ((TextView) mItemView.findViewById(R.id.ranking_extra))
+                    .setText(mInfo.rankingExtra);
 
-            row.itemView.setOnClickListener(
-                    new View.OnClickListener() {
-                        @Override
-                        public void onClick(View view) {
-                            extra.setVisibility(extra.getVisibility() == View.VISIBLE
-                                    ? View.GONE : View.VISIBLE);
-                            sLastExpandedTimestamp = mInfo.timestamp;
-                        }
-                    });
+            mItemView.findViewById(R.id.extra).setVisibility(
+                    mInfo.timestamp == sLastExpandedTimestamp ? View.VISIBLE : View.GONE);
 
-            row.itemView.setAlpha(mInfo.active ? 1.0f : 0.5f);
+            mItemView.setAlpha(mInfo.active ? 1.0f : 0.5f);
+
+            mItemView.findViewById(R.id.alerted_icon).setVisibility(
+                    mInfo.alerted ? View.VISIBLE : View.GONE);
         }
 
         @Override
         public void performClick() {
-//            Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
-//                    Uri.fromParts("package", mInfo.pkg, null));
-//            intent.setComponent(intent.resolveActivity(getContext().getPackageManager()));
-//            getContext().startActivity(intent);
+            Intent intent =  new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
+                    .putExtra(EXTRA_APP_PACKAGE, mInfo.pkg)
+                    .putExtra(EXTRA_CHANNEL_ID, mInfo.channel.getId());
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            getContext().startActivity(intent);
         }
     }
 }
diff --git a/src/com/android/settings/notification/ZenAccessSettings.java b/src/com/android/settings/notification/ZenAccessSettings.java
index 947bf1f..1d1a48b 100644
--- a/src/com/android/settings/notification/ZenAccessSettings.java
+++ b/src/com/android/settings/notification/ZenAccessSettings.java
@@ -25,7 +25,6 @@
 import android.content.pm.PackageItemInfo;
 import android.content.pm.PackageManager;
 import android.os.Bundle;
-import android.provider.SearchIndexableResource;
 import android.util.ArraySet;
 import android.view.View;
 
@@ -37,7 +36,6 @@
 import com.android.settings.applications.specialaccess.zenaccess.ZenAccessDetails;
 import com.android.settings.applications.specialaccess.zenaccess.ZenAccessSettingObserverMixin;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settings.widget.EmptyTextSettings;
 import com.android.settingslib.search.SearchIndexable;
 import com.android.settingslib.widget.apppreference.AppPreference;
@@ -80,7 +78,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.zen_access_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -159,6 +157,6 @@
                 : R.string.app_permission_summary_not_allowed;
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.zen_access_settings);
 }
diff --git a/src/com/android/settings/notification/ZenModeAutomationSettings.java b/src/com/android/settings/notification/ZenModeAutomationSettings.java
index 5498c3a..ae5029f 100644
--- a/src/com/android/settings/notification/ZenModeAutomationSettings.java
+++ b/src/com/android/settings/notification/ZenModeAutomationSettings.java
@@ -23,7 +23,6 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.os.Bundle;
-import android.provider.SearchIndexableResource;
 import android.service.notification.ConditionProviderService;
 import android.view.Menu;
 import android.view.MenuInflater;
@@ -33,7 +32,6 @@
 
 import com.android.settings.R;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settings.utils.ManagedServiceSettings;
 import com.android.settings.utils.ZenServiceListing;
 import com.android.settingslib.core.AbstractPreferenceController;
@@ -81,7 +79,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.zen_mode_automation_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -148,7 +146,7 @@
     /**
      * For Search.
      */
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.zen_mode_automation_settings) {
 
                 @Override
diff --git a/src/com/android/settings/notification/ZenModeBlockedEffectsSettings.java b/src/com/android/settings/notification/ZenModeBlockedEffectsSettings.java
index d361de8..ac6698b 100644
--- a/src/com/android/settings/notification/ZenModeBlockedEffectsSettings.java
+++ b/src/com/android/settings/notification/ZenModeBlockedEffectsSettings.java
@@ -27,7 +27,6 @@
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.os.Bundle;
-import android.provider.SearchIndexableResource;
 
 import com.android.settings.R;
 import com.android.settings.search.BaseSearchIndexProvider;
@@ -82,7 +81,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.zen_mode_block_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -93,7 +92,7 @@
     /**
      * For Search.
      */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.zen_mode_block_settings) {
 
             @Override
diff --git a/src/com/android/settings/notification/ZenModeBypassingAppsSettings.java b/src/com/android/settings/notification/ZenModeBypassingAppsSettings.java
index 2c0c84a..5767c96 100644
--- a/src/com/android/settings/notification/ZenModeBypassingAppsSettings.java
+++ b/src/com/android/settings/notification/ZenModeBypassingAppsSettings.java
@@ -20,7 +20,6 @@
 import android.app.Application;
 import android.app.settings.SettingsEnums;
 import android.content.Context;
-import android.provider.SearchIndexableResource;
 
 import androidx.fragment.app.Fragment;
 
@@ -59,7 +58,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.zen_mode_bypassing_apps;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -75,7 +74,7 @@
     /**
      * For Search.
      */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.zen_mode_bypassing_apps) {
 
                 @Override
diff --git a/src/com/android/settings/notification/ZenModeCallsSettings.java b/src/com/android/settings/notification/ZenModeCallsSettings.java
index 0e979e5..8656b04 100644
--- a/src/com/android/settings/notification/ZenModeCallsSettings.java
+++ b/src/com/android/settings/notification/ZenModeCallsSettings.java
@@ -67,7 +67,7 @@
     /**
      * For Search.
      */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.zen_mode_calls_settings) {
 
                 @Override
diff --git a/src/com/android/settings/notification/ZenModeMessagesSettings.java b/src/com/android/settings/notification/ZenModeMessagesSettings.java
index a514420..66088a9 100644
--- a/src/com/android/settings/notification/ZenModeMessagesSettings.java
+++ b/src/com/android/settings/notification/ZenModeMessagesSettings.java
@@ -20,7 +20,6 @@
 
 import android.app.settings.SettingsEnums;
 import android.content.Context;
-import android.provider.SearchIndexableResource;
 
 import com.android.settings.R;
 import com.android.settings.search.BaseSearchIndexProvider;
@@ -53,7 +52,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.zen_mode_messages_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -64,7 +63,7 @@
     /**
      * For Search.
      */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.zen_mode_messages_settings) {
 
                 @Override
diff --git a/src/com/android/settings/notification/ZenModeRestrictNotificationsSettings.java b/src/com/android/settings/notification/ZenModeRestrictNotificationsSettings.java
index ea7e213..17cc370 100644
--- a/src/com/android/settings/notification/ZenModeRestrictNotificationsSettings.java
+++ b/src/com/android/settings/notification/ZenModeRestrictNotificationsSettings.java
@@ -77,7 +77,7 @@
     /**
      * For Search.
      */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.zen_mode_restrict_notifications_settings) {
 
             @Override
diff --git a/src/com/android/settings/notification/ZenModeSettings.java b/src/com/android/settings/notification/ZenModeSettings.java
index d4e5e3c..3497d10 100644
--- a/src/com/android/settings/notification/ZenModeSettings.java
+++ b/src/com/android/settings/notification/ZenModeSettings.java
@@ -313,7 +313,7 @@
     /**
      * For Search.
      */
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.zen_mode_settings) {
 
                 @Override
diff --git a/src/com/android/settings/notification/ZenModeSoundVibrationSettings.java b/src/com/android/settings/notification/ZenModeSoundVibrationSettings.java
index 0b96867..431f171 100644
--- a/src/com/android/settings/notification/ZenModeSoundVibrationSettings.java
+++ b/src/com/android/settings/notification/ZenModeSoundVibrationSettings.java
@@ -70,7 +70,7 @@
     /**
      * For Search.
      */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.zen_mode_sound_vibration_settings) {
 
                 @Override
diff --git a/src/com/android/settings/print/PrintSettingsFragment.java b/src/com/android/settings/print/PrintSettingsFragment.java
index b262ebe..3fd6f58 100644
--- a/src/com/android/settings/print/PrintSettingsFragment.java
+++ b/src/com/android/settings/print/PrintSettingsFragment.java
@@ -491,6 +491,6 @@
         }
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.print_settings);
 }
diff --git a/src/com/android/settings/privacy/AccessibilityUsagePreferenceController.java b/src/com/android/settings/privacy/AccessibilityUsagePreferenceController.java
index 8aff223..a36d3ce 100644
--- a/src/com/android/settings/privacy/AccessibilityUsagePreferenceController.java
+++ b/src/com/android/settings/privacy/AccessibilityUsagePreferenceController.java
@@ -29,20 +29,31 @@
 import java.util.List;
 
 
-public class AccessibilityUsagePreferenceController extends BasePreferenceController  {
+public class AccessibilityUsagePreferenceController extends BasePreferenceController {
 
-    private final @NonNull List<AccessibilityServiceInfo> mEnabledServiceInfos;
+    private final AccessibilityManager mAccessibilityManager;
+    @NonNull
+    private List<AccessibilityServiceInfo> mEnabledServiceInfos;
 
     public AccessibilityUsagePreferenceController(Context context, String preferenceKey) {
         super(context, preferenceKey);
-
-        final AccessibilityManager accessibilityManager = context.getSystemService(
-                AccessibilityManager.class);
-        mEnabledServiceInfos = accessibilityManager.getEnabledAccessibilityServiceList(
+        mAccessibilityManager = mContext.getSystemService(AccessibilityManager.class);
+        mEnabledServiceInfos = mAccessibilityManager.getEnabledAccessibilityServiceList(
                 AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
     }
 
     @Override
+    public void updateState(Preference preference) {
+        super.updateState(preference);
+        mEnabledServiceInfos = mAccessibilityManager.getEnabledAccessibilityServiceList(
+                AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
+
+        if (mEnabledServiceInfos.isEmpty()) {
+            preference.setVisible(false);
+        }
+    }
+
+    @Override
     public int getAvailabilityStatus() {
         return mEnabledServiceInfos.isEmpty() ? UNSUPPORTED_ON_DEVICE : AVAILABLE;
     }
diff --git a/src/com/android/settings/privacy/PrivacyDashboardFragment.java b/src/com/android/settings/privacy/PrivacyDashboardFragment.java
index af83ec1..c7c564d 100644
--- a/src/com/android/settings/privacy/PrivacyDashboardFragment.java
+++ b/src/com/android/settings/privacy/PrivacyDashboardFragment.java
@@ -19,13 +19,11 @@
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.os.Bundle;
-import android.provider.SearchIndexableResource;
 import android.view.View;
 
 import androidx.annotation.VisibleForTesting;
 
 import com.android.settings.R;
-import com.android.settings.Utils;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.notification.LockScreenNotificationPreferenceController;
 import com.android.settings.search.BaseSearchIndexProvider;
@@ -105,18 +103,8 @@
 
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider() {
-                @Override
-                public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
-                        boolean enabled) {
-                    final ArrayList<SearchIndexableResource> result = new ArrayList<>();
-
-                    final SearchIndexableResource sir = new SearchIndexableResource(context);
-                    sir.xmlResId = R.xml.privacy_dashboard_settings;
-                    result.add(sir);
-                    return result;
-                }
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider(R.xml.privacy_dashboard_settings) {
 
                 @Override
                 public List<AbstractPreferenceController> createPreferenceControllers(
diff --git a/src/com/android/settings/search/BaseSearchIndexProvider.java b/src/com/android/settings/search/BaseSearchIndexProvider.java
index 64e6a9c..58b571e 100644
--- a/src/com/android/settings/search/BaseSearchIndexProvider.java
+++ b/src/com/android/settings/search/BaseSearchIndexProvider.java
@@ -103,7 +103,6 @@
         return nonIndexableKeys;
     }
 
-    @Override
     public List<AbstractPreferenceController> getPreferenceControllers(Context context) {
         final List<AbstractPreferenceController> controllersFromCode =
                 createPreferenceControllers(context);
@@ -136,6 +135,13 @@
     }
 
     /**
+     * Returns the xml resource Id.
+     */
+    public int getXmlResourceId() {
+        return mXmlRes;
+    }
+
+    /**
      * Returns true if the page should be considered in search query. If return false, entire page
      * will be suppressed during search query.
      */
diff --git a/src/com/android/settings/search/Indexable.java b/src/com/android/settings/search/Indexable.java
index eef7184..e3d9176 100644
--- a/src/com/android/settings/search/Indexable.java
+++ b/src/com/android/settings/search/Indexable.java
@@ -70,12 +70,5 @@
          */
         @Keep
         List<String> getNonIndexableKeys(Context context);
-
-        /**
-         * @return a list of {@link AbstractPreferenceController} for ResultPayload data during
-         * Indexing.
-         */
-        @Keep
-        List<AbstractPreferenceController> getPreferenceControllers(Context context);
     }
 }
diff --git a/src/com/android/settings/security/EncryptionAndCredential.java b/src/com/android/settings/security/EncryptionAndCredential.java
index a6d2a0a..5688b20 100644
--- a/src/com/android/settings/security/EncryptionAndCredential.java
+++ b/src/com/android/settings/security/EncryptionAndCredential.java
@@ -21,7 +21,6 @@
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.os.UserManager;
-import android.provider.SearchIndexableResource;
 
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
@@ -60,7 +59,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.encryption_and_credential;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
@@ -88,28 +87,19 @@
     /**
      * For Search. Please keep it in sync when updating "createPreferenceHierarchy()"
      */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new SecuritySearchIndexProvider();
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider(R.xml.encryption_and_credential) {
+                @Override
+                public List<AbstractPreferenceController> createPreferenceControllers(
+                        Context context) {
+                    return buildPreferenceControllers(context, null /* lifecycle */);
+                }
 
-    private static class SecuritySearchIndexProvider extends BaseSearchIndexProvider {
-
-        @Override
-        public List<SearchIndexableResource> getXmlResourcesToIndex(
-                Context context, boolean enabled) {
-            final SearchIndexableResource sir = new SearchIndexableResource(context);
-            sir.xmlResId = R.xml.encryption_and_credential;
-            return Arrays.asList(sir);
-        }
-
-        @Override
-        public List<AbstractPreferenceController> createPreferenceControllers(Context context) {
-            return buildPreferenceControllers(context, null /* lifecycle */);
-        }
-
-        @Override
-        protected boolean isPageSearchEnabled(Context context) {
-            final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
-            return um.isAdminUser();
-        }
-    }
+                @Override
+                protected boolean isPageSearchEnabled(Context context) {
+                    final UserManager um = (UserManager) context.getSystemService(
+                            Context.USER_SERVICE);
+                    return um.isAdminUser();
+                }
+            };
 }
diff --git a/src/com/android/settings/security/LockscreenDashboardFragment.java b/src/com/android/settings/security/LockscreenDashboardFragment.java
index f502ee6..f63ccb2 100644
--- a/src/com/android/settings/security/LockscreenDashboardFragment.java
+++ b/src/com/android/settings/security/LockscreenDashboardFragment.java
@@ -19,7 +19,6 @@
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.hardware.display.AmbientDisplayConfiguration;
-import android.provider.SearchIndexableResource;
 
 import androidx.annotation.VisibleForTesting;
 
@@ -37,7 +36,6 @@
 import com.android.settingslib.search.SearchIndexable;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -79,7 +77,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.security_lockscreen_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -130,7 +128,7 @@
         return mConfig;
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.security_lockscreen_settings) {
 
                 @Override
diff --git a/src/com/android/settings/security/ScreenPinningSettings.java b/src/com/android/settings/security/ScreenPinningSettings.java
index c60fd47..849db40 100644
--- a/src/com/android/settings/security/ScreenPinningSettings.java
+++ b/src/com/android/settings/security/ScreenPinningSettings.java
@@ -216,7 +216,7 @@
     /**
      * For search
      */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
         new BaseSearchIndexProvider() {
 
             @Override
diff --git a/src/com/android/settings/security/SecuritySettings.java b/src/com/android/settings/security/SecuritySettings.java
index 021d203..da8f003 100644
--- a/src/com/android/settings/security/SecuritySettings.java
+++ b/src/com/android/settings/security/SecuritySettings.java
@@ -138,7 +138,7 @@
     /**
      * For Search. Please keep it in sync when updating "createPreferenceHierarchy()"
      */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.security_dashboard_settings) {
 
                 @Override
diff --git a/src/com/android/settings/security/screenlock/ScreenLockSettings.java b/src/com/android/settings/security/screenlock/ScreenLockSettings.java
index dab4836..1cc6b3f 100644
--- a/src/com/android/settings/security/screenlock/ScreenLockSettings.java
+++ b/src/com/android/settings/security/screenlock/ScreenLockSettings.java
@@ -86,7 +86,7 @@
     }
 
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.screen_lock_settings) {
 
                 @Override
diff --git a/src/com/android/settings/security/trustagent/TrustAgentSettings.java b/src/com/android/settings/security/trustagent/TrustAgentSettings.java
index 4f652b2..0129fce 100644
--- a/src/com/android/settings/security/trustagent/TrustAgentSettings.java
+++ b/src/com/android/settings/security/trustagent/TrustAgentSettings.java
@@ -53,6 +53,6 @@
         return R.xml.trust_agent_settings;
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.trust_agent_settings);
 }
diff --git a/src/com/android/settings/sim/SimSelectNotification.java b/src/com/android/settings/sim/SimSelectNotification.java
index 7153d15..0b7e652 100644
--- a/src/com/android/settings/sim/SimSelectNotification.java
+++ b/src/com/android/settings/sim/SimSelectNotification.java
@@ -46,6 +46,7 @@
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.settings.HelpTrampoline;
 import com.android.settings.R;
 import com.android.settings.network.SubscriptionUtil;
 import com.android.settings.network.telephony.MobileNetworkActivity;
@@ -292,10 +293,9 @@
                         .setAutoCancel(true);
 
         // Create the pending intent that will lead to the helper page.
-        Intent resultIntent = HelpUtils.getHelpIntent(
-                context,
-                context.getString(R.string.help_uri_sim_combination_warning),
-                context.getClass().getName());
+        Intent resultIntent = new Intent(context, HelpTrampoline.class);
+        resultIntent.putExtra(Intent.EXTRA_TEXT, "help_uri_sim_combination_warning");
+
         PendingIntent resultPendingIntent = PendingIntent.getActivity(context, 0, resultIntent,
                 PendingIntent.FLAG_CANCEL_CURRENT);
         builder.setContentIntent(resultPendingIntent);
diff --git a/src/com/android/settings/sim/SimSettings.java b/src/com/android/settings/sim/SimSettings.java
index 1222913..8134ab0 100644
--- a/src/com/android/settings/sim/SimSettings.java
+++ b/src/com/android/settings/sim/SimSettings.java
@@ -336,7 +336,7 @@
     /**
      * For search
      */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
diff --git a/src/com/android/settings/support/SupportDashboardActivity.java b/src/com/android/settings/support/SupportDashboardActivity.java
index 8703ec7..0710843 100644
--- a/src/com/android/settings/support/SupportDashboardActivity.java
+++ b/src/com/android/settings/support/SupportDashboardActivity.java
@@ -53,7 +53,7 @@
     /**
      * For Search.
      */
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 private static final String SUPPORT_SEARCH_INDEX_KEY = "support_dashboard_activity";
 
diff --git a/src/com/android/settings/system/ResetDashboardFragment.java b/src/com/android/settings/system/ResetDashboardFragment.java
index b0611fc..fc53d4e 100644
--- a/src/com/android/settings/system/ResetDashboardFragment.java
+++ b/src/com/android/settings/system/ResetDashboardFragment.java
@@ -67,7 +67,7 @@
         return controllers;
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.reset_dashboard_fragment) {
 
                 @Override
diff --git a/src/com/android/settings/system/SystemDashboardFragment.java b/src/com/android/settings/system/SystemDashboardFragment.java
index 3ab31e3..9736176 100644
--- a/src/com/android/settings/system/SystemDashboardFragment.java
+++ b/src/com/android/settings/system/SystemDashboardFragment.java
@@ -102,7 +102,7 @@
     /**
      * For Search.
      */
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableResource> getXmlResourcesToIndex(
diff --git a/src/com/android/settings/tts/TextToSpeechSettings.java b/src/com/android/settings/tts/TextToSpeechSettings.java
index bcfad92..2bfc6ea 100644
--- a/src/com/android/settings/tts/TextToSpeechSettings.java
+++ b/src/com/android/settings/tts/TextToSpeechSettings.java
@@ -28,7 +28,6 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.provider.SearchIndexableResource;
 import android.provider.Settings.Secure;
 import android.speech.tts.TextToSpeech;
 import android.speech.tts.TextToSpeech.EngineInfo;
@@ -45,9 +44,8 @@
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settings.Utils;
+import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.widget.GearPreference;
 import com.android.settings.widget.SeekBarPreference;
 import com.android.settingslib.search.SearchIndexable;
@@ -55,7 +53,6 @@
 
 import java.text.Collator;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -795,7 +792,7 @@
         }
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.tts_settings);
 
 }
diff --git a/src/com/android/settings/tts/TtsEnginePreferenceFragment.java b/src/com/android/settings/tts/TtsEnginePreferenceFragment.java
index 3308f1e..c2f4e16 100644
--- a/src/com/android/settings/tts/TtsEnginePreferenceFragment.java
+++ b/src/com/android/settings/tts/TtsEnginePreferenceFragment.java
@@ -7,7 +7,6 @@
 import android.content.DialogInterface;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
-import android.provider.SearchIndexableResource;
 import android.speech.tts.TextToSpeech;
 import android.speech.tts.TextToSpeech.EngineInfo;
 import android.speech.tts.TtsEngines;
@@ -17,13 +16,11 @@
 
 import com.android.settings.R;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settings.widget.RadioButtonPickerFragment;
 import com.android.settingslib.search.SearchIndexable;
 import com.android.settingslib.widget.CandidateInfo;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -141,7 +138,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.tts_engine_picker;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     private boolean shouldDisplayDataAlert(EngineCandidateInfo info) {
@@ -221,6 +218,6 @@
         }
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.tts_engine_picker);
 }
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index c98f174..65057d9 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -1221,7 +1221,7 @@
     public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY =
             (activity, summaryLoader) -> new SummaryProvider(activity, summaryLoader);
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.user_settings) {
 
                 @Override
diff --git a/src/com/android/settings/utils/CandidateInfoExtra.java b/src/com/android/settings/utils/CandidateInfoExtra.java
new file mode 100644
index 0000000..5bccea6
--- /dev/null
+++ b/src/com/android/settings/utils/CandidateInfoExtra.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2019 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.utils;
+
+import android.graphics.drawable.Drawable;
+
+import com.android.settingslib.widget.CandidateInfo;
+
+public class CandidateInfoExtra extends CandidateInfo {
+    private final CharSequence mLabel;
+    private final CharSequence mSummary;
+    private final String mKey;
+
+    public CandidateInfoExtra(CharSequence label, CharSequence summary, String key,
+            boolean enabled) {
+        super(enabled);
+        mLabel = label;
+        mSummary = summary;
+        mKey = key;
+    }
+
+    @Override
+    public CharSequence loadLabel() {
+        return mLabel;
+    }
+
+    public CharSequence loadSummary() {
+        return mSummary;
+    }
+
+    @Override
+    public Drawable loadIcon() {
+        return null;
+    }
+
+    @Override
+    public String getKey() {
+        return mKey;
+    }
+}
diff --git a/src/com/android/settings/wallpaper/WallpaperSuggestionActivity.java b/src/com/android/settings/wallpaper/WallpaperSuggestionActivity.java
index 57222f1..53f92c8 100644
--- a/src/com/android/settings/wallpaper/WallpaperSuggestionActivity.java
+++ b/src/com/android/settings/wallpaper/WallpaperSuggestionActivity.java
@@ -53,7 +53,7 @@
         return manager.getWallpaperId(WallpaperManager.FLAG_SYSTEM) > 0;
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 private static final String SUPPORT_SEARCH_INDEX_KEY = "wallpaper_type";
 
diff --git a/src/com/android/settings/wfd/WifiDisplaySettings.java b/src/com/android/settings/wfd/WifiDisplaySettings.java
index d7385dc..cf6b871 100755
--- a/src/com/android/settings/wfd/WifiDisplaySettings.java
+++ b/src/com/android/settings/wfd/WifiDisplaySettings.java
@@ -835,6 +835,6 @@
     public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
             = (activity, summaryLoader) -> new SummaryProvider(activity, summaryLoader);
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.wifi_display_settings);
 }
diff --git a/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java b/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java
index 313a204..81dc98b 100644
--- a/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java
+++ b/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java
@@ -160,7 +160,7 @@
             return;
         }
         mFadeInAnimated = true;
-        final int colorFrom = Color.WHITE;
+        final int colorFrom = mNormalBackgroundRes;
         final int colorTo = mHighlightColor;
         final ValueAnimator fadeInLoop = ValueAnimator.ofObject(
                 new ArgbEvaluator(), colorFrom, colorTo);
@@ -188,7 +188,7 @@
             return;
         }
         int colorFrom = mHighlightColor;
-        int colorTo = Color.WHITE;
+        int colorTo = mNormalBackgroundRes;
 
         v.setTag(R.id.preference_highlighted, false);
         final ValueAnimator colorAnimation = ValueAnimator.ofObject(
diff --git a/src/com/android/settings/wifi/ConfigureWifiSettings.java b/src/com/android/settings/wifi/ConfigureWifiSettings.java
index 6dd68c7..340dd55 100644
--- a/src/com/android/settings/wifi/ConfigureWifiSettings.java
+++ b/src/com/android/settings/wifi/ConfigureWifiSettings.java
@@ -23,18 +23,15 @@
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 import android.net.wifi.WifiManager;
-import android.provider.SearchIndexableResource;
 
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settings.wifi.p2p.WifiP2pPreferenceController;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.search.SearchIndexable;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
 @SearchIndexable
@@ -69,7 +66,7 @@
 
     @Override
     protected int getPreferenceScreenResId() {
-        return R.xml.wifi_configure_settings;
+        return SEARCH_INDEX_DATA_PROVIDER.getXmlResourceId();
     }
 
     @Override
@@ -108,7 +105,7 @@
         super.onActivityResult(requestCode, resultCode, data);
     }
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.wifi_configure_settings) {
 
                 @Override
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 8ac868f..afc8da5 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -1206,7 +1206,7 @@
         ((AccessPointPreference) accessPoint.getTag()).onLevelChanged();
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableRaw> getRawDataToIndex(Context context,
diff --git a/src/com/android/settings/wifi/WifiSettings2.java b/src/com/android/settings/wifi/WifiSettings2.java
index d715ac0..3ebdda4 100644
--- a/src/com/android/settings/wifi/WifiSettings2.java
+++ b/src/com/android/settings/wifi/WifiSettings2.java
@@ -655,7 +655,7 @@
         return R.string.help_url_wifi;
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableRaw> getRawDataToIndex(Context context,
diff --git a/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettings.java b/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettings.java
index 4daf7da..cf2fc99 100644
--- a/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettings.java
+++ b/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettings.java
@@ -17,22 +17,16 @@
 package com.android.settings.wifi.savedaccesspoints;
 
 import android.annotation.Nullable;
-import android.app.Dialog;
 import android.app.settings.SettingsEnums;
 import android.content.Context;
-import android.content.DialogInterface;
-import android.net.wifi.WifiManager;
 import android.os.Bundle;
 import android.util.FeatureFlagUtils;
-import android.util.Log;
 
 import com.android.settings.R;
 import com.android.settings.core.FeatureFlags;
 import com.android.settings.core.SubSettingLauncher;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.development.featureflags.FeatureFlagPersistent;
-import com.android.settings.wifi.WifiConfigUiBase;
-import com.android.settings.wifi.WifiDialog;
 import com.android.settings.wifi.WifiSettings;
 import com.android.settings.wifi.details.WifiNetworkDetailsFragment;
 import com.android.settingslib.wifi.AccessPoint;
diff --git a/src/com/android/settings/wifi/tether/WifiTetherSettings.java b/src/com/android/settings/wifi/tether/WifiTetherSettings.java
index 6b11cba..84e044f 100644
--- a/src/com/android/settings/wifi/tether/WifiTetherSettings.java
+++ b/src/com/android/settings/wifi/tether/WifiTetherSettings.java
@@ -236,7 +236,7 @@
                 .updateDisplay();
     }
 
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.wifi_tether_settings) {
 
                 @Override
diff --git a/tests/robotests/Android.bp b/tests/robotests/Android.bp
index 28c987b..4920e11 100644
--- a/tests/robotests/Android.bp
+++ b/tests/robotests/Android.bp
@@ -67,6 +67,7 @@
 
     test_options: {
         timeout: 36000,
+        shards: 10,
     },
 
     coverage_libs: [
diff --git a/tests/robotests/assets/grandfather_slice_controller_not_in_xml b/tests/robotests/assets/grandfather_slice_controller_not_in_xml
index 55ecffe..94d5815 100644
--- a/tests/robotests/assets/grandfather_slice_controller_not_in_xml
+++ b/tests/robotests/assets/grandfather_slice_controller_not_in_xml
@@ -3,6 +3,7 @@
 com.android.settings.biometrics.face.FaceSettingsAttentionPreferenceController
 com.android.settings.network.telephony.MmsMessagePreferenceController
 com.android.settings.network.telephony.DataDuringCallsPreferenceController
+com.android.settings.network.telephony.Enhanced4gBasePreferenceController
 com.android.settings.testutils.FakeToggleController
 com.android.settings.testutils.FakeSliderController
 com.android.settings.testutils.FakeInvalidSliderController
diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragmentTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragmentTest.java
index 55c2009..3e96847 100644
--- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragmentTest.java
@@ -37,9 +37,9 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Answers;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 
@@ -49,20 +49,20 @@
 @RunWith(RobolectricTestRunner.class)
 public class DefaultAppPickerFragmentTest {
 
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private FragmentActivity mActivity;
     @Mock
     private PreferenceScreen mScreen;
     @Mock
     private UserManager mUserManager;
 
     private FakeFeatureFactory mFeatureFactory;
+    private FragmentActivity mActivity;
     private TestFragment mFragment;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mFeatureFactory = FakeFeatureFactory.setupForTest();
+        mActivity = spy(Robolectric.buildActivity(FragmentActivity.class).get());
         mFragment = spy(new TestFragment());
 
         when(mActivity.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentSearchIndexProviderInspector.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentSearchIndexProviderInspector.java
index 7106cf6..4a488bf 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentSearchIndexProviderInspector.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentSearchIndexProviderInspector.java
@@ -22,6 +22,7 @@
 
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.core.PreferenceControllerListHelper;
+import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.DatabaseIndexingUtils;
 import com.android.settings.search.Indexable;
 import com.android.settingslib.core.AbstractPreferenceController;
@@ -45,8 +46,8 @@
             return true;
         }
 
-        final Indexable.SearchIndexProvider provider =
-                DatabaseIndexingUtils.getSearchIndexProvider(clazz);
+        final BaseSearchIndexProvider provider =
+                (BaseSearchIndexProvider) DatabaseIndexingUtils.getSearchIndexProvider(clazz);
         if (provider == null) {
             return true;
         }
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
index 9aae249..188f566 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
@@ -31,6 +31,7 @@
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
+import android.net.Uri;
 import android.os.Bundle;
 
 import androidx.preference.Preference;
@@ -240,14 +241,28 @@
     }
 
     @Test
-    public void checkUiBlocker_hasUiBlocker_controllerNotNull() {
+    public void checkUiBlocker_hasUiBlockerAndControllerIsAvailable_controllerNotNull() {
+        final BlockingSlicePrefController controller =
+                new BlockingSlicePrefController(mContext, "pref_key");
+        controller.setSliceUri(Uri.parse("testUri"));
+        mTestFragment.mBlockerController = null;
+        mControllers.add(new TestPreferenceController(mContext));
+        mControllers.add(controller);
+
+        mTestFragment.checkUiBlocker(mControllers);
+
+        assertThat(mTestFragment.mBlockerController).isNotNull();
+    }
+
+    @Test
+    public void checkUiBlocker_hasUiBlockerAndControllerIsNotAvailable_controllerIsNull() {
         mTestFragment.mBlockerController = null;
         mControllers.add(new TestPreferenceController(mContext));
         mControllers.add(new BlockingSlicePrefController(mContext, "pref_key"));
 
         mTestFragment.checkUiBlocker(mControllers);
 
-        assertThat(mTestFragment.mBlockerController).isNotNull();
+        assertThat(mTestFragment.mBlockerController).isNull();
     }
 
     public static class TestPreferenceController extends AbstractPreferenceController
diff --git a/tests/robotests/src/com/android/settings/development/CameraLaserSensorPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/CameraLaserSensorPreferenceControllerTest.java
index aa9cb46..d469c71 100644
--- a/tests/robotests/src/com/android/settings/development/CameraLaserSensorPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/CameraLaserSensorPreferenceControllerTest.java
@@ -128,16 +128,4 @@
                         CameraLaserSensorPreferenceController.PROPERTY_CAMERA_LASER_SENSOR,
                         Integer.toString(CameraLaserSensorPreferenceController.ENABLED)));
     }
-
-    @Test
-    public void onDeveloperOptionsSwitchDisabled_preferenceShouldBeEnabled() {
-        mController.onDeveloperOptionsSwitchDisabled();
-
-        verify(mPreference).setEnabled(false);
-        verify(mPreference).setChecked(false);
-        assertThat(Integer.toString(CameraLaserSensorPreferenceController.DISABLED)).isEqualTo(
-                SystemProperties.get(
-                        CameraLaserSensorPreferenceController.PROPERTY_CAMERA_LASER_SENSOR,
-                        Integer.toString(CameraLaserSensorPreferenceController.ENABLED)));
-    }
 }
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardControllerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardControllerTest.java
index 69242fe..502a62b 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardControllerTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardControllerTest.java
@@ -18,11 +18,17 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyMap;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
+import android.service.settings.suggestions.Suggestion;
 
+import com.android.settings.R;
+import com.android.settings.homepage.contextualcards.ContextualCard;
 import com.android.settings.homepage.contextualcards.ContextualCardUpdateListener;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settingslib.suggestions.SuggestionController;
@@ -91,4 +97,49 @@
 
         verify(mSuggestionController).getSuggestions();
     }
+
+    @Test
+    public void onDismiss_shouldCallSuggestionControllerDismiss() {
+        mController.mSuggestionController = mSuggestionController;
+        mController.setCardUpdateListener(mCardUpdateListener);
+
+        mController.onDismissed(buildContextualCard("test1"));
+
+        verify(mSuggestionController).dismissSuggestions(any(Suggestion.class));
+    }
+
+    @Test
+    public void onDismiss_shouldRemoveSuggestionFromList() {
+        mController.setCardUpdateListener(mCardUpdateListener);
+        mController.mSuggestions.add(buildContextualCard("test1"));
+        final ContextualCard card2 = buildContextualCard("test2");
+        mController.mSuggestions.add(card2);
+        assertThat(mController.mSuggestions).hasSize(2);
+
+        mController.onDismissed(card2);
+
+        assertThat(mController.mSuggestions).hasSize(1);
+    }
+
+    @Test
+    public void onDismiss_shouldCallUpdateAdapter() {
+        mController.setCardUpdateListener(mCardUpdateListener);
+        final ContextualCard card = buildContextualCard("test1");
+        mController.mSuggestions.add(card);
+
+        mController.onDismissed(card);
+
+        verify(mCardUpdateListener).onContextualCardUpdated(anyMap());
+    }
+
+    private ContextualCard buildContextualCard(String name) {
+        return new LegacySuggestionContextualCard.Builder()
+                .setSuggestion(mock(Suggestion.class))
+                .setName(name)
+                .setTitleText("test_title")
+                .setSummaryText("test_summary")
+                .setIconDrawable(mContext.getDrawable(R.drawable.ic_do_not_disturb_on_24dp))
+                .setViewType(LegacySuggestionContextualCardRenderer.VIEW_TYPE)
+                .build();
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRendererTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRendererTest.java
index 596e95d6..65b3233 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRendererTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardRendererTest.java
@@ -83,6 +83,25 @@
     }
 
     @Test
+    public void bindView_closeButton_shouldSetListener() {
+        final RecyclerView recyclerView = new RecyclerView(mActivity);
+        recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
+        final ContextualCard card = buildContextualCard();
+        final View cardView = LayoutInflater.from(mActivity).inflate(card.getViewType(),
+                recyclerView, false);
+        final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(cardView,
+                card.getViewType());
+        final View closeButton = viewHolder.itemView.findViewById(R.id.close_button);
+        when(mControllerRendererPool.getController(mActivity,
+                ContextualCard.CardType.LEGACY_SUGGESTION)).thenReturn(mController);
+
+        mRenderer.bindView(viewHolder, buildContextualCard());
+
+        assertThat(closeButton).isNotNull();
+        assertThat(closeButton.hasOnClickListeners()).isTrue();
+    }
+
+    @Test
     public void viewClick_shouldInvokeControllerPrimaryClick() {
         final RecyclerView recyclerView = new RecyclerView(mActivity);
         recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
@@ -102,6 +121,27 @@
         verify(mController).onPrimaryClick(any(ContextualCard.class));
     }
 
+    @Test
+    public void viewClick_closeButton_shouldInvokeControllerDismissClick() {
+        final RecyclerView recyclerView = new RecyclerView(mActivity);
+        recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
+        final ContextualCard card = buildContextualCard();
+        final View cardView = LayoutInflater.from(mActivity).inflate(card.getViewType(),
+                recyclerView, false);
+        final RecyclerView.ViewHolder viewHolder = mRenderer.createViewHolder(cardView,
+                card.getViewType());
+        final View closeButton = viewHolder.itemView.findViewById(R.id.close_button);
+        when(mControllerRendererPool.getController(mActivity,
+                ContextualCard.CardType.LEGACY_SUGGESTION)).thenReturn(mController);
+
+        mRenderer.bindView(viewHolder, buildContextualCard());
+
+        assertThat(closeButton).isNotNull();
+        closeButton.performClick();
+
+        verify(mController).onDismissed(any(ContextualCard.class));
+    }
+
     private ContextualCard buildContextualCard() {
         return new LegacySuggestionContextualCard.Builder()
                 .setName("test_name")
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardTest.java
index e0e5a0c..2ffbdc9 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/legacysuggestion/LegacySuggestionContextualCardTest.java
@@ -21,6 +21,7 @@
 import static org.mockito.Mockito.mock;
 
 import android.app.PendingIntent;
+import android.service.settings.suggestions.Suggestion;
 
 import com.android.settings.homepage.contextualcards.ContextualCard;
 
@@ -51,4 +52,12 @@
                 .build()
                 .getPendingIntent()).isNotNull();
     }
+
+    @Test
+    public void build_shouldSetSuggestion() {
+        assertThat(new LegacySuggestionContextualCard.Builder()
+                .setSuggestion(mock(Suggestion.class))
+                .build()
+                .getSuggestion()).isNotNull();
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceControllerTest.java
new file mode 100644
index 0000000..e4eac68
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gBasePreferenceControllerTest.java
@@ -0,0 +1,126 @@
+/*
+ * 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.network.telephony;
+
+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 android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+
+import androidx.preference.SwitchPreference;
+
+import com.android.ims.ImsManager;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.RestrictedSwitchPreference;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class Enhanced4gBasePreferenceControllerTest {
+    private static final int SUB_ID = 2;
+
+    @Mock
+    private TelephonyManager mTelephonyManager;
+    @Mock
+    private TelephonyManager mInvalidTelephonyManager;
+    @Mock
+    private SubscriptionManager mSubscriptionManager;
+    @Mock
+    private CarrierConfigManager mCarrierConfigManager;
+    @Mock
+    private ImsManager mImsManager;
+
+    private Enhanced4gLtePreferenceController mController;
+    private SwitchPreference mPreference;
+    private PersistableBundle mCarrierConfig;
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = spy(RuntimeEnvironment.application);
+        doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE);
+        doReturn(mSubscriptionManager).when(mContext).getSystemService(SubscriptionManager.class);
+        doReturn(mCarrierConfigManager).when(mContext).getSystemService(CarrierConfigManager.class);
+        doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(SUB_ID);
+        doReturn(mInvalidTelephonyManager).when(mTelephonyManager).createForSubscriptionId(
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+
+        mCarrierConfig = new PersistableBundle();
+        doReturn(mCarrierConfig).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
+
+        mPreference = new RestrictedSwitchPreference(mContext);
+        mController = new Enhanced4gLtePreferenceController(mContext, "roaming");
+        mController.init(SUB_ID);
+        mController.mImsManager = mImsManager;
+        mPreference.setKey(mController.getPreferenceKey());
+    }
+
+    @Test
+    public void getAvailabilityStatus_default_returnUnavailable() {
+        mController.init(SUB_ID);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(
+                BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_volteDisabled_returnUnavailable() {
+        doReturn(false).when(mImsManager).isVolteEnabledByPlatform();
+        doReturn(true).when(mImsManager).isVolteProvisionedOnDevice();
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(
+                BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
+    }
+
+    @Test
+    public void updateState_configEnabled_prefEnabled() {
+        mPreference.setEnabled(false);
+        mCarrierConfig.putInt(CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 1);
+        doReturn(TelephonyManager.CALL_STATE_IDLE).when(mTelephonyManager).getCallState(SUB_ID);
+        doReturn(true).when(mImsManager).isNonTtyOrTtyOnVolteEnabled();
+        mCarrierConfig.putBoolean(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL, true);
+
+        mController.updateState(mPreference);
+
+        assertThat(mPreference.isEnabled()).isTrue();
+    }
+
+    @Test
+    public void updateState_configOn_prefChecked() {
+        mPreference.setChecked(false);
+        doReturn(true).when(mImsManager).isEnhanced4gLteModeSettingEnabledByUser();
+        doReturn(true).when(mImsManager).isNonTtyOrTtyOnVolteEnabled();
+
+        mController.updateState(mPreference);
+
+        assertThat(mPreference.isChecked()).isTrue();
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gLtePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gLtePreferenceControllerTest.java
deleted file mode 100644
index bea8f67..0000000
--- a/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gLtePreferenceControllerTest.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.network.telephony;
-
-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 android.os.PersistableBundle;
-import android.telephony.CarrierConfigManager;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-
-import androidx.preference.SwitchPreference;
-
-import com.android.ims.ImsManager;
-import com.android.settings.R;
-import com.android.settings.core.BasePreferenceController;
-import com.android.settingslib.RestrictedSwitchPreference;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-@RunWith(RobolectricTestRunner.class)
-public class Enhanced4gLtePreferenceControllerTest {
-    private static final int SUB_ID = 2;
-
-    @Mock
-    private TelephonyManager mTelephonyManager;
-    @Mock
-    private TelephonyManager mInvalidTelephonyManager;
-    @Mock
-    private SubscriptionManager mSubscriptionManager;
-    @Mock
-    private CarrierConfigManager mCarrierConfigManager;
-    @Mock
-    private ImsManager mImsManager;
-
-    private Enhanced4gLtePreferenceController mController;
-    private SwitchPreference mPreference;
-    private PersistableBundle mCarrierConfig;
-    private Context mContext;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        mContext = spy(RuntimeEnvironment.application);
-        doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE);
-        doReturn(mSubscriptionManager).when(mContext).getSystemService(SubscriptionManager.class);
-        doReturn(mCarrierConfigManager).when(mContext).getSystemService(CarrierConfigManager.class);
-        doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(SUB_ID);
-        doReturn(mInvalidTelephonyManager).when(mTelephonyManager).createForSubscriptionId(
-                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-
-        mCarrierConfig = new PersistableBundle();
-        doReturn(mCarrierConfig).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
-
-        mPreference = new RestrictedSwitchPreference(mContext);
-        mController = new Enhanced4gLtePreferenceController(mContext, "roaming");
-        mController.init(SUB_ID);
-        mController.mImsManager = mImsManager;
-        mPreference.setKey(mController.getPreferenceKey());
-    }
-
-    @Test
-    public void getAvailabilityStatus_invalidSubId_returnUnavailable() {
-        mController.init(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(
-                BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
-    }
-
-    @Test
-    public void getAvailabilityStatus_volteDisabled_returnUnavailable() {
-        doReturn(false).when(mImsManager).isVolteEnabledByPlatform();
-        doReturn(true).when(mImsManager).isVolteProvisionedOnDevice();
-
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(
-                BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
-    }
-
-    @Test
-    public void updateState_doNotShow4GForLTE_showVolteTitleAndSummary() {
-        mCarrierConfig.putBoolean(CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL, false);
-
-        mCarrierConfig.putInt(CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 0);
-        mController.updateState(mPreference);
-        assertThat(mPreference.getTitle()).isEqualTo(
-            mContext.getString(R.string.enhanced_4g_lte_mode_title));
-        assertThat(mPreference.getSummary()).isEqualTo(
-            mContext.getString(R.string.enhanced_4g_lte_mode_summary));
-
-        mCarrierConfig.putInt(CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 2);
-        mController.updateState(mPreference);
-        assertThat(mPreference.getTitle()).isEqualTo(
-            mContext.getString(R.string.enhanced_4g_lte_mode_title));
-        assertThat(mPreference.getSummary()).isEqualTo(
-            mContext.getString(R.string.enhanced_4g_lte_mode_summary));
-    }
-
-    @Test
-    public void updateState_show4GForLTE_show4GTitleAndSummary() {
-        mCarrierConfig.putBoolean(CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL, true);
-
-        mCarrierConfig.putInt(CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 0);
-        mController.updateState(mPreference);
-        assertThat(mPreference.getTitle()).isEqualTo(
-            mContext.getString(R.string.enhanced_4g_lte_mode_title_4g_calling));
-        assertThat(mPreference.getSummary()).isEqualTo(
-            mContext.getString(R.string.enhanced_4g_lte_mode_summary_4g_calling));
-
-        mCarrierConfig.putInt(CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 2);
-        mController.updateState(mPreference);
-        assertThat(mPreference.getTitle()).isEqualTo(
-            mContext.getString(R.string.enhanced_4g_lte_mode_title_4g_calling));
-        assertThat(mPreference.getSummary()).isEqualTo(
-            mContext.getString(R.string.enhanced_4g_lte_mode_summary_4g_calling));
-    }
-
-    @Test
-    public void updateState_variantAdvancedCalling_showAdvancedCallingTitleAndSummary() {
-        mCarrierConfig.putInt(CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 1);
-
-        mCarrierConfig.putBoolean(CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL, false);
-        mController.updateState(mPreference);
-        assertThat(mPreference.getTitle()).isEqualTo(
-            mContext.getString(R.string.enhanced_4g_lte_mode_title_advanced_calling));
-        assertThat(mPreference.getSummary()).isEqualTo(
-            mContext.getString(R.string.enhanced_4g_lte_mode_summary));
-
-        mCarrierConfig.putBoolean(CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL, true);
-        mController.updateState(mPreference);
-        assertThat(mPreference.getTitle()).isEqualTo(
-            mContext.getString(R.string.enhanced_4g_lte_mode_title_advanced_calling));
-        assertThat(mPreference.getSummary()).isEqualTo(
-            mContext.getString(R.string.enhanced_4g_lte_mode_summary));
-    }
-
-    @Test
-    public void updateState_configEnabled_prefEnabled() {
-        mPreference.setEnabled(false);
-        mCarrierConfig.putInt(CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 1);
-        doReturn(TelephonyManager.CALL_STATE_IDLE).when(mTelephonyManager).getCallState(SUB_ID);
-        doReturn(true).when(mImsManager).isNonTtyOrTtyOnVolteEnabled();
-        mCarrierConfig.putBoolean(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL, true);
-
-        mController.updateState(mPreference);
-
-        assertThat(mPreference.isEnabled()).isTrue();
-    }
-
-    @Test
-    public void updateState_configOn_prefChecked() {
-        mPreference.setChecked(false);
-        doReturn(true).when(mImsManager).isEnhanced4gLteModeSettingEnabledByUser();
-        doReturn(true).when(mImsManager).isNonTtyOrTtyOnVolteEnabled();
-
-        mController.updateState(mPreference);
-
-        assertThat(mPreference.isChecked()).isTrue();
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java
index 86f2355..f079396 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java
@@ -16,7 +16,7 @@
 
 package com.android.settings.network.telephony;
 
-import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
+import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -88,10 +88,10 @@
     }
 
     @Test
-    public void getAvailabilityStatus_invalidSubscription_returnDisabledDependentSetting() {
+    public void getAvailabilityStatus_invalidSubscription_returnAvailableUnsearchable() {
         mController.init(mFragmentManager, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
 
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/network/telephony/NetworkScanHelperTest.java b/tests/robotests/src/com/android/settings/network/telephony/NetworkScanHelperTest.java
new file mode 100644
index 0000000..1f8c16d
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/network/telephony/NetworkScanHelperTest.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2019 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.network.telephony;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.telephony.CellInfo;
+import android.telephony.NetworkScan;
+import android.telephony.NetworkScanRequest;
+import android.telephony.TelephonyManager;
+import android.telephony.TelephonyScanManager;
+import com.android.internal.telephony.CellNetworkScanResult;
+import com.android.internal.telephony.OperatorInfo;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class NetworkScanHelperTest {
+
+    @Mock
+    private TelephonyManager mTelephonyManager;
+
+    @Mock
+    private CellNetworkScanResult mCellNetworkScanResult;
+
+    @Mock
+    private NetworkScanHelper.NetworkScanCallback mNetworkScanCallback;
+
+    private static final long THREAD_EXECUTION_TIMEOUT_MS = 3000L;
+
+    private ExecutorService mNetworkScanExecutor;
+    private NetworkScanHelper mNetworkScanHelper;
+
+    private static final int SCAN_ID = 1234;
+    private static final int SUB_ID = 1;
+
+    private NetworkScan mNetworkScan;
+    private OperatorInfo mOperatorInfo;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mNetworkScanExecutor = Executors.newFixedThreadPool(1);
+
+        mNetworkScanHelper = new NetworkScanHelper(mTelephonyManager,
+                mNetworkScanCallback, mNetworkScanExecutor);
+
+        mNetworkScan = spy(new NetworkScan(SCAN_ID, SUB_ID));
+        mOperatorInfo = new OperatorInfo("Testing", "Test", "12345", "unknown");
+    }
+
+    @Test
+    public void startNetworkScan_scanOnceAndSuccess_completionWithResult() {
+        ArrayList<OperatorInfo> expectedResult = new ArrayList<OperatorInfo>();
+        expectedResult.add(mOperatorInfo);
+
+        when(mTelephonyManager.getAvailableNetworks()).thenReturn(mCellNetworkScanResult);
+        when(mCellNetworkScanResult.getStatus()).thenReturn(
+                CellNetworkScanResult.STATUS_SUCCESS);
+        when(mCellNetworkScanResult.getOperators()).thenReturn(expectedResult);
+
+        ArgumentCaptor<List<CellInfo>> argument = ArgumentCaptor.forClass(List.class);
+
+        startNetworkScan_waitForAll(true);
+
+        verify(mNetworkScanCallback, times(1)).onResults(argument.capture());
+        List<CellInfo> actualResult = argument.getValue();
+        assertThat(actualResult.size()).isEqualTo(expectedResult.size());
+        verify(mNetworkScanCallback, times(1)).onComplete();
+    }
+
+    @Test
+    public void startNetworkScan_scanOnceAndFail_failureWithErrorCode() {
+        when(mTelephonyManager.getAvailableNetworks()).thenReturn(mCellNetworkScanResult);
+        when(mCellNetworkScanResult.getStatus()).thenReturn(
+                CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE);
+
+        startNetworkScan_waitForAll(true);
+
+        verify(mNetworkScanCallback, times(1)).onError(anyInt());
+    }
+
+    @Test
+    public void startNetworkScan_scanOnceAndAbort_withoutCrash() {
+        when(mCellNetworkScanResult.getStatus()).thenReturn(
+                CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE);
+
+        doAnswer(new Answer() {
+            @Override
+            public Object answer(InvocationOnMock invocation) throws Throwable {
+                Thread.sleep(THREAD_EXECUTION_TIMEOUT_MS);
+                return mCellNetworkScanResult;
+            }
+        }).when(mTelephonyManager).getAvailableNetworks();
+
+        startNetworkScan_waitForAll(false);
+
+        verify(mNetworkScanCallback, times(0)).onError(anyInt());
+    }
+
+    @Test
+    public void startNetworkScan_incrementalAndSuccess_completionWithResult() {
+        ArrayList<CellInfo> expectedResult = new ArrayList<CellInfo>();
+        expectedResult.add(CellInfoUtil.convertOperatorInfoToCellInfo(mOperatorInfo));
+
+        doAnswer(new Answer() {
+            @Override
+            public Object answer(InvocationOnMock invocation) throws Throwable {
+                TelephonyScanManager.NetworkScanCallback callback =
+                        (TelephonyScanManager.NetworkScanCallback)
+                        (invocation.getArguments()[2]);
+                callback.onResults(expectedResult);
+                callback.onComplete();
+                return mNetworkScan;
+            }
+        }).when(mTelephonyManager).requestNetworkScan(
+                any(NetworkScanRequest.class), any(Executor.class),
+                any(TelephonyScanManager.NetworkScanCallback.class));
+
+        ArgumentCaptor<List<CellInfo>> argument = ArgumentCaptor.forClass(List.class);
+
+        startNetworkScan_incremental(true);
+
+        verify(mNetworkScanCallback, times(1)).onResults(argument.capture());
+        List<CellInfo> actualResult = argument.getValue();
+        assertThat(actualResult.size()).isEqualTo(expectedResult.size());
+        verify(mNetworkScanCallback, times(1)).onComplete();
+    }
+
+    @Test
+    public void startNetworkScan_incrementalAndImmediateFailure_failureWithErrorCode() {
+        doReturn(null).when(mTelephonyManager).requestNetworkScan(
+                any(NetworkScanRequest.class), any(Executor.class),
+                any(TelephonyScanManager.NetworkScanCallback.class));
+
+        startNetworkScan_incremental(true);
+
+        verify(mNetworkScanCallback, times(1)).onError(anyInt());
+    }
+
+    @Test
+    public void startNetworkScan_incrementalAndFailure_failureWithErrorCode() {
+        doAnswer(new Answer() {
+            @Override
+            public Object answer(InvocationOnMock invocation) throws Throwable {
+                TelephonyScanManager.NetworkScanCallback callback =
+                        (TelephonyScanManager.NetworkScanCallback)
+                        (invocation.getArguments()[2]);
+                callback.onError(CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE);
+                return mNetworkScan;
+            }
+        }).when(mTelephonyManager).requestNetworkScan(
+                any(NetworkScanRequest.class), any(Executor.class),
+                any(TelephonyScanManager.NetworkScanCallback.class));
+
+        startNetworkScan_incremental(true);
+
+        verify(mNetworkScanCallback, times(1)).onError(anyInt());
+    }
+
+    @Test
+    public void startNetworkScan_incrementalAndAbort_doStop() {
+        doReturn(mNetworkScan).when(mTelephonyManager).requestNetworkScan(
+                any(NetworkScanRequest.class), any(Executor.class),
+                any(TelephonyScanManager.NetworkScanCallback.class));
+
+        startNetworkScan_incremental(false);
+
+        verify(mNetworkScan, times(1)).stopScan();
+    }
+
+    private void startNetworkScan_waitForAll(boolean waitForCompletion) {
+        mNetworkScanHelper.startNetworkScan(
+                NetworkScanHelper.NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS);
+        if (!waitForCompletion) {
+            mNetworkScanHelper.stopNetworkQuery();
+        }
+
+        mNetworkScanExecutor.shutdown();
+
+        boolean executorTerminate = false;
+        try {
+            executorTerminate = mNetworkScanExecutor.awaitTermination(
+                    THREAD_EXECUTION_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+        } catch (Exception ex) {
+        }
+
+        assertThat(executorTerminate).isEqualTo(waitForCompletion);
+    }
+
+    private void startNetworkScan_incremental(boolean waitForCompletion) {
+        mNetworkScanHelper.startNetworkScan(
+                NetworkScanHelper.NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS);
+        if (!waitForCompletion) {
+            mNetworkScanHelper.stopNetworkQuery();
+        }
+    }
+
+}
diff --git a/tests/robotests/src/com/android/settings/privacy/AccessibilityUsagePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/privacy/AccessibilityUsagePreferenceControllerTest.java
index 33109b0..c07b1ad 100644
--- a/tests/robotests/src/com/android/settings/privacy/AccessibilityUsagePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/privacy/AccessibilityUsagePreferenceControllerTest.java
@@ -20,12 +20,13 @@
 import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
 
 import static com.google.common.truth.Truth.assertThat;
+
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.content.Context;
-import android.provider.DeviceConfig;
 import android.view.accessibility.AccessibilityManager;
 
-import com.android.settings.Utils;
+import androidx.preference.Preference;
+
 import com.android.settings.testutils.shadow.ShadowDeviceConfig;
 
 import org.junit.After;
@@ -65,10 +66,8 @@
 
     @Test
     public void getAvailabilityStatus_noEnabledServices_shouldReturnUnsupported() {
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_PRIVACY,
-                Utils.PROPERTY_PERMISSIONS_HUB_ENABLED, "true", true);
         mAccessibilityManager.setEnabledAccessibilityServiceList(new ArrayList<>());
-        AccessibilityUsagePreferenceController controller =
+        final AccessibilityUsagePreferenceController controller =
                 new AccessibilityUsagePreferenceController(mContext, "test_key");
 
         assertThat(controller.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
@@ -76,13 +75,24 @@
 
     @Test
     public void getAvailabilityStatus_enabledServices_shouldReturnAvailable() {
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_PRIVACY,
-                Utils.PROPERTY_PERMISSIONS_HUB_ENABLED, "false", true);
         mAccessibilityManager.setEnabledAccessibilityServiceList(
                 new ArrayList<>(Arrays.asList(new AccessibilityServiceInfo())));
-        AccessibilityUsagePreferenceController controller =
+        final AccessibilityUsagePreferenceController controller =
                 new AccessibilityUsagePreferenceController(mContext, "test_key");
 
         assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE);
     }
+
+    @Test
+    public void updateState_noEnabledServices_shouldHidePreference() {
+        mAccessibilityManager.setEnabledAccessibilityServiceList(new ArrayList<>());
+        final AccessibilityUsagePreferenceController controller =
+                new AccessibilityUsagePreferenceController(mContext, "test_key");
+        final Preference preference = new Preference(mContext);
+        preference.setVisible(true);
+
+        controller.updateState(preference);
+
+        assertThat(preference.isVisible()).isFalse();
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/search/FakeSettingsFragment.java b/tests/robotests/src/com/android/settings/search/FakeSettingsFragment.java
index 7011dda..ee27261 100644
--- a/tests/robotests/src/com/android/settings/search/FakeSettingsFragment.java
+++ b/tests/robotests/src/com/android/settings/search/FakeSettingsFragment.java
@@ -70,7 +70,7 @@
     }
 
     /** Index provider used to expose this fragment in search. */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
                 @Override
                 public List<SearchIndexableRaw> getRawDataToIndex(Context context,
diff --git a/tests/robotests/src/com/android/settings/testutils/FakeIndexProvider.java b/tests/robotests/src/com/android/settings/testutils/FakeIndexProvider.java
index a8a65e5..05ba163 100644
--- a/tests/robotests/src/com/android/settings/testutils/FakeIndexProvider.java
+++ b/tests/robotests/src/com/android/settings/testutils/FakeIndexProvider.java
@@ -29,7 +29,7 @@
 
     public static final String KEY = "TestKey";
 
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider(R.xml.location_settings) {
 
                 @Override
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java
index e692fed..226dfdb 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiConfigControllerTest.java
@@ -40,6 +40,7 @@
 import android.view.inputmethod.InputMethodManager;
 import android.widget.ArrayAdapter;
 import android.widget.CheckBox;
+import android.widget.LinearLayout;
 import android.widget.Spinner;
 import android.widget.TextView;
 
@@ -546,4 +547,14 @@
 
         assertThat(eapMethodSpinner.getSelectedItemPosition()).isEqualTo(Eap.TLS);
     }
+
+    @Test
+    public void getHiddenSettingsPosition_whenAdvancedToggled_shouldBeFirst() {
+        final LinearLayout advancedFieldsLayout = mView.findViewById(R.id.wifi_advanced_fields);
+        final LinearLayout hiddenSettingLayout = mView.findViewById(R.id.hidden_settings_field);
+
+        final LinearLayout firstChild = (LinearLayout) advancedFieldsLayout.getChildAt(0);
+
+        assertThat(firstChild).isEqualTo(hiddenSettingLayout);
+    }
 }
diff --git a/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java b/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java
index ad6be04..3fcccf6 100644
--- a/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java
+++ b/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java
@@ -28,8 +28,8 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.DatabaseIndexingUtils;
-import com.android.settings.search.Indexable;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.search.SearchIndexableResources;
 
@@ -62,8 +62,8 @@
                         .getSearchIndexableResources();
         for (Class<?> clazz : resources.getProviderValues()) {
 
-            final Indexable.SearchIndexProvider provider =
-                    DatabaseIndexingUtils.getSearchIndexProvider(clazz);
+            final BaseSearchIndexProvider provider =
+                    (BaseSearchIndexProvider) DatabaseIndexingUtils.getSearchIndexProvider(clazz);
             if (provider == null) {
                 continue;
             }