Merge "Handle non-visually-interruptive updates better in bubbles" into rvc-qpr-dev

This commit is contained in:
TreeHugger Robot
2020-09-24 19:06:52 +00:00
committed by Android (Google) Code Review
5 changed files with 76 additions and 7 deletions

View File

@@ -285,6 +285,15 @@ class Bubble implements BubbleViewProvider {
mInflateSynchronously = inflateSynchronously; mInflateSynchronously = inflateSynchronously;
} }
/**
* Sets whether this bubble is considered visually interruptive. Normally pulled from the
* {@link NotificationEntry}, this method is purely for testing.
*/
@VisibleForTesting
void setVisuallyInterruptiveForTest(boolean visuallyInterruptive) {
mIsVisuallyInterruptive = visuallyInterruptive;
}
/** /**
* Starts a task to inflate & load any necessary information to display a bubble. * Starts a task to inflate & load any necessary information to display a bubble.
* *
@@ -411,6 +420,7 @@ class Bubble implements BubbleViewProvider {
} else if (mIntent != null && entry.getBubbleMetadata().getIntent() == null) { } else if (mIntent != null && entry.getBubbleMetadata().getIntent() == null) {
// Was an intent bubble now it's a shortcut bubble... still unregister the listener // Was an intent bubble now it's a shortcut bubble... still unregister the listener
mIntent.unregisterCancelListener(mIntentCancelListener); mIntent.unregisterCancelListener(mIntentCancelListener);
mIntentActive = false;
mIntent = null; mIntent = null;
} }
mDeleteIntent = entry.getBubbleMetadata().getDeleteIntent(); mDeleteIntent = entry.getBubbleMetadata().getDeleteIntent();

View File

@@ -82,7 +82,6 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility; import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.Dumpable; import com.android.systemui.Dumpable;
import com.android.systemui.bubbles.animation.StackAnimationController;
import com.android.systemui.bubbles.dagger.BubbleModule; import com.android.systemui.bubbles.dagger.BubbleModule;
import com.android.systemui.dump.DumpManager; import com.android.systemui.dump.DumpManager;
import com.android.systemui.model.SysUiState; import com.android.systemui.model.SysUiState;
@@ -407,7 +406,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
if (bubble.getBubbleIntent() == null) { if (bubble.getBubbleIntent() == null) {
return; return;
} }
if (bubble.isIntentActive()) { if (bubble.isIntentActive()
|| mBubbleData.hasBubbleInStackWithKey(bubble.getKey())) {
bubble.setPendingIntentCanceled(); bubble.setPendingIntentCanceled();
return; return;
} }
@@ -1120,9 +1120,18 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
if (notif.getImportance() >= NotificationManager.IMPORTANCE_HIGH) { if (notif.getImportance() >= NotificationManager.IMPORTANCE_HIGH) {
notif.setInterruption(); notif.setInterruption();
} }
if (!notif.getRanking().visuallyInterruptive()
&& (notif.getBubbleMetadata() != null
&& !notif.getBubbleMetadata().getAutoExpandBubble())
&& mBubbleData.hasOverflowBubbleWithKey(notif.getKey())) {
// Update the bubble but don't promote it out of overflow
Bubble b = mBubbleData.getOverflowBubbleWithKey(notif.getKey());
b.setEntry(notif);
} else {
Bubble bubble = mBubbleData.getOrCreateBubble(notif, null /* persistedBubble */); Bubble bubble = mBubbleData.getOrCreateBubble(notif, null /* persistedBubble */);
inflateAndAdd(bubble, suppressFlyout, showInShade); inflateAndAdd(bubble, suppressFlyout, showInShade);
} }
}
void inflateAndAdd(Bubble bubble, boolean suppressFlyout, boolean showInShade) { void inflateAndAdd(Bubble bubble, boolean suppressFlyout, boolean showInShade) {
// Lazy init stack view when a bubble is created // Lazy init stack view when a bubble is created

View File

@@ -277,7 +277,8 @@ public class BubbleData {
} else { } else {
// Updates an existing bubble // Updates an existing bubble
bubble.setSuppressFlyout(suppressFlyout); bubble.setSuppressFlyout(suppressFlyout);
doUpdate(bubble); // If there is no flyout, we probably shouldn't show the bubble at the top
doUpdate(bubble, !suppressFlyout /* reorder */);
} }
if (bubble.shouldAutoExpand()) { if (bubble.shouldAutoExpand()) {
@@ -431,12 +432,12 @@ public class BubbleData {
} }
} }
private void doUpdate(Bubble bubble) { private void doUpdate(Bubble bubble, boolean reorder) {
if (DEBUG_BUBBLE_DATA) { if (DEBUG_BUBBLE_DATA) {
Log.d(TAG, "doUpdate: " + bubble); Log.d(TAG, "doUpdate: " + bubble);
} }
mStateChange.updatedBubble = bubble; mStateChange.updatedBubble = bubble;
if (!isExpanded()) { if (!isExpanded() && reorder) {
int prevPos = mBubbles.indexOf(bubble); int prevPos = mBubbles.indexOf(bubble);
mBubbles.remove(bubble); mBubbles.remove(bubble);
mBubbles.add(0, bubble); mBubbles.add(0, bubble);

View File

@@ -999,6 +999,29 @@ public class BubbleControllerTest extends SysuiTestCase {
verify(mNotificationGroupManager, times(1)).onEntryRemoved(groupSummary.getEntry()); verify(mNotificationGroupManager, times(1)).onEntryRemoved(groupSummary.getEntry());
} }
/**
* Verifies that when a non visually interruptive update occurs for a bubble in the overflow,
* the that bubble does not get promoted from the overflow.
*/
@Test
public void test_notVisuallyInterruptive_updateOverflowBubble_notAdded() {
// Setup
mBubbleController.updateBubble(mRow.getEntry());
mBubbleController.updateBubble(mRow2.getEntry());
assertTrue(mBubbleController.hasBubbles());
// Overflow it
mBubbleData.dismissBubbleWithKey(mRow.getEntry().getKey(),
BubbleController.DISMISS_USER_GESTURE);
assertThat(mBubbleData.hasBubbleInStackWithKey(mRow.getEntry().getKey())).isFalse();
assertThat(mBubbleData.hasOverflowBubbleWithKey(mRow.getEntry().getKey())).isTrue();
// Test
mBubbleController.updateBubble(mRow.getEntry());
assertThat(mBubbleData.hasBubbleInStackWithKey(mRow.getEntry().getKey())).isFalse();
}
/** /**
* Sets the bubble metadata flags for this entry. These ]flags are normally set by * Sets the bubble metadata flags for this entry. These ]flags are normally set by
* NotificationManagerService when the notification is sent, however, these tests do not * NotificationManagerService when the notification is sent, however, these tests do not

View File

@@ -512,6 +512,26 @@ public class BubbleDataTest extends SysuiTestCase {
assertSelectionChangedTo(mBubbleA1); assertSelectionChangedTo(mBubbleA1);
} }
/**
* Verifies that when a non visually interruptive update occurs, that the selection does not
* change.
*/
@Test
public void test_notVisuallyInterruptive_updateBubble_selectionDoesntChange() {
// Setup
sendUpdatedEntryAtTime(mEntryA1, 1000);
sendUpdatedEntryAtTime(mEntryB1, 2000);
sendUpdatedEntryAtTime(mEntryB2, 3000);
sendUpdatedEntryAtTime(mEntryA2, 4000); // [A2, B2, B1, A1]
mBubbleData.setListener(mListener);
assertThat(mBubbleData.getSelectedBubble()).isEqualTo(mBubbleA2);
// Test
sendUpdatedEntryAtTime(mEntryB1, 5000, false /* isVisuallyInterruptive */);
assertThat(mBubbleData.getSelectedBubble()).isEqualTo(mBubbleA2);
}
/** /**
* Verifies that a request to expand the stack has no effect if there are no bubbles. * Verifies that a request to expand the stack has no effect if there are no bubbles.
*/ */
@@ -883,9 +903,15 @@ public class BubbleDataTest extends SysuiTestCase {
} }
private void sendUpdatedEntryAtTime(NotificationEntry entry, long postTime) { private void sendUpdatedEntryAtTime(NotificationEntry entry, long postTime) {
sendUpdatedEntryAtTime(entry, postTime, true /* visuallyInterruptive */);
}
private void sendUpdatedEntryAtTime(NotificationEntry entry, long postTime,
boolean visuallyInterruptive) {
setPostTime(entry, postTime); setPostTime(entry, postTime);
// BubbleController calls this: // BubbleController calls this:
Bubble b = mBubbleData.getOrCreateBubble(entry, null /* persistedBubble */); Bubble b = mBubbleData.getOrCreateBubble(entry, null /* persistedBubble */);
b.setVisuallyInterruptiveForTest(visuallyInterruptive);
// And then this // And then this
mBubbleData.notificationEntryUpdated(b, false /* suppressFlyout*/, mBubbleData.notificationEntryUpdated(b, false /* suppressFlyout*/,
true /* showInShade */); true /* showInShade */);