Fix java crash by inconsistent single-line view and view model

Fix the java crash when a conversation notification entry has null
MessagingStyle.

Fix: 368441586
Flag: com.android.systemui.notification_async_hybrid_view_inflation
Test: SingleLineViewBinderTest
Change-Id: If47e3f0ccfcc5e7079189288a6f3820691abd3e8
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 8c80fd4..36e3e92 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
@@ -203,13 +203,16 @@
                 messagingStyle = mConversationProcessor
                         .processNotification(entry, builder, mLogger);
             }
-            result.mInflatedSingleLineViewModel = SingleLineViewInflater
+            SingleLineViewModel viewModel = SingleLineViewInflater
                     .inflateSingleLineViewModel(
                             entry.getSbn().getNotification(),
                             messagingStyle,
                             builder,
                             row.getContext()
                     );
+            // If the messagingStyle is null, we want to inflate the normal view
+            isConversation = viewModel.isConversation();
+            result.mInflatedSingleLineViewModel = viewModel;
             result.mInflatedSingleLineView =
                     SingleLineViewInflater.inflatePrivateSingleLineView(
                             isConversation,
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 3b0f1ee..a17197c 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
@@ -24,14 +24,14 @@
 object SingleLineViewBinder {
     @JvmStatic
     fun bind(viewModel: SingleLineViewModel?, view: HybridNotificationView?) {
-        if (viewModel?.isConversation() == true && view is HybridConversationNotificationView) {
+        if (view is HybridConversationNotificationView) {
             if (AsyncHybridViewInflation.isUnexpectedlyInLegacyMode()) return
 
-            viewModel.conversationData?.avatar?.let { view.setAvatar(it) }
+            viewModel?.conversationData?.avatar?.let { view.setAvatar(it) }
             view.setText(
-                viewModel.titleText,
-                viewModel.contentText,
-                viewModel.conversationData?.conversationSenderName
+                viewModel?.titleText,
+                viewModel?.contentText,
+                viewModel?.conversationData?.conversationSenderName,
             )
         } else {
             // bind the title and content text views
@@ -39,7 +39,7 @@
                 bind(
                     /* title = */ viewModel?.titleText,
                     /* text = */ viewModel?.contentText,
-                    /* contentView = */ null
+                    /* contentView = */ null,
                 )
             }
         }
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 6b3fb5b..503fa78 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
@@ -29,12 +29,13 @@
 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 kotlin.test.assertEquals
 import kotlin.test.assertNotNull
+import kotlin.test.assertNull
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
@@ -69,7 +70,7 @@
                 reinflateFlags = FLAG_CONTENT_VIEW_SINGLE_LINE,
                 entry = row.entry,
                 context = context,
-                logger = mock()
+                logger = mock(),
             )
 
         val publicView =
@@ -78,7 +79,7 @@
                 reinflateFlags = FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE,
                 entry = row.entry,
                 context = context,
-                logger = mock()
+                logger = mock(),
             )
         assertNotNull(publicView)
 
@@ -114,7 +115,7 @@
                 .addMessage(
                     "How about lunch?",
                     System.currentTimeMillis(),
-                    Person.Builder().setName("user2").build()
+                    Person.Builder().setName("user2").build(),
                 )
                 .setGroupConversation(true)
         notificationBuilder.setStyle(style).setShortcutId(SHORTCUT_ID)
@@ -127,7 +128,7 @@
                 reinflateFlags = FLAG_CONTENT_VIEW_SINGLE_LINE,
                 entry = row.entry,
                 context = context,
-                logger = mock()
+                logger = mock(),
             )
                 as HybridConversationNotificationView
 
@@ -137,7 +138,7 @@
                 reinflateFlags = FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE,
                 entry = row.entry,
                 context = context,
-                logger = mock()
+                logger = mock(),
             )
                 as HybridConversationNotificationView
         assertNotNull(publicView)
@@ -150,10 +151,7 @@
                 systemUiContext = context,
             )
         // WHEN: binds the view
-        SingleLineViewBinder.bind(
-            viewModel,
-            view,
-        )
+        SingleLineViewBinder.bind(viewModel, view)
 
         // THEN: the single-line conversation view should be bound with view model's corresponding
         // fields
@@ -161,10 +159,55 @@
         assertEquals(viewModel.contentText, view.textView.text)
         assertEquals(
             viewModel.conversationData?.conversationSenderName,
-            view.conversationSenderNameView.text
+            view.conversationSenderNameView.text,
         )
     }
 
+    @Test
+    @EnableFlags(AsyncHybridViewInflation.FLAG_NAME)
+    fun bindConversationSingleLineView_nonConversationViewModel() {
+        // GIVEN: a ConversationSingleLineView, and a nonConversationViewModel
+        val style = Notification.BigTextStyle().bigText(CONTENT_TEXT)
+        notificationBuilder.setStyle(style)
+        val notification = notificationBuilder.build()
+        val row: ExpandableNotificationRow = helper.createRow(notification)
+
+        val view =
+            inflatePrivateSingleLineView(
+                isConversation = true,
+                reinflateFlags = FLAG_CONTENT_VIEW_SINGLE_LINE,
+                entry = row.entry,
+                context = context,
+                logger = mock(),
+            )
+
+        val publicView =
+            inflatePublicSingleLineView(
+                isConversation = true,
+                reinflateFlags = FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE,
+                entry = row.entry,
+                context = context,
+                logger = mock(),
+            )
+        assertNotNull(publicView)
+
+        val viewModel =
+            SingleLineViewInflater.inflateSingleLineViewModel(
+                notification = notification,
+                messagingStyle = null,
+                builder = notificationBuilder,
+                systemUiContext = context,
+            )
+        // WHEN: binds the view with the view model
+        SingleLineViewBinder.bind(viewModel, view)
+
+        // THEN: the single-line view should be bound with view model's corresponding
+        // fields as a normal non-conversation single-line view
+        assertEquals(viewModel.titleText, view?.titleView?.text)
+        assertEquals(viewModel.contentText, view?.textView?.text)
+        assertNull(viewModel.conversationData)
+    }
+
     private companion object {
         const val CHANNEL_ID = "CHANNEL_ID"
         const val CONTENT_TITLE = "A Cool New Feature"