Hiding the icon of notifications that were replied to

Because those notifications now stay around but the user
has already seen them, were hiding the icon instead.

Change-Id: I6b8590e31295ed79218698b1ac54df33b273d38c
Fixes: 78486801
Test: add notification, reply, observe icon gone
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 419e262..e24d65a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -32,10 +32,13 @@
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
+import android.app.Person;
 import android.content.Context;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.graphics.drawable.Icon;
+import android.os.Bundle;
+import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.service.notification.NotificationListenerService.Ranking;
@@ -50,6 +53,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.statusbar.StatusBarIcon;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.NotificationColorUtil;
 import com.android.systemui.Dependency;
 import com.android.systemui.ForegroundServiceController;
@@ -117,6 +121,11 @@
          */
         public Boolean mIsSystemNotification;
 
+        /**
+         * Has the user sent a reply through this Notification.
+         */
+        private boolean hasSentReply;
+
         public Entry(StatusBarNotification n) {
             this.key = n.getKey();
             this.notification = n;
@@ -298,6 +307,40 @@
             lastRemoteInputSent = NOT_LAUNCHED_YET;
             remoteInputTextWhenReset = null;
         }
+
+        public void setHasSentReply() {
+            hasSentReply = true;
+        }
+
+        public boolean isLastMessageFromReply() {
+            if (!hasSentReply) {
+                return false;
+            }
+            Bundle extras = notification.getNotification().extras;
+            CharSequence[] replyTexts = extras.getCharSequenceArray(
+                    Notification.EXTRA_REMOTE_INPUT_HISTORY);
+            if (!ArrayUtils.isEmpty(replyTexts)) {
+                return true;
+            }
+            Parcelable[] messages = extras.getParcelableArray(Notification.EXTRA_MESSAGES);
+            if (messages != null && messages.length > 0) {
+                Parcelable message = messages[messages.length - 1];
+                if (message instanceof Bundle) {
+                    Notification.MessagingStyle.Message lastMessage =
+                            Notification.MessagingStyle.Message.getMessageFromBundle(
+                                    (Bundle) message);
+                    if (lastMessage != null) {
+                        Person senderPerson = lastMessage.getSenderPerson();
+                        if (senderPerson == null) {
+                            return true;
+                        }
+                        Person user = extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON);
+                        return Objects.equals(user, senderPerson);
+                    }
+                }
+            }
+            return false;
+        }
     }
 
     private final ArrayMap<String, Entry> mEntries = new ArrayMap<>();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index b043100..44d666e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -141,7 +141,7 @@
     }
 
     protected boolean shouldShowNotificationIcon(NotificationData.Entry entry,
-            boolean showAmbient, boolean hideDismissed) {
+            boolean showAmbient, boolean hideDismissed, boolean hideRepliedMessages) {
         if (mEntryManager.getNotificationData().isAmbient(entry.key) && !showAmbient) {
             return false;
         }
@@ -155,6 +155,10 @@
             return false;
         }
 
+        if (hideRepliedMessages && entry.isLastMessageFromReply()) {
+            return false;
+        }
+
         // showAmbient == show in shade but not shelf
         if (!showAmbient && mEntryManager.getNotificationData().shouldSuppressStatusBar(entry)) {
             return false;
@@ -170,14 +174,15 @@
 
         updateStatusBarIcons();
         updateIconsForLayout(entry -> entry.expandedIcon, mShelfIcons,
-                NotificationShelf.SHOW_AMBIENT_ICONS, false /* hideDismissed */);
+                NotificationShelf.SHOW_AMBIENT_ICONS, false /* hideDismissed */,
+                false /* hideRepliedMessages */);
 
         applyNotificationIconsTint();
     }
 
-    private void updateStatusBarIcons() {
+    public void updateStatusBarIcons() {
         updateIconsForLayout(entry -> entry.icon, mNotificationIcons,
-                false /* showAmbient */, true /* hideDismissed */);
+                false /* showAmbient */, true /* hideDismissed */, true /* hideRepliedMessages */);
     }
 
     /**
@@ -187,9 +192,11 @@
      * @param hostLayout which layout should be updated
      * @param showAmbient should ambient notification icons be shown
      * @param hideDismissed should dismissed icons be hidden
+     * @param hideRepliedMessages should messages that have been replied to be hidden
      */
     private void updateIconsForLayout(Function<NotificationData.Entry, StatusBarIconView> function,
-            NotificationIconContainer hostLayout, boolean showAmbient, boolean hideDismissed) {
+            NotificationIconContainer hostLayout, boolean showAmbient, boolean hideDismissed,
+            boolean hideRepliedMessages) {
         ArrayList<StatusBarIconView> toShow = new ArrayList<>(
                 mNotificationScrollLayout.getChildCount());
 
@@ -198,7 +205,8 @@
             View view = mNotificationScrollLayout.getChildAt(i);
             if (view instanceof ExpandableNotificationRow) {
                 NotificationData.Entry ent = ((ExpandableNotificationRow) view).getEntry();
-                if (shouldShowNotificationIcon(ent, showAmbient, hideDismissed)) {
+                if (shouldShowNotificationIcon(ent, showAmbient, hideDismissed,
+                        hideRepliedMessages)) {
                     toShow.add(function.apply(ent));
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index 310f14c..da451d1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -151,6 +151,7 @@
         mController.removeRemoteInput(mEntry, mToken);
         mEditText.mShowImeOnInputConnection = false;
         mController.remoteInputSent(mEntry);
+        mEntry.setHasSentReply();
 
         // Tell ShortcutManager that this package has been "activated".  ShortcutManager
         // will reset the throttling for this package.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
index cc802a8..7ef4dc3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
@@ -212,6 +212,7 @@
             Intent intent = new Intent().addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
             RemoteInput.addResultsToIntent(new RemoteInput[]{remoteInput}, intent, results);
             RemoteInput.setResultsSource(intent, RemoteInput.SOURCE_CHOICE);
+            entry.setHasSentReply();
             try {
                 pendingIntent.send(context, 0, intent);
             } catch (PendingIntent.CanceledException e) {