[Ongoing Call Chip] Remove the chip when an ongoing call notification is
updated to a non-ongoing call notification.

Test: atest (+ new unit tests) and manual
Fixes: 187815982
Bug: 183229367
Change-Id: I0f1c6ac849ec231d68d3204f437b6a529f74bfa9
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
index e9d256c..3fa87dd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
@@ -82,16 +82,14 @@
                     entry.sbn.notification.contentIntent.intent,
                     entry.sbn.uid)
                 updateChip()
+            } else if (isCallNotification(entry)) {
+                removeChip()
             }
         }
 
         override fun onEntryRemoved(entry: NotificationEntry, reason: Int) {
             if (isOngoingCallNotification(entry)) {
-                ongoingCallInfo = null
-                mListeners.forEach { l -> l.onOngoingCallStateChanged(animate = true) }
-                if (uidObserver != null) {
-                    iActivityManager.unregisterUidObserver(uidObserver)
-                }
+                removeChip()
             }
         }
     }
@@ -224,6 +222,14 @@
         return procState <= ActivityManager.PROCESS_STATE_TOP
     }
 
+    private fun removeChip() {
+        ongoingCallInfo = null
+        mListeners.forEach { l -> l.onOngoingCallStateChanged(animate = true) }
+        if (uidObserver != null) {
+            iActivityManager.unregisterUidObserver(uidObserver)
+        }
+    }
+
     private class OngoingCallInfo(
         val callStartTime: Long,
         val intent: Intent,
@@ -233,10 +239,15 @@
 
 private fun isOngoingCallNotification(entry: NotificationEntry): Boolean {
     val extras = entry.sbn.notification.extras
-    val callStyleTemplateName = Notification.CallStyle::class.java.name
-    return extras.getString(Notification.EXTRA_TEMPLATE) == callStyleTemplateName &&
+    return isCallNotification(entry) &&
             extras.getInt(Notification.EXTRA_CALL_TYPE, -1) == CALL_TYPE_ONGOING
 }
 
+private fun isCallNotification(entry: NotificationEntry): Boolean {
+    val extras = entry.sbn.notification.extras
+    val callStyleTemplateName = Notification.CallStyle::class.java.name
+    return extras.getString(Notification.EXTRA_TEMPLATE) == callStyleTemplateName
+}
+
 private const val TAG = "OngoingCallController"
 private val DEBUG = Log.isLoggable(TAG, Log.DEBUG)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
index 9a7ab28..930377a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
@@ -116,7 +116,7 @@
     }
 
     @Test
-    fun onEntryUpdated_isOngoingCallNotif_listenerNotifiedWithRightCallTime() {
+    fun onEntryUpdated_isOngoingCallNotif_listenerNotified() {
         notifCollectionListener.onEntryUpdated(createOngoingCallNotifEntry())
 
         verify(mockOngoingCallListener).onOngoingCallStateChanged(anyBoolean())
@@ -130,6 +130,15 @@
     }
 
     @Test
+    fun onEntryUpdated_ongoingCallNotifThenScreeningCallNotif_listenerNotifiedTwice() {
+        notifCollectionListener.onEntryUpdated(createOngoingCallNotifEntry())
+        notifCollectionListener.onEntryUpdated(createScreeningCallNotifEntry())
+
+        verify(mockOngoingCallListener, times(2))
+                .onOngoingCallStateChanged(anyBoolean())
+    }
+
+    @Test
     fun onEntryRemoved_ongoingCallNotif_listenerNotified() {
         notifCollectionListener.onEntryRemoved(createOngoingCallNotifEntry(), REASON_USER_STOPPED)
 
@@ -188,6 +197,22 @@
         assertThat(controller.hasOngoingCall()).isFalse()
     }
 
+    @Test
+    fun hasOngoingCall_ongoingCallNotifSentThenScreeningCallNotifSent_returnsFalse() {
+        notifCollectionListener.onEntryUpdated(createOngoingCallNotifEntry())
+        notifCollectionListener.onEntryUpdated(createScreeningCallNotifEntry())
+
+        assertThat(controller.hasOngoingCall()).isFalse()
+    }
+
+    @Test
+    fun hasOngoingCall_ongoingCallNotifSentThenUnrelatedNotifSent_returnsTrue() {
+        notifCollectionListener.onEntryUpdated(createOngoingCallNotifEntry())
+        notifCollectionListener.onEntryUpdated(createNotCallNotifEntry())
+
+        assertThat(controller.hasOngoingCall()).isTrue()
+    }
+
     /**
      * This test fakes a theme change during an ongoing call.
      *
@@ -281,9 +306,13 @@
     // Other tests for notifyChipVisibilityChanged are in [OngoingCallLogger], since
     // [OngoingCallController.notifyChipVisibilityChanged] just delegates to that class.
 
-    private fun createOngoingCallNotifEntry(): NotificationEntry {
+    private fun createOngoingCallNotifEntry() = createCallNotifEntry(ongoingCallStyle)
+
+    private fun createScreeningCallNotifEntry() = createCallNotifEntry(screeningCallStyle)
+
+    private fun createCallNotifEntry(callStyle: Notification.CallStyle): NotificationEntry {
         val notificationEntryBuilder = NotificationEntryBuilder()
-        notificationEntryBuilder.modifyNotification(context).style = ongoingCallStyle
+        notificationEntryBuilder.modifyNotification(context).style = callStyle
 
         val contentIntent = mock(PendingIntent::class.java)
         `when`(contentIntent.intent).thenReturn(mock(Intent::class.java))
@@ -295,6 +324,9 @@
     private fun createNotCallNotifEntry() = NotificationEntryBuilder().build()
 }
 
-private val ongoingCallStyle = Notification.CallStyle.forOngoingCall(
-        Person.Builder().setName("name").build(),
-        /* hangUpIntent= */ mock(PendingIntent::class.java))
+private val person = Person.Builder().setName("name").build()
+private val hangUpIntent = mock(PendingIntent::class.java)
+
+private val ongoingCallStyle = Notification.CallStyle.forOngoingCall(person, hangUpIntent)
+private val screeningCallStyle = Notification.CallStyle.forScreeningCall(
+        person, hangUpIntent, /* answerIntent= */ mock(PendingIntent::class.java))
\ No newline at end of file