From cf5499bd7d4ccd6c154516c8f31cfacf628a6006 Mon Sep 17 00:00:00 2001 From: Jeff DeCew Date: Fri, 30 Apr 2021 15:26:08 -0400 Subject: [PATCH] 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 --- .../NotificationRemoteInputManager.java | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java index 0e56ab73397ba..70b3a7be02fb4 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 @@ public class NotificationRemoteInputManager implements Dumpable { action == null ? false : action.isAuthenticationRequired(), () -> { Pair 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 @@ public class NotificationRemoteInputManager implements Dumpable { || 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;