Merge "Developer option off must not affect laser sensor"
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/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/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/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/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/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/gestures/SystemNavigationGestureSettings.java b/src/com/android/settings/gestures/SystemNavigationGestureSettings.java
index 54064ad..b9c390d 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,39 +325,6 @@
                 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 =
             new BaseSearchIndexProvider(R.xml.system_navigation_gesture_settings) {
 
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/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..2dc9f91 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
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/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/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/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/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/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/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/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);
+    }
 }