Merge "[Catalyst] Migrate Airplane Mode preference" into main
diff --git a/OWNERS b/OWNERS
index 12cd4ea..5aa30d5 100644
--- a/OWNERS
+++ b/OWNERS
@@ -13,16 +13,10 @@
 sunnyshao@google.com
 
 # Android Settings extended
-chaohuiw@google.com
-songferngwang@google.com
-tomhsu@google.com
-wengsu@google.com
-ykhung@google.com
+zhibinliu@google.com
 
 # Emergency only
 cipson@google.com
-hanxu@google.com
-yangfan@google.com
 
 # Exempt resource files (because they are in a flat directory and too hard to manage via OWNERS)
 per-file res*/**=*
diff --git a/res/layout/notification_ls_minimalism_selector.xml b/res/layout/notification_ls_minimalism_selector.xml
new file mode 100644
index 0000000..d37ad54
--- /dev/null
+++ b/res/layout/notification_ls_minimalism_selector.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2024 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.
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+    <TextView
+        android:id="@+id/notif_ls_style_desc"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingVertical="@dimen/settingslib_illustration_padding"
+        android:paddingEnd="48dp"
+        android:paddingStart="48dp"
+        android:layout_gravity="center_horizontal"
+        android:gravity="center"
+        android:focusable="true"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:textColor="?android:attr/textColorSecondary"/>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="16dp"
+        android:orientation="horizontal">
+
+        <Space
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1"/>
+
+        <LinearLayout
+            android:id="@+id/button_compact"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:orientation="vertical">
+
+            <FrameLayout
+                android:layout_width="@dimen/contrast_button_total_size"
+                android:layout_height="@dimen/contrast_button_total_size"
+                android:background="@drawable/accessibility_contrast_button_background">
+
+                <ImageView
+                    android:layout_gravity="center"
+                    android:layout_height="wrap_content"
+                    android:layout_width="wrap_content"
+                    android:contentDescription="@null"
+                    android:src="@drawable/ic_contrast_standard"/>
+            </FrameLayout>
+
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="@dimen/contrast_button_text_spacing"
+                android:gravity="center_horizontal|top"
+                android:ellipsize="end"
+                android:singleLine="true"
+                android:textSize="@dimen/contrast_button_text_size"
+                android:text="@string/lock_screen_notifs_show_compact"
+                android:textColor="?androidprv:attr/materialColorOnSurface"/>
+        </LinearLayout>
+
+        <Space
+            android:layout_width="@dimen/contrast_button_horizontal_spacing"
+            android:layout_height="match_parent" />
+
+        <LinearLayout
+            android:id="@+id/button_full"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:orientation="vertical">
+
+            <FrameLayout
+                android:layout_width="@dimen/contrast_button_total_size"
+                android:layout_height="@dimen/contrast_button_total_size"
+                android:background="@drawable/accessibility_contrast_button_background">
+
+                <ImageView
+                    android:layout_gravity="center"
+                    android:layout_height="wrap_content"
+                    android:layout_width="wrap_content"
+                    android:contentDescription="@null"
+                    android:src="@drawable/ic_contrast_high"/>
+            </FrameLayout>
+
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="@dimen/contrast_button_text_spacing"
+                android:gravity="center_horizontal|top"
+                android:ellipsize="end"
+                android:singleLine="true"
+                android:textSize="@dimen/contrast_button_text_size"
+                android:text="@string/lock_screen_notifs_show_full_list"
+                android:textColor="?androidprv:attr/materialColorOnSurface"/>
+        </LinearLayout>
+
+        <Space
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1"/>
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 1ad507a..847e27c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -8789,6 +8789,18 @@
     <!-- Configure notifications: Summary for option of showing only new notifications on the lock screen. [CHAR LIMIT=100] -->
     <string name="unseen_notifs_lock_screen_summary">Automatically remove previously viewed notifications from the lock screen</string>
 
+    <!-- Configure notifications: Value for lockscreen notifications: show all notifications [CHAR LIMIT=60] -->
+    <string name="lock_screen_notifs_show_full_list">Full list</string>
+
+    <!-- Configure notifications: Summary for lockscreen notifications: show all notifications [CHAR LIMIT=100] -->
+    <string name="lock_screen_notifs_full_list_desc">The current default placement is a full shelf and notification stack.</string>
+
+    <!-- Configure notifications: Value for lockscreen notifications: show compact notifications (minimalism on) [CHAR LIMIT=60] -->
+    <string name="lock_screen_notifs_show_compact">Compact</string>
+
+    <!-- Configure notifications: Summary for lockscreen notifications: show compact notifications (minimalism on) [CHAR LIMIT=60] -->
+    <string name="lock_screen_notifs_compact_desc">New notifications are collapsed into a shelf on your lockscreen.</string>
+
     <!-- Configure notifications: Title for determining which notifications appear on the lock screen [CHAR LIMIT=60] -->
     <string name="lock_screen_notifs_title">Notifications on lock screen</string>
 
@@ -8851,6 +8863,18 @@
     <!-- Security > Choose PIN/PW/Pattern > Notification redaction interstitial: Message asking the user how they want their profile notifications to appear when the device is locked [CHAR LIMIT=NONE] -->
     <string name="lock_screen_notifications_interstitial_message_profile">When your device is locked, how do you want profile notifications to show?</string>
 
+    <!-- Notification Settings > Notifications on lock screen > Title for hiding seen notifications toggle. [CHAR LIMIT=30] -->
+    <string name="lock_screen_notification_hide_seen_title">Hide seen notifications</string>
+
+    <!-- Notification Settings > Notifications on lock screen > Summary for hiding seen notifications toggle. [CHAR LIMIT=30] -->
+    <string name="lock_screen_notification_hide_seen_summary">Seen notifications are removed from the lock screen.</string>
+
+    <!-- Notification Settings > Notifications on lock screen > Title for hiding silent notifications toggle. [CHAR LIMIT=30] -->
+    <string name="lock_screen_notification_hide_silent_title">Hide silent notifications</string>
+
+    <!-- Notification Settings > Notifications on lock screen > Summary for hiding seen notifications toggle. [CHAR LIMIT=30] -->
+    <string name="lock_screen_notification_hide_silent_summary">Silent notifications and conversations are removed from the lock screen.</string>
+
     <!-- Security > Choose PIN/PW/Pattern > Notification redaction interstitial: Title for the screen asking the user how they want their profile notifications to appear when the device is locked [CHAR LIMIT=30] -->
     <string name="lock_screen_notifications_interstitial_title_profile">Profile notifications</string>
 
diff --git a/res/xml/configure_notification_settings.xml b/res/xml/configure_notification_settings.xml
index aedf0b4..e5fddc4 100644
--- a/res/xml/configure_notification_settings.xml
+++ b/res/xml/configure_notification_settings.xml
@@ -92,23 +92,31 @@
             android:singleLineTitle="false"
             android:summary="@string/summary_placeholder" />
 
+        <Preference
+            android:key="lock_screen_notifications_page"
+            android:order="14"
+            android:persistent="false"
+            android:title="@string/lock_screen_notifs_title"
+            android:fragment="com.android.settings.notification.LockScreenNotificationsPreferencePageFragment"
+            settings:controller="com.android.settings.notification.LockScreenNotificationsPreferencePageController" />
+
         <com.android.settingslib.RestrictedSwitchPreference
             android:key="lock_screen_redact"
-            android:order="14"
+            android:order="15"
             android:title="@string/lock_screen_notifs_redact"
             android:summary="@string/lock_screen_notifs_redact_summary"
             settings:controller="com.android.settings.notification.RedactNotificationPreferenceController" />
 
         <com.android.settingslib.RestrictedSwitchPreference
             android:key="lock_screen_work_redact"
-            android:order="15"
+            android:order="16"
             android:title="@string/lock_screen_notifs_redact_work"
             android:summary="@string/lock_screen_notifs_redact_work_summary"
             settings:controller="com.android.settings.notification.RedactNotificationPreferenceController" />
 
         <SwitchPreferenceCompat
             android:key="notification_lockscreen_bypass"
-            android:order="16"
+            android:order="17"
             android:title="@string/lockscreen_bypass_title"
             android:summary="@string/lockscreen_bypass_summary"
             settings:searchable="false"
@@ -129,14 +137,14 @@
         <Preference
             android:fragment="com.android.settings.notification.PoliteNotificationsPreferenceFragment"
             android:key="polite_notifications_preference"
-            android:order="17"
+            android:order="18"
             android:persistent="false"
             android:title="@string/notification_polite_title"
             settings:controller="com.android.settings.notification.PoliteNotificationsPreferenceController" />
 
         <com.android.settingslib.RestrictedPreference
             android:key="zen_mode_notifications"
-            android:order="18"
+            android:order="19"
             android:title="@string/zen_mode_settings_title"
             settings:useAdminDisabledSummary="true"
             android:fragment="com.android.settings.notification.zen.ZenModeSettings"
@@ -145,7 +153,7 @@
 
         <SwitchPreferenceCompat
             android:key="lock_screen_notif_minimalism"
-            android:order="19"
+            android:order="20"
             android:title="@string/lock_screen_notif_minimalism"
             android:summary="@string/lock_screen_notif_minimalism_summary"
             settings:controller="com.android.settings.notification.LockscreenNotificationMinimalismPreferenceController"
@@ -153,7 +161,7 @@
 
         <SwitchPreferenceCompat
             android:key="lock_screen_show_only_unseen_notifs"
-            android:order="20"
+            android:order="21"
             android:title="@string/unseen_notifs_lock_screen"
             android:summary="@string/unseen_notifs_lock_screen_summary"
             settings:controller="com.android.settings.notification.ShowOnlyUnseenNotificationsOnLockscreenPreferenceController"
@@ -162,7 +170,7 @@
         <Preference
             android:fragment="com.android.settings.accessibility.FlashNotificationsPreferenceFragment"
             android:key="flash_notifications_preference"
-            android:order="21"
+            android:order="22"
             android:persistent="false"
             android:title="@string/flash_notifications_title"
             settings:searchable="false"
@@ -170,7 +178,7 @@
 
         <com.android.settingslib.RestrictedPreference
             android:key="app_and_notif_cell_broadcast_settings"
-            android:order="22"
+            android:order="23"
             android:title="@string/cell_broadcast_settings"
             settings:useAdminDisabledSummary="true">
             <intent
@@ -181,33 +189,33 @@
 
         <SwitchPreferenceCompat
              android:key="silent_icons"
-             android:order="23"
+             android:order="24"
              android:title="@string/silent_notifications_status_bar"
              settings:controller="com.android.settings.notification.SilentStatusBarPreferenceController"/>
 
         <SwitchPreferenceCompat
             android:key="show_snooze_options"
-            android:order="24"
+            android:order="25"
             android:title="@string/snooze_options_title"
             settings:controller="com.android.settings.notification.SnoozeNotificationPreferenceController" />
 
         <!-- Notification badging -->
         <SwitchPreferenceCompat
             android:key="notification_badging"
-            android:order="25"
+            android:order="26"
             android:title="@string/notification_badging_title"
             settings:controller="com.android.settings.notification.BadgingNotificationPreferenceController"/>
 
         <!-- Pulse notification light, on devices that support it -->
         <SwitchPreferenceCompat
             android:key="notification_pulse"
-            android:order="26"
+            android:order="27"
             android:title="@string/notification_pulse_title"
             settings:controller="com.android.settings.notification.PulseNotificationPreferenceController"/>
 
         <SwitchPreferenceCompat
             android:key="notification_assistant"
-            android:order="27"
+            android:order="28"
             android:title="@string/notification_assistant_title"
             android:summary="@string/notification_assistant_summary"
             settings:controller="com.android.settings.notification.NotificationAssistantPreferenceController"/>
diff --git a/res/xml/lock_screen_notifications_settings.xml b/res/xml/lock_screen_notifications_settings.xml
new file mode 100644
index 0000000..b5fb128
--- /dev/null
+++ b/res/xml/lock_screen_notifications_settings.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2024 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.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+    android:title="@string/lock_screen_notifs_title"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <com.android.settingslib.widget.MainSwitchPreference
+        android:key="lock_screen_notification_global_pref"
+        android:title="@string/switch_on_text"
+        settings:controller="com.android.settings.notification.LockScreenNotificationsGlobalPreferenceController"/>
+
+<!--    TODO: replace res with actual illustrations when we have -->
+    <com.android.settingslib.widget.IllustrationPreference
+        android:key="compact_illustration"
+        settings:searchable="false"
+        android:selectable="false"
+        settings:dynamicColor="true"/>
+
+    <com.android.settingslib.widget.IllustrationPreference
+        android:key="full_list_illustration"
+        settings:searchable="false"
+        android:selectable="false"
+        settings:dynamicColor="true"/>
+
+    <com.android.settingslib.widget.LayoutPreference
+        android:key="ls_minimalism"
+        android:selectable="false"
+        android:layout="@layout/notification_ls_minimalism_selector"
+        settings:controller="com.android.settings.notification.lockscreen.MinimalismPreferenceController" />
+
+    <com.android.settingslib.RestrictedSwitchPreference
+        android:key="lock_screen_notification_show_sensitive_toggle"
+        android:title="@string/lock_screen_notifications_summary_hide"
+        settings:controller="com.android.settings.notification.LockScreenNotificationShowSensitiveToggleController" />
+
+    <com.android.settingslib.RestrictedSwitchPreference
+        android:key="work_profile_show_sensitive_notif_toggle"
+        android:title="@string/lock_screen_notifications_summary_hide_profile"
+        settings:controller="com.android.settings.notification.LockScreenNotificationShowSensitiveToggleController" />
+
+    <SwitchPreferenceCompat
+        android:key="lock_screen_notification_hide_seen_toggle"
+        android:title="@string/lock_screen_notification_hide_seen_title"
+        android:summary="@string/lock_screen_notification_hide_seen_summary"
+        settings:controller="com.android.settings.notification.LockScreenNotificationHideSeenToggleController" />
+
+    <SwitchPreferenceCompat
+        android:key="lock_screen_notification_hide_silent_toggle"
+        android:title="@string/lock_screen_notification_hide_silent_title"
+        android:summary="@string/lock_screen_notification_hide_silent_summary"
+        settings:controller="com.android.settings.notification.LockScreenNotificationHideSilentToggleController" />
+
+</PreferenceScreen>
diff --git a/res/xml/more_security_privacy_settings.xml b/res/xml/more_security_privacy_settings.xml
index f200493..56706c3 100644
--- a/res/xml/more_security_privacy_settings.xml
+++ b/res/xml/more_security_privacy_settings.xml
@@ -83,6 +83,12 @@
             android:summary="@string/summary_placeholder"
             settings:searchable="false"/>
 
+        <Preference
+            android:key="more_security_lock_screen_notifications_page"
+            android:title="@string/lock_screen_notifs_title"
+            android:fragment="com.android.settings.notification.LockScreenNotificationsPreferencePageFragment"
+            settings:controller="com.android.settings.notification.LockScreenNotificationsPreferencePageController" />
+
         <!-- Show media on lock screen -->
         <SwitchPreferenceCompat
             android:key="privacy_media_controls_lockscreen"
diff --git a/res/xml/power_background_usage_detail.xml b/res/xml/power_background_usage_detail.xml
index 32d80b5..05e4cfb 100644
--- a/res/xml/power_background_usage_detail.xml
+++ b/res/xml/power_background_usage_detail.xml
@@ -20,9 +20,8 @@
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:title="@string/manager_battery_usage_allow_background_usage_settings_title">
 
-    <com.android.settingslib.widget.LayoutPreference
+    <com.android.settingslib.widget.IntroPreference
         android:key="header_view"
-        android:layout="@layout/settings_entity_header"
         android:selectable="false"/>
 
     <PreferenceCategory
diff --git a/res/xml/power_usage_detail.xml b/res/xml/power_usage_detail.xml
index 655dbc5..c2b1c5e 100644
--- a/res/xml/power_usage_detail.xml
+++ b/res/xml/power_usage_detail.xml
@@ -19,9 +19,8 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:settings="http://schemas.android.com/apk/res-auto">
 
-    <com.android.settingslib.widget.LayoutPreference
+    <com.android.settingslib.widget.IntroPreference
         android:key="header_view"
-        android:layout="@layout/settings_entity_header"
         android:selectable="false"/>
 
     <com.android.settingslib.widget.ActionButtonsPreference
diff --git a/res/xml/privacy_dashboard_settings.xml b/res/xml/privacy_dashboard_settings.xml
index d5cb2f5..248f6c8 100644
--- a/res/xml/privacy_dashboard_settings.xml
+++ b/res/xml/privacy_dashboard_settings.xml
@@ -91,6 +91,12 @@
         android:title="@string/lock_screen_notifs_title"
         android:summary="@string/summary_placeholder"/>
 
+    <Preference
+        android:key="privacy_lock_screen_notifications_page"
+        android:title="@string/lock_screen_notifs_title"
+        android:fragment="com.android.settings.notification.LockScreenNotificationsPreferencePageFragment"
+        settings:controller="com.android.settings.notification.LockScreenNotificationsPreferencePageController" />
+
     <!-- Show media on lock screen -->
     <SwitchPreferenceCompat
         android:key="privacy_media_controls_lockscreen"
diff --git a/res/xml/security_lockscreen_settings.xml b/res/xml/security_lockscreen_settings.xml
index fdc738a..9b9df3e 100644
--- a/res/xml/security_lockscreen_settings.xml
+++ b/res/xml/security_lockscreen_settings.xml
@@ -29,6 +29,13 @@
             android:summary="@string/summary_placeholder"
             settings:keywords="@string/keywords_lock_screen_notif"/>
 
+        <Preference
+            android:key="security_lock_screen_notifications_page"
+            android:title="@string/lock_screen_notifs_title"
+            android:summary="@string/summary_placeholder"
+            android:fragment="com.android.settings.notification.LockScreenNotificationsPreferencePageFragment"
+            settings:controller="com.android.settings.notification.LockScreenNotificationsPreferencePageController" />
+
         <SwitchPreferenceCompat
             android:key="security_display_lockscreen_bypass"
             android:title="@string/lockscreen_bypass_title"
diff --git a/src/com/android/settings/bluetooth/ui/view/DeviceDetailsFragmentFormatter.kt b/src/com/android/settings/bluetooth/ui/view/DeviceDetailsFragmentFormatter.kt
index 5ce51de..2acabff 100644
--- a/src/com/android/settings/bluetooth/ui/view/DeviceDetailsFragmentFormatter.kt
+++ b/src/com/android/settings/bluetooth/ui/view/DeviceDetailsFragmentFormatter.kt
@@ -214,9 +214,11 @@
             }
         }
 
-        if (isLoading) {
-            fragment.setLoading(false, false)
-            isLoading = false
+        fragment.listView.post {
+            if (isLoading) {
+                fragment.setLoading(false, false)
+                isLoading = false
+            }
         }
     }
 
diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
index 28d7d58..288ec20 100644
--- a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
+++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
@@ -27,13 +27,11 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.util.Log;
-import android.view.View;
 
 import androidx.annotation.VisibleForTesting;
 
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
-import com.android.settings.Utils;
 import com.android.settings.applications.appinfo.AppButtonsPreferenceController;
 import com.android.settings.applications.appinfo.ButtonActionDialogFragment;
 import com.android.settings.core.InstrumentedPreferenceFragment;
@@ -44,12 +42,11 @@
 import com.android.settings.fuelgauge.batteryusage.BatteryDiffEntry;
 import com.android.settings.fuelgauge.batteryusage.BatteryEntry;
 import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.widget.EntityHeaderController;
-import com.android.settingslib.applications.AppUtils;
+import com.android.settingslib.Utils;
 import com.android.settingslib.applications.ApplicationsState;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.instrumentation.Instrumentable;
-import com.android.settingslib.widget.LayoutPreference;
+import com.android.settingslib.widget.IntroPreference;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -285,30 +282,26 @@
 
     @VisibleForTesting
     void initHeader() {
-        final LayoutPreference headerPreference = findPreference(KEY_PREF_HEADER);
-        final View appSnippet = headerPreference.findViewById(R.id.entity_header);
+        final IntroPreference introPreference = findPreference(KEY_PREF_HEADER);
+        if (introPreference == null) {
+            return;
+        }
         final Activity context = getActivity();
         final Bundle bundle = getArguments();
-        EntityHeaderController controller =
-                EntityHeaderController.newInstance(context, this, appSnippet)
-                        .setButtonActions(
-                                EntityHeaderController.ActionType.ACTION_NONE,
-                                EntityHeaderController.ActionType.ACTION_NONE);
 
         if (mAppEntry == null) {
-            controller.setLabel(bundle.getString(EXTRA_LABEL));
+            introPreference.setTitle(bundle.getString(EXTRA_LABEL));
 
             final int iconId = bundle.getInt(EXTRA_ICON_ID, 0);
             if (iconId == 0) {
-                controller.setIcon(context.getPackageManager().getDefaultActivityIcon());
+                introPreference.setIcon(context.getPackageManager().getDefaultActivityIcon());
             } else {
-                controller.setIcon(context.getDrawable(bundle.getInt(EXTRA_ICON_ID)));
+                introPreference.setIcon(context.getDrawable(bundle.getInt(EXTRA_ICON_ID)));
             }
         } else {
             mState.ensureIcon(mAppEntry);
-            controller.setLabel(mAppEntry);
-            controller.setIcon(mAppEntry);
-            controller.setIsInstantApp(AppUtils.isInstant(mAppEntry.info));
+            introPreference.setTitle(mAppEntry.label);
+            introPreference.setIcon(Utils.getBadgedIcon(context, mAppEntry.info));
         }
 
         if (mPowerUsageTimeController != null) {
@@ -324,7 +317,6 @@
                     anomalyHintPrefKey,
                     anomalyHintText);
         }
-        controller.done(true /* rebindActions */);
     }
 
     @Override
diff --git a/src/com/android/settings/fuelgauge/PowerBackgroundUsageDetail.java b/src/com/android/settings/fuelgauge/PowerBackgroundUsageDetail.java
index dadf2e8..90ced96 100644
--- a/src/com/android/settings/fuelgauge/PowerBackgroundUsageDetail.java
+++ b/src/com/android/settings/fuelgauge/PowerBackgroundUsageDetail.java
@@ -25,7 +25,6 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.util.Log;
-import android.view.View;
 
 import androidx.annotation.VisibleForTesting;
 
@@ -34,13 +33,12 @@
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.fuelgauge.batteryusage.AppOptModeSharedPreferencesUtils;
 import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.widget.EntityHeaderController;
 import com.android.settingslib.HelpUtils;
-import com.android.settingslib.applications.AppUtils;
+import com.android.settingslib.Utils;
 import com.android.settingslib.applications.ApplicationsState;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.widget.FooterPreference;
-import com.android.settingslib.widget.LayoutPreference;
+import com.android.settingslib.widget.IntroPreference;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -153,36 +151,27 @@
 
     @VisibleForTesting
     void initHeader() {
-        final LayoutPreference headerPreference = findPreference(KEY_PREF_HEADER);
-        if (headerPreference == null) {
+        final IntroPreference introPreference = findPreference(KEY_PREF_HEADER);
+        if (introPreference == null) {
             return;
         }
-        final View appSnippet = headerPreference.findViewById(R.id.entity_header);
         final Activity context = getActivity();
         final Bundle bundle = getArguments();
-        EntityHeaderController controller =
-                EntityHeaderController.newInstance(context, this, appSnippet)
-                        .setButtonActions(
-                                EntityHeaderController.ActionType.ACTION_NONE,
-                                EntityHeaderController.ActionType.ACTION_NONE);
 
         if (mAppEntry == null) {
-            controller.setLabel(bundle.getString(EXTRA_LABEL));
+            introPreference.setTitle(bundle.getString(EXTRA_LABEL));
 
             final int iconId = bundle.getInt(EXTRA_ICON_ID, 0);
             if (iconId == 0) {
-                controller.setIcon(context.getPackageManager().getDefaultActivityIcon());
+                introPreference.setIcon(context.getPackageManager().getDefaultActivityIcon());
             } else {
-                controller.setIcon(context.getDrawable(bundle.getInt(EXTRA_ICON_ID)));
+                introPreference.setIcon(context.getDrawable(bundle.getInt(EXTRA_ICON_ID)));
             }
         } else {
             mState.ensureIcon(mAppEntry);
-            controller.setLabel(mAppEntry);
-            controller.setIcon(mAppEntry);
-            controller.setIsInstantApp(AppUtils.isInstant(mAppEntry.info));
+            introPreference.setTitle(mAppEntry.label);
+            introPreference.setIcon(Utils.getBadgedIcon(context, mAppEntry.info));
         }
-
-        controller.done(true /* rebindActions */);
     }
 
     @VisibleForTesting
diff --git a/src/com/android/settings/notification/LockScreenNotificationHideSeenToggleController.java b/src/com/android/settings/notification/LockScreenNotificationHideSeenToggleController.java
new file mode 100644
index 0000000..3253937
--- /dev/null
+++ b/src/com/android/settings/notification/LockScreenNotificationHideSeenToggleController.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2024 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.notification;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+import android.provider.Settings;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleEventObserver;
+import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.server.notification.Flags;
+import com.android.settings.core.TogglePreferenceController;
+
+/**
+ * Controls the toggle that determines whether to hide seen notifications from the lock screen.
+ * Toggle for setting: Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS
+ */
+public class LockScreenNotificationHideSeenToggleController extends TogglePreferenceController
+        implements LifecycleEventObserver {
+
+    private static final int UNSET = 0;
+    static final int ON = 1;
+    static final int OFF = 2;
+    @Nullable private Preference mPreference;
+    private final ContentResolver mContentResolver;
+
+    final ContentObserver mContentObserver = new ContentObserver(
+            new Handler(Looper.getMainLooper())) {
+        @Override
+        public void onChange(boolean selfChange, @Nullable Uri uri) {
+            if (mPreference == null) return;
+            updateState(mPreference);
+        }
+    };
+
+    public LockScreenNotificationHideSeenToggleController(@NonNull Context context,
+            @NonNull String preferenceKey) {
+        super(context, preferenceKey);
+        mContentResolver = context.getContentResolver();
+    }
+
+    @Override
+    public void displayPreference(@NonNull PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreference = screen.findPreference(getPreferenceKey());
+    }
+
+    @Override
+    public void onStateChanged(@NonNull LifecycleOwner lifecycleOwner,
+            @NonNull Lifecycle.Event event) {
+        if (event == Lifecycle.Event.ON_RESUME) {
+            mContentResolver.registerContentObserver(
+                    Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS),
+                    /* notifyForDescendants= */ false, mContentObserver);
+            mContentResolver.registerContentObserver(
+                    Settings.Secure.getUriFor(
+                            Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS),
+                    /* notifyForDescendants= */ false,
+                    mContentObserver
+            );
+        } else if (event == Lifecycle.Event.ON_PAUSE) {
+            mContentResolver.unregisterContentObserver(mContentObserver);
+        }
+    }
+
+    @Override
+    public void updateState(@NonNull Preference preference) {
+        super.updateState(preference);
+        setChecked(lockScreenShowOnlyUnseenNotifications());
+        preference.setVisible(isAvailable());
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        if (!Flags.notificationMinimalism()) {
+            return CONDITIONALLY_UNAVAILABLE;
+        }
+        if (!lockScreenShowNotification()) {
+            return CONDITIONALLY_UNAVAILABLE;
+        }
+        return AVAILABLE;
+    }
+
+    /**
+     * @return Whether showing notifications on the lockscreen is enabled.
+     */
+    private boolean lockScreenShowNotification() {
+        return Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, OFF) == ON;
+    }
+
+    @Override
+    public boolean isChecked() {
+        return lockScreenShowOnlyUnseenNotifications();
+    }
+
+    private boolean lockScreenShowOnlyUnseenNotifications() {
+        return Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS, UNSET) == ON;
+    }
+
+    @Override
+    public boolean setChecked(boolean isChecked) {
+        return Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS, (isChecked ? ON : OFF));
+    }
+
+    @Override
+    public int getSliceHighlightMenuRes() {
+        // not needed because Sliceable is deprecated
+        return NO_RES;
+    }
+}
diff --git a/src/com/android/settings/notification/LockScreenNotificationHideSilentToggleController.java b/src/com/android/settings/notification/LockScreenNotificationHideSilentToggleController.java
new file mode 100644
index 0000000..ad33ec3
--- /dev/null
+++ b/src/com/android/settings/notification/LockScreenNotificationHideSilentToggleController.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2024 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.notification;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+import android.provider.Settings;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleEventObserver;
+import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.core.TogglePreferenceController;
+
+/**
+ * Controls the toggle that determines whether to show silent notifications when screen locked.
+ * Toggle for: Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS
+ */
+public class LockScreenNotificationHideSilentToggleController extends TogglePreferenceController
+        implements LifecycleEventObserver {
+
+    private static final int ON = 1;
+    private static final int OFF = 0;
+
+    @Nullable private Preference mPreference;
+    private final ContentResolver mContentResolver;
+
+    final ContentObserver mContentObserver = new ContentObserver(
+            new Handler(Looper.getMainLooper())) {
+        @Override
+        public void onChange(boolean selfChange, @Nullable Uri uri) {
+            if (mPreference == null) return;
+            updateState(mPreference);
+        }
+    };
+
+    public LockScreenNotificationHideSilentToggleController(@NonNull Context context,
+            @NonNull String preferenceKey) {
+        super(context, preferenceKey);
+        mContentResolver = context.getContentResolver();
+    }
+
+    @Override
+    public void onStateChanged(@NonNull LifecycleOwner lifecycleOwner,
+            @NonNull Lifecycle.Event event) {
+        if (event == Lifecycle.Event.ON_RESUME) {
+            mContentResolver.registerContentObserver(
+                    Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS),
+                    /* notifyForDescendants= */ false, mContentObserver);
+            mContentResolver.registerContentObserver(
+                    Settings.Secure.getUriFor(
+                            Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS),
+                    /* notifyForDescendants= */ false,
+                    mContentObserver
+            );
+        } else if (event == Lifecycle.Event.ON_PAUSE) {
+            mContentResolver.unregisterContentObserver(mContentObserver);
+        }
+    }
+
+    @Override
+    public void displayPreference(@NonNull PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreference = screen.findPreference(getPreferenceKey());
+    }
+
+    @Override
+    public void updateState(@NonNull Preference preference) {
+        super.updateState(preference);
+        setChecked(hideSilentNotificationsWhenLocked());
+        preference.setVisible(isAvailable());
+    }
+
+    private boolean hideSilentNotificationsWhenLocked() {
+        return Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, OFF) == OFF;
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        if (!lockScreenShowNotification()) {
+            return CONDITIONALLY_UNAVAILABLE;
+        }
+        return AVAILABLE;
+    }
+
+    /**
+     * @return Whether showing notifications on the lockscreen is enabled.
+     */
+    private boolean lockScreenShowNotification() {
+        return Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, OFF) == ON;
+    }
+
+    @Override
+    public boolean isChecked() {
+        return hideSilentNotificationsWhenLocked();
+    }
+
+    @Override
+    public boolean setChecked(boolean isChecked) {
+        return Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, (isChecked ? OFF : ON));
+    }
+
+    @Override
+    public int getSliceHighlightMenuRes() {
+        // not needed since it's not sliceable
+        return NO_RES;
+    }
+}
diff --git a/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java b/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java
index f1857de..619cdfb 100644
--- a/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java
+++ b/src/com/android/settings/notification/LockScreenNotificationPreferenceController.java
@@ -37,6 +37,7 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.internal.widget.LockPatternUtils;
+import com.android.server.notification.Flags;
 import com.android.settings.R;
 import com.android.settings.RestrictedListPreference;
 import com.android.settings.Utils;
@@ -94,6 +95,13 @@
     @Override
     public void displayPreference(PreferenceScreen screen) {
         super.displayPreference(screen);
+        // Hide the preference when the lock screen notification page shows
+        if (Flags.notificationLockScreenSettings()) {
+            setVisible(screen, mSettingKey, false);
+            setVisible(screen, mWorkSettingKey, false);
+            setVisible(screen, mWorkSettingCategoryKey, false);
+            return;
+        }
         mLockscreen = screen.findPreference(mSettingKey);
         if (mLockscreen == null) {
             Log.i(TAG, "Preference not found: " + mSettingKey);
diff --git a/src/com/android/settings/notification/LockScreenNotificationShowSensitiveToggleController.java b/src/com/android/settings/notification/LockScreenNotificationShowSensitiveToggleController.java
new file mode 100644
index 0000000..738714d
--- /dev/null
+++ b/src/com/android/settings/notification/LockScreenNotificationShowSensitiveToggleController.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2024 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.notification;
+
+import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS;
+import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;
+
+import android.app.KeyguardManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleEventObserver;
+import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.core.TogglePreferenceController;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtilsInternal;
+import com.android.settingslib.RestrictedSwitchPreference;
+
+import java.util.List;
+
+/**
+ * Controls the toggle that determines whether to show sensitive notifications on the lock screen
+ * when locked.
+ * Toggle for: Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS
+ */
+public class LockScreenNotificationShowSensitiveToggleController
+        extends TogglePreferenceController implements LifecycleEventObserver {
+
+    private static final int ON = 1;
+    private static final int OFF = 0;
+    @VisibleForTesting
+    static final String KEY_SHOW_SENSITIVE = "lock_screen_notification_show_sensitive_toggle";
+    @VisibleForTesting
+    static final String KEY_SHOW_SENSITIVE_WORK_PROFILE =
+            "work_profile_show_sensitive_notif_toggle";
+    @Nullable private RestrictedSwitchPreference mPreference;
+    private final ContentResolver mContentResolver;
+    private UserManager mUserManager;
+    private KeyguardManager mKeyguardManager;
+    @VisibleForTesting
+    int mWorkProfileUserId;
+
+    final ContentObserver mContentObserver = new ContentObserver(
+            new Handler(Looper.getMainLooper())) {
+        @Override
+        public void onChange(boolean selfChange, @Nullable Uri uri) {
+            updateState(mPreference);
+        }
+    };
+
+    public LockScreenNotificationShowSensitiveToggleController(@NonNull Context context,
+            @NonNull String preferenceKey) {
+        super(context, preferenceKey);
+        mContentResolver = context.getContentResolver();
+
+        mUserManager = context.getSystemService(UserManager.class);
+        mKeyguardManager = context.getSystemService(KeyguardManager.class);
+        mWorkProfileUserId = UserHandle.myUserId();
+        final List<UserInfo> profiles = mUserManager.getProfiles(UserHandle.myUserId());
+
+        for (UserInfo profile: profiles) {
+            if (profile.isManagedProfile()
+                    && profile.getUserHandle().getIdentifier() != UserHandle.myUserId()) {
+                mWorkProfileUserId = profile.getUserHandle().getIdentifier();
+            }
+        }
+    }
+
+    @Override
+    public void onStateChanged(@NonNull LifecycleOwner lifecycleOwner,
+            @NonNull Lifecycle.Event event) {
+        if (event == Lifecycle.Event.ON_RESUME) {
+            mContentResolver.registerContentObserver(
+                    Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS),
+                    /* notifyForDescendants= */ false, mContentObserver);
+            mContentResolver.registerContentObserver(
+                    Settings.Secure.getUriFor(
+                            Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS),
+                    /* notifyForDescendants= */ false,
+                    mContentObserver
+            );
+        } else if (event == Lifecycle.Event.ON_PAUSE) {
+            mContentResolver.unregisterContentObserver(mContentObserver);
+        }
+    }
+
+    @Override
+    public void displayPreference(@NonNull PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreference = screen.findPreference(getPreferenceKey());
+        int userId = getUserId();
+
+        if (mPreference != null && userId != UserHandle.USER_NULL) {
+            mPreference.setDisabledByAdmin(getEnforcedAdmin(userId));
+        }
+    }
+
+    private RestrictedLockUtils.EnforcedAdmin getEnforcedAdmin(int userId) {
+        RestrictedLockUtils.EnforcedAdmin admin =
+                RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
+                        mContext, KEYGUARD_DISABLE_SECURE_NOTIFICATIONS, userId);
+        if (admin != null) {
+            return admin;
+        }
+        admin = RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
+                mContext, KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS, userId);
+        return admin;
+    }
+
+    private int getUserId() {
+        return KEY_SHOW_SENSITIVE.equals(getPreferenceKey())
+                ? UserHandle.myUserId() : mWorkProfileUserId;
+    }
+
+    @Override
+    public void updateState(@Nullable Preference preference) {
+        if (preference == null) return;
+        setChecked(showSensitiveContentOnlyWhenUnlocked());
+        preference.setVisible(isAvailable());
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        // hide setting if no lock screen notification
+        if (!lockScreenShowNotification()) {
+            return CONDITIONALLY_UNAVAILABLE;
+        }
+
+        // hide setting if no screen lock
+        if (!isLockScreenSecure()) {
+            return CONDITIONALLY_UNAVAILABLE;
+        }
+
+        // For the work profile toggle
+        if (KEY_SHOW_SENSITIVE_WORK_PROFILE.equals(getPreferenceKey())) {
+            // hide work profile setting if no work profile
+            if (mWorkProfileUserId == UserHandle.myUserId()) {
+                return CONDITIONALLY_UNAVAILABLE;
+            }
+
+            // specifically the work profile setting requires the work profile to be unlocked
+            if (mKeyguardManager.isDeviceLocked(mWorkProfileUserId)) {
+                return CONDITIONALLY_UNAVAILABLE;
+            }
+        }
+
+        return AVAILABLE;
+    }
+
+    /**
+     * @return Whether showing notifications on the lockscreen is enabled.
+     */
+    private boolean lockScreenShowNotification() {
+        return Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, ON) != OFF;
+    }
+
+    @Override
+    public boolean isChecked() {
+        return showSensitiveContentOnlyWhenUnlocked();
+    }
+
+    private boolean showSensitiveContentOnlyWhenUnlocked() {
+        int userId = getUserId();
+        if (!isLockScreenSecure()) return false;
+        if (getEnforcedAdmin(userId) != null) return true;
+        return Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, ON, userId) == OFF;
+    }
+
+    @Override
+    public boolean setChecked(boolean isChecked) {
+        return Settings.Secure.putIntForUser(
+                mContext.getContentResolver(),
+                Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+                (isChecked ? OFF : ON), getUserId()
+        );
+    }
+
+    private boolean isLockScreenSecure() {
+        return FeatureFactory.getFeatureFactory()
+                .getSecurityFeatureProvider()
+                .getLockPatternUtils(mContext)
+                .isSecure(UserHandle.myUserId());
+    }
+
+    @Override
+    public int getSliceHighlightMenuRes() {
+        // not needed since it's not sliceable
+        return NO_RES;
+    }
+}
diff --git a/src/com/android/settings/notification/LockScreenNotificationsGlobalPreferenceController.java b/src/com/android/settings/notification/LockScreenNotificationsGlobalPreferenceController.java
new file mode 100644
index 0000000..7c7664e
--- /dev/null
+++ b/src/com/android/settings/notification/LockScreenNotificationsGlobalPreferenceController.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2024 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.notification;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+import android.provider.Settings;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleEventObserver;
+import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.server.notification.Flags;
+import com.android.settings.widget.SettingsMainSwitchPreferenceController;
+
+public class LockScreenNotificationsGlobalPreferenceController
+        extends SettingsMainSwitchPreferenceController
+        implements LifecycleEventObserver {
+
+    public static final int ON = 1;
+    public static final int OFF = 0;
+    private final ContentResolver mContentResolver;
+    private final ContentObserver mContentObserver;
+    @Nullable private Preference mPreference;
+
+
+    public LockScreenNotificationsGlobalPreferenceController(
+            @NonNull Context context,
+            @NonNull String preferenceKey
+    ) {
+        super(context, preferenceKey);
+        mContentResolver = context.getContentResolver();
+        mContentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
+            @Override
+            public void onChange(boolean selfChange, @Nullable Uri uri) {
+                if (mPreference == null) return;
+                updateState(mPreference);
+            }
+        };
+    }
+
+    @Override
+    public void displayPreference(@NonNull PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreference = screen.findPreference(getPreferenceKey());
+    }
+
+    @Override
+    public void updateState(@NonNull Preference preference) {
+        super.updateState(preference);
+        setChecked(lockScreenShowNotifications());
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        // TODO: b/367455695 - remove this when the feature flag is removed!
+        return Flags.notificationLockScreenSettings() ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
+    }
+
+    @Override
+    public boolean isChecked() {
+        return lockScreenShowNotifications();
+    }
+
+    private boolean lockScreenShowNotifications() {
+        return Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, OFF) == ON;
+    }
+
+    @Override
+    public boolean setChecked(boolean isChecked) {
+        return Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, (isChecked ? ON : OFF));
+    }
+
+    @Override
+    public int getSliceHighlightMenuRes() {
+        // not needed since it's not sliceable
+        return NO_RES;
+    }
+
+    @Override
+    public void onStateChanged(@NonNull LifecycleOwner lifecycleOwner,
+            @NonNull Lifecycle.Event event) {
+        if (event == Lifecycle.Event.ON_RESUME) {
+            mContentResolver.registerContentObserver(
+                    Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS),
+                    /* notifyForDescendants= */ false,
+                    mContentObserver
+            );
+        } else {
+            mContentResolver.unregisterContentObserver(mContentObserver);
+        }
+    }
+}
diff --git a/src/com/android/settings/notification/LockScreenNotificationsPreferencePageController.java b/src/com/android/settings/notification/LockScreenNotificationsPreferencePageController.java
new file mode 100644
index 0000000..61ac274
--- /dev/null
+++ b/src/com/android/settings/notification/LockScreenNotificationsPreferencePageController.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 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.notification;
+
+import android.content.Context;
+
+import com.android.server.notification.Flags;
+import com.android.settings.core.BasePreferenceController;
+
+// TODO(b/367455695): remove controller when the feature flag is removed!
+
+/**
+ * Controller for lock screen notifications settings page.
+ */
+public class LockScreenNotificationsPreferencePageController extends BasePreferenceController {
+
+    public LockScreenNotificationsPreferencePageController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return Flags.notificationLockScreenSettings() ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
+    }
+
+}
diff --git a/src/com/android/settings/notification/LockScreenNotificationsPreferencePageFragment.java b/src/com/android/settings/notification/LockScreenNotificationsPreferencePageFragment.java
new file mode 100644
index 0000000..ef53e2d
--- /dev/null
+++ b/src/com/android/settings/notification/LockScreenNotificationsPreferencePageFragment.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2024 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.notification;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+
+import com.android.server.notification.Flags;
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.search.SearchIndexable;
+
+/**
+ * Fragment for notifications on lock screen preference page.
+ */
+@SearchIndexable
+public class LockScreenNotificationsPreferencePageFragment extends DashboardFragment {
+
+    @Override
+    public int getMetricsCategory() {
+        //TODO(b/367455695): create a new metrics category
+        return SettingsEnums.SETTINGS_LOCK_SCREEN_PREFERENCES;
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.lock_screen_notifications_settings;
+    }
+    @Override
+    protected String getLogTag() {
+        return "LockScreenNotificationsPreferenceFragment";
+    }
+
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider(R.xml.lock_screen_notifications_settings) {
+                @Override
+                protected boolean isPageSearchEnabled(Context context) {
+                    return Flags.notificationLockScreenSettings();
+                }
+            };
+}
diff --git a/src/com/android/settings/notification/LockscreenNotificationMinimalismPreferenceController.java b/src/com/android/settings/notification/LockscreenNotificationMinimalismPreferenceController.java
index 7b48ba7..0387556 100644
--- a/src/com/android/settings/notification/LockscreenNotificationMinimalismPreferenceController.java
+++ b/src/com/android/settings/notification/LockscreenNotificationMinimalismPreferenceController.java
@@ -56,6 +56,10 @@
 
     @Override
     public int getAvailabilityStatus() {
+        // Hide when the notifications on lock screen settings page flag is enabled.
+        if (Flags.notificationLockScreenSettings()) {
+            return CONDITIONALLY_UNAVAILABLE;
+        }
         if (!Flags.notificationMinimalism()) {
             return CONDITIONALLY_UNAVAILABLE;
         }
diff --git a/src/com/android/settings/notification/PoliteNotificationsPreferenceController.java b/src/com/android/settings/notification/PoliteNotificationsPreferenceController.java
index e6e0947..49edcb8 100644
--- a/src/com/android/settings/notification/PoliteNotificationsPreferenceController.java
+++ b/src/com/android/settings/notification/PoliteNotificationsPreferenceController.java
@@ -18,16 +18,19 @@
 
 import android.content.Context;
 
+import androidx.annotation.NonNull;
+
 import com.android.server.notification.Flags;
 import com.android.settings.core.BasePreferenceController;
 
-// TODO: b/291897570 - remove controller when the feature flag is removed!
+// TODO(b/330606963): remove controller when the feature flag is removed!
 /**
  * Controller for polite notifications settings page.
  */
 public class PoliteNotificationsPreferenceController extends BasePreferenceController {
 
-    public PoliteNotificationsPreferenceController(Context context, String preferenceKey) {
+    public PoliteNotificationsPreferenceController(@NonNull Context context,
+            @NonNull String preferenceKey) {
         super(context, preferenceKey);
     }
 
diff --git a/src/com/android/settings/notification/RedactNotificationPreferenceController.java b/src/com/android/settings/notification/RedactNotificationPreferenceController.java
index 4ebf08e..ea52be6 100644
--- a/src/com/android/settings/notification/RedactNotificationPreferenceController.java
+++ b/src/com/android/settings/notification/RedactNotificationPreferenceController.java
@@ -33,6 +33,7 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.internal.widget.LockPatternUtils;
+import com.android.server.notification.Flags;
 import com.android.settings.R;
 import com.android.settings.core.TogglePreferenceController;
 import com.android.settings.overlay.FeatureFactory;
@@ -120,6 +121,11 @@
 
     @Override
     public int getAvailabilityStatus() {
+        // Hide when the notifications on lock screen settings page flag is enabled.
+        if (Flags.notificationLockScreenSettings()) {
+            return CONDITIONALLY_UNAVAILABLE;
+        }
+
         // hide work profile setting if no work profile
         if (KEY_LOCKSCREEN_WORK_PROFILE_REDACT.equals(getPreferenceKey())
                 && mProfileUserId == UserHandle.myUserId()) {
diff --git a/src/com/android/settings/notification/ShowOnLockScreenNotificationPreferenceController.java b/src/com/android/settings/notification/ShowOnLockScreenNotificationPreferenceController.java
index 1addd82..fc5fa74 100644
--- a/src/com/android/settings/notification/ShowOnLockScreenNotificationPreferenceController.java
+++ b/src/com/android/settings/notification/ShowOnLockScreenNotificationPreferenceController.java
@@ -26,6 +26,7 @@
 import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
 
+import com.android.server.notification.Flags;
 import com.android.settings.R;
 import com.android.settings.RestrictedListPreference;
 import com.android.settings.core.PreferenceControllerMixin;
@@ -63,7 +64,8 @@
 
     @Override
     public boolean isAvailable() {
-        return true;
+        // When notificationLockScreenSettings is enabled, show the lock screen notif settings page
+        return !Flags.notificationLockScreenSettings();
     }
 
     @Override
diff --git a/src/com/android/settings/notification/ShowOnlyUnseenNotificationsOnLockscreenPreferenceController.java b/src/com/android/settings/notification/ShowOnlyUnseenNotificationsOnLockscreenPreferenceController.java
index 9534483..225fc7c 100644
--- a/src/com/android/settings/notification/ShowOnlyUnseenNotificationsOnLockscreenPreferenceController.java
+++ b/src/com/android/settings/notification/ShowOnlyUnseenNotificationsOnLockscreenPreferenceController.java
@@ -57,6 +57,10 @@
 
     @Override
     public int getAvailabilityStatus() {
+        // Hide when the notifications on lock screen page flag is enabled.
+        if (Flags.notificationLockScreenSettings()) {
+            return CONDITIONALLY_UNAVAILABLE;
+        }
         if (Flags.notificationMinimalism()) {
             if (!isNotifOnLockScreenEnabled()) {
                 return DISABLED_DEPENDENT_SETTING;
diff --git a/src/com/android/settings/notification/lockscreen/MinimalismPreferenceController.java b/src/com/android/settings/notification/lockscreen/MinimalismPreferenceController.java
new file mode 100644
index 0000000..78be16a
--- /dev/null
+++ b/src/com/android/settings/notification/lockscreen/MinimalismPreferenceController.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2024 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.notification.lockscreen;
+
+import static android.provider.Settings.Secure.LOCK_SCREEN_NOTIFICATION_MINIMALISM;
+import static android.provider.Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+import android.provider.Settings;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleEventObserver;
+import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.PreferenceScreen;
+
+import com.android.server.notification.Flags;
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.widget.IllustrationPreference;
+import com.android.settingslib.widget.LayoutPreference;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class MinimalismPreferenceController
+        extends BasePreferenceController
+        implements LifecycleEventObserver {
+
+    private static final int LS_SHOW_NOTIF_ON = 1;
+    private static final int LS_SHOW_NOTIF_OFF = 0;
+    private static final int LS_MINIMALISM_OFF = 0;
+    private static final int LS_MINIMALISM_ON = 1;
+    private static final String KEY_MINIMALISM_PREFERENCE = "ls_minimalism";
+    private static final String KEY_FULL_LIST_ILLUSTRATION = "full_list_illustration";
+    private static final String KEY_COMPACT_ILLUSTRATION = "compact_illustration";
+    private static final Uri URI_LOCK_SCREEN_NOTIFICATION_MINIMALISM =
+            Settings.Secure.getUriFor(LOCK_SCREEN_NOTIFICATION_MINIMALISM);
+    private static final Uri URI_LOCK_SCREEN_SHOW_NOTIFICATIONS =
+            Settings.Secure.getUriFor(LOCK_SCREEN_SHOW_NOTIFICATIONS);
+
+    @Nullable private LayoutPreference mPreference;
+    @Nullable private TextView mDescView;
+    private Map<Integer, LinearLayout> mButtons = new HashMap<>();
+    private Map<Integer, IllustrationPreference> mIllustrations = new HashMap<>();
+    private final Map<Integer, Integer> mDescriptionTexts = Map.ofEntries(
+            Map.entry(LS_MINIMALISM_OFF, R.string.lock_screen_notifs_full_list_desc),
+            Map.entry(LS_MINIMALISM_ON, R.string.lock_screen_notifs_compact_desc)
+    );
+
+    private final ContentResolver mContentResolver;
+
+    final ContentObserver mContentObserver = new ContentObserver(
+            new Handler(Looper.getMainLooper())) {
+        @Override
+        public void onChange(boolean selfChange, @Nullable Uri uri) {
+            refreshState(uri);
+        }
+    };
+
+    public MinimalismPreferenceController(@NonNull Context context, @NonNull String preferenceKey) {
+        super(context, preferenceKey);
+        mContentResolver = context.getContentResolver();
+    }
+
+    @Override
+    public void onStateChanged(@NonNull LifecycleOwner lifecycleOwner,
+            @NonNull Lifecycle.Event event) {
+        if (event == Lifecycle.Event.ON_RESUME) {
+            mContentResolver.registerContentObserver(
+                    URI_LOCK_SCREEN_NOTIFICATION_MINIMALISM,
+                    /* notifyForDescendants= */ false,
+                    mContentObserver
+            );
+            mContentResolver.registerContentObserver(
+                    URI_LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                    /* notifyForDescendants= */ false,
+                    mContentObserver
+            );
+        } else if (event == Lifecycle.Event.ON_PAUSE) {
+            mContentResolver.unregisterContentObserver(mContentObserver);
+        }
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        if (!Flags.notificationMinimalism()) {
+            return CONDITIONALLY_UNAVAILABLE;
+        }
+        if (!lockScreenShowNotification()) {
+            return CONDITIONALLY_UNAVAILABLE;
+        }
+        return AVAILABLE;
+    }
+
+    /**
+     * @return Whether showing notifications on the lockscreen is enabled.
+     */
+    private boolean lockScreenShowNotification() {
+        return Settings.Secure.getInt(
+                mContext.getContentResolver(),
+                Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                LS_SHOW_NOTIF_OFF
+        ) == LS_SHOW_NOTIF_ON;
+    }
+
+    @Override
+    public void displayPreference(@NonNull PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreference = screen.findPreference(KEY_MINIMALISM_PREFERENCE);
+        mDescView = mPreference.findViewById(R.id.notif_ls_style_desc);
+
+        mButtons = Map.ofEntries(
+                Map.entry(LS_MINIMALISM_OFF,
+                        mPreference.findViewById(R.id.button_full)),
+                Map.entry(LS_MINIMALISM_ON,
+                        mPreference.findViewById(R.id.button_compact))
+        );
+
+        mIllustrations = Map.ofEntries(
+                Map.entry(LS_MINIMALISM_OFF,
+                        screen.findPreference(KEY_FULL_LIST_ILLUSTRATION)),
+                Map.entry(LS_MINIMALISM_ON,
+                        screen.findPreference(KEY_COMPACT_ILLUSTRATION))
+        );
+        mButtons.forEach((value, button) -> button.setOnClickListener(v ->
+                Settings.Secure.putInt(
+                        mContext.getContentResolver(),
+                        Settings.Secure.LOCK_SCREEN_NOTIFICATION_MINIMALISM,
+                        value
+                )
+        ));
+
+        refreshState(URI_LOCK_SCREEN_NOTIFICATION_MINIMALISM);
+    }
+
+    private void highlightButton(int currentValue) {
+        mButtons.forEach((value, button) -> button.setSelected(currentValue == value));
+    }
+
+    private void highlightIllustration(int currentValue) {
+        mIllustrations.forEach((value, preference)
+                -> preference.setVisible(currentValue == value));
+    }
+
+    private void highlightDescription(int value) {
+        if (mDescView == null) return;
+        Integer descStringId = mDescriptionTexts.get(value);
+        if (descStringId != null) {
+            mDescView.setText(descStringId);
+        }
+    }
+
+    private int getCurrentMinimalismValue() {
+        return Settings.Secure.getInt(mContext.getContentResolver(),
+                LOCK_SCREEN_NOTIFICATION_MINIMALISM, LS_MINIMALISM_ON);
+    }
+
+    private void refreshState(@Nullable Uri uri) {
+        if (mPreference == null) return;
+        if (URI_LOCK_SCREEN_SHOW_NOTIFICATIONS.equals(uri) && !lockScreenShowNotification()) {
+            // hide all preferences when showing notifications on lock screen is disabled
+            mIllustrations.forEach((value, preference)
+                    -> preference.setVisible(false));
+            mPreference.setVisible(false);
+        } else {
+            mPreference.setVisible(isAvailable());
+            int currentValue = getCurrentMinimalismValue();
+            highlightButton(currentValue);
+            highlightIllustration(currentValue);
+            highlightDescription(currentValue);
+        }
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
index f3848b3..139a15f 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
@@ -25,6 +25,7 @@
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
@@ -39,6 +40,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.InstallSourceInfo;
 import android.content.pm.PackageManager;
+import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.UserHandle;
@@ -55,12 +57,12 @@
 import com.android.settings.fuelgauge.batteryusage.ConvertUtils;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
-import com.android.settings.widget.EntityHeaderController;
+import com.android.settingslib.Utils;
 import com.android.settingslib.applications.AppUtils;
 import com.android.settingslib.applications.ApplicationsState;
 import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
-import com.android.settingslib.widget.LayoutPreference;
+import com.android.settingslib.widget.IntroPreference;
 
 import org.junit.After;
 import org.junit.Before;
@@ -75,6 +77,8 @@
 import org.mockito.stubbing.Answer;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
 import org.robolectric.util.ReflectionHelpers;
 
 import java.util.concurrent.TimeUnit;
@@ -82,7 +86,6 @@
 @RunWith(RobolectricTestRunner.class)
 @Config(
         shadows = {
-            ShadowEntityHeaderController.class,
             com.android.settings.testutils.shadow.ShadowFragment.class,
         })
 public class AdvancedPowerUsageDetailTest {
@@ -90,6 +93,7 @@
     @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
 
     private static final String APP_LABEL = "app label";
+    private static final String APP_ENTRY_LABEL = "app entry label";
     private static final String SUMMARY = "summary";
     private static final String PACKAGE_NAME = "com.android.app";
     private static final String INITIATING_PACKAGE_NAME = "com.android.vending";
@@ -100,17 +104,16 @@
     private static final long FOREGROUND_SERVICE_TIME_MS = 123;
     private static final long BACKGROUND_TIME_MS = 100;
     private static final long SCREEN_ON_TIME_MS = 321;
+    private static final Drawable TEST_DRAWABLE = new ColorDrawable(0);
 
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private FragmentActivity mActivity;
 
-    @Mock private EntityHeaderController mEntityHeaderController;
     @Mock private ApplicationsState mState;
     @Mock private ApplicationsState.AppEntry mAppEntry;
     @Mock private BatteryEntry mBatteryEntry;
     @Mock private PackageManager mPackageManager;
     @Mock private InstallSourceInfo mInstallSourceInfo;
-    @Mock private LayoutPreference mLayoutPreference;
     @Mock private AppOpsManager mAppOpsManager;
     @Mock private LoaderManager mLoaderManager;
 
@@ -123,6 +126,15 @@
     private BatteryDiffEntry mBatteryDiffEntry;
     private Bundle mBundle;
     private BatteryOptimizeUtils mBatteryOptimizeUtils;
+    private IntroPreference mIntroPreference;
+
+    @Implements(Utils.class)
+    private static class ShadowUtils {
+        @Implementation
+        public static Drawable getBadgedIcon(Context context, ApplicationInfo appInfo) {
+            return AdvancedPowerUsageDetailTest.TEST_DRAWABLE;
+        }
+    }
 
     @Before
     public void setUp() throws Exception {
@@ -136,7 +148,8 @@
         prepareTestBatteryOptimizationUtils();
         mFragment = spy(new AdvancedPowerUsageDetail());
         mFragment.mBatteryOptimizeUtils = mBatteryOptimizeUtils;
-        doReturn(mLayoutPreference).when(mFragment).findPreference(any());
+        mIntroPreference = new IntroPreference(mContext);
+        doReturn(mIntroPreference).when(mFragment).findPreference(any());
         mBundle = spy(new Bundle());
         doReturn(mContext).when(mFragment).getContext();
         doReturn(mActivity).when(mFragment).getActivity();
@@ -145,29 +158,6 @@
         when(mFragment.getArguments()).thenReturn(mBundle);
         doReturn(mLoaderManager).when(mFragment).getLoaderManager();
 
-        ShadowEntityHeaderController.setUseMock(mEntityHeaderController);
-        doReturn(mEntityHeaderController)
-                .when(mEntityHeaderController)
-                .setButtonActions(anyInt(), anyInt());
-        doReturn(mEntityHeaderController)
-                .when(mEntityHeaderController)
-                .setIcon(nullable(Drawable.class));
-        doReturn(mEntityHeaderController)
-                .when(mEntityHeaderController)
-                .setIcon(nullable(ApplicationsState.AppEntry.class));
-        doReturn(mEntityHeaderController)
-                .when(mEntityHeaderController)
-                .setLabel(nullable(String.class));
-        doReturn(mEntityHeaderController)
-                .when(mEntityHeaderController)
-                .setLabel(nullable(String.class));
-        doReturn(mEntityHeaderController)
-                .when(mEntityHeaderController)
-                .setLabel(nullable(ApplicationsState.AppEntry.class));
-        doReturn(mEntityHeaderController)
-                .when(mEntityHeaderController)
-                .setSummary(nullable(String.class));
-
         when(mBatteryEntry.getUid()).thenReturn(UID);
         when(mBatteryEntry.getLabel()).thenReturn(APP_LABEL);
         when(mBatteryEntry.getTimeInForegroundMs()).thenReturn(FOREGROUND_TIME_MS);
@@ -202,7 +192,9 @@
         mFragment.mState = mState;
         mFragment.mBatteryOptimizeUtils = mBatteryOptimizeUtils;
         mFragment.mLogStringBuilder = new StringBuilder();
+        doNothing().when(mState).ensureIcon(mAppEntry);
         mAppEntry.info = mock(ApplicationInfo.class);
+        mAppEntry.label = APP_ENTRY_LABEL;
 
         mTestActivity = spy(new SettingsActivity());
         doReturn(mPackageManager).when(mTestActivity).getPackageManager();
@@ -235,34 +227,27 @@
     }
 
     @Test
+    @Config(shadows = ShadowUtils.class)
     public void initHeader_NoAppEntry_BuildByBundle() {
         mFragment.mAppEntry = null;
         mFragment.initHeader();
 
-        verify(mEntityHeaderController).setIcon(nullable(Drawable.class));
-        verify(mEntityHeaderController).setLabel(APP_LABEL);
+        assertThat(mIntroPreference.getIcon()).isNotEqualTo(TEST_DRAWABLE);
+        assertThat(mIntroPreference.getTitle()).isEqualTo(APP_LABEL);
     }
 
     @Test
+    @Config(shadows = ShadowUtils.class)
     public void initHeader_HasAppEntry_BuildByAppEntry() {
-        ReflectionHelpers.setStaticField(
-                AppUtils.class,
-                "sInstantAppDataProvider",
-                new InstantAppDataProvider() {
-                    @Override
-                    public boolean isInstantApp(ApplicationInfo info) {
-                        return false;
-                    }
-                });
         mFragment.mAppEntry = mAppEntry;
         mFragment.initHeader();
 
-        verify(mEntityHeaderController).setIcon(mAppEntry);
-        verify(mEntityHeaderController).setLabel(mAppEntry);
-        verify(mEntityHeaderController).setIsInstantApp(false);
+        assertThat(mIntroPreference.getIcon()).isEqualTo(TEST_DRAWABLE);
+        assertThat(mIntroPreference.getTitle()).isEqualTo(mAppEntry.label);
     }
 
     @Test
+    @Config(shadows = ShadowUtils.class)
     public void initHeader_HasAppEntry_InstantApp() {
         ReflectionHelpers.setStaticField(
                 AppUtils.class,
@@ -276,9 +261,8 @@
         mFragment.mAppEntry = mAppEntry;
         mFragment.initHeader();
 
-        verify(mEntityHeaderController).setIcon(mAppEntry);
-        verify(mEntityHeaderController).setLabel(mAppEntry);
-        verify(mEntityHeaderController).setIsInstantApp(true);
+        assertThat(mIntroPreference.getIcon()).isEqualTo(TEST_DRAWABLE);
+        assertThat(mIntroPreference.getTitle()).isEqualTo(mAppEntry.label);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerBackgroundUsageDetailTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerBackgroundUsageDetailTest.java
index 9f98d78..2451cc5 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerBackgroundUsageDetailTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerBackgroundUsageDetailTest.java
@@ -25,6 +25,7 @@
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
@@ -39,6 +40,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.InstallSourceInfo;
 import android.content.pm.PackageManager;
+import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.UserHandle;
@@ -51,15 +53,12 @@
 import com.android.settings.SettingsActivity;
 import com.android.settings.fuelgauge.batteryusage.BatteryEntry;
 import com.android.settings.testutils.FakeFeatureFactory;
-import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
 import com.android.settings.testutils.shadow.ShadowHelpUtils;
-import com.android.settings.widget.EntityHeaderController;
-import com.android.settingslib.applications.AppUtils;
+import com.android.settingslib.Utils;
 import com.android.settingslib.applications.ApplicationsState;
-import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.widget.FooterPreference;
-import com.android.settingslib.widget.LayoutPreference;
+import com.android.settingslib.widget.IntroPreference;
 
 import org.junit.After;
 import org.junit.Before;
@@ -74,14 +73,14 @@
 import org.mockito.stubbing.Answer;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
-import org.robolectric.util.ReflectionHelpers;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
 
 import java.util.concurrent.TimeUnit;
 
 @RunWith(RobolectricTestRunner.class)
 @Config(
         shadows = {
-            ShadowEntityHeaderController.class,
             ShadowHelpUtils.class,
             com.android.settings.testutils.shadow.ShadowFragment.class,
         })
@@ -90,6 +89,7 @@
     @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
 
     private static final String APP_LABEL = "app label";
+    private static final String APP_ENTRY_LABEL = "app entry label";
     private static final String SUMMARY = "summary";
     private static final int ICON_ID = 123;
     private static final int UID = 1;
@@ -97,6 +97,7 @@
     private static final String KEY_PREF_HEADER = "header_view";
     private static final String KEY_FOOTER_PREFERENCE = "app_usage_footer_preference";
     private static final String INITIATING_PACKAGE_NAME = "com.android.vending";
+    private static final Drawable TEST_DRAWABLE = new ColorDrawable(0);
 
     private int mTestMode;
     private Context mContext;
@@ -104,11 +105,11 @@
     private MetricsFeatureProvider mMetricsFeatureProvider;
     private SettingsActivity mTestActivity;
     private BatteryOptimizeUtils mBatteryOptimizeUtils;
+    private IntroPreference mIntroPreference;
 
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private FragmentActivity mActivity;
 
-    @Mock private EntityHeaderController mEntityHeaderController;
     @Mock private ApplicationsState mState;
     @Mock private Bundle mBundle;
     @Mock private LoaderManager mLoaderManager;
@@ -117,9 +118,16 @@
     @Mock private PackageManager mPackageManager;
     @Mock private AppOpsManager mAppOpsManager;
     @Mock private InstallSourceInfo mInstallSourceInfo;
-    @Mock private LayoutPreference mLayoutPreference;
     @Mock private FooterPreference mFooterPreference;
 
+    @Implements(Utils.class)
+    private static class ShadowUtils {
+        @Implementation
+        public static Drawable getBadgedIcon(Context context, ApplicationInfo appInfo) {
+            return PowerBackgroundUsageDetailTest.TEST_DRAWABLE;
+        }
+    }
+
     @Before
     public void setUp() throws Exception {
         mContext = spy(ApplicationProvider.getApplicationContext());
@@ -134,7 +142,8 @@
         mFragment = spy(new PowerBackgroundUsageDetail());
         mFragment.mBatteryOptimizeUtils = mBatteryOptimizeUtils;
         mFragment.mLogStringBuilder = new StringBuilder();
-        doReturn(mLayoutPreference).when(mFragment).findPreference(KEY_PREF_HEADER);
+        mIntroPreference = new IntroPreference(mContext);
+        doReturn(mIntroPreference).when(mFragment).findPreference(KEY_PREF_HEADER);
         doReturn(mFooterPreference).when(mFragment).findPreference(KEY_FOOTER_PREFERENCE);
         doReturn(mContext).when(mFragment).getContext();
         doReturn(mActivity).when(mFragment).getActivity();
@@ -143,35 +152,14 @@
         when(mFragment.getArguments()).thenReturn(mBundle);
         doReturn(mLoaderManager).when(mFragment).getLoaderManager();
 
-        ShadowEntityHeaderController.setUseMock(mEntityHeaderController);
-        doReturn(mEntityHeaderController)
-                .when(mEntityHeaderController)
-                .setButtonActions(anyInt(), anyInt());
-        doReturn(mEntityHeaderController)
-                .when(mEntityHeaderController)
-                .setIcon(nullable(Drawable.class));
-        doReturn(mEntityHeaderController)
-                .when(mEntityHeaderController)
-                .setIcon(nullable(ApplicationsState.AppEntry.class));
-        doReturn(mEntityHeaderController)
-                .when(mEntityHeaderController)
-                .setLabel(nullable(String.class));
-        doReturn(mEntityHeaderController)
-                .when(mEntityHeaderController)
-                .setLabel(nullable(String.class));
-        doReturn(mEntityHeaderController)
-                .when(mEntityHeaderController)
-                .setLabel(nullable(ApplicationsState.AppEntry.class));
-        doReturn(mEntityHeaderController)
-                .when(mEntityHeaderController)
-                .setSummary(nullable(String.class));
-
         when(mBatteryEntry.getUid()).thenReturn(UID);
         when(mBatteryEntry.getLabel()).thenReturn(APP_LABEL);
         mBatteryEntry.mIconId = ICON_ID;
 
         mFragment.mState = mState;
+        doNothing().when(mState).ensureIcon(mAppEntry);
         mAppEntry.info = mock(ApplicationInfo.class);
+        mAppEntry.label = APP_ENTRY_LABEL;
 
         mTestActivity = spy(new SettingsActivity());
         doReturn(mPackageManager).when(mTestActivity).getPackageManager();
@@ -194,55 +182,37 @@
 
     @After
     public void reset() {
-        ShadowEntityHeaderController.reset();
         ShadowHelpUtils.reset();
     }
 
     @Test
+    @Config(shadows = ShadowUtils.class)
     public void initHeader_NoAppEntry_BuildByBundle() {
         mFragment.mAppEntry = null;
         mFragment.initHeader();
 
-        verify(mEntityHeaderController).setIcon(nullable(Drawable.class));
-        verify(mEntityHeaderController).setLabel(APP_LABEL);
+        assertThat(mIntroPreference.getIcon()).isNotEqualTo(TEST_DRAWABLE);
+        assertThat(mIntroPreference.getTitle()).isEqualTo(APP_LABEL);
     }
 
     @Test
+    @Config(shadows = ShadowUtils.class)
     public void initHeader_HasAppEntry_BuildByAppEntry() {
-        ReflectionHelpers.setStaticField(
-                AppUtils.class,
-                "sInstantAppDataProvider",
-                new InstantAppDataProvider() {
-                    @Override
-                    public boolean isInstantApp(ApplicationInfo info) {
-                        return false;
-                    }
-                });
         mFragment.mAppEntry = mAppEntry;
         mFragment.initHeader();
 
-        verify(mEntityHeaderController).setIcon(mAppEntry);
-        verify(mEntityHeaderController).setLabel(mAppEntry);
-        verify(mEntityHeaderController).setIsInstantApp(false);
+        assertThat(mIntroPreference.getIcon()).isEqualTo(TEST_DRAWABLE);
+        assertThat(mIntroPreference.getTitle()).isEqualTo(mAppEntry.label);
     }
 
     @Test
+    @Config(shadows = ShadowUtils.class)
     public void initHeader_HasAppEntry_InstantApp() {
-        ReflectionHelpers.setStaticField(
-                AppUtils.class,
-                "sInstantAppDataProvider",
-                new InstantAppDataProvider() {
-                    @Override
-                    public boolean isInstantApp(ApplicationInfo info) {
-                        return true;
-                    }
-                });
         mFragment.mAppEntry = mAppEntry;
         mFragment.initHeader();
 
-        verify(mEntityHeaderController).setIcon(mAppEntry);
-        verify(mEntityHeaderController).setLabel(mAppEntry);
-        verify(mEntityHeaderController).setIsInstantApp(true);
+        assertThat(mIntroPreference.getIcon()).isEqualTo(TEST_DRAWABLE);
+        assertThat(mIntroPreference.getTitle()).isEqualTo(mAppEntry.label);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/notification/LockScreenNotificationShowSensitiveToggleControllerTest.java b/tests/robotests/src/com/android/settings/notification/LockScreenNotificationShowSensitiveToggleControllerTest.java
new file mode 100644
index 0000000..ea556a5
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/LockScreenNotificationShowSensitiveToggleControllerTest.java
@@ -0,0 +1,354 @@
+/*
+ * 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.notification;
+
+import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS;
+import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;
+import static android.provider.Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS;
+import static android.provider.Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+import android.app.KeyguardManager;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+
+import androidx.preference.PreferenceScreen;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal;
+import com.android.settings.testutils.shadow.ShadowUtils;
+import com.android.settingslib.RestrictedSwitchPreference;
+
+import org.junit.After;
+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;
+import org.robolectric.annotation.Config;
+
+import java.util.Arrays;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {
+        ShadowUtils.class,
+        ShadowRestrictedLockUtilsInternal.class,
+})
+public class LockScreenNotificationShowSensitiveToggleControllerTest {
+
+    @Mock
+    private DevicePolicyManager mDpm;
+    @Mock
+    UserManager mUm;
+    @Mock
+    KeyguardManager mKm;
+    @Mock
+    private PreferenceScreen mScreen;
+    @Mock
+    private LockPatternUtils mLockPatternUtils;
+    @Mock
+    private Context mMockContext;
+
+    private Context mContext;
+    private LockScreenNotificationShowSensitiveToggleController mController;
+    private LockScreenNotificationShowSensitiveToggleController mWorkController;
+    private RestrictedSwitchPreference mPreference;
+    private RestrictedSwitchPreference mWorkPreference;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+
+        FakeFeatureFactory featureFactory = FakeFeatureFactory.setupForTest();
+        when(featureFactory.securityFeatureProvider.getLockPatternUtils(mMockContext))
+                .thenReturn(mLockPatternUtils);
+        when(mMockContext.getContentResolver()).thenReturn(mContext.getContentResolver());
+        when(mMockContext.getSystemService(UserManager.class)).thenReturn(mUm);
+        when(mMockContext.getSystemService(DevicePolicyManager.class)).thenReturn(mDpm);
+        when(mMockContext.getSystemService(KeyguardManager.class)).thenReturn(mKm);
+        when(mUm.getProfiles(anyInt())).thenReturn(Arrays.asList(new UserInfo(0, "", 0)));
+
+        mController = new LockScreenNotificationShowSensitiveToggleController(
+                mMockContext,
+                LockScreenNotificationShowSensitiveToggleController.KEY_SHOW_SENSITIVE
+        );
+        mPreference = new RestrictedSwitchPreference(mContext);
+        mPreference.setKey(mController.getPreferenceKey());
+        when(mScreen.findPreference(
+                mController.getPreferenceKey())).thenReturn(mPreference);
+
+        when(mUm.getProfiles(anyInt())).thenReturn(Arrays.asList(
+                new UserInfo(5, "", 0),
+                new UserInfo(10, "", UserInfo.FLAG_MANAGED_PROFILE | UserInfo.FLAG_PROFILE)));
+        mWorkController = new LockScreenNotificationShowSensitiveToggleController(
+                mMockContext,
+                LockScreenNotificationShowSensitiveToggleController.KEY_SHOW_SENSITIVE_WORK_PROFILE
+        );
+        mWorkPreference = new RestrictedSwitchPreference(mContext);
+        mWorkPreference.setKey(mWorkController.getPreferenceKey());
+        when(mScreen.findPreference(
+                mWorkController.getPreferenceKey())).thenReturn(mWorkPreference);
+    }
+
+    @After
+    public void tearDown() {
+        ShadowRestrictedLockUtilsInternal.reset();
+    }
+
+    @Test
+    public void profileUserIds() {
+        assertThat(mController.mWorkProfileUserId).isEqualTo(0);
+        assertThat(mWorkController.mWorkProfileUserId).isEqualTo(10);
+    }
+
+    @Test
+    public void getAvailabilityStatus_noSecureLockscreen() {
+        when(mLockPatternUtils.isSecure(anyInt())).thenReturn(false);
+        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                1, 0);
+        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                1, 10);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
+        assertThat(mWorkController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_noWorkProfile() {
+        // reset controllers with no work profile
+        when(mUm.getProfiles(anyInt())).thenReturn(Arrays.asList(
+                new UserInfo(UserHandle.myUserId(), "", 0)));
+        mWorkController = new LockScreenNotificationShowSensitiveToggleController(
+                mMockContext,
+                LockScreenNotificationShowSensitiveToggleController.KEY_SHOW_SENSITIVE_WORK_PROFILE
+        );
+        mController = new LockScreenNotificationShowSensitiveToggleController(mMockContext,
+                LockScreenNotificationShowSensitiveToggleController.KEY_SHOW_SENSITIVE);
+
+        // should otherwise show
+        when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
+        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                1, 0);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+        assertThat(mWorkController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
+    }
+
+    @Test
+    public void displayPreference_adminSaysNoRedaction() {
+        ShadowRestrictedLockUtilsInternal.setKeyguardDisabledFeatures(
+                KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
+
+        mController.displayPreference(mScreen);
+        assertThat(mPreference.isDisabledByAdmin()).isTrue();
+        mWorkController.displayPreference(mScreen);
+        assertThat(mWorkPreference.isDisabledByAdmin()).isTrue();
+    }
+
+    @Test
+    public void displayPreference_adminSaysNoSecure() {
+        ShadowRestrictedLockUtilsInternal.setKeyguardDisabledFeatures(
+                KEYGUARD_DISABLE_SECURE_NOTIFICATIONS);
+
+        mController.displayPreference(mScreen);
+        assertThat(mPreference.isDisabledByAdmin()).isTrue();
+        mWorkController.displayPreference(mScreen);
+        assertThat(mWorkPreference.isDisabledByAdmin()).isTrue();
+    }
+
+    @Test
+    public void displayPreference() {
+        ShadowRestrictedLockUtilsInternal.setKeyguardDisabledFeatures(0);
+
+        mController.displayPreference(mScreen);
+        assertThat(mPreference.isDisabledByAdmin()).isFalse();
+        mWorkController.displayPreference(mScreen);
+        assertThat(mWorkPreference.isDisabledByAdmin()).isFalse();
+    }
+
+    @Test
+    public void getAvailabilityStatus_adminSaysNoNotifications() {
+        when(mDpm.getKeyguardDisabledFeatures(eq(null), anyInt())).thenReturn(
+                KEYGUARD_DISABLE_SECURE_NOTIFICATIONS);
+
+        // should show
+        when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
+        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                1, 0);
+        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                1, 10);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+        assertThat(mWorkController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_noNotifications() {
+        when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
+
+        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                0, 0);
+        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                0, 10);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
+        assertThat(mWorkController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_workProfileLocked() {
+        // should otherwise show
+        when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
+        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                1, 0);
+        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                1, 10);
+
+        when(mKm.isDeviceLocked(10)).thenReturn(true);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+        assertThat(mWorkController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_show() {
+        // should show
+        when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
+        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                1, 0);
+        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                1, 10);
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+        assertThat(mWorkController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+    }
+
+    @Test
+    public void isChecked() {
+        when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
+        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+                0, 0);
+
+        assertThat(mController.isChecked()).isTrue();
+
+        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+                1, 0);
+
+        assertThat(mController.isChecked()).isFalse();
+    }
+
+    @Test
+    public void isChecked_work() {
+        when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
+        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+                0, 10);
+
+        assertThat(mWorkController.isChecked()).isTrue();
+
+        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+                1, 10);
+
+        assertThat(mWorkController.isChecked()).isFalse();
+    }
+
+    @Test
+    public void isChecked_admin() {
+        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+                1, 0);
+
+        ShadowRestrictedLockUtilsInternal.setKeyguardDisabledFeatures(
+                KEYGUARD_DISABLE_SECURE_NOTIFICATIONS);
+
+        assertThat(mController.isChecked()).isFalse();
+    }
+
+    @Test
+    public void setChecked_false() throws Exception {
+        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+                0, 0);
+
+        mController.setChecked(false);
+        assertThat(Settings.Secure.getIntForUser(
+                mContext.getContentResolver(), LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0))
+                .isEqualTo(1);
+    }
+
+    @Test
+    public void setChecked_workProfile_true() throws Exception {
+        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+                1, 10);
+
+        mWorkController.setChecked(true);
+        assertThat(Settings.Secure.getIntForUser(
+                mContext.getContentResolver(), LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 10))
+                .isEqualTo(0);
+    }
+
+    @Test
+    public void setChecked_true() throws Exception {
+        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+                1, 0);
+        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+                1, 10);
+
+        mController.setChecked(true);
+        mWorkController.setChecked(true);
+        assertThat(Settings.Secure.getIntForUser(
+                mContext.getContentResolver(), LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 10))
+                .isEqualTo(0);
+        assertThat(Settings.Secure.getIntForUser(
+                mContext.getContentResolver(), LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0))
+                .isEqualTo(0);
+    }
+}
+
diff --git a/tests/robotests/src/com/android/settings/notification/LockScreenNotificationsPreferencePageControllerTest.java b/tests/robotests/src/com/android/settings/notification/LockScreenNotificationsPreferencePageControllerTest.java
new file mode 100644
index 0000000..472d9cb
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/LockScreenNotificationsPreferencePageControllerTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2024 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.notification;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.flag.junit.SetFlagsRule;
+
+import com.android.server.notification.Flags;
+import com.android.settings.core.BasePreferenceController;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+// TODO(b/367455695): remove test when feature flag is cleaned
+@RunWith(RobolectricTestRunner.class)
+public class LockScreenNotificationsPreferencePageControllerTest {
+
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
+    private static final String PREFERENCE_KEY = "lock_screen_notifications_page";
+
+    private LockScreenNotificationsPreferencePageController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mController = new LockScreenNotificationsPreferencePageController(
+                RuntimeEnvironment.application,
+                PREFERENCE_KEY);
+    }
+
+    @Test
+    public void isAvailable_flagEnabled_shouldReturnTrue() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_NOTIFICATION_LOCK_SCREEN_SETTINGS);
+        assertThat(mController.isAvailable()).isTrue();
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(
+                BasePreferenceController.AVAILABLE);
+    }
+
+    @Test
+    public void isAvailable_flagDisabled_shouldReturnFalse() {
+        mSetFlagsRule.disableFlags(Flags.FLAG_NOTIFICATION_LOCK_SCREEN_SETTINGS);
+        assertThat(mController.isAvailable()).isFalse();
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(
+                BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
+    }
+
+}
diff --git a/tests/spa_unit/src/com/android/settings/spa/network/PrimarySimRepositoryTest.kt b/tests/spa_unit/src/com/android/settings/spa/network/PrimarySimRepositoryTest.kt
index 459afa9..ce4df2e 100644
--- a/tests/spa_unit/src/com/android/settings/spa/network/PrimarySimRepositoryTest.kt
+++ b/tests/spa_unit/src/com/android/settings/spa/network/PrimarySimRepositoryTest.kt
@@ -101,6 +101,16 @@
             SUB_INFO_1,
             SUB_INFO_2
         )
+
+        context.stub {
+            on { resources } doReturn spyResources
+        }
+        spyResources.stub {
+            on {
+                getBoolean(com.android.internal.R.bool.config_sms_ask_every_time_support)
+            } doReturn true
+        }
+
         val expectedList = listOf(
             ListPreferenceOption(
                 id = SUB_INFO_1.subscriptionId,