From 55ddc123e6c2f077194315f90f360d4aabd17252 Mon Sep 17 00:00:00 2001 From: Mady Mellor Date: Wed, 10 Jun 2020 22:04:23 -0700 Subject: [PATCH] Prevent NPE when dragging last bubble from expanded state - We null out stackview when it's removed from the window, this happens when the last bubble is removed from the view - When the last bubble is dragged out, we trigger some other updates these get applied *after* the remove step so stackview is null at that time. These updates are to set selected bubble to null & collapse the stack. These don't technically need to tell stackView about them. - I don't think this is an ideal solution Test: drag out last bubble while stack is expanded Fixes: 157778325 Change-Id: Ia55bf3ba315599ed8afb390ad481e0d3700b1b97 --- .../systemui/bubbles/BubbleController.java | 19 +++++++++++-------- .../android/systemui/bubbles/BubbleData.java | 3 ++- .../systemui/bubbles/BubbleStackView.java | 5 +++-- .../systemui/bubbles/BubbleDataTest.java | 2 +- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index 35cac4d9d63d5..2ea50c403ad6c 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -705,6 +705,9 @@ public class BubbleController implements ConfigurationController.ConfigurationLi * the new params if the stack has been added. */ private void updateWmFlags() { + if (mStackView == null) { + return; + } if (isStackExpanded() && !mImeVisible) { // If we're expanded, and the IME isn't visible, we want to be focusable. This ensures // that any taps within Bubbles (including on the ActivityView) results in Bubbles @@ -716,7 +719,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi mWmLayoutParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; } - if (mStackView != null && mAddedToWindowManager) { + if (mAddedToWindowManager) { try { mWindowManager.updateViewLayout(mStackView, mWmLayoutParams); } catch (IllegalArgumentException e) { @@ -1235,24 +1238,23 @@ public class BubbleController implements ConfigurationController.ConfigurationLi } mDataRepository.removeBubbles(mCurrentUserId, bubblesToBeRemovedFromRepository); - if (update.addedBubble != null) { + if (update.addedBubble != null && mStackView != null) { mDataRepository.addBubble(mCurrentUserId, update.addedBubble); mStackView.addBubble(update.addedBubble); - } - if (update.updatedBubble != null) { + if (update.updatedBubble != null && mStackView != null) { mStackView.updateBubble(update.updatedBubble); } // At this point, the correct bubbles are inflated in the stack. // Make sure the order in bubble data is reflected in bubble row. - if (update.orderChanged) { + if (update.orderChanged && mStackView != null) { mDataRepository.addBubbles(mCurrentUserId, update.bubbles); mStackView.updateBubbleOrder(update.bubbles); } - if (update.selectionChanged) { + if (update.selectionChanged && mStackView != null) { mStackView.setSelectedBubble(update.selectedBubble); if (update.selectedBubble != null && update.selectedBubble.getEntry() != null) { mNotificationGroupManager.updateSuppression( @@ -1262,7 +1264,9 @@ public class BubbleController implements ConfigurationController.ConfigurationLi // Expanding? Apply this last. if (update.expandedChanged && update.expanded) { - mStackView.setExpanded(true); + if (mStackView != null) { + mStackView.setExpanded(true); + } } for (NotifCallback cb : mCallbacks) { @@ -1368,7 +1372,6 @@ public class BubbleController implements ConfigurationController.ConfigurationLi } /** - * Lets any listeners know if bubble state has changed. * Updates the visibility of the bubbles based on current state. * Does not un-bubble, just hides or un-hides. * Updates stack description for TalkBack focus. diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java index 24d44d5cb291c..20a9a8cf324c4 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java @@ -417,7 +417,8 @@ public class BubbleData { if (mBubbles.size() == 1) { // Going to become empty, handle specially. setExpandedInternal(false); - setSelectedBubbleInternal(null); + // Don't use setSelectedBubbleInternal because we don't want to trigger an applyUpdate + mSelectedBubble = null; } if (indexToRemove < mBubbles.size() - 1) { // Removing anything but the last bubble means positions will change. diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java index 84f3ba5df917b..7bc688a3e568e 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java @@ -93,7 +93,6 @@ import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.SysUiStatsLog; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment; -import com.android.systemui.statusbar.phone.NotificationShadeWindowController; import com.android.systemui.util.DismissCircleView; import com.android.systemui.util.FloatingContentCoordinator; import com.android.systemui.util.RelativeTouchListener; @@ -1504,7 +1503,9 @@ public class BubbleStackView extends FrameLayout // expanded view becomes visible on the screen. See b/126856255 mExpandedViewContainer.setAlpha(0.0f); mSurfaceSynchronizer.syncSurfaceAndRun(() -> { - previouslySelected.setContentVisibility(false); + if (previouslySelected != null) { + previouslySelected.setContentVisibility(false); + } updateExpandedBubble(); requestUpdate(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java index 17022da3ecde0..1ca2f02db1bd3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java @@ -537,7 +537,7 @@ public class BubbleDataTest extends SysuiTestCase { // Verify the selection was cleared. verifyUpdateReceived(); assertThat(mBubbleData.isExpanded()).isFalse(); - assertSelectionCleared(); + assertThat(mBubbleData.getSelectedBubble()).isNull(); } // EXPANDED / ADD / UPDATE