Move showInShade off of NotificationEntry and into Bubble
There are minimal usages of showInShade outside of the bubbles package and
things that want to know stuff about bubbles should probs go through
bubbleController.
This CL:
* moves showInShade off of NotificationEntry and onto Bubble, updates
usages & tests
* adds method on BubbleController to check if a notif should be suppressed
from the shade
* removes the NotificationFilter code to filter out bubbles -- this turned
out to be unneeded -- NotificationViewHiearchyManager can query
BubbleController and do the right thing based on that (this also
works around the issue from b/135280077)
Test: atest SystemUITests
Bug: 135280077
Bug: 135214687
Change-Id: Id9261eae892f39059cbb3116fe05488fcf8ff0dc
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
index fad4e19..5a7673f 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
@@ -61,6 +61,14 @@
private long mLastAccessed;
private boolean mIsRemoved;
+ /**
+ * Whether this notification should be shown in the shade when it is also displayed as a bubble.
+ *
+ * <p>When a notification is a bubble we don't show it in the shade once the bubble has been
+ * expanded</p>
+ */
+ private boolean mShowInShadeWhenBubble = true;
+
public static String groupId(NotificationEntry entry) {
UserHandle user = entry.notification.getUser();
return user.getIdentifier() + "|" + entry.notification.getPackageName();
@@ -99,14 +107,6 @@
return mEntry;
}
- public boolean showInShadeWhenBubble() {
- return mEntry.showInShadeWhenBubble();
- }
-
- public void setShowInShadeWhenBubble(boolean showInShade) {
- mEntry.setShowInShadeWhenBubble(showInShade);
- }
-
public String getGroupId() {
return mGroupId;
}
@@ -129,11 +129,11 @@
}
}
- public BubbleView getIconView() {
+ BubbleView getIconView() {
return mIconView;
}
- public BubbleExpandedView getExpandedView() {
+ BubbleExpandedView getExpandedView() {
return mExpandedView;
}
@@ -182,7 +182,7 @@
return mIsRemoved;
}
- void setEntry(NotificationEntry entry) {
+ void updateEntry(NotificationEntry entry) {
mEntry = entry;
mLastUpdated = entry.notification.getPostTime();
if (mInflated) {
@@ -228,6 +228,23 @@
}
/**
+ * Whether this notification should be shown in the shade when it is also displayed as a
+ * bubble.
+ */
+ boolean showInShadeWhenBubble() {
+ return !mEntry.isRowDismissed() && !shouldSuppressNotification()
+ && (!mEntry.isClearable() || mShowInShadeWhenBubble);
+ }
+
+ /**
+ * Sets whether this notification should be shown in the shade when it is also displayed as a
+ * bubble.
+ */
+ void setShowInShadeWhenBubble(boolean showInShade) {
+ mShowInShadeWhenBubble = showInShade;
+ }
+
+ /**
* Returns whether the notification for this bubble is a foreground service. It shows that this
* is an ongoing bubble.
*/
@@ -355,6 +372,11 @@
return 0;
}
+ private boolean shouldSuppressNotification() {
+ return mEntry.getBubbleMetadata() != null
+ && mEntry.getBubbleMetadata().isNotificationSuppressed();
+ }
+
@Override
public String toString() {
return "Bubble{" + mKey + '}';
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index 5bf8b59..6471c71 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -80,7 +80,6 @@
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.row.NotificationContentInflater.InflationFlag;
import com.android.systemui.statusbar.phone.StatusBarWindowController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ZenModeController;
@@ -345,6 +344,17 @@
mBubbleData.setExpanded(false /* expanded */);
}
+ /**
+ * Whether (1) there is a bubble associated with the provided key and
+ * (2) if the notification for that bubble is hidden from the shade.
+ *
+ * False if there isn't a bubble or if the notification for that bubble appears in the shade.
+ */
+ public boolean isBubbleNotificationSuppressedFromShade(String key) {
+ return mBubbleData.hasBubbleWithKey(key)
+ && !mBubbleData.getBubbleWithKey(key).showInShadeWhenBubble();
+ }
+
void selectBubble(Bubble bubble) {
mBubbleData.setSelectedBubble(bubble);
}
@@ -438,7 +448,7 @@
boolean bubbleExtended = entry.isBubble() && !bubble.isRemoved()
&& userRemovedNotif;
if (bubbleExtended) {
- entry.setShowInShadeWhenBubble(false);
+ bubble.setShowInShadeWhenBubble(false);
if (mStackView != null) {
mStackView.updateDotVisibility(entry.key);
}
@@ -462,17 +472,6 @@
}
if (mNotificationInterruptionStateProvider.shouldBubbleUp(entry)
&& canLaunchInActivityView(mContext, entry)) {
- updateShowInShadeForSuppressNotification(entry);
- }
- }
-
- @Override
- public void onEntryInflated(NotificationEntry entry, @InflationFlag int inflatedFlags) {
- if (!areBubblesEnabled(mContext)) {
- return;
- }
- if (mNotificationInterruptionStateProvider.shouldBubbleUp(entry)
- && canLaunchInActivityView(mContext, entry)) {
updateBubble(entry);
}
}
@@ -488,7 +487,6 @@
// It was previously a bubble but no longer a bubble -- lets remove it
removeBubble(entry.key, DISMISS_NO_LONGER_BUBBLE);
} else if (shouldBubble) {
- updateShowInShadeForSuppressNotification(entry);
Bubble b = mBubbleData.getBubbleWithKey(entry.key);
b.setRemoved(false); // updates come back as bubbles even if dismissed
updateBubble(entry);
@@ -683,17 +681,6 @@
return mStackView;
}
- private void updateShowInShadeForSuppressNotification(NotificationEntry entry) {
- boolean suppressNotification = entry.getBubbleMetadata() != null
- && entry.getBubbleMetadata().isNotificationSuppressed();
- Bubble b = mBubbleData.getBubbleWithKey(entry.key);
- if (b != null && mBubbleData.getSelectedBubble() == b && mBubbleData.isExpanded()) {
- // If we're expanded & selected don't show in shade
- suppressNotification = true;
- }
- entry.setShowInShadeWhenBubble(!suppressNotification);
- }
-
static String formatBubblesString(List<Bubble> bubbles, Bubble selected) {
StringBuilder sb = new StringBuilder();
for (Bubble bubble : bubbles) {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
index fc7dae7..7b87ac8 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
@@ -176,7 +176,7 @@
trim();
} else {
// Updates an existing bubble
- bubble.setEntry(entry);
+ bubble.updateEntry(entry);
doUpdate(bubble);
}
if (shouldAutoExpand(entry)) {
@@ -187,6 +187,7 @@
} else if (mSelectedBubble == null) {
setSelectedBubbleInternal(bubble);
}
+ bubble.setShowInShadeWhenBubble(!mExpanded || mSelectedBubble != bubble);
dispatchPendingChanges();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index 0b3c6a5..f304c94 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -25,7 +25,7 @@
import android.view.ViewGroup;
import com.android.systemui.R;
-import com.android.systemui.bubbles.BubbleData;
+import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -79,7 +79,7 @@
* possible.
*/
private final boolean mAlwaysExpandNonGroupedNotification;
- private final BubbleData mBubbleData;
+ private final BubbleController mBubbleController;
private final DynamicPrivacyController mDynamicPrivacyController;
private final KeyguardBypassController mBypassController;
@@ -97,8 +97,8 @@
StatusBarStateController statusBarStateController,
NotificationEntryManager notificationEntryManager,
Lazy<ShadeController> shadeController,
- BubbleData bubbleData,
KeyguardBypassController bypassController,
+ BubbleController bubbleController,
DynamicPrivacyController privacyController) {
mLockscreenUserManager = notificationLockscreenUserManager;
mBypassController = bypassController;
@@ -110,7 +110,7 @@
Resources res = context.getResources();
mAlwaysExpandNonGroupedNotification =
res.getBoolean(R.bool.config_alwaysExpandNonGroupedNotifications);
- mBubbleData = bubbleData;
+ mBubbleController = bubbleController;
mDynamicPrivacyController = privacyController;
privacyController.addListener(this);
}
@@ -136,7 +136,7 @@
for (int i = 0; i < N; i++) {
NotificationEntry ent = activeNotifications.get(i);
if (ent.isRowDismissed() || ent.isRowRemoved()
- || (mBubbleData.hasBubbleWithKey(ent.key) && !ent.showInShadeWhenBubble())) {
+ || mBubbleController.isBubbleNotificationSuppressedFromShade(ent.key)) {
// we don't want to update removed notifications because they could
// temporarily become children if they were isolated before.
continue;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationFilter.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationFilter.java
index 154d7b35..f99662e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationFilter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationFilter.java
@@ -133,11 +133,6 @@
}
}
}
-
- if (entry.isBubble() && !entry.showInShadeWhenBubble()) {
- return true;
- }
-
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index 6aab59f..4c22ccc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -154,14 +154,6 @@
public boolean canBubble;
/**
- * Whether this notification should be shown in the shade when it is also displayed as a bubble.
- *
- * <p>When a notification is a bubble we don't show it in the shade once the bubble has been
- * expanded</p>
- */
- private boolean mShowInShadeWhenBubble = true;
-
- /**
* Whether this notification is shown to the user as a high priority notification: visible on
* the lock screen/status bar and in the top section in the shade.
*/
@@ -219,23 +211,6 @@
}
/**
- * Sets whether this notification should be shown in the shade when it is also displayed as a
- * bubble.
- */
- public void setShowInShadeWhenBubble(boolean showInShade) {
- mShowInShadeWhenBubble = showInShade;
- }
-
- /**
- * Whether this notification should be shown in the shade when it is also displayed as a
- * bubble.
- */
- public boolean showInShadeWhenBubble() {
- // We always show it in the shade if non-clearable
- return !isRowDismissed() && (!isClearable() || mShowInShadeWhenBubble);
- }
-
- /**
* Returns the data needed for a bubble for this notification, if it exists.
*/
public Notification.BubbleMetadata getBubbleMetadata() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
index 6044f83..944b5cd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
@@ -217,10 +217,10 @@
mBubbleController.updateBubble(mRow.getEntry());
assertTrue(mBubbleController.hasBubbles());
- assertTrue(mRow.getEntry().showInShadeWhenBubble());
+ assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
// Make it look like dismissed notif
- mRow.getEntry().setShowInShadeWhenBubble(false);
+ mBubbleData.getBubbleWithKey(mRow.getEntry().key).setShowInShadeWhenBubble(false);
// Now remove the bubble
mBubbleController.removeBubble(mRow.getEntry().key, BubbleController.DISMISS_USER_GESTURE);
@@ -257,9 +257,9 @@
mEntryListener.onPendingEntryAdded(mRow.getEntry());
mBubbleController.updateBubble(mRow.getEntry());
- // We should have bubbles & their notifs should show in the shade
+ // We should have bubbles & their notifs should not be suppressed
assertTrue(mBubbleController.hasBubbles());
- assertTrue(mRow.getEntry().showInShadeWhenBubble());
+ assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
assertFalse(mStatusBarWindowController.getBubbleExpanded());
// Expand the stack
@@ -269,8 +269,8 @@
verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().key);
assertTrue(mStatusBarWindowController.getBubbleExpanded());
- // Make sure it's no longer in the shade
- assertFalse(mRow.getEntry().showInShadeWhenBubble());
+ // Make sure the notif is suppressed
+ assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
// Collapse
mBubbleController.collapseStack();
@@ -287,10 +287,11 @@
mBubbleController.updateBubble(mRow.getEntry());
mBubbleController.updateBubble(mRow2.getEntry());
- // We should have bubbles & their notifs should show in the shade
+ // We should have bubbles & their notifs should not be suppressed
assertTrue(mBubbleController.hasBubbles());
- assertTrue(mRow.getEntry().showInShadeWhenBubble());
- assertTrue(mRow2.getEntry().showInShadeWhenBubble());
+ assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
+ assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
+ mRow2.getEntry().key));
// Expand
BubbleStackView stackView = mBubbleController.getStackView();
@@ -300,13 +301,13 @@
// Last added is the one that is expanded
assertEquals(mRow2.getEntry(), stackView.getExpandedBubbleView().getEntry());
- assertFalse(mRow2.getEntry().showInShadeWhenBubble());
+ assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow2.getEntry().key));
// Switch which bubble is expanded
mBubbleController.selectBubble(mRow.getEntry().key);
stackView.setExpandedBubble(mRow.getEntry().key);
assertEquals(mRow.getEntry(), stackView.getExpandedBubbleView().getEntry());
- assertFalse(mRow.getEntry().showInShadeWhenBubble());
+ assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
// collapse for previous bubble
verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow2.getEntry().key);
@@ -324,9 +325,9 @@
mEntryListener.onPendingEntryAdded(mRow.getEntry());
mBubbleController.updateBubble(mRow.getEntry());
- // We should have bubbles & their notifs should show in the shade
+ // We should have bubbles & their notifs should not be suppressed
assertTrue(mBubbleController.hasBubbles());
- assertTrue(mRow.getEntry().showInShadeWhenBubble());
+ assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
// Expand
BubbleStackView stackView = mBubbleController.getStackView();
@@ -334,8 +335,8 @@
assertTrue(mBubbleController.isStackExpanded());
verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().key);
- // No longer show shade in notif after expansion
- assertFalse(mRow.getEntry().showInShadeWhenBubble());
+ // Notif is suppressed after expansion
+ assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
}
@Test
@@ -356,7 +357,7 @@
// Last added is the one that is expanded
assertEquals(mRow2.getEntry(), stackView.getExpandedBubbleView().getEntry());
- assertFalse(mRow2.getEntry().showInShadeWhenBubble());
+ assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow2.getEntry().key));
// Dismiss currently expanded
mBubbleController.removeBubble(stackView.getExpandedBubbleView().getKey(),
@@ -423,9 +424,8 @@
mEntryListener.onPendingEntryAdded(mRow.getEntry());
mBubbleController.updateBubble(mRow.getEntry());
- // Should show in shade because we weren't forground
- assertTrue(mRow.getEntry().showInShadeWhenBubble());
-
+ // Should not be suppressed because we weren't forground
+ assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
// # of bubbles should change
verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
}
@@ -439,8 +439,8 @@
mEntryListener.onPendingEntryAdded(mRow.getEntry());
mBubbleController.updateBubble(mRow.getEntry());
- // Should NOT show in shade because we were foreground
- assertFalse(mRow.getEntry().showInShadeWhenBubble());
+ // Notif should be suppressed because we were foreground
+ assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
// # of bubbles should change
verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
@@ -462,7 +462,7 @@
@Test
public void testMarkNewNotificationAsShowInShade() {
mEntryListener.onPendingEntryAdded(mRow.getEntry());
- assertTrue(mRow.getEntry().showInShadeWhenBubble());
+ assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
}
@Test
@@ -530,7 +530,7 @@
mBubbleController.updateBubble(mRow.getEntry());
assertTrue(mBubbleController.hasBubbles());
- assertTrue(mRow.getEntry().showInShadeWhenBubble());
+ assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
mRow.getEntry().key, REASON_CANCEL_ALL);
@@ -538,7 +538,7 @@
// Intercept!
assertTrue(intercepted);
// Should update show in shade state
- assertFalse(mRow.getEntry().showInShadeWhenBubble());
+ assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
verify(mNotificationEntryManager, never()).performRemoveNotification(
any(), anyInt());
@@ -551,7 +551,7 @@
mBubbleController.updateBubble(mRow.getEntry());
assertTrue(mBubbleController.hasBubbles());
- assertTrue(mRow.getEntry().showInShadeWhenBubble());
+ assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
mRow.getEntry().key, REASON_CANCEL);
@@ -559,7 +559,7 @@
// Intercept!
assertTrue(intercepted);
// Should update show in shade state
- assertFalse(mRow.getEntry().showInShadeWhenBubble());
+ assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
verify(mNotificationEntryManager, never()).performRemoveNotification(
any(), anyInt());
@@ -572,7 +572,7 @@
mBubbleController.updateBubble(mRow.getEntry());
assertTrue(mBubbleController.hasBubbles());
- assertTrue(mRow.getEntry().showInShadeWhenBubble());
+ assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry().key));
// Dismiss the bubble
mBubbleController.removeBubble(mRow.getEntry().key, BubbleController.DISMISS_USER_GESTURE);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
index 010b85e..5253823 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
@@ -37,7 +37,7 @@
import com.android.systemui.Dependency;
import com.android.systemui.InitController;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.bubbles.BubbleData;
+import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -100,8 +100,9 @@
mViewHierarchyManager = new NotificationViewHierarchyManager(mContext,
mLockscreenUserManager, mGroupManager, mVisualStabilityManager,
mock(StatusBarStateControllerImpl.class), mEntryManager,
- () -> mShadeController, new BubbleData(mContext),
+ () -> mShadeController,
mock(KeyguardBypassController.class),
+ mock(BubbleController.class),
mock(DynamicPrivacyController.class));
Dependency.get(InitController.class).executePostInitTasks();
mViewHierarchyManager.setUpWithPresenter(mPresenter, mListContainer);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
index 06d76eb..5a6f27d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
@@ -153,8 +153,6 @@
StatusBarNotification bubbleSbn = mBubbleNotificationRow.getStatusBarNotification();
bubbleSbn.getNotification().contentIntent = mContentIntent;
bubbleSbn.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
- // Do what BubbleController's NotificationEntryListener#onPendingEntryAdded does:
- mBubbleNotificationRow.getEntry().setShowInShadeWhenBubble(true);
mActiveNotifications = new ArrayList<>();
mActiveNotifications.add(mNotificationRow.getEntry());