From ca184aaecd7950dbb010e54bb33e460927673e00 Mon Sep 17 00:00:00 2001 From: Mady Mellor Date: Tue, 17 Sep 2019 16:07:12 -0700 Subject: [PATCH] Notify display is empty even if it's not the expanded bubble onSingleTaskDisplayEmpty occurs when the activity is removed from the activity view (e.g. app crash). When a bubble'd app crashes we want to collapse the bubble (if expanded) & notify that it's empty so that next time it's opened it will try to populate the activity again. We were only doing this if the crashed app was the currently expanded bubble, but that's not always the case. This CL adds a method in BubbleData to clean up the display for a given displayId & calls that in the non-expanded case. Also adds some null pointer checks. Test: manual - modify bubbles test app to have a crash when you click a button - post some bubbles - expand / collapse a bubble - crash the bubbles test app => see crash dialog - expand bubble => bubble should be populated Bug: 138461119 Change-Id: I2fb226766676226980c67dc0536ed37eb43cedf1 --- .../systemui/bubbles/BubbleController.java | 14 ++++++-------- .../com/android/systemui/bubbles/BubbleData.java | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index fb2f177b76bb4..3cc91de434385 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -560,7 +560,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi // Need to check for !appCancel here because the notification may have // previously been dismissed & entry.isRowDismissed would still be true - boolean userRemovedNotif = (entry.isRowDismissed() && !isAppCancel) + boolean userRemovedNotif = (entry != null && entry.isRowDismissed() && !isAppCancel) || isClearAll || isUserDimiss || isSummaryCancel; if (isSummaryOfBubbles) { @@ -570,7 +570,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi // The bubble notification sticks around in the data as long as the bubble is // not dismissed and the app hasn't cancelled the notification. Bubble bubble = mBubbleData.getBubbleWithKey(key); - boolean bubbleExtended = entry.isBubble() && userRemovedNotif; + boolean bubbleExtended = entry != null && entry.isBubble() && userRemovedNotif; if (bubbleExtended) { bubble.setShowInShadeWhenBubble(false); bubble.setShowBubbleDot(false); @@ -579,7 +579,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi } mNotificationEntryManager.updateNotifications(); return true; - } else if (!userRemovedNotif) { + } else if (!userRemovedNotif && entry != null) { // This wasn't a user removal so we should remove the bubble as well mBubbleData.notificationEntryRemoved(entry, DISMISS_NOTIF_CANCEL); return false; @@ -939,13 +939,11 @@ public class BubbleController implements ConfigurationController.ConfigurationLi final Bubble expandedBubble = mStackView != null ? mStackView.getExpandedBubble() : null; - if (expandedBubble == null) { - return; - } - if (expandedBubble.getDisplayId() == displayId) { + int expandedId = expandedBubble != null ? expandedBubble.getDisplayId() : -1; + if (mStackView != null && mStackView.isExpanded() && expandedId == displayId) { mBubbleData.setExpanded(false); - expandedBubble.getExpandedView().notifyDisplayEmpty(); } + mBubbleData.notifyDisplayEmpty(displayId); } } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java index 81c8da8247eca..eb826e54d340f 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java @@ -392,6 +392,22 @@ public class BubbleData { dispatchPendingChanges(); } + /** + * Indicates that the provided display is no longer in use and should be cleaned up. + * + * @param displayId the id of the display to clean up. + */ + void notifyDisplayEmpty(int displayId) { + for (Bubble b : mBubbles) { + if (b.getDisplayId() == displayId) { + if (b.getExpandedView() != null) { + b.getExpandedView().notifyDisplayEmpty(); + } + return; + } + } + } + private void dispatchPendingChanges() { if (mListener != null && mStateChange.anythingChanged()) { mListener.applyUpdate(mStateChange);