summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mady Mellor <madym@google.com> 2020-05-27 00:06:33 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2020-05-27 00:06:33 +0000
commit8ae715575631e5ea3739e323454767b7d581e7a1 (patch)
treed2ccab407ab7c8a7c1036e41745b5a96163ada95
parentc6d6c0b466cc8fd4c64ddba68f550cc6f00bfc4a (diff)
parenta55133daa73bbe5722762b1736518f17b7fb521e (diff)
Merge "Removing groups & ongoing from bubble ordering" into rvc-dev
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java33
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java160
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleDebugConfig.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java320
5 files changed, 103 insertions, 420 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
index f1b401e77fbc..24ef324842d9 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
@@ -57,7 +57,6 @@ class Bubble implements BubbleViewProvider {
private NotificationEntry mEntry;
private final String mKey;
- private final String mGroupId;
private long mLastUpdated;
private long mLastAccessed;
@@ -96,17 +95,10 @@ class Bubble implements BubbleViewProvider {
private int mDotColor;
private Path mDotPath;
-
- public static String groupId(NotificationEntry entry) {
- UserHandle user = entry.getSbn().getUser();
- return user.getIdentifier() + "|" + entry.getSbn().getPackageName();
- }
-
// TODO: Decouple Bubble from NotificationEntry and transform ShortcutInfo into Bubble
Bubble(ShortcutInfo shortcutInfo) {
mShortcutInfo = shortcutInfo;
mKey = shortcutInfo.getId();
- mGroupId = shortcutInfo.getId();
}
/** Used in tests when no UI is required. */
@@ -116,7 +108,6 @@ class Bubble implements BubbleViewProvider {
mEntry = e;
mKey = e.getKey();
mLastUpdated = e.getSbn().getPostTime();
- mGroupId = groupId(e);
mSuppressionListener = listener;
}
@@ -129,10 +120,6 @@ class Bubble implements BubbleViewProvider {
return mEntry;
}
- public String getGroupId() {
- return mGroupId;
- }
-
public String getPackageName() {
return mEntry.getSbn().getPackageName();
}
@@ -297,20 +284,13 @@ class Bubble implements BubbleViewProvider {
}
/**
- * @return the newer of {@link #getLastUpdateTime()} and {@link #getLastAccessTime()}
+ * @return the last time this bubble was updated or accessed, whichever is most recent.
*/
long getLastActivity() {
return Math.max(mLastUpdated, mLastAccessed);
}
/**
- * @return the timestamp in milliseconds of the most recent notification entry for this bubble
- */
- long getLastUpdateTime() {
- return mLastUpdated;
- }
-
- /**
* @return if the bubble was ever expanded
*/
boolean getWasAccessed() {
@@ -411,15 +391,6 @@ class Bubble implements BubbleViewProvider {
return mFlyoutMessage;
}
- /**
- * Returns whether the notification for this bubble is a foreground service. It shows that this
- * is an ongoing bubble.
- */
- boolean isOngoing() {
- int flags = mEntry.getSbn().getNotification().flags;
- return (flags & Notification.FLAG_FOREGROUND_SERVICE) != 0;
- }
-
float getDesiredHeight(Context context) {
Notification.BubbleMetadata data = mEntry.getBubbleMetadata();
boolean useRes = data.getDesiredHeightResId() != 0;
@@ -562,7 +533,7 @@ class Bubble implements BubbleViewProvider {
normalX,
normalY,
this.showInShade(),
- this.isOngoing(),
+ false /* isOngoing (unused) */,
false /* isAppForeground (unused) */);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
index 65d5bebc625d..43f65ded29cb 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
@@ -21,8 +21,6 @@ import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_DATA;
import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
-import static java.util.stream.Collectors.toList;
-
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
@@ -45,7 +43,6 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import java.util.Objects;
import javax.inject.Inject;
@@ -62,9 +59,6 @@ public class BubbleData {
private static final Comparator<Bubble> BUBBLES_BY_SORT_KEY_DESCENDING =
Comparator.comparing(BubbleData::sortKey).reversed();
- private static final Comparator<Map.Entry<String, Long>> GROUPS_BY_MAX_SORT_KEY_DESCENDING =
- Comparator.<Map.Entry<String, Long>, Long>comparing(Map.Entry::getValue).reversed();
-
/** Contains information about changes that have been made to the state of bubbles. */
static final class Update {
boolean expandedChanged;
@@ -295,8 +289,6 @@ public class BubbleData {
if (!mExpanded) {
setExpandedInternal(true);
}
- } else if (mSelectedBubble == null) {
- setSelectedBubbleInternal(bubble);
}
boolean isBubbleExpandedAndSelected = mExpanded && mSelectedBubble == bubble;
@@ -370,20 +362,11 @@ public class BubbleData {
if (DEBUG_BUBBLE_DATA) {
Log.d(TAG, "doAdd: " + bubble);
}
- int minInsertPoint = 0;
- boolean newGroup = !hasBubbleWithGroupId(bubble.getGroupId());
- if (isExpanded()) {
- // first bubble of a group goes to the beginning, otherwise within the existing group
- minInsertPoint = newGroup ? 0 : findFirstIndexForGroup(bubble.getGroupId());
- }
- if (insertBubble(minInsertPoint, bubble) < mBubbles.size() - 1) {
- mStateChange.orderChanged = true;
- }
+ mBubbles.add(0, bubble);
mStateChange.addedBubble = bubble;
-
+ // Adding the first bubble doesn't change the order
+ mStateChange.orderChanged = mBubbles.size() > 1;
if (!isExpanded()) {
- mStateChange.orderChanged |= packGroup(findFirstIndexForGroup(bubble.getGroupId()));
- // Top bubble becomes selected.
setSelectedBubbleInternal(mBubbles.get(0));
}
}
@@ -406,14 +389,10 @@ public class BubbleData {
}
mStateChange.updatedBubble = bubble;
if (!isExpanded()) {
- // while collapsed, update causes re-pack
int prevPos = mBubbles.indexOf(bubble);
mBubbles.remove(bubble);
- int newPos = insertBubble(0, bubble);
- if (prevPos != newPos) {
- packGroup(newPos);
- mStateChange.orderChanged = true;
- }
+ mBubbles.add(0, bubble);
+ mStateChange.orderChanged = prevPos != 0;
setSelectedBubbleInternal(mBubbles.get(0));
}
}
@@ -581,7 +560,6 @@ public class BubbleData {
Log.e(TAG, "Attempt to expand stack without selected bubble!");
return;
}
- mSelectedBubble.markUpdatedAt(mTimeSource.currentTimeMillis());
mSelectedBubble.markAsAccessedAt(mTimeSource.currentTimeMillis());
mStateChange.orderChanged |= repackAll();
} else if (!mBubbles.isEmpty()) {
@@ -596,17 +574,11 @@ public class BubbleData {
}
if (mBubbles.indexOf(mSelectedBubble) > 0) {
// Move the selected bubble to the top while collapsed.
- if (!mSelectedBubble.isOngoing() && mBubbles.get(0).isOngoing()) {
- // The selected bubble cannot be raised to the first position because
- // there is an ongoing bubble there. Instead, force the top ongoing bubble
- // to become selected.
- setSelectedBubbleInternal(mBubbles.get(0));
- } else {
- // Raise the selected bubble (and it's group) up to the front so the selected
- // bubble remains on top.
+ int index = mBubbles.indexOf(mSelectedBubble);
+ if (index != 0) {
mBubbles.remove(mSelectedBubble);
mBubbles.add(0, mSelectedBubble);
- mStateChange.orderChanged |= packGroup(0);
+ mStateChange.orderChanged = true;
}
}
}
@@ -616,91 +588,12 @@ public class BubbleData {
}
private static long sortKey(Bubble bubble) {
- long key = bubble.getLastUpdateTime();
- if (bubble.isOngoing()) {
- // Set 2nd highest bit (signed long int), to partition between ongoing and regular
- key |= 0x4000000000000000L;
- }
- return key;
- }
-
- /**
- * Locates and inserts the bubble into a sorted position. The is inserted
- * based on sort key, groupId is not considered. A call to {@link #packGroup(int)} may be
- * required to keep grouping intact.
- *
- * @param minPosition the first insert point to consider
- * @param newBubble the bubble to insert
- * @return the position where the bubble was inserted
- */
- private int insertBubble(int minPosition, Bubble newBubble) {
- long newBubbleSortKey = sortKey(newBubble);
- String previousGroupId = null;
-
- for (int pos = minPosition; pos < mBubbles.size(); pos++) {
- Bubble bubbleAtPos = mBubbles.get(pos);
- String groupIdAtPos = bubbleAtPos.getGroupId();
- boolean atStartOfGroup = !groupIdAtPos.equals(previousGroupId);
-
- if (atStartOfGroup && newBubbleSortKey > sortKey(bubbleAtPos)) {
- // Insert before the start of first group which has older bubbles.
- mBubbles.add(pos, newBubble);
- return pos;
- }
- previousGroupId = groupIdAtPos;
- }
- mBubbles.add(newBubble);
- return mBubbles.size() - 1;
- }
-
- private boolean hasBubbleWithGroupId(String groupId) {
- return mBubbles.stream().anyMatch(b -> b.getGroupId().equals(groupId));
- }
-
- private int findFirstIndexForGroup(String appId) {
- for (int i = 0; i < mBubbles.size(); i++) {
- Bubble bubbleAtPos = mBubbles.get(i);
- if (bubbleAtPos.getGroupId().equals(appId)) {
- return i;
- }
- }
- return 0;
+ return bubble.getLastActivity();
}
/**
- * Starting at the given position, moves all bubbles with the same group id to follow. Bubbles
- * at positions lower than {@code position} are unchanged. Relative order within the group
- * unchanged. Relative order of any other bubbles are also unchanged.
- *
- * @param position the position of the first bubble for the group
- * @return true if the position of any bubbles has changed as a result
- */
- private boolean packGroup(int position) {
- if (DEBUG_BUBBLE_DATA) {
- Log.d(TAG, "packGroup: position=" + position);
- }
- Bubble groupStart = mBubbles.get(position);
- final String groupAppId = groupStart.getGroupId();
- List<Bubble> moving = new ArrayList<>();
-
- // Walk backward, collect bubbles within the group
- for (int i = mBubbles.size() - 1; i > position; i--) {
- if (mBubbles.get(i).getGroupId().equals(groupAppId)) {
- moving.add(0, mBubbles.get(i));
- }
- }
- if (moving.isEmpty()) {
- return false;
- }
- mBubbles.removeAll(moving);
- mBubbles.addAll(position + 1, moving);
- return true;
- }
-
- /**
- * This applies a full sort and group pass to all existing bubbles. The bubbles are grouped
- * by groupId. Each group is then sorted by the max(lastUpdated) time of its bubbles. Bubbles
- * within each group are then sorted by lastUpdated descending.
+ * This applies a full sort and group pass to all existing bubbles.
+ * Bubbles are sorted by lastUpdated descending.
*
* @return true if the position of any bubbles changed as a result
*/
@@ -711,31 +604,11 @@ public class BubbleData {
if (mBubbles.isEmpty()) {
return false;
}
- Map<String, Long> groupLastActivity = new HashMap<>();
- for (Bubble bubble : mBubbles) {
- long maxSortKeyForGroup = groupLastActivity.getOrDefault(bubble.getGroupId(), 0L);
- long sortKeyForBubble = sortKey(bubble);
- if (sortKeyForBubble > maxSortKeyForGroup) {
- groupLastActivity.put(bubble.getGroupId(), sortKeyForBubble);
- }
- }
-
- // Sort groups by their most recently active bubble
- List<String> groupsByMostRecentActivity =
- groupLastActivity.entrySet().stream()
- .sorted(GROUPS_BY_MAX_SORT_KEY_DESCENDING)
- .map(Map.Entry::getKey)
- .collect(toList());
-
List<Bubble> repacked = new ArrayList<>(mBubbles.size());
-
- // For each group, add bubbles, freshest to oldest
- for (String appId : groupsByMostRecentActivity) {
- mBubbles.stream()
- .filter((b) -> b.getGroupId().equals(appId))
- .sorted(BUBBLES_BY_SORT_KEY_DESCENDING)
- .forEachOrdered(repacked::add);
- }
+ // Add bubbles, freshest to oldest
+ mBubbles.stream()
+ .sorted(BUBBLES_BY_SORT_KEY_DESCENDING)
+ .forEachOrdered(repacked::add);
if (repacked.equals(mBubbles)) {
return false;
}
@@ -778,11 +651,12 @@ public class BubbleData {
public List<Bubble> getBubbles() {
return Collections.unmodifiableList(mBubbles);
}
+
/**
* The set of bubbles in overflow.
*/
@VisibleForTesting(visibility = PRIVATE)
- public List<Bubble> getOverflowBubbles() {
+ List<Bubble> getOverflowBubbles() {
return Collections.unmodifiableList(mOverflowBubbles);
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDebugConfig.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDebugConfig.java
index 19733a5f895c..d98fee399470 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDebugConfig.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDebugConfig.java
@@ -69,10 +69,10 @@ public class BubbleDebugConfig {
&& selected.getKey() != BubbleOverflow.KEY
&& bubble == selected);
String arrow = isSelected ? "=>" : " ";
- sb.append(String.format("%s Bubble{act=%12d, ongoing=%d, key=%s}\n",
+ sb.append(String.format("%s Bubble{act=%12d, showInShade=%d, key=%s}\n",
arrow,
bubble.getLastActivity(),
- (bubble.isOngoing() ? 1 : 0),
+ (bubble.showInShade() ? 1 : 0),
bubble.getKey()));
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index bdfcb35f7df2..418cc505daa8 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -49,7 +49,6 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.os.Bundle;
-import android.os.Vibrator;
import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import android.util.Log;
@@ -188,7 +187,6 @@ public class BubbleStackView extends FrameLayout
private final SpringAnimation mExpandedViewYAnim;
private final BubbleData mBubbleData;
- private final Vibrator mVibrator;
private final ValueAnimator mDesaturateAndDarkenAnimator;
private final Paint mDesaturateAndDarkenPaint = new Paint();
@@ -701,8 +699,6 @@ public class BubbleStackView extends FrameLayout
// We use the real size & subtract screen decorations / window insets ourselves when needed
wm.getDefaultDisplay().getRealSize(mDisplaySize);
- mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
-
mExpandedViewPadding = res.getDimensionPixelSize(R.dimen.bubble_expanded_view_padding);
int elevation = res.getDimensionPixelSize(R.dimen.bubble_elevation);
@@ -2334,7 +2330,7 @@ public class BubbleStackView extends FrameLayout
getNormalizedXPosition(),
getNormalizedYPosition(),
bubble.showInShade(),
- bubble.isOngoing(),
+ false /* isOngoing (unused) */,
false /* isAppForeground (unused) */);
}
}
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 66f119a082a6..eca78ec38a88 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java
@@ -20,11 +20,8 @@ import static com.android.systemui.statusbar.NotificationEntryHelper.modifyRanki
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
@@ -258,14 +255,15 @@ public class BubbleDataTest extends SysuiTestCase {
assertThat(update.updatedBubble.showFlyout()).isFalse();
}
- // COLLAPSED / ADD
+ //
+ // Overflow
+ //
/**
- * Verifies that the number of bubbles is not allowed to exceed the maximum. The limit is
- * enforced by expiring the bubble which was least recently updated (lowest timestamp).
+ * Verifies that when the bubble stack reaches its maximum, the oldest bubble is overflowed.
*/
@Test
- public void test_collapsed_addBubble_atMaxBubbles_overflowsOldest() {
+ public void testOverflow_add_stackAtMaxBubbles_overflowsOldest() {
// Setup
sendUpdatedEntryAtTime(mEntryA1, 1000);
sendUpdatedEntryAtTime(mEntryA2, 2000);
@@ -288,8 +286,12 @@ public class BubbleDataTest extends SysuiTestCase {
assertOverflowChangedTo(ImmutableList.of(mBubbleA2));
}
+ /**
+ * Verifies that once the number of overflowed bubbles reaches its maximum, the oldest
+ * overflow bubble is removed.
+ */
@Test
- public void testOverflowBubble_maxReached_bubbleRemoved() {
+ public void testOverflow_maxReached_bubbleRemoved() {
// Setup
sendUpdatedEntryAtTime(mEntryA1, 1000);
sendUpdatedEntryAtTime(mEntryA2, 2000);
@@ -308,69 +310,60 @@ public class BubbleDataTest extends SysuiTestCase {
}
/**
- * Verifies that new bubbles insert to the left when collapsed, carrying along grouped bubbles.
- * <p>
- * Placement within the list is based on lastUpdate (post time of the notification), descending
- * order (with most recent first).
- *
- * @see #test_expanded_addBubble_sortAndGrouping_newGroup()
- * @see #test_expanded_addBubble_sortAndGrouping_existingGroup()
+ * Verifies that overflow bubbles are canceled on notif entry removal.
*/
@Test
- public void test_collapsed_addBubble_sortAndGrouping() {
+ public void testOverflow_notifCanceled_removesOverflowBubble() {
// Setup
+ sendUpdatedEntryAtTime(mEntryA1, 1000);
+ sendUpdatedEntryAtTime(mEntryA2, 2000);
+ sendUpdatedEntryAtTime(mEntryA3, 3000);
+ sendUpdatedEntryAtTime(mEntryB1, 4000);
+ sendUpdatedEntryAtTime(mEntryB2, 5000);
+ sendUpdatedEntryAtTime(mEntryB3, 6000); // [A2, A3, B1, B2, B3], overflow: [A1]
+ sendUpdatedEntryAtTime(mEntryC1, 7000); // [A3, B1, B2, B3, C1], overflow: [A2, A1]
mBubbleData.setListener(mListener);
// Test
- sendUpdatedEntryAtTime(mEntryA1, 1000);
- verifyUpdateReceived();
- assertOrderNotChanged();
-
- sendUpdatedEntryAtTime(mEntryB1, 2000);
- verifyUpdateReceived();
- assertOrderChangedTo(mBubbleB1, mBubbleA1);
-
- sendUpdatedEntryAtTime(mEntryB2, 3000);
+ mBubbleData.notificationEntryRemoved(mEntryA1, BubbleController.DISMISS_NOTIF_CANCEL);
verifyUpdateReceived();
- assertOrderChangedTo(mBubbleB2, mBubbleB1, mBubbleA1);
+ assertOverflowChangedTo(ImmutableList.of(mBubbleA2));
- sendUpdatedEntryAtTime(mEntryA2, 4000);
+ // Test
+ mBubbleData.notificationEntryRemoved(mEntryA2, BubbleController.DISMISS_GROUP_CANCELLED);
verifyUpdateReceived();
- assertOrderChangedTo(mBubbleA2, mBubbleA1, mBubbleB2, mBubbleB1);
+ assertOverflowChangedTo(ImmutableList.of());
}
+ // COLLAPSED / ADD
+
/**
- * Verifies that new bubbles insert to the left when collapsed, carrying along grouped bubbles.
- * Additionally, any bubble which is ongoing is considered "newer" than any non-ongoing bubble.
+ * Verifies that new bubbles insert to the left when collapsed.
* <p>
- * Because of the ongoing bubble, the new bubble cannot be placed in the first position. This
- * causes the 'B' group to remain last, despite having a new button added.
- *
- * @see #test_expanded_addBubble_sortAndGrouping_newGroup()
- * @see #test_expanded_addBubble_sortAndGrouping_existingGroup()
+ * Placement within the list is based on {@link Bubble#getLastActivity()}, descending
+ * order (with most recent first).
*/
@Test
- public void test_collapsed_addBubble_sortAndGrouping_withOngoing() {
+ public void test_collapsed_addBubble() {
// Setup
mBubbleData.setListener(mListener);
// Test
- setOngoing(mEntryA1, true);
sendUpdatedEntryAtTime(mEntryA1, 1000);
verifyUpdateReceived();
assertOrderNotChanged();
sendUpdatedEntryAtTime(mEntryB1, 2000);
verifyUpdateReceived();
- assertOrderNotChanged();
+ assertOrderChangedTo(mBubbleB1, mBubbleA1);
sendUpdatedEntryAtTime(mEntryB2, 3000);
verifyUpdateReceived();
- assertOrderChangedTo(mBubbleA1, mBubbleB2, mBubbleB1);
+ assertOrderChangedTo(mBubbleB2, mBubbleB1, mBubbleA1);
sendUpdatedEntryAtTime(mEntryA2, 4000);
verifyUpdateReceived();
- assertOrderChangedTo(mBubbleA1, mBubbleA2, mBubbleB2, mBubbleB1);
+ assertOrderChangedTo(mBubbleA2, mBubbleB2, mBubbleB1, mBubbleA1);
}
/**
@@ -378,7 +371,6 @@ public class BubbleDataTest extends SysuiTestCase {
* the collapsed state.
*
* @see #test_collapsed_updateBubble_selectionChanges()
- * @see #test_collapsed_updateBubble_noSelectionChanges_withOngoing()
*/
@Test
public void test_collapsed_addBubble_selectionChanges() {
@@ -403,58 +395,27 @@ public class BubbleDataTest extends SysuiTestCase {
assertSelectionChangedTo(mBubbleA2);
}
- /**
- * Verifies that while collapsed, the selection will not change if the selected bubble is
- * ongoing. It remains the top bubble and as such remains selected.
- *
- * @see #test_collapsed_addBubble_selectionChanges()
- */
- @Test
- public void test_collapsed_addBubble_noSelectionChanges_withOngoing() {
- // Setup
- setOngoing(mEntryA1, true);
- sendUpdatedEntryAtTime(mEntryA1, 1000);
- assertThat(mBubbleData.getSelectedBubble()).isEqualTo(mBubbleA1);
- mBubbleData.setListener(mListener);
-
- // Test
- sendUpdatedEntryAtTime(mEntryB1, 2000);
- verifyUpdateReceived();
- assertSelectionNotChanged();
-
- sendUpdatedEntryAtTime(mEntryB2, 3000);
- verifyUpdateReceived();
- assertSelectionNotChanged();
-
- sendUpdatedEntryAtTime(mEntryA2, 4000);
- verifyUpdateReceived();
- assertSelectionNotChanged();
-
- assertThat(mBubbleData.getSelectedBubble()).isEqualTo(mBubbleA1); // selection unchanged
- }
-
// COLLAPSED / REMOVE
/**
- * Verifies that groups may reorder when bubbles are removed, while the stack is in the
- * collapsed state.
+ * Verifies order of bubbles after a removal.
*/
@Test
- public void test_collapsed_removeBubble_sortAndGrouping() {
+ public void test_collapsed_removeBubble_sort() {
// Setup
sendUpdatedEntryAtTime(mEntryA1, 1000);
sendUpdatedEntryAtTime(mEntryB1, 2000);
sendUpdatedEntryAtTime(mEntryB2, 3000);
- sendUpdatedEntryAtTime(mEntryA2, 4000); // [A2, A1, B2, B1]
+ sendUpdatedEntryAtTime(mEntryA2, 4000); // [A2, B2, B1, A1]
mBubbleData.setListener(mListener);
// Test
mBubbleData.notificationEntryRemoved(mEntryA2, BubbleController.DISMISS_USER_GESTURE);
verifyUpdateReceived();
+ // TODO: this should fail if things work as I expect them to?
assertOrderChangedTo(mBubbleB2, mBubbleB1, mBubbleA1);
}
-
/**
* Verifies that onOrderChanged is not called when a bubble is removed if the removal does not
* cause other bubbles to change position.
@@ -465,62 +426,16 @@ public class BubbleDataTest extends SysuiTestCase {
sendUpdatedEntryAtTime(mEntryA1, 1000);
sendUpdatedEntryAtTime(mEntryB1, 2000);
sendUpdatedEntryAtTime(mEntryB2, 3000);
- sendUpdatedEntryAtTime(mEntryA2, 4000); // [A2, A1, B2, B1]
+ sendUpdatedEntryAtTime(mEntryA2, 4000); // [A2, B2, B1, A1]
mBubbleData.setListener(mListener);
// Test
- mBubbleData.notificationEntryRemoved(mEntryB1, BubbleController.DISMISS_USER_GESTURE);
+ mBubbleData.notificationEntryRemoved(mEntryA1, BubbleController.DISMISS_USER_GESTURE);
verifyUpdateReceived();
assertOrderNotChanged();
}
/**
- * Verifies that bubble ordering reverts to normal when an ongoing bubble is removed. A group
- * which has a newer bubble may move to the front after the ongoing bubble is removed.
- */
- @Test
- public void test_collapsed_removeBubble_sortAndGrouping_withOngoing() {
- // Setup
- setOngoing(mEntryA1, true);
- sendUpdatedEntryAtTime(mEntryA1, 1000);
- sendUpdatedEntryAtTime(mEntryA2, 2000);
- sendUpdatedEntryAtTime(mEntryB1, 3000);
- sendUpdatedEntryAtTime(mEntryB2, 4000); // [A1*, A2, B2, B1]
- mBubbleData.setListener(mListener);
-
- // Test
- mBubbleData.notificationEntryRemoved(mEntryA1, BubbleController.DISMISS_NOTIF_CANCEL);
- verifyUpdateReceived();
- assertOrderChangedTo(mBubbleB2, mBubbleB1, mBubbleA2);
- }
-
- /**
- * Verifies that overflow bubbles are canceled on notif entry removal.
- */
- @Test
- public void test_removeOverflowBubble_forCanceledNotif() {
- // Setup
- sendUpdatedEntryAtTime(mEntryA1, 1000);
- sendUpdatedEntryAtTime(mEntryA2, 2000);
- sendUpdatedEntryAtTime(mEntryA3, 3000);
- sendUpdatedEntryAtTime(mEntryB1, 4000);
- sendUpdatedEntryAtTime(mEntryB2, 5000);
- sendUpdatedEntryAtTime(mEntryB3, 6000); // [A2, A3, B1, B2, B3], overflow: [A1]
- sendUpdatedEntryAtTime(mEntryC1, 7000); // [A3, B1, B2, B3, C1], overflow: [A2, A1]
- mBubbleData.setListener(mListener);
-
- // Test
- mBubbleData.notificationEntryRemoved(mEntryA1, BubbleController.DISMISS_NOTIF_CANCEL);
- verifyUpdateReceived();
- assertOverflowChangedTo(ImmutableList.of(mBubbleA2));
-
- // Test
- mBubbleData.notificationEntryRemoved(mEntryA2, BubbleController.DISMISS_GROUP_CANCELLED);
- verifyUpdateReceived();
- assertOverflowChangedTo(ImmutableList.of());
- }
-
- /**
* Verifies that when the selected bubble is removed with the stack in the collapsed state,
* the selection moves to the next most-recently updated bubble.
*/
@@ -530,7 +445,7 @@ public class BubbleDataTest extends SysuiTestCase {
sendUpdatedEntryAtTime(mEntryA1, 1000);
sendUpdatedEntryAtTime(mEntryB1, 2000);
sendUpdatedEntryAtTime(mEntryB2, 3000);
- sendUpdatedEntryAtTime(mEntryA2, 4000); // [A2, A1, B2, B1]
+ sendUpdatedEntryAtTime(mEntryA2, 4000); // [A2, B2, B1, A1]
mBubbleData.setListener(mListener);
// Test
@@ -542,26 +457,26 @@ public class BubbleDataTest extends SysuiTestCase {
// COLLAPSED / UPDATE
/**
- * Verifies that bubble and group ordering may change with updates while the stack is in the
+ * Verifies that bubble ordering changes with updates while the stack is in the
* collapsed state.
*/
@Test
- public void test_collapsed_updateBubble_orderAndGrouping() {
+ public void test_collapsed_updateBubble() {
// Setup
sendUpdatedEntryAtTime(mEntryA1, 1000);
sendUpdatedEntryAtTime(mEntryB1, 2000);
sendUpdatedEntryAtTime(mEntryB2, 3000);
- sendUpdatedEntryAtTime(mEntryA2, 4000); // [A2, A1, B2, B1]
+ sendUpdatedEntryAtTime(mEntryA2, 4000); // [A2, B2, B1, A1]
mBubbleData.setListener(mListener);
// Test
sendUpdatedEntryAtTime(mEntryB1, 5000);
verifyUpdateReceived();
- assertOrderChangedTo(mBubbleB1, mBubbleB2, mBubbleA2, mBubbleA1);
+ assertOrderChangedTo(mBubbleB1, mBubbleA2, mBubbleB2, mBubbleA1);
sendUpdatedEntryAtTime(mEntryA1, 6000);
verifyUpdateReceived();
- assertOrderChangedTo(mBubbleA1, mBubbleA2, mBubbleB1, mBubbleB2);
+ assertOrderChangedTo(mBubbleA1, mBubbleB1, mBubbleA2, mBubbleB2);
}
/**
@@ -573,7 +488,7 @@ public class BubbleDataTest extends SysuiTestCase {
sendUpdatedEntryAtTime(mEntryA1, 1000);
sendUpdatedEntryAtTime(mEntryB1, 2000);
sendUpdatedEntryAtTime(mEntryB2, 3000);
- sendUpdatedEntryAtTime(mEntryA2, 4000); // [A2, A1, B2, B1]
+ sendUpdatedEntryAtTime(mEntryA2, 4000); // [A2, B2, B1, A1]
mBubbleData.setListener(mListener);
// Test
@@ -587,26 +502,6 @@ public class BubbleDataTest extends SysuiTestCase {
}
/**
- * Verifies that selection does not change in response to updates when collapsed, if the
- * selected bubble is ongoing.
- */
- @Test
- public void test_collapsed_updateBubble_noSelectionChanges_withOngoing() {
- // Setup
- setOngoing(mEntryA1, true);
- sendUpdatedEntryAtTime(mEntryA1, 1000);
- sendUpdatedEntryAtTime(mEntryB1, 2000);
- sendUpdatedEntryAtTime(mEntryB2, 3000);
- sendUpdatedEntryAtTime(mEntryA2, 4000); // [A1*, A2, B2, B1]
- mBubbleData.setListener(mListener);
-
- // Test
- sendUpdatedEntryAtTime(mEntryB2, 5000); // [A1*, A2, B2, B1]
- verifyUpdateReceived();
- assertSelectionNotChanged();
- }
-
- /**
* Verifies that a request to expand the stack has no effect if there are no bubbles.
*/
@Test
@@ -618,6 +513,9 @@ public class BubbleDataTest extends SysuiTestCase {
verifyZeroInteractions(mListener);
}
+ /**
+ * Verifies that removing the last bubble clears the selected bubble and collapses the stack.
+ */
@Test
public void test_collapsed_removeLastBubble_clearsSelectedBubble() {
// Setup
@@ -629,23 +527,22 @@ public class BubbleDataTest extends SysuiTestCase {
// Verify the selection was cleared.
verifyUpdateReceived();
+ assertThat(mBubbleData.isExpanded()).isFalse();
assertSelectionCleared();
}
- // EXPANDED / ADD
+ // EXPANDED / ADD / UPDATE
/**
- * Verifies that bubbles added as part of a new group insert before existing groups while
- * expanded.
+ * Verifies that bubbles are added at the front of the stack.
* <p>
- * Placement within the list is based on lastUpdate (post time of the notification), descending
+ * Placement within the list is based on {@link Bubble#getLastActivity()}, descending
* order (with most recent first).
*
- * @see #test_collapsed_addBubble_sortAndGrouping()
- * @see #test_expanded_addBubble_sortAndGrouping_existingGroup()
+ * @see #test_collapsed_addBubble()
*/
@Test
- public void test_expanded_addBubble_sortAndGrouping_newGroup() {
+ public void test_expanded_addBubble() {
// Setup
sendUpdatedEntryAtTime(mEntryA1, 1000);
sendUpdatedEntryAtTime(mEntryA2, 2000);
@@ -656,65 +553,15 @@ public class BubbleDataTest extends SysuiTestCase {
// Test
sendUpdatedEntryAtTime(mEntryC1, 4000);
verifyUpdateReceived();
- assertOrderChangedTo(mBubbleB1, mBubbleC1, mBubbleA2, mBubbleA1);
- }
-
- /**
- * Verifies that bubbles added as part of a new group insert before existing groups while
- * expanded, but not before any groups with ongoing bubbles.
- *
- * @see #test_collapsed_addBubble_sortAndGrouping_withOngoing()
- * @see #test_expanded_addBubble_sortAndGrouping_existingGroup()
- */
- @Test
- public void test_expanded_addBubble_sortAndGrouping_newGroup_withOngoing() {
- // Setup
- setOngoing(mEntryA1, true);
- sendUpdatedEntryAtTime(mEntryA1, 1000);
- sendUpdatedEntryAtTime(mEntryA2, 2000);
- sendUpdatedEntryAtTime(mEntryB1, 3000); // [A1*, A2, B1]
- changeExpandedStateAtTime(true, 4000L);
- mBubbleData.setListener(mListener);
-
- // Test
- sendUpdatedEntryAtTime(mEntryC1, 4000);
- verifyUpdateReceived();
- assertOrderChangedTo(mBubbleA1, mBubbleA2, mBubbleC1, mBubbleB1);
+ assertOrderChangedTo(mBubbleC1, mBubbleB1, mBubbleA2, mBubbleA1);
}
/**
- * Verifies that bubbles added as part of an existing group insert to the beginning of that
- * group. The order of groups within the list must not change while in the expanded state.
- *
- * @see #test_collapsed_addBubble_sortAndGrouping()
- * @see #test_expanded_addBubble_sortAndGrouping_newGroup()
- */
- @Test
- public void test_expanded_addBubble_sortAndGrouping_existingGroup() {
- // Setup
- sendUpdatedEntryAtTime(mEntryA1, 1000);
- sendUpdatedEntryAtTime(mEntryA2, 2000);
- sendUpdatedEntryAtTime(mEntryB1, 3000); // [B1, A2, A1]
- changeExpandedStateAtTime(true, 4000L);
- mBubbleData.setListener(mListener);
-
- // Test
- sendUpdatedEntryAtTime(mEntryA3, 4000);
- verifyUpdateReceived();
- assertOrderChangedTo(mBubbleB1, mBubbleA3, mBubbleA2, mBubbleA1);
- }
-
- // EXPANDED / UPDATE
-
- /**
* Verifies that updates to bubbles while expanded do not result in any change to sorting
- * or grouping of bubbles or sorting of groups.
- *
- * @see #test_collapsed_addBubble_sortAndGrouping()
- * @see #test_expanded_addBubble_sortAndGrouping_existingGroup()
+ * of bubbles.
*/
@Test
- public void test_expanded_updateBubble_sortAndGrouping_noChanges() {
+ public void test_expanded_updateBubble_noChanges() {
// Setup
sendUpdatedEntryAtTime(mEntryA1, 1000);
sendUpdatedEntryAtTime(mEntryA2, 2000);
@@ -733,7 +580,6 @@ public class BubbleDataTest extends SysuiTestCase {
* Verifies that updates to bubbles while expanded do not result in any change to selection.
*
* @see #test_collapsed_addBubble_selectionChanges()
- * @see #test_collapsed_updateBubble_noSelectionChanges_withOngoing()
*/
@Test
public void test_expanded_updateBubble_noSelectionChanges() {
@@ -762,26 +608,24 @@ public class BubbleDataTest extends SysuiTestCase {
// EXPANDED / REMOVE
/**
- * Verifies that removing a bubble while expanded does not result in reordering of groups
- * or any of the remaining bubbles.
+ * Verifies that removing a bubble while expanded does not result in reordering of bubbles.
*
- * @see #test_collapsed_addBubble_sortAndGrouping()
- * @see #test_expanded_addBubble_sortAndGrouping_existingGroup()
+ * @see #test_collapsed_addBubble()
*/
@Test
- public void test_expanded_removeBubble_sortAndGrouping() {
+ public void test_expanded_removeBubble() {
// Setup
sendUpdatedEntryAtTime(mEntryA1, 1000);
sendUpdatedEntryAtTime(mEntryB1, 2000);
sendUpdatedEntryAtTime(mEntryA2, 3000);
- sendUpdatedEntryAtTime(mEntryB2, 4000); // [B2, B1, A2, A1]
+ sendUpdatedEntryAtTime(mEntryB2, 4000); // [B2, A2, B1, A1]
changeExpandedStateAtTime(true, 5000L);
mBubbleData.setListener(mListener);
// Test
mBubbleData.notificationEntryRemoved(mEntryB2, BubbleController.DISMISS_USER_GESTURE);
verifyUpdateReceived();
- assertOrderChangedTo(mBubbleB1, mBubbleA2, mBubbleA1);
+ assertOrderChangedTo(mBubbleA2, mBubbleB1, mBubbleA1);
}
/**
@@ -789,8 +633,7 @@ public class BubbleDataTest extends SysuiTestCase {
* selected. The replacement selection is the bubble which appears at the same index as the
* previous one, or the previous index if this was the last position.
*
- * @see #test_collapsed_addBubble_sortAndGrouping()
- * @see #test_expanded_addBubble_sortAndGrouping_existingGroup()
+ * @see #test_collapsed_addBubble()
*/
@Test
public void test_expanded_removeBubble_selectionChanges_whenSelectedRemoved() {
@@ -800,17 +643,17 @@ public class BubbleDataTest extends SysuiTestCase {
sendUpdatedEntryAtTime(mEntryA2, 3000);
sendUpdatedEntryAtTime(mEntryB2, 4000);
changeExpandedStateAtTime(true, 5000L);
- mBubbleData.setSelectedBubble(mBubbleA2); // [B2, B1, ^A2, A1]
+ mBubbleData.setSelectedBubble(mBubbleA2); // [B2, A2^, B1, A1]
mBubbleData.setListener(mListener);
// Test
mBubbleData.notificationEntryRemoved(mEntryA2, BubbleController.DISMISS_USER_GESTURE);
verifyUpdateReceived();
- assertSelectionChangedTo(mBubbleA1);
+ assertSelectionChangedTo(mBubbleB1);
- mBubbleData.notificationEntryRemoved(mEntryA1, BubbleController.DISMISS_USER_GESTURE);
+ mBubbleData.notificationEntryRemoved(mEntryB1, BubbleController.DISMISS_USER_GESTURE);
verifyUpdateReceived();
- assertSelectionChangedTo(mBubbleB1);
+ assertSelectionChangedTo(mBubbleA1);
}
@Test
@@ -838,7 +681,6 @@ public class BubbleDataTest extends SysuiTestCase {
* expanded.
* <p>
* When the stack transitions to the collapsed state, the selected bubble is brought to the top.
- * Bubbles within the same group should move up with it.
* <p>
* When the stack transitions back to the expanded state, this new order is kept as is.
*/
@@ -849,13 +691,13 @@ public class BubbleDataTest extends SysuiTestCase {
sendUpdatedEntryAtTime(mEntryB1, 2000);
sendUpdatedEntryAtTime(mEntryA2, 3000);
sendUpdatedEntryAtTime(mEntryB2, 4000);
- changeExpandedStateAtTime(true, 5000L); // [B2=4000, B1=2000, A2=3000, A1=1000]
- sendUpdatedEntryAtTime(mEntryB1, 6000); // [B2=4000, B1=6000*, A2=3000, A1=1000]
+ changeExpandedStateAtTime(true, 5000L); // [B2=4000, A2=3000, B1=2000, A1=1000]
+ sendUpdatedEntryAtTime(mEntryB1, 6000); // [B2=4000, A2=3000, B1=6000, A1=1000]
setCurrentTime(7000);
mBubbleData.setSelectedBubble(mBubbleA2);
mBubbleData.setListener(mListener);
assertThat(mBubbleData.getBubbles()).isEqualTo(
- ImmutableList.of(mBubbleB2, mBubbleB1, mBubbleA2, mBubbleA1));
+ ImmutableList.of(mBubbleB2, mBubbleA2, mBubbleB1, mBubbleA1));
// Test
@@ -863,18 +705,17 @@ public class BubbleDataTest extends SysuiTestCase {
// stack is expanded. When next collapsed, sorting will be applied and saved, just prior
// to moving the selected bubble to the top (first).
//
- // In this case, the expected re-expand state will be: [A2, A1, B1, B2]
+ // In this case, the expected re-expand state will be: [A2^, B1, B2, A1]
//
// collapse -> selected bubble (A2) moves first.
changeExpandedStateAtTime(false, 8000L);
verifyUpdateReceived();
- assertOrderChangedTo(mBubbleA2, mBubbleA1, mBubbleB1, mBubbleB2);
+ assertOrderChangedTo(mBubbleA2, mBubbleB1, mBubbleB2, mBubbleA1);
}
/**
* When a change occurs while collapsed (any update, add, remove), the previous expanded
- * order and grouping becomes invalidated, and the order and grouping when next expanded will
- * remain the same as collapsed.
+ * order becomes invalidated, the stack is resorted and will reflect that when next expanded.
*/
@Test
public void test_expansionChanges_withUpdatesWhileCollapsed() {
@@ -883,10 +724,10 @@ public class BubbleDataTest extends SysuiTestCase {
sendUpdatedEntryAtTime(mEntryB1, 2000);
sendUpdatedEntryAtTime(mEntryA2, 3000);
sendUpdatedEntryAtTime(mEntryB2, 4000);
- changeExpandedStateAtTime(true, 5000L); // [B2=4000, B1=2000, A2=3000, A1=1000]
- sendUpdatedEntryAtTime(mEntryB1, 6000); // [B2=4000, B1=*6000, A2=3000, A1=1000]
+ changeExpandedStateAtTime(true, 5000L); // [B2=4000, A2=3000, B1=2000, A1=1000]
+ sendUpdatedEntryAtTime(mEntryB1, 6000); // [B2=4000, A2=3000, B1=6000, A1=1000]
setCurrentTime(7000);
- mBubbleData.setSelectedBubble(mBubbleA2); // [B2, B1, ^A2, A1]
+ mBubbleData.setSelectedBubble(mBubbleA2); // [B2, A2^, B1, A1]
mBubbleData.setListener(mListener);
// Test
@@ -895,7 +736,7 @@ public class BubbleDataTest extends SysuiTestCase {
// stack is expanded. When next collapsed, sorting will be applied and saved, just prior
// to moving the selected bubble to the top (first).
//
- // In this case, the expected re-expand state will be: [B1, B2, A2*, A1]
+ // In this case, the expected re-expand state will be: [A2^, B1, B2, A1]
//
// That state is restored as long as no changes occur (add/remove/update) while in
// the collapsed state.
@@ -903,11 +744,12 @@ public class BubbleDataTest extends SysuiTestCase {
// collapse -> selected bubble (A2) moves first.
changeExpandedStateAtTime(false, 8000L);
verifyUpdateReceived();
- assertOrderChangedTo(mBubbleA2, mBubbleA1, mBubbleB1, mBubbleB2);
+ assertOrderChangedTo(mBubbleA2, mBubbleB1, mBubbleB2, mBubbleA1);
// An update occurs, which causes sorting, and this invalidates the previously saved order.
- sendUpdatedEntryAtTime(mEntryA2, 9000);
+ sendUpdatedEntryAtTime(mEntryA1, 9000);
verifyUpdateReceived();
+ assertOrderChangedTo(mBubbleA1, mBubbleA2, mBubbleB1, mBubbleB2);
// No order changes when expanding because the new sorted order remains.
changeExpandedStateAtTime(true, 10000L);