Mark bubbles as updated when they're added to the stack

If you add a bubble via the button on the notification but
if the notif for it is older than the notifs for the bubbles
in the stack, then that added bubble is removed immediately.

This isn't expected and can result in the view state being
out of sync with bubble data, i.e. BubbleStackView contains
the view but BubbleData doesn't have the bubble so it can
get added again (but the view is already in BSV causing the
crash).

This fixes the issue by marking newly added bubbles as
"updated" which will ensure the newly added bubble won't
be immediately removed.

Had to adjust the tests to be setting a current time since
that's what's used to mark the update time.

Test: atest BubbleDataTest
Bug: 207083906
Change-Id: I425de9c1ca514066340f9123b6004820e98674fd
This commit is contained in:
Mady Mellor
2021-12-08 15:30:53 -08:00
parent eeb998c093
commit fecc199440
2 changed files with 33 additions and 0 deletions

View File

@@ -328,6 +328,7 @@ public class BubbleData {
if (prevBubble == null) {
// Create a new bubble
bubble.setSuppressFlyout(suppressFlyout);
bubble.markUpdatedAt(mTimeSource.currentTimeMillis());
doAdd(bubble);
trim();
} else {

View File

@@ -39,6 +39,7 @@ import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.Log;
import android.util.Pair;
import android.view.WindowManager;
@@ -913,6 +914,31 @@ public class BubbleDataTest extends ShellTestCase {
assertSelectionChangedTo(mBubbleA2);
}
/**
* - have a maxed out bubble stack & all of the bubbles have been recently accessed
* - bubble a notification that was posted before any of those bubbles were accessed
* => that bubble should be added
*
*/
@Test
public void test_addOldNotifWithNewerBubbles() {
sendUpdatedEntryAtTime(mEntryA1, 2000);
sendUpdatedEntryAtTime(mEntryA2, 3000);
sendUpdatedEntryAtTime(mEntryA3, 4000);
sendUpdatedEntryAtTime(mEntryB1, 5000);
sendUpdatedEntryAtTime(mEntryB2, 6000);
mBubbleData.setListener(mListener);
sendUpdatedEntryAtTime(mEntryB3, 1000 /* postTime */, 7000 /* currentTime */);
verifyUpdateReceived();
// B3 is in the stack
assertThat(mBubbleData.getBubbleInStackWithKey(mBubbleB3.getKey())).isNotNull();
// A1 is the oldest so it's in the overflow
assertThat(mBubbleData.getOverflowBubbleWithKey(mEntryA1.getKey())).isNotNull();
assertOrderChangedTo(mBubbleB3, mBubbleB2, mBubbleB1, mBubbleA3, mBubbleA2);
}
private void verifyUpdateReceived() {
verify(mListener).applyUpdate(mUpdateCaptor.capture());
reset(mListener);
@@ -1014,6 +1040,12 @@ public class BubbleDataTest extends ShellTestCase {
}
private void sendUpdatedEntryAtTime(BubbleEntry entry, long postTime) {
setCurrentTime(postTime);
sendUpdatedEntryAtTime(entry, postTime, true /* isTextChanged */);
}
private void sendUpdatedEntryAtTime(BubbleEntry entry, long postTime, long currentTime) {
setCurrentTime(currentTime);
sendUpdatedEntryAtTime(entry, postTime, true /* isTextChanged */);
}