Loading libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleBarUpdate.java +7 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,10 @@ public class BubbleBarUpdate implements Parcelable { public Point expandedViewDropTargetSize; public boolean showOverflowChanged; public boolean showOverflow; /** * Whether to suppress the animation of this update. Currently, this is only used for jumpcut. */ public boolean suppressAnimation; // This is only populated if bubbles have been removed. public List<RemovedBubble> removedBubbles = new ArrayList<>(); Loading Loading @@ -96,6 +100,7 @@ public class BubbleBarUpdate implements Parcelable { Point.class); showOverflowChanged = parcel.readBoolean(); showOverflow = parcel.readBoolean(); suppressAnimation = parcel.readBoolean(); } /** Loading Loading @@ -135,6 +140,7 @@ public class BubbleBarUpdate implements Parcelable { + " expandedViewDropTargetSize=" + expandedViewDropTargetSize + " showOverflowChanged=" + showOverflowChanged + " showOverflow=" + showOverflow + " suppressAnimation=" + suppressAnimation + " }"; } Loading @@ -161,6 +167,7 @@ public class BubbleBarUpdate implements Parcelable { parcel.writeParcelable(expandedViewDropTargetSize, flags); parcel.writeBoolean(showOverflowChanged); parcel.writeBoolean(showOverflow); parcel.writeBoolean(suppressAnimation); } /** Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java +34 −0 Original line number Diff line number Diff line Loading @@ -98,6 +98,14 @@ public class BubbleData { BubbleBarLocation mBubbleBarLocation; // Pair with Bubble and @DismissReason Integer final List<Pair<Bubble, Integer>> removedBubbles = new ArrayList<>(); /** * The closing Bubble of a jumpcut Bubble switch transition animation. * * This is different from {@link #removedBubbles} that the applying of this change will not * cleanup the TaskView, but will only notify the listener about the removal. */ @Nullable Bubble jumpcutBubbleSwitchClosingBubble; // A read-only view of the bubbles list, changes there will be reflected here. final List<Bubble> bubbles; Loading @@ -114,6 +122,7 @@ public class BubbleData { || addedBubble != null || updatedBubble != null || !removedBubbles.isEmpty() || jumpcutBubbleSwitchClosingBubble != null || addedOverflowBubble != null || removedOverflowBubble != null || orderChanged Loading @@ -129,6 +138,10 @@ public class BubbleData { removedBubbles.add(new Pair<>(bubbleToRemove, reason)); } void setJumpcutBubbleSwitchClosingBubble(Bubble closingBubble) { jumpcutBubbleSwitchClosingBubble = closingBubble; } /** * Converts the update to a {@link BubbleBarUpdate} which contains updates relevant * to the bubble bar. Only used when {@link BubbleController#isShowingAsBubbleBar()} is Loading Loading @@ -167,6 +180,11 @@ public class BubbleData { new RemovedBubble(pair.first.getKey(), pair.second)); } } if (jumpcutBubbleSwitchClosingBubble != null) { bubbleBarUpdate.removedBubbles.add(new RemovedBubble( jumpcutBubbleSwitchClosingBubble.getKey(), Bubbles.DISMISS_JUMPCUT_BUBBLE_SWITCH)); } if (orderChanged) { // Include the new order for (int i = 0; i < bubbles.size(); i++) { Loading @@ -176,6 +194,8 @@ public class BubbleData { bubbleBarUpdate.showOverflowChanged = showOverflowChanged; bubbleBarUpdate.showOverflow = !overflowBubbles.isEmpty(); bubbleBarUpdate.bubbleBarLocation = mBubbleBarLocation; bubbleBarUpdate.suppressAnimation = addedBubble != null && addedBubble.isJumpcutBubbleSwitching(); return bubbleBarUpdate; } Loading Loading @@ -613,6 +633,20 @@ public class BubbleData { dispatchPendingChanges(); } /** * Notifies about the jumpcut Bubble switching, which contains * - All info in the opening Bubble has completed loading. * - The BubbleBar Icon of the closing Bubble can be removed. */ void jumpcutBubbleSwitch(Bubble openingBubble, Bubble closingBubble) { // Notify launcher about the closing Bubble, but don't actually remove its TaskView yet // because we still need it to be visible until the opening Bubble is fully visible. // The cleanup will be done onTaskVanished. mStateChange.setJumpcutBubbleSwitchClosingBubble(closingBubble); notificationEntryUpdated(openingBubble, /* suppressFlyout= */ true, /* showInShade= */ false); } /** Dismisses the bubble with the matching key, if it exists. */ public void dismissBubbleWithKey(String key, @DismissReason int reason) { dismissBubbleWithKey(key, reason, mTimeSource.currentTimeMillis()); Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java +1 −2 Original line number Diff line number Diff line Loading @@ -954,8 +954,7 @@ public class BubbleTransitions { mFinishCb = finishCallback; mTaskLeash = enterBubbleTask.getLeash(); mBubbleData.notificationEntryUpdated(mOpeningBubble, /* suppressFlyout= */ true, /* showInShade= */ false); mBubbleData.jumpcutBubbleSwitch(mOpeningBubble, mClosingBubble); // Keep showing the closing Bubble Task within the closing Bubble TaskView until the // opening Bubble TaskView is ready. Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java +1 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ public interface Bubbles { int DISMISS_USER_ACCOUNT_REMOVED = 16; int DISMISS_SWITCH_TO_STACK = 17; int DISMISS_USER_GESTURE_FROM_LAUNCHER = 18; int DISMISS_JUMPCUT_BUBBLE_SWITCH = 19; /** Returns a binder that can be passed to an external process to manipulate Bubbles. */ default IBubbles createExternalInterface() { Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java +33 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.wm.shell.bubbles; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.wm.shell.Flags.FLAG_ENABLE_OPTIONAL_BUBBLE_OVERFLOW; import static com.google.common.truth.Truth.assertThat; Loading @@ -25,6 +26,7 @@ import static junit.framework.Assert.assertNotNull; import static junit.framework.TestCase.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; Loading Loading @@ -1498,6 +1500,37 @@ public class BubbleDataTest extends ShellTestCase { assertThat(mBubbleData.isExpanded()).isTrue(); } @Test public void testJumpcutBubbleSwitch() { mBubbleData.setListener(mListener); mBubbleData.jumpcutBubbleSwitch(mBubbleA1, mBubbleC1); verifyUpdateReceived(); BubbleData.Update update = mUpdateCaptor.getValue(); assertThat(update.addedBubble).isEqualTo(mBubbleA1); assertThat(update.jumpcutBubbleSwitchClosingBubble).isEqualTo(mBubbleC1); assertThat(update.removedBubbles).isEmpty(); } @Test public void testToBubbleBarUpdate_suppressAnimationForJumpcutBubbleSwitch() { spyOn(mBubbleA1); doReturn(true).when(mBubbleA1).isJumpcutBubbleSwitching(); mBubbleData.setListener(mListener); mBubbleData.jumpcutBubbleSwitch(mBubbleA1, mBubbleC1); verifyUpdateReceived(); BubbleData.Update update = mUpdateCaptor.getValue(); BubbleBarUpdate bubbleBarUpdate = update.toBubbleBarUpdate(); assertThat(bubbleBarUpdate.suppressAnimation).isTrue(); assertThat(bubbleBarUpdate.removedBubbles).hasSize(1); assertThat(bubbleBarUpdate.removedBubbles.get(0).getKey()).isEqualTo(mBubbleC1.getKey()); assertThat(bubbleBarUpdate.removedBubbles.get(0).getRemovalReason()) .isEqualTo(Bubbles.DISMISS_JUMPCUT_BUBBLE_SWITCH); } private void verifyUpdateReceived() { verify(mListener).applyUpdate(mUpdateCaptor.capture()); reset(mListener); Loading Loading
libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleBarUpdate.java +7 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,10 @@ public class BubbleBarUpdate implements Parcelable { public Point expandedViewDropTargetSize; public boolean showOverflowChanged; public boolean showOverflow; /** * Whether to suppress the animation of this update. Currently, this is only used for jumpcut. */ public boolean suppressAnimation; // This is only populated if bubbles have been removed. public List<RemovedBubble> removedBubbles = new ArrayList<>(); Loading Loading @@ -96,6 +100,7 @@ public class BubbleBarUpdate implements Parcelable { Point.class); showOverflowChanged = parcel.readBoolean(); showOverflow = parcel.readBoolean(); suppressAnimation = parcel.readBoolean(); } /** Loading Loading @@ -135,6 +140,7 @@ public class BubbleBarUpdate implements Parcelable { + " expandedViewDropTargetSize=" + expandedViewDropTargetSize + " showOverflowChanged=" + showOverflowChanged + " showOverflow=" + showOverflow + " suppressAnimation=" + suppressAnimation + " }"; } Loading @@ -161,6 +167,7 @@ public class BubbleBarUpdate implements Parcelable { parcel.writeParcelable(expandedViewDropTargetSize, flags); parcel.writeBoolean(showOverflowChanged); parcel.writeBoolean(showOverflow); parcel.writeBoolean(suppressAnimation); } /** Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java +34 −0 Original line number Diff line number Diff line Loading @@ -98,6 +98,14 @@ public class BubbleData { BubbleBarLocation mBubbleBarLocation; // Pair with Bubble and @DismissReason Integer final List<Pair<Bubble, Integer>> removedBubbles = new ArrayList<>(); /** * The closing Bubble of a jumpcut Bubble switch transition animation. * * This is different from {@link #removedBubbles} that the applying of this change will not * cleanup the TaskView, but will only notify the listener about the removal. */ @Nullable Bubble jumpcutBubbleSwitchClosingBubble; // A read-only view of the bubbles list, changes there will be reflected here. final List<Bubble> bubbles; Loading @@ -114,6 +122,7 @@ public class BubbleData { || addedBubble != null || updatedBubble != null || !removedBubbles.isEmpty() || jumpcutBubbleSwitchClosingBubble != null || addedOverflowBubble != null || removedOverflowBubble != null || orderChanged Loading @@ -129,6 +138,10 @@ public class BubbleData { removedBubbles.add(new Pair<>(bubbleToRemove, reason)); } void setJumpcutBubbleSwitchClosingBubble(Bubble closingBubble) { jumpcutBubbleSwitchClosingBubble = closingBubble; } /** * Converts the update to a {@link BubbleBarUpdate} which contains updates relevant * to the bubble bar. Only used when {@link BubbleController#isShowingAsBubbleBar()} is Loading Loading @@ -167,6 +180,11 @@ public class BubbleData { new RemovedBubble(pair.first.getKey(), pair.second)); } } if (jumpcutBubbleSwitchClosingBubble != null) { bubbleBarUpdate.removedBubbles.add(new RemovedBubble( jumpcutBubbleSwitchClosingBubble.getKey(), Bubbles.DISMISS_JUMPCUT_BUBBLE_SWITCH)); } if (orderChanged) { // Include the new order for (int i = 0; i < bubbles.size(); i++) { Loading @@ -176,6 +194,8 @@ public class BubbleData { bubbleBarUpdate.showOverflowChanged = showOverflowChanged; bubbleBarUpdate.showOverflow = !overflowBubbles.isEmpty(); bubbleBarUpdate.bubbleBarLocation = mBubbleBarLocation; bubbleBarUpdate.suppressAnimation = addedBubble != null && addedBubble.isJumpcutBubbleSwitching(); return bubbleBarUpdate; } Loading Loading @@ -613,6 +633,20 @@ public class BubbleData { dispatchPendingChanges(); } /** * Notifies about the jumpcut Bubble switching, which contains * - All info in the opening Bubble has completed loading. * - The BubbleBar Icon of the closing Bubble can be removed. */ void jumpcutBubbleSwitch(Bubble openingBubble, Bubble closingBubble) { // Notify launcher about the closing Bubble, but don't actually remove its TaskView yet // because we still need it to be visible until the opening Bubble is fully visible. // The cleanup will be done onTaskVanished. mStateChange.setJumpcutBubbleSwitchClosingBubble(closingBubble); notificationEntryUpdated(openingBubble, /* suppressFlyout= */ true, /* showInShade= */ false); } /** Dismisses the bubble with the matching key, if it exists. */ public void dismissBubbleWithKey(String key, @DismissReason int reason) { dismissBubbleWithKey(key, reason, mTimeSource.currentTimeMillis()); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java +1 −2 Original line number Diff line number Diff line Loading @@ -954,8 +954,7 @@ public class BubbleTransitions { mFinishCb = finishCallback; mTaskLeash = enterBubbleTask.getLeash(); mBubbleData.notificationEntryUpdated(mOpeningBubble, /* suppressFlyout= */ true, /* showInShade= */ false); mBubbleData.jumpcutBubbleSwitch(mOpeningBubble, mClosingBubble); // Keep showing the closing Bubble Task within the closing Bubble TaskView until the // opening Bubble TaskView is ready. Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java +1 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ public interface Bubbles { int DISMISS_USER_ACCOUNT_REMOVED = 16; int DISMISS_SWITCH_TO_STACK = 17; int DISMISS_USER_GESTURE_FROM_LAUNCHER = 18; int DISMISS_JUMPCUT_BUBBLE_SWITCH = 19; /** Returns a binder that can be passed to an external process to manipulate Bubbles. */ default IBubbles createExternalInterface() { Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java +33 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.wm.shell.bubbles; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.wm.shell.Flags.FLAG_ENABLE_OPTIONAL_BUBBLE_OVERFLOW; import static com.google.common.truth.Truth.assertThat; Loading @@ -25,6 +26,7 @@ import static junit.framework.Assert.assertNotNull; import static junit.framework.TestCase.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; Loading Loading @@ -1498,6 +1500,37 @@ public class BubbleDataTest extends ShellTestCase { assertThat(mBubbleData.isExpanded()).isTrue(); } @Test public void testJumpcutBubbleSwitch() { mBubbleData.setListener(mListener); mBubbleData.jumpcutBubbleSwitch(mBubbleA1, mBubbleC1); verifyUpdateReceived(); BubbleData.Update update = mUpdateCaptor.getValue(); assertThat(update.addedBubble).isEqualTo(mBubbleA1); assertThat(update.jumpcutBubbleSwitchClosingBubble).isEqualTo(mBubbleC1); assertThat(update.removedBubbles).isEmpty(); } @Test public void testToBubbleBarUpdate_suppressAnimationForJumpcutBubbleSwitch() { spyOn(mBubbleA1); doReturn(true).when(mBubbleA1).isJumpcutBubbleSwitching(); mBubbleData.setListener(mListener); mBubbleData.jumpcutBubbleSwitch(mBubbleA1, mBubbleC1); verifyUpdateReceived(); BubbleData.Update update = mUpdateCaptor.getValue(); BubbleBarUpdate bubbleBarUpdate = update.toBubbleBarUpdate(); assertThat(bubbleBarUpdate.suppressAnimation).isTrue(); assertThat(bubbleBarUpdate.removedBubbles).hasSize(1); assertThat(bubbleBarUpdate.removedBubbles.get(0).getKey()).isEqualTo(mBubbleC1.getKey()); assertThat(bubbleBarUpdate.removedBubbles.get(0).getRemovalReason()) .isEqualTo(Bubbles.DISMISS_JUMPCUT_BUBBLE_SWITCH); } private void verifyUpdateReceived() { verify(mListener).applyUpdate(mUpdateCaptor.capture()); reset(mListener); Loading