Merge "Handle non-visually-interruptive updates better in bubbles" into rvc-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
abeb577396
@@ -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();
|
||||||
|
|||||||
@@ -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,8 +1120,17 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
|
|||||||
if (notif.getImportance() >= NotificationManager.IMPORTANCE_HIGH) {
|
if (notif.getImportance() >= NotificationManager.IMPORTANCE_HIGH) {
|
||||||
notif.setInterruption();
|
notif.setInterruption();
|
||||||
}
|
}
|
||||||
Bubble bubble = mBubbleData.getOrCreateBubble(notif, null /* persistedBubble */);
|
if (!notif.getRanking().visuallyInterruptive()
|
||||||
inflateAndAdd(bubble, suppressFlyout, showInShade);
|
&& (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 */);
|
||||||
|
inflateAndAdd(bubble, suppressFlyout, showInShade);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void inflateAndAdd(Bubble bubble, boolean suppressFlyout, boolean showInShade) {
|
void inflateAndAdd(Bubble bubble, boolean suppressFlyout, boolean showInShade) {
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 */);
|
||||||
|
|||||||
Reference in New Issue
Block a user