Fix "Mark as Read" bug.

When a notification has had its lifetime extended by the NotificationRemoteInputManager$RemoteInputHistoryExtender, we will now terminate that lifetime extension 200ms after any other action has successfully started a PendingIntent. This gives apps 200ms to update the notification without the user seeing anything, and should otherwise prevent the 'dead notification' problem.

Bug: 183025105
Test: Use inline notification reply or smart replies for an app which cancels the notification on reply.  Then tap "mark as read" or "done" on the notification. Notice that the notification now disappears.
Change-Id: I627aaaacf4caee98cc6e282da8f2d0f2bd42bffb
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index 0e56ab7..70b3a7b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -15,8 +15,6 @@
  */
 package com.android.systemui.statusbar;
 
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
-
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
@@ -170,7 +168,9 @@
                     action == null ? false : action.isAuthenticationRequired(), () -> {
                     Pair<Intent, ActivityOptions> options = response.getLaunchOptions(view);
                     mLogger.logStartingIntentWithDefaultHandler(entry, pendingIntent);
-                    return RemoteViews.startPendingIntent(view, pendingIntent, options);
+                    boolean started = RemoteViews.startPendingIntent(view, pendingIntent, options);
+                    if (started) releaseNotificationIfKeptForRemoteInputHistory(entry.getKey());
+                    return started;
             });
         }
 
@@ -602,6 +602,22 @@
                 || entry.hasJustSentRemoteInput());
     }
 
+    /**
+     * Checks if the notification is being kept due to the user sending an inline reply, and if
+     * so, releases that hold.  This is called anytime an action on the notification is dispatched
+     * (after unlock, if applicable), and will then wait a short time to allow the app to update the
+     * notification in response to the action.
+     */
+    private void releaseNotificationIfKeptForRemoteInputHistory(String key) {
+        if (isNotificationKeptForRemoteInputHistory(key)) {
+            mMainHandler.postDelayed(() -> {
+                if (isNotificationKeptForRemoteInputHistory(key)) {
+                    mNotificationLifetimeFinishedCallback.onSafeToRemove(key);
+                }
+            }, REMOTE_INPUT_KEPT_ENTRY_AUTO_CANCEL_DELAY);
+        }
+    }
+
     public boolean shouldKeepForSmartReplyHistory(NotificationEntry entry) {
         if (!FORCE_REMOTE_INPUT_HISTORY) {
             return false;