Merge "Create a redacted single line view" into main
diff --git a/packages/SystemUI/res/drawable/ic_redacted_notification_single_line_icon.xml b/packages/SystemUI/res/drawable/ic_redacted_notification_single_line_icon.xml
new file mode 100644
index 0000000..8146c16
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_redacted_notification_single_line_icon.xml
@@ -0,0 +1,27 @@
+<!--
+  ~ 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.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="32dp"
+    android:height="32dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="?android:attr/colorAccent"
+        android:pathData="M12,15m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"/>
+    <path
+        android:fillColor="?android:attr/colorAccent"
+        android:pathData="M18,8h-1.5V5.5C16.5,3.01 14.49,1 12,1S7.5,3.01 7.5,5.5V8H6c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V10C20,8.9 19.1,8 18,8zM9.5,5.5C9.5,4.12 10.62,3 12,3c1.38,0 2.5,1.12 2.5,2.5V8h-5V5.5zM18,20H6V10h1.5h9H18V20z"/>
+</vector>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 19eebf5..159fb2e 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -3713,6 +3713,11 @@
     <!-- Education toast text for All Apps [CHAR_LIMIT=100] -->
     <string name="all_apps_edu_toast_content">To view all your apps, press the action key on your keyboard</string>
 
+    <!-- Title of the one line view of a redacted notification -->
+    <string name="redacted_notification_single_line_title">Redacted</string>
+    <!-- Main text of the one line view of a redacted notification -->
+    <string name="redacted_notification_single_line_text">Unlock to view</string>
+
     <!-- Education notification title for Back [CHAR_LIMIT=100] -->
     <string name="back_edu_notification_title">Use your touchpad to go back</string>
     <!-- Education notification text for Back [CHAR_LIMIT=100] -->
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index bb26f92..7244f8a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -16,7 +16,6 @@
 package com.android.systemui.statusbar;
 
 import static android.app.Flags.keyguardPrivateNotifications;
-import static android.app.Flags.redactSensitiveContentNotificationsOnLockscreen;
 import static android.app.StatusBarManager.ACTION_KEYGUARD_PRIVATE_NOTIFICATIONS_CHANGED;
 import static android.app.StatusBarManager.EXTRA_KM_PRIVATE_NOTIFS_ALLOWED;
 import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED;
@@ -72,6 +71,7 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
+import com.android.systemui.statusbar.notification.row.shared.LockscreenOtpRedaction;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.ListenerSet;
@@ -655,7 +655,7 @@
                 !userAllowsPrivateNotificationsInPublic(mCurrentUserId);
         boolean isNotifForManagedProfile = mCurrentManagedProfiles.contains(userId);
         boolean isNotifUserRedacted = !userAllowsPrivateNotificationsInPublic(userId);
-        boolean isNotifSensitive = redactSensitiveContentNotificationsOnLockscreen()
+        boolean isNotifSensitive = LockscreenOtpRedaction.isEnabled()
                 && ent.getRanking() != null && ent.getRanking().hasSensitiveContent();
 
         // redact notifications if the current user is redacting notifications or the notification
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
index 4a895c0..c52632e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
@@ -20,6 +20,7 @@
 import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED;
 import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_EXPANDED;
 import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC;
+import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE;
 import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_SINGLE_LINE;
 import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_GROUP_SUMMARY_HEADER;
 import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER;
@@ -54,6 +55,7 @@
 import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent;
 import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation;
 import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation;
+import com.android.systemui.statusbar.notification.row.shared.LockscreenOtpRedaction;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 
 import javax.inject.Inject;
@@ -253,10 +255,11 @@
         params.requireContentViews(FLAG_CONTENT_VIEW_EXPANDED);
         params.setUseIncreasedCollapsedHeight(useIncreasedCollapsedHeight);
         params.setUseMinimized(isMinimized);
-
-        if (screenshareNotificationHiding()
+        boolean needsRedaction = screenshareNotificationHiding()
                 ? inflaterParams.getNeedsRedaction()
-                : mNotificationLockscreenUserManager.needsRedaction(entry)) {
+                : mNotificationLockscreenUserManager.needsRedaction(entry);
+
+        if (needsRedaction) {
             params.requireContentViews(FLAG_CONTENT_VIEW_PUBLIC);
         } else {
             params.markContentViewsFreeable(FLAG_CONTENT_VIEW_PUBLIC);
@@ -272,6 +275,14 @@
             }
         }
 
+        if (LockscreenOtpRedaction.isEnabled()) {
+            if (inflaterParams.isChildInGroup() && needsRedaction) {
+                params.requireContentViews(FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE);
+            } else {
+                params.markContentViewsFreeable(FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE);
+            }
+        }
+
         if (AsyncGroupHeaderViewInflation.isEnabled()) {
             if (inflaterParams.isGroupSummary()) {
                 params.requireContentViews(FLAG_GROUP_SUMMARY_HEADER);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 06af980..9d13a17 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -102,6 +102,7 @@
 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag;
 import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation;
+import com.android.systemui.statusbar.notification.row.shared.LockscreenOtpRedaction;
 import com.android.systemui.statusbar.notification.row.wrapper.NotificationCompactMessagingTemplateViewWrapper;
 import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
 import com.android.systemui.statusbar.notification.shared.NotificationContentAlphaOptimization;
@@ -997,6 +998,9 @@
         }
         mNotificationParent = isChildInGroup ? parent : null;
         mPrivateLayout.setIsChildInGroup(isChildInGroup);
+        if (LockscreenOtpRedaction.isEnabled()) {
+            mPublicLayout.setIsChildInGroup(isChildInGroup);
+        }
 
         updateBackgroundForGroupState();
         updateClickAndFocus();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java
index ba1cfcc..0738a03 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridConversationNotificationView.java
@@ -46,7 +46,7 @@
 import java.util.Objects;
 
 /**
- * A hybrid view which may contain information about one ore more conversations.
+ * A hybrid view which may contain information about one or more conversations.
  */
 public class HybridConversationNotificationView extends HybridNotificationView {
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
index af5117e..8c80fd4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
@@ -56,8 +56,8 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation;
 import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation;
+import com.android.systemui.statusbar.notification.row.shared.LockscreenOtpRedaction;
 import com.android.systemui.statusbar.notification.row.shared.NotificationRowContentBinderRefactor;
-import com.android.systemui.statusbar.notification.row.ui.viewbinder.SingleLineConversationViewBinder;
 import com.android.systemui.statusbar.notification.row.ui.viewbinder.SingleLineViewBinder;
 import com.android.systemui.statusbar.notification.row.ui.viewmodel.SingleLineViewModel;
 import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
@@ -196,8 +196,8 @@
 
         result = inflateSmartReplyViews(result, reInflateFlags, entry, row.getContext(),
                 packageContext, row.getExistingSmartReplyState(), smartRepliesInflater, mLogger);
+        boolean isConversation = entry.getRanking().isConversation();
         if (AsyncHybridViewInflation.isEnabled()) {
-            boolean isConversation = entry.getRanking().isConversation();
             Notification.MessagingStyle messagingStyle = null;
             if (isConversation) {
                 messagingStyle = mConversationProcessor
@@ -210,8 +210,22 @@
                             builder,
                             row.getContext()
                     );
-            result.mInflatedSingleLineViewHolder =
-                    SingleLineViewInflater.inflateSingleLineViewHolder(
+            result.mInflatedSingleLineView =
+                    SingleLineViewInflater.inflatePrivateSingleLineView(
+                            isConversation,
+                            reInflateFlags,
+                            entry,
+                            row.getContext(),
+                            mLogger
+                    );
+        }
+
+        if (LockscreenOtpRedaction.isEnabled()) {
+            result.mPublicInflatedSingleLineViewModel =
+                    SingleLineViewInflater.inflateRedactedSingleLineViewModel(row.getContext(),
+                            isConversation);
+            result.mPublicInflatedSingleLineView =
+                    SingleLineViewInflater.inflatePublicSingleLineView(
                             isConversation,
                             reInflateFlags,
                             entry,
@@ -291,6 +305,16 @@
                     row.getPrivateLayout().setHeadsUpInflatedSmartReplies(null);
                 });
                 break;
+            case FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE:
+                if (LockscreenOtpRedaction.isEnabled()) {
+                    row.getPublicLayout()
+                            .performWhenContentInactive(VISIBLE_TYPE_SINGLELINE, () -> {
+                                row.getPublicLayout().setSingleLineView(null);
+                                mRemoteViewCache.removeCachedView(entry,
+                                        FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE);
+                            });
+                }
+                break;
             case FLAG_CONTENT_VIEW_PUBLIC:
                 row.getPublicLayout().performWhenContentInactive(VISIBLE_TYPE_CONTRACTED, () -> {
                     row.getPublicLayout().setContractedChild(null);
@@ -334,6 +358,10 @@
             row.getPublicLayout().removeContentInactiveRunnable(VISIBLE_TYPE_CONTRACTED);
         }
         if (AsyncHybridViewInflation.isEnabled()
+                && (contentViews & FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE) != 0) {
+            row.getPublicLayout().removeContentInactiveRunnable(VISIBLE_TYPE_SINGLELINE);
+        }
+        if (LockscreenOtpRedaction.isEnabled()
                 && (contentViews & FLAG_CONTENT_VIEW_SINGLE_LINE) != 0) {
             row.getPrivateLayout().removeContentInactiveRunnable(VISIBLE_TYPE_SINGLELINE);
         }
@@ -935,19 +963,21 @@
 
         if (AsyncHybridViewInflation.isEnabled()
                 && (reInflateFlags & FLAG_CONTENT_VIEW_SINGLE_LINE) != 0) {
-            HybridNotificationView viewHolder = result.mInflatedSingleLineViewHolder;
+            HybridNotificationView view = result.mInflatedSingleLineView;
             SingleLineViewModel viewModel = result.mInflatedSingleLineViewModel;
-            if (viewHolder != null && viewModel != null) {
-                if (viewModel.isConversation()) {
-                    SingleLineConversationViewBinder.bind(
-                            result.mInflatedSingleLineViewModel,
-                            result.mInflatedSingleLineViewHolder
-                    );
-                } else {
-                    SingleLineViewBinder.bind(result.mInflatedSingleLineViewModel,
-                            result.mInflatedSingleLineViewHolder);
-                }
-                privateLayout.setSingleLineView(result.mInflatedSingleLineViewHolder);
+            if (view != null && viewModel != null) {
+                SingleLineViewBinder.bind(viewModel, view);
+                privateLayout.setSingleLineView(result.mInflatedSingleLineView);
+            }
+        }
+
+        if (LockscreenOtpRedaction.isEnabled()
+                && (reInflateFlags & FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE) != 0) {
+            HybridNotificationView view = result.mPublicInflatedSingleLineView;
+            SingleLineViewModel viewModel = result.mPublicInflatedSingleLineViewModel;
+            if (view != null && viewModel != null) {
+                SingleLineViewBinder.bind(viewModel, view);
+                publicLayout.setSingleLineView(result.mPublicInflatedSingleLineView);
             }
         }
 
@@ -1211,8 +1241,22 @@
                                 recoveredBuilder,
                                 mContext
                         );
-                result.mInflatedSingleLineViewHolder =
-                        SingleLineViewInflater.inflateSingleLineViewHolder(
+                result.mInflatedSingleLineView =
+                        SingleLineViewInflater.inflatePrivateSingleLineView(
+                                isConversation,
+                                mReInflateFlags,
+                                mEntry,
+                                mContext,
+                                mLogger
+                        );
+            }
+
+            if (LockscreenOtpRedaction.isEnabled()) {
+                result.mPublicInflatedSingleLineViewModel =
+                        SingleLineViewInflater.inflateRedactedSingleLineViewModel(mContext,
+                                isConversation);
+                result.mPublicInflatedSingleLineView =
+                        SingleLineViewInflater.inflatePublicSingleLineView(
                                 isConversation,
                                 mReInflateFlags,
                                 mEntry,
@@ -1347,8 +1391,13 @@
 
         // ViewModel for SingleLineView, holds the UI State
         SingleLineViewModel mInflatedSingleLineViewModel;
+        // ViewModel for public SingleLineView, holds the UI State
+        SingleLineViewModel mPublicInflatedSingleLineViewModel;
         // Inflated SingleLineViewHolder, SingleLineView that lacks the UI State
-        HybridNotificationView mInflatedSingleLineViewHolder;
+        HybridNotificationView mInflatedSingleLineView;
+        // Inflated SingleLineViewHolder, SingleLineView that lacks the UI State for the public
+        // single line view
+        HybridNotificationView mPublicInflatedSingleLineView;
     }
 
     @VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index 3f46902..7119145 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -113,7 +113,8 @@
     private View mContractedChild;
     private View mExpandedChild;
     private View mHeadsUpChild;
-    private HybridNotificationView mSingleLineView;
+    @VisibleForTesting
+    protected HybridNotificationView mSingleLineView;
 
     @Nullable public DisposableHandle mContractedBinderHandle;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java
index fe0ee52..07384af 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java
@@ -89,6 +89,7 @@
                     FLAG_CONTENT_VIEW_SINGLE_LINE,
                     FLAG_GROUP_SUMMARY_HEADER,
                     FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER,
+                    FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE,
                     FLAG_CONTENT_VIEW_ALL})
     @interface InflationFlag {}
     /**
@@ -105,7 +106,7 @@
      */
     int FLAG_CONTENT_VIEW_HEADS_UP = 1 << 2;
     /**
-     * The public view.  This is a version of the contracted view that hides sensitive
+     * The public view. This is a version of the contracted view that hides sensitive
      * information and is used on the lock screen if we determine that the notification's
      * content should be hidden.
      */
@@ -126,7 +127,14 @@
      */
     int FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER = 1 << 6;
 
-    int FLAG_CONTENT_VIEW_ALL = (1 << 7) - 1;
+    /**
+     * The public single line view. This is a version of the contracted view that hides sensitive
+     * information and is used on the lock screen if we determine that the notification's
+     * content should be hidden, and the notification is shown as a child in a group.
+     */
+    int FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE = 1 << 7;
+
+    int FLAG_CONTENT_VIEW_ALL = (1 << 8) - 1;
 
     /**
      * Parameters for content view binding
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
index 492d802..a5cd2a2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
@@ -55,6 +55,7 @@
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_EXPANDED
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC
+import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_SINGLE_LINE
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_GROUP_SUMMARY_HEADER
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER
@@ -63,11 +64,11 @@
 import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation
 import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation
 import com.android.systemui.statusbar.notification.row.shared.HeadsUpStatusBarModel
+import com.android.systemui.statusbar.notification.row.shared.LockscreenOtpRedaction
 import com.android.systemui.statusbar.notification.row.shared.NewRemoteViews
 import com.android.systemui.statusbar.notification.row.shared.NotificationContentModel
 import com.android.systemui.statusbar.notification.row.shared.NotificationRowContentBinderRefactor
 import com.android.systemui.statusbar.notification.row.shared.RichOngoingContentModel
-import com.android.systemui.statusbar.notification.row.ui.viewbinder.SingleLineConversationViewBinder
 import com.android.systemui.statusbar.notification.row.ui.viewbinder.SingleLineViewBinder
 import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper
 import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer
@@ -202,7 +203,19 @@
         if (AsyncHybridViewInflation.isEnabled) {
             result.inflatedSingleLineView =
                 result.contentModel.singleLineViewModel?.let { viewModel ->
-                    SingleLineViewInflater.inflateSingleLineViewHolder(
+                    SingleLineViewInflater.inflatePrivateSingleLineView(
+                        viewModel.isConversation(),
+                        reInflateFlags,
+                        entry,
+                        systemUIContext,
+                        logger,
+                    )
+                }
+        }
+        if (LockscreenOtpRedaction.isEnabled) {
+            result.inflatedPublicSingleLineView =
+                result.contentModel.publicSingleLineViewModel?.let { viewModel ->
+                    SingleLineViewInflater.inflatePublicSingleLineView(
                         viewModel.isConversation(),
                         reInflateFlags,
                         entry,
@@ -294,6 +307,13 @@
                     }
                 }
             }
+            FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE -> {
+                if (LockscreenOtpRedaction.isEnabled) {
+                    row.publicLayout.performWhenContentInactive(VISIBLE_TYPE_SINGLELINE) {
+                        row.publicLayout.setSingleLineView(null)
+                    }
+                }
+            }
             else -> {}
         }
     }
@@ -327,6 +347,12 @@
         ) {
             row.privateLayout.removeContentInactiveRunnable(VISIBLE_TYPE_SINGLELINE)
         }
+        if (
+            LockscreenOtpRedaction.isEnabled &&
+                contentViews and FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE != 0
+        ) {
+            row.publicLayout.removeContentInactiveRunnable(VISIBLE_TYPE_SINGLELINE)
+        }
     }
 
     /**
@@ -449,7 +475,7 @@
                 logger.logAsyncTaskProgress(entry, "inflating single line view")
                 inflationProgress.inflatedSingleLineView =
                     inflationProgress.contentModel.singleLineViewModel?.let {
-                        SingleLineViewInflater.inflateSingleLineViewHolder(
+                        SingleLineViewInflater.inflatePrivateSingleLineView(
                             it.isConversation(),
                             reInflateFlags,
                             entry,
@@ -459,6 +485,20 @@
                     }
             }
 
+            if (LockscreenOtpRedaction.isEnabled) {
+                logger.logAsyncTaskProgress(entry, "inflating public single line view")
+                inflationProgress.inflatedPublicSingleLineView =
+                    inflationProgress.contentModel.publicSingleLineViewModel?.let { viewModel ->
+                        SingleLineViewInflater.inflatePublicSingleLineView(
+                            viewModel.isConversation(),
+                            reInflateFlags,
+                            entry,
+                            context,
+                            logger
+                        )
+                    }
+            }
+
             if (reInflateFlags and CONTENT_VIEWS_TO_CREATE_RICH_ONGOING != 0) {
                 logger.logAsyncTaskProgress(entry, "inflating RON view")
                 inflationProgress.richOngoingNotificationViewHolder =
@@ -582,6 +622,8 @@
 
         // Inflated SingleLineView that lacks the UI State
         var inflatedSingleLineView: HybridNotificationView? = null
+        // Inflated public SingleLineView that lacks the UI State
+        var inflatedPublicSingleLineView: HybridNotificationView? = null
     }
 
     @VisibleForTesting
@@ -706,6 +748,18 @@
                     )
                 } else null
 
+            val publicSingleLineViewModel =
+                if (
+                    LockscreenOtpRedaction.isEnabled &&
+                        reInflateFlags and FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE != 0
+                ) {
+                    logger.logAsyncTaskProgress(entry, "inflating public single line view model")
+                    SingleLineViewInflater.inflateRedactedSingleLineViewModel(
+                        systemUIContext,
+                        entry.ranking.isConversation
+                    )
+                } else null
+
             val headsUpStatusBarModel =
                 HeadsUpStatusBarModel(
                     privateText = builder.getHeadsUpStatusBarText(/* publicMode= */ false),
@@ -716,6 +770,7 @@
                 NotificationContentModel(
                     headsUpStatusBarModel = headsUpStatusBarModel,
                     singleLineViewModel = singleLineViewModel,
+                    publicSingleLineViewModel = publicSingleLineViewModel,
                     richOngoingContentModel = richOngoingContentModel,
                 )
 
@@ -1405,15 +1460,23 @@
                 val singleLineView = result.inflatedSingleLineView
                 val viewModel = result.contentModel.singleLineViewModel
                 if (singleLineView != null && viewModel != null) {
-                    if (viewModel.isConversation()) {
-                        SingleLineConversationViewBinder.bind(viewModel, singleLineView)
-                    } else {
-                        SingleLineViewBinder.bind(viewModel, singleLineView)
-                    }
+                    SingleLineViewBinder.bind(viewModel, singleLineView)
                     row.privateLayout.setSingleLineView(result.inflatedSingleLineView)
                 }
             }
 
+            if (
+                LockscreenOtpRedaction.isEnabled &&
+                    reInflateFlags and FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE != 0
+            ) {
+                val singleLineView = result.inflatedPublicSingleLineView
+                val viewModel = result.contentModel.publicSingleLineViewModel
+                if (singleLineView != null && viewModel != null) {
+                    SingleLineViewBinder.bind(viewModel, singleLineView)
+                    row.publicLayout.setSingleLineView(result.inflatedPublicSingleLineView)
+                }
+            }
+
             // after updating the content model, set the view, then start the new binder
             result.richOngoingNotificationViewHolder?.let { viewHolder ->
                 row.privateLayout.contractedChild = viewHolder.view
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflater.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflater.kt
index 463192c..d67947d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflater.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflater.kt
@@ -30,6 +30,7 @@
 import com.android.internal.widget.PeopleHelper
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.logKey
+import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_SINGLE_LINE
 import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation
 import com.android.systemui.statusbar.notification.row.ui.viewmodel.ConversationAvatar
@@ -107,6 +108,36 @@
         )
     }
 
+    @JvmStatic
+    fun inflateRedactedSingleLineViewModel(
+        context: Context,
+        isConversation: Boolean = false
+    ): SingleLineViewModel {
+        val conversationData =
+            if (isConversation) {
+                ConversationData(
+                    null,
+                    SingleIcon(
+                        context.getDrawable(
+                            com.android.systemui.res.R.drawable
+                                .ic_redacted_notification_single_line_icon
+                        )
+                    )
+                )
+            } else {
+                null
+            }
+        return SingleLineViewModel(
+            context.getString(
+                com.android.systemui.res.R.string.redacted_notification_single_line_title
+            ),
+            context.getString(
+                com.android.systemui.res.R.string.redacted_notification_single_line_text
+            ),
+            conversationData
+        )
+    }
+
     /** load conversation text data from the MessagingStyle of conversation notifications */
     private fun MessagingStyle.loadConversationTextData(
         systemUiContext: Context
@@ -137,8 +168,8 @@
 
         // We need to find back-up values for those texts if they are needed and empty
         return ConversationTextData(
-            conversationTitle = conversationTitle
-                    ?: findBackUpConversationTitle(senderName, systemUiContext),
+            conversationTitle =
+                conversationTitle ?: findBackUpConversationTitle(senderName, systemUiContext),
             conversationText = conversationText,
             senderName = senderName,
         )
@@ -328,12 +359,27 @@
         return FacePile(
             topIconDrawable = secondLastIcon.loadDrawable(systemUiContext),
             bottomIconDrawable = lastIcon.loadDrawable(systemUiContext),
-            bottomBackgroundColor = builder.getBackgroundColor(/* isHeader = */ false),
+            bottomBackgroundColor = builder.getBackgroundColor(/* isHeader= */ false),
         )
     }
 
     @JvmStatic
-    fun inflateSingleLineViewHolder(
+    fun inflatePublicSingleLineView(
+        isConversation: Boolean,
+        reinflateFlags: Int,
+        entry: NotificationEntry,
+        context: Context,
+        logger: NotificationRowContentBinderLogger,
+    ): HybridNotificationView? {
+        return if ((reinflateFlags and FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE) == 0) {
+            null
+        } else {
+            inflateSingleLineView(isConversation, reinflateFlags, entry, context, logger)
+        }
+    }
+
+    @JvmStatic
+    fun inflatePrivateSingleLineView(
         isConversation: Boolean,
         reinflateFlags: Int,
         entry: NotificationEntry,
@@ -341,9 +387,21 @@
         logger: NotificationRowContentBinderLogger,
     ): HybridNotificationView? {
         if (AsyncHybridViewInflation.isUnexpectedlyInLegacyMode()) return null
-        if (reinflateFlags and FLAG_CONTENT_VIEW_SINGLE_LINE == 0) {
-            return null
+        return if ((reinflateFlags and FLAG_CONTENT_VIEW_SINGLE_LINE) == 0) {
+            null
+        } else {
+            inflateSingleLineView(isConversation, reinflateFlags, entry, context, logger)
         }
+    }
+
+    private fun inflateSingleLineView(
+        isConversation: Boolean,
+        reinflateFlags: Int,
+        entry: NotificationEntry,
+        context: Context,
+        logger: NotificationRowContentBinderLogger,
+    ): HybridNotificationView? {
+        if (AsyncHybridViewInflation.isUnexpectedlyInLegacyMode()) return null
 
         logger.logInflateSingleLine(entry, reinflateFlags, isConversation)
         logger.logAsyncTaskProgress(entry, "inflating single-line content view")
@@ -356,7 +414,7 @@
                 if (isConversation)
                     com.android.systemui.res.R.layout.hybrid_conversation_notification
                 else com.android.systemui.res.R.layout.hybrid_notification
-            view = inflater.inflate(layoutRes, /* root = */ null) as HybridNotificationView
+            view = inflater.inflate(layoutRes, /* root= */ null) as HybridNotificationView
             if (view == null) {
                 Log.wtf(TAG, "Single-line view inflation result is null for entry: ${entry.logKey}")
             }
@@ -368,7 +426,7 @@
         name: CharSequence?,
         uniqueNames: PeopleHelper.NameToPrefixMap? = null
     ): Icon {
-        val layoutColor = getSmallIconColor(/* isHeader = */ false)
+        val layoutColor = getSmallIconColor(/* isHeader= */ false)
         if (!name.isNullOrEmpty()) {
             val symbol = uniqueNames?.getPrefix(name) ?: ""
             return peopleHelper.createAvatarSymbol(
@@ -379,7 +437,7 @@
         }
         // If name is null, create default avatar with background color
         // TODO(b/319829062): Investigate caching default icon for color
-        return peopleHelper.createAvatarSymbol(/* name = */ "", /* symbol = */ "", layoutColor)
+        return peopleHelper.createAvatarSymbol(/* name= */ "", /* symbol= */ "", layoutColor)
     }
 
     private fun Person.getKeyOrName(): CharSequence? = if (key == null) name else key
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/LockscreenOtpRedaction.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/LockscreenOtpRedaction.kt
new file mode 100644
index 0000000..078deb9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/LockscreenOtpRedaction.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2023 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.systemui.statusbar.notification.row.shared
+
+import android.app.Flags
+import android.app.Flags.redactSensitiveContentNotificationsOnLockscreen
+import com.android.systemui.flags.FlagToken
+
+/** Helper for reading or using the async hybrid view inflation flag state. */
+object LockscreenOtpRedaction {
+    const val FLAG_NAME = Flags.FLAG_REDACT_SENSITIVE_CONTENT_NOTIFICATIONS_ON_LOCKSCREEN
+
+    /** A token used for dependency declaration */
+    val token: FlagToken
+        get() = FlagToken(FLAG_NAME, isEnabled)
+
+    @JvmStatic
+    inline val isEnabled
+        get() =
+            redactSensitiveContentNotificationsOnLockscreen() && AsyncHybridViewInflation.isEnabled
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/NotificationContentModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/NotificationContentModel.kt
index 46010a1..0f9a5a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/NotificationContentModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/NotificationContentModel.kt
@@ -21,6 +21,7 @@
 data class NotificationContentModel(
     val headsUpStatusBarModel: HeadsUpStatusBarModel,
     val singleLineViewModel: SingleLineViewModel? = null,
+    val publicSingleLineViewModel: SingleLineViewModel? = null,
     val richOngoingContentModel: RichOngoingContentModel? = null,
 )
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/SingleLineConversationViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/SingleLineConversationViewBinder.kt
deleted file mode 100644
index 69284bd..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/SingleLineConversationViewBinder.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2023 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.systemui.statusbar.notification.row.ui.viewbinder
-
-import com.android.systemui.statusbar.notification.row.HybridConversationNotificationView
-import com.android.systemui.statusbar.notification.row.HybridNotificationView
-import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation
-import com.android.systemui.statusbar.notification.row.ui.viewmodel.SingleLineViewModel
-
-object SingleLineConversationViewBinder {
-    @JvmStatic
-    fun bind(viewModel: SingleLineViewModel, view: HybridNotificationView?) {
-        if (AsyncHybridViewInflation.isUnexpectedlyInLegacyMode()) return
-        if (view !is HybridConversationNotificationView || !viewModel.isConversation()) {
-            SingleLineViewBinder.bind(viewModel, view)
-            return
-        }
-
-        viewModel.conversationData?.avatar?.let { view.setAvatar(it) }
-        view.setText(
-            viewModel.titleText,
-            viewModel.contentText,
-            viewModel.conversationData?.conversationSenderName
-        )
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/SingleLineViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/SingleLineViewBinder.kt
index 22e10c1..3b0f1ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/SingleLineViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/SingleLineViewBinder.kt
@@ -16,19 +16,32 @@
 
 package com.android.systemui.statusbar.notification.row.ui.viewbinder
 
+import com.android.systemui.statusbar.notification.row.HybridConversationNotificationView
 import com.android.systemui.statusbar.notification.row.HybridNotificationView
+import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation
 import com.android.systemui.statusbar.notification.row.ui.viewmodel.SingleLineViewModel
 
 object SingleLineViewBinder {
     @JvmStatic
     fun bind(viewModel: SingleLineViewModel?, view: HybridNotificationView?) {
-        // bind the title and content text views
-        view?.apply {
-            bind(
-                /* title = */ viewModel?.titleText,
-                /* text = */ viewModel?.contentText,
-                /* contentView = */ null
+        if (viewModel?.isConversation() == true && view is HybridConversationNotificationView) {
+            if (AsyncHybridViewInflation.isUnexpectedlyInLegacyMode()) return
+
+            viewModel.conversationData?.avatar?.let { view.setAvatar(it) }
+            view.setText(
+                viewModel.titleText,
+                viewModel.contentText,
+                viewModel.conversationData?.conversationSenderName
             )
+        } else {
+            // bind the title and content text views
+            view?.apply {
+                bind(
+                    /* title = */ viewModel?.titleText,
+                    /* text = */ viewModel?.contentText,
+                    /* contentView = */ null
+                )
+            }
         }
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt
index 54a26f7..3f28164 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt
@@ -16,6 +16,7 @@
 package com.android.systemui.statusbar.notification.row
 
 import android.app.Notification
+import android.app.Person
 import android.content.Context
 import android.os.AsyncTask
 import android.os.Build
@@ -39,6 +40,7 @@
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_EXPANDED
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP
+import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationCallback
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag
 import com.android.systemui.statusbar.notification.row.shared.HeadsUpStatusBarModel
@@ -561,6 +563,40 @@
         verify(row, times(0)).onNotificationUpdated()
     }
 
+    // TODO b/356709333: Add screenshot tests for these views
+    @Test
+    fun testInflatePublicSingleLineView() {
+        row.publicLayout.removeAllViews()
+        inflateAndWait(false, notificationInflater, FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE, row)
+        Assert.assertNotNull(row.publicLayout.mSingleLineView)
+        Assert.assertTrue(row.publicLayout.mSingleLineView is HybridNotificationView)
+    }
+
+    @Test
+    fun testInflatePublicSingleLineConversationView() {
+        val testPerson = Person.Builder().setName("Person").build()
+        val messagingBuilder =
+            Notification.Builder(mContext, "no-id")
+                .setSmallIcon(R.drawable.ic_person)
+                .setContentTitle("Title")
+                .setContentText("Text")
+                .setStyle(Notification.MessagingStyle(testPerson))
+
+        val messagingRow = spy(testHelper.createRow(messagingBuilder.build()))
+        messagingRow.publicLayout.removeAllViews()
+        inflateAndWait(
+            false,
+            notificationInflater,
+            FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE,
+            messagingRow
+        )
+        Assert.assertNotNull(messagingRow.publicLayout.mSingleLineView)
+        // assert this is the conversation layout
+        Assert.assertTrue(
+            messagingRow.publicLayout.mSingleLineView is HybridConversationNotificationView
+        )
+    }
+
     private class ExceptionHolder {
         var exception: Exception? = null
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index d7fdce2..75376e6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -620,8 +620,12 @@
                 .setUser(userHandle)
                 .setPostTime(System.currentTimeMillis())
                 .setChannel(channel)
+                .updateRanking(rankingBuilder -> rankingBuilder.setIsConversation(
+                        notification.isStyle(Notification.MessagingStyle.class)
+                ))
                 .build();
 
+
         return generateRow(entry, extraInflationFlags);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineConversationViewBinderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineConversationViewBinderTest.kt
deleted file mode 100644
index 53a1198..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineConversationViewBinderTest.kt
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2023 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.systemui.statusbar.notification.row
-
-import android.app.Notification
-import android.app.Person
-import android.platform.test.annotations.EnableFlags
-import android.testing.TestableLooper
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.internal.R
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_SINGLE_LINE
-import com.android.systemui.statusbar.notification.row.SingleLineViewInflater.inflateSingleLineViewHolder
-import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation
-import com.android.systemui.statusbar.notification.row.ui.viewbinder.SingleLineConversationViewBinder
-import com.android.systemui.util.mockito.mock
-import kotlin.test.assertEquals
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-@TestableLooper.RunWithLooper
-class SingleLineConversationViewBinderTest : SysuiTestCase() {
-    private lateinit var notificationBuilder: Notification.Builder
-    private lateinit var helper: NotificationTestHelper
-
-    @Before
-    fun setUp() {
-        allowTestableLooperAsMainThread()
-        helper = NotificationTestHelper(context, mDependency, TestableLooper.get(this))
-        notificationBuilder = Notification.Builder(context, CHANNEL_ID)
-        notificationBuilder
-            .setSmallIcon(R.drawable.ic_corp_icon)
-            .setContentTitle(CONTENT_TITLE)
-            .setContentText(CONTENT_TEXT)
-    }
-
-    @Test
-    @EnableFlags(AsyncHybridViewInflation.FLAG_NAME)
-    fun bindGroupConversationSingleLineView() {
-        // GIVEN a row with a group conversation notification
-        val user =
-            Person.Builder()
-                //                .setIcon(Icon.createWithResource(mContext,
-                // R.drawable.ic_account_circle))
-                .setName(USER_NAME)
-                .build()
-        val style =
-            Notification.MessagingStyle(user)
-                .addMessage(MESSAGE_TEXT, System.currentTimeMillis(), user)
-                .addMessage(
-                    "How about lunch?",
-                    System.currentTimeMillis(),
-                    Person.Builder().setName("user2").build()
-                )
-                .setGroupConversation(true)
-        notificationBuilder.setStyle(style).setShortcutId(SHORTCUT_ID)
-        val notification = notificationBuilder.build()
-        val row = helper.createRow(notification)
-
-        val viewHolder =
-            inflateSingleLineViewHolder(
-                isConversation = true,
-                reinflateFlags = FLAG_CONTENT_VIEW_SINGLE_LINE,
-                entry = row.entry,
-                context = context,
-                logger = mock()
-            )
-                as HybridConversationNotificationView
-        val viewModel =
-            SingleLineViewInflater.inflateSingleLineViewModel(
-                notification = notification,
-                messagingStyle = style,
-                builder = notificationBuilder,
-                systemUiContext = context,
-            )
-        // WHEN: binds the viewHolder
-        SingleLineConversationViewBinder.bind(
-            viewModel,
-            viewHolder,
-        )
-
-        // THEN: the single-line conversation view should be bind with view model's corresponding
-        // fields
-        assertEquals(viewModel.titleText, viewHolder.titleView.text)
-        assertEquals(viewModel.contentText, viewHolder.textView.text)
-        assertEquals(
-            viewModel.conversationData?.conversationSenderName,
-            viewHolder.conversationSenderNameView.text
-        )
-    }
-
-    private companion object {
-        const val CHANNEL_ID = "CHANNEL_ID"
-        const val CONTENT_TITLE = "CONTENT_TITLE"
-        const val CONTENT_TEXT = "CONTENT_TEXT"
-        const val USER_NAME = "USER_NAME"
-        const val MESSAGE_TEXT = "MESSAGE_TEXT"
-        const val SHORTCUT_ID = "Shortcut"
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineViewBinderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineViewBinderTest.kt
index ee819c4..6b3fb5b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineViewBinderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineViewBinderTest.kt
@@ -16,18 +16,22 @@
 package com.android.systemui.statusbar.notification.row
 
 import android.app.Notification
+import android.app.Person
 import android.platform.test.annotations.EnableFlags
 import android.testing.TestableLooper
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.R
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_SINGLE_LINE
-import com.android.systemui.statusbar.notification.row.SingleLineViewInflater.inflateSingleLineViewHolder
+import com.android.systemui.statusbar.notification.row.SingleLineViewInflater.inflatePrivateSingleLineView
+import com.android.systemui.statusbar.notification.row.SingleLineViewInflater.inflatePublicSingleLineView
 import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation
 import com.android.systemui.statusbar.notification.row.ui.viewbinder.SingleLineViewBinder
 import com.android.systemui.util.mockito.mock
-import org.junit.Assert
+import kotlin.test.assertEquals
+import kotlin.test.assertNotNull
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -59,14 +63,25 @@
         val notification = notificationBuilder.build()
         val row: ExpandableNotificationRow = helper.createRow(notification)
 
-        val viewHolder =
-            inflateSingleLineViewHolder(
+        val view =
+            inflatePrivateSingleLineView(
                 isConversation = false,
                 reinflateFlags = FLAG_CONTENT_VIEW_SINGLE_LINE,
                 entry = row.entry,
                 context = context,
                 logger = mock()
             )
+
+        val publicView =
+            inflatePublicSingleLineView(
+                isConversation = false,
+                reinflateFlags = FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE,
+                entry = row.entry,
+                context = context,
+                logger = mock()
+            )
+        assertNotNull(publicView)
+
         val viewModel =
             SingleLineViewInflater.inflateSingleLineViewModel(
                 notification = notification,
@@ -76,16 +91,86 @@
             )
 
         // WHEN: binds the viewHolder
-        SingleLineViewBinder.bind(viewModel, viewHolder)
+        SingleLineViewBinder.bind(viewModel, view)
 
         // THEN: the single-line view should be bind with viewModel's title and content text
-        Assert.assertEquals(viewModel.titleText, viewHolder?.titleView?.text)
-        Assert.assertEquals(viewModel.contentText, viewHolder?.textView?.text)
+        assertEquals(viewModel.titleText, view?.titleView?.text)
+        assertEquals(viewModel.contentText, view?.textView?.text)
+    }
+
+    @Test
+    @EnableFlags(AsyncHybridViewInflation.FLAG_NAME)
+    fun bindGroupConversationSingleLineView() {
+        // GIVEN a row with a group conversation notification
+        val user =
+            Person.Builder()
+                //                .setIcon(Icon.createWithResource(mContext,
+                // R.drawable.ic_account_circle))
+                .setName(USER_NAME)
+                .build()
+        val style =
+            Notification.MessagingStyle(user)
+                .addMessage(MESSAGE_TEXT, System.currentTimeMillis(), user)
+                .addMessage(
+                    "How about lunch?",
+                    System.currentTimeMillis(),
+                    Person.Builder().setName("user2").build()
+                )
+                .setGroupConversation(true)
+        notificationBuilder.setStyle(style).setShortcutId(SHORTCUT_ID)
+        val notification = notificationBuilder.build()
+        val row = helper.createRow(notification)
+
+        val view =
+            inflatePrivateSingleLineView(
+                isConversation = true,
+                reinflateFlags = FLAG_CONTENT_VIEW_SINGLE_LINE,
+                entry = row.entry,
+                context = context,
+                logger = mock()
+            )
+                as HybridConversationNotificationView
+
+        val publicView =
+            inflatePublicSingleLineView(
+                isConversation = true,
+                reinflateFlags = FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE,
+                entry = row.entry,
+                context = context,
+                logger = mock()
+            )
+                as HybridConversationNotificationView
+        assertNotNull(publicView)
+
+        val viewModel =
+            SingleLineViewInflater.inflateSingleLineViewModel(
+                notification = notification,
+                messagingStyle = style,
+                builder = notificationBuilder,
+                systemUiContext = context,
+            )
+        // WHEN: binds the view
+        SingleLineViewBinder.bind(
+            viewModel,
+            view,
+        )
+
+        // THEN: the single-line conversation view should be bound with view model's corresponding
+        // fields
+        assertEquals(viewModel.titleText, view.titleView.text)
+        assertEquals(viewModel.contentText, view.textView.text)
+        assertEquals(
+            viewModel.conversationData?.conversationSenderName,
+            view.conversationSenderNameView.text
+        )
     }
 
     private companion object {
         const val CHANNEL_ID = "CHANNEL_ID"
         const val CONTENT_TITLE = "A Cool New Feature"
         const val CONTENT_TEXT = "Checkout out new feature!"
+        const val USER_NAME = "USER_NAME"
+        const val MESSAGE_TEXT = "MESSAGE_TEXT"
+        const val SHORTCUT_ID = "Shortcut"
     }
 }