Loading libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelperTest.kt +52 −6 Original line number Diff line number Diff line Loading @@ -77,6 +77,14 @@ class BubbleBarAnimationHelperTest { companion object { const val SCREEN_WIDTH = 2000 const val SCREEN_HEIGHT = 1000 val isRobolectricTest by lazy { try { Class.forName("org.robolectric.Robolectric") true } catch (e: ClassNotFoundException) { false } } } private val context = ApplicationProvider.getApplicationContext<Context>() Loading Loading @@ -114,7 +122,7 @@ class BubbleBarAnimationHelperTest { mainExecutor = TestShellExecutor() bgExecutor = TestShellExecutor() animationHelper = BubbleBarAnimationHelper(context, bubblePositioner) animationHelper = BubbleBarAnimationHelper(context, bubblePositioner, mainExecutor) } @After Loading @@ -132,7 +140,8 @@ class BubbleBarAnimationHelperTest { val after = Runnable { semaphore.release() } activityScenario.onActivity { animationHelper.animateSwitch(fromBubble, toBubble, after) animationHelper.animateSwitch(fromBubble, toBubble, /* shouldApplyAsJumpcut= */ false, after) animatorTestRule.advanceTimeBy(1000) } getInstrumentation().waitForIdleSync() Loading @@ -147,6 +156,40 @@ class BubbleBarAnimationHelperTest { assertThat(toBubble.bubbleBarExpandedView?.isSurfaceZOrderedOnTop).isFalse() } @Test fun animateSwitch_bubbleToBubble_oldHiddenNewShown_applyAsJumpcut() { val fromBubble = createBubble(key = "from").initialize(container) val toBubble = createBubble(key = "to").initialize(container) val semaphore = Semaphore(0) val after = Runnable { semaphore.release() } activityScenario.onActivity { animationHelper.animateSwitch(fromBubble, toBubble, /* shouldApplyAsJumpcut= */ true, after) } getInstrumentation().waitForIdleSync() if (!isRobolectricTest) { // The endRunnable is on TransactionCommittedListener, which won't be trigger with the // shadow implementation of SurfaceControl. // Wait for surface transaction applied. getInstrumentation().getUiAutomation().syncInputTransactions() mainExecutor.flushAll() assertThat(semaphore.tryAcquire()).isTrue() } assertThat(fromBubble.bubbleBarExpandedView?.visibility).isEqualTo(View.INVISIBLE) assertThat(fromBubble.bubbleBarExpandedView?.alpha).isEqualTo(0f) assertThat(fromBubble.bubbleBarExpandedView?.isSurfaceZOrderedOnTop).isFalse() assertThat(toBubble.bubbleBarExpandedView?.visibility).isEqualTo(View.VISIBLE) assertThat(toBubble.bubbleBarExpandedView?.alpha).isEqualTo(1f) assertThat(toBubble.bubbleBarExpandedView?.isSurfaceZOrderedOnTop).isFalse() } @Test fun animateSwitch_bubbleToBubble_handleColorTransferred() { val fromBubble = createBubble(key = "from").initialize(container) Loading @@ -159,7 +202,8 @@ class BubbleBarAnimationHelperTest { val toBubble = createBubble(key = "to").initialize(container) activityScenario.onActivity { animationHelper.animateSwitch(fromBubble, toBubble, /* afterAnimation= */ null) animationHelper.animateSwitch(fromBubble, toBubble, /* shouldApplyAsJumpcut= */ false, /* afterAnimation= */ null) animatorTestRule.advanceTimeBy(1000) } getInstrumentation().waitForIdleSync() Loading @@ -177,7 +221,7 @@ class BubbleBarAnimationHelperTest { container) activityScenario.onActivity { animationHelper.animateSwitch(fromBubble, toBubble) {} animationHelper.animateSwitch(fromBubble, toBubble, /* shouldApplyAsJumpcut= */ false) {} // Start the animation, but don't finish animatorTestRule.advanceTimeBy(100) } Loading @@ -199,7 +243,8 @@ class BubbleBarAnimationHelperTest { val after = Runnable { semaphore.release() } activityScenario.onActivity { animationHelper.animateSwitch(fromBubble, overflow, after) animationHelper.animateSwitch(fromBubble, overflow, /* shouldApplyAsJumpcut= */ false, after) animatorTestRule.advanceTimeBy(1000) } getInstrumentation().waitForIdleSync() Loading @@ -222,7 +267,8 @@ class BubbleBarAnimationHelperTest { val after = Runnable { semaphore.release() } activityScenario.onActivity { animationHelper.animateSwitch(overflow, toBubble, after) animationHelper.animateSwitch(overflow, toBubble, /* shouldApplyAsJumpcut= */ false, after) animatorTestRule.advanceTimeBy(1000) } getInstrumentation().waitForIdleSync() Loading libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt +2 −1 Original line number Diff line number Diff line Loading @@ -180,7 +180,8 @@ class BubbleBarLayerViewTest { // Flush so that proxy gets set mainExecutor.flushAll() bubbleBarLayerView = BubbleBarLayerView(context, bubbleController, bubbleData, bubbleLogger) bubbleBarLayerView = BubbleBarLayerView(context, bubbleController, bubbleData, bubbleLogger, mainExecutor) expandedViewManager = FakeBubbleExpandedViewManager(bubbleBar = true, expanded = true) } Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java +6 −0 Original line number Diff line number Diff line Loading @@ -719,6 +719,12 @@ public class Bubble implements BubbleViewProvider { && getPreparingTransition().isConvertingBubbleToBar(); } /** Whether this bubble is currently switching to expanded from another bubble using jumpcut. */ public boolean isJumpcutBubbleSwitching() { return getPreparingTransition() != null && getPreparingTransition().isJumpcutBubbleSwitching(); } /** * Sets whether this bubble is considered text changed. This method is purely for * testing. Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +9 −3 Original line number Diff line number Diff line Loading @@ -1083,7 +1083,8 @@ public class BubbleController implements ConfigurationChangeListener, // window to show this in, but we use a separate code path. // TODO(b/273312602): consider foldables where we do need a stack view when folded if (mLayerView == null) { mLayerView = new BubbleBarLayerView(mContext, this, mBubbleData, mLogger); mLayerView = new BubbleBarLayerView(mContext, this, mBubbleData, mLogger, mMainExecutor); mLayerView.setUnBubbleConversationCallback(mSysuiProxy::onUnbubbleConversation); } } else { Loading Loading @@ -2676,9 +2677,14 @@ public class BubbleController implements ConfigurationChangeListener, public void selectionChanged(BubbleViewProvider selectedBubble) { // Only need to update the layer view if we're currently expanded for selection changes. if (mLayerView != null && mLayerView.isExpanded()) { final Bubble b = (selectedBubble instanceof Bubble bubble) ? bubble : null; if (b == null || !b.isJumpcutBubbleSwitching()) { // Otherwise the animation will be called by the TransitionHandler when ready to // play. mLayerView.showExpandedView(selectedBubble); } if (selectedBubble instanceof Bubble) { if (b != null) { mLogger.log((Bubble) selectedBubble, BubbleLogger.Event.BUBBLE_BAR_BUBBLE_SWITCHED); } Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java +4 −0 Original line number Diff line number Diff line Loading @@ -445,6 +445,10 @@ public class BubbleTransitions { default boolean isConvertingBubbleToBar() { return (this instanceof FloatingToBarConversion); } /** Whether this transition is for switching from one bubble to another using jumpcut. */ default boolean isJumpcutBubbleSwitching() { return (this instanceof JumpcutBubbleSwitchTransition); } } /** Loading Loading
libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelperTest.kt +52 −6 Original line number Diff line number Diff line Loading @@ -77,6 +77,14 @@ class BubbleBarAnimationHelperTest { companion object { const val SCREEN_WIDTH = 2000 const val SCREEN_HEIGHT = 1000 val isRobolectricTest by lazy { try { Class.forName("org.robolectric.Robolectric") true } catch (e: ClassNotFoundException) { false } } } private val context = ApplicationProvider.getApplicationContext<Context>() Loading Loading @@ -114,7 +122,7 @@ class BubbleBarAnimationHelperTest { mainExecutor = TestShellExecutor() bgExecutor = TestShellExecutor() animationHelper = BubbleBarAnimationHelper(context, bubblePositioner) animationHelper = BubbleBarAnimationHelper(context, bubblePositioner, mainExecutor) } @After Loading @@ -132,7 +140,8 @@ class BubbleBarAnimationHelperTest { val after = Runnable { semaphore.release() } activityScenario.onActivity { animationHelper.animateSwitch(fromBubble, toBubble, after) animationHelper.animateSwitch(fromBubble, toBubble, /* shouldApplyAsJumpcut= */ false, after) animatorTestRule.advanceTimeBy(1000) } getInstrumentation().waitForIdleSync() Loading @@ -147,6 +156,40 @@ class BubbleBarAnimationHelperTest { assertThat(toBubble.bubbleBarExpandedView?.isSurfaceZOrderedOnTop).isFalse() } @Test fun animateSwitch_bubbleToBubble_oldHiddenNewShown_applyAsJumpcut() { val fromBubble = createBubble(key = "from").initialize(container) val toBubble = createBubble(key = "to").initialize(container) val semaphore = Semaphore(0) val after = Runnable { semaphore.release() } activityScenario.onActivity { animationHelper.animateSwitch(fromBubble, toBubble, /* shouldApplyAsJumpcut= */ true, after) } getInstrumentation().waitForIdleSync() if (!isRobolectricTest) { // The endRunnable is on TransactionCommittedListener, which won't be trigger with the // shadow implementation of SurfaceControl. // Wait for surface transaction applied. getInstrumentation().getUiAutomation().syncInputTransactions() mainExecutor.flushAll() assertThat(semaphore.tryAcquire()).isTrue() } assertThat(fromBubble.bubbleBarExpandedView?.visibility).isEqualTo(View.INVISIBLE) assertThat(fromBubble.bubbleBarExpandedView?.alpha).isEqualTo(0f) assertThat(fromBubble.bubbleBarExpandedView?.isSurfaceZOrderedOnTop).isFalse() assertThat(toBubble.bubbleBarExpandedView?.visibility).isEqualTo(View.VISIBLE) assertThat(toBubble.bubbleBarExpandedView?.alpha).isEqualTo(1f) assertThat(toBubble.bubbleBarExpandedView?.isSurfaceZOrderedOnTop).isFalse() } @Test fun animateSwitch_bubbleToBubble_handleColorTransferred() { val fromBubble = createBubble(key = "from").initialize(container) Loading @@ -159,7 +202,8 @@ class BubbleBarAnimationHelperTest { val toBubble = createBubble(key = "to").initialize(container) activityScenario.onActivity { animationHelper.animateSwitch(fromBubble, toBubble, /* afterAnimation= */ null) animationHelper.animateSwitch(fromBubble, toBubble, /* shouldApplyAsJumpcut= */ false, /* afterAnimation= */ null) animatorTestRule.advanceTimeBy(1000) } getInstrumentation().waitForIdleSync() Loading @@ -177,7 +221,7 @@ class BubbleBarAnimationHelperTest { container) activityScenario.onActivity { animationHelper.animateSwitch(fromBubble, toBubble) {} animationHelper.animateSwitch(fromBubble, toBubble, /* shouldApplyAsJumpcut= */ false) {} // Start the animation, but don't finish animatorTestRule.advanceTimeBy(100) } Loading @@ -199,7 +243,8 @@ class BubbleBarAnimationHelperTest { val after = Runnable { semaphore.release() } activityScenario.onActivity { animationHelper.animateSwitch(fromBubble, overflow, after) animationHelper.animateSwitch(fromBubble, overflow, /* shouldApplyAsJumpcut= */ false, after) animatorTestRule.advanceTimeBy(1000) } getInstrumentation().waitForIdleSync() Loading @@ -222,7 +267,8 @@ class BubbleBarAnimationHelperTest { val after = Runnable { semaphore.release() } activityScenario.onActivity { animationHelper.animateSwitch(overflow, toBubble, after) animationHelper.animateSwitch(overflow, toBubble, /* shouldApplyAsJumpcut= */ false, after) animatorTestRule.advanceTimeBy(1000) } getInstrumentation().waitForIdleSync() Loading
libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt +2 −1 Original line number Diff line number Diff line Loading @@ -180,7 +180,8 @@ class BubbleBarLayerViewTest { // Flush so that proxy gets set mainExecutor.flushAll() bubbleBarLayerView = BubbleBarLayerView(context, bubbleController, bubbleData, bubbleLogger) bubbleBarLayerView = BubbleBarLayerView(context, bubbleController, bubbleData, bubbleLogger, mainExecutor) expandedViewManager = FakeBubbleExpandedViewManager(bubbleBar = true, expanded = true) } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java +6 −0 Original line number Diff line number Diff line Loading @@ -719,6 +719,12 @@ public class Bubble implements BubbleViewProvider { && getPreparingTransition().isConvertingBubbleToBar(); } /** Whether this bubble is currently switching to expanded from another bubble using jumpcut. */ public boolean isJumpcutBubbleSwitching() { return getPreparingTransition() != null && getPreparingTransition().isJumpcutBubbleSwitching(); } /** * Sets whether this bubble is considered text changed. This method is purely for * testing. Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +9 −3 Original line number Diff line number Diff line Loading @@ -1083,7 +1083,8 @@ public class BubbleController implements ConfigurationChangeListener, // window to show this in, but we use a separate code path. // TODO(b/273312602): consider foldables where we do need a stack view when folded if (mLayerView == null) { mLayerView = new BubbleBarLayerView(mContext, this, mBubbleData, mLogger); mLayerView = new BubbleBarLayerView(mContext, this, mBubbleData, mLogger, mMainExecutor); mLayerView.setUnBubbleConversationCallback(mSysuiProxy::onUnbubbleConversation); } } else { Loading Loading @@ -2676,9 +2677,14 @@ public class BubbleController implements ConfigurationChangeListener, public void selectionChanged(BubbleViewProvider selectedBubble) { // Only need to update the layer view if we're currently expanded for selection changes. if (mLayerView != null && mLayerView.isExpanded()) { final Bubble b = (selectedBubble instanceof Bubble bubble) ? bubble : null; if (b == null || !b.isJumpcutBubbleSwitching()) { // Otherwise the animation will be called by the TransitionHandler when ready to // play. mLayerView.showExpandedView(selectedBubble); } if (selectedBubble instanceof Bubble) { if (b != null) { mLogger.log((Bubble) selectedBubble, BubbleLogger.Event.BUBBLE_BAR_BUBBLE_SWITCHED); } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java +4 −0 Original line number Diff line number Diff line Loading @@ -445,6 +445,10 @@ public class BubbleTransitions { default boolean isConvertingBubbleToBar() { return (this instanceof FloatingToBarConversion); } /** Whether this transition is for switching from one bubble to another using jumpcut. */ default boolean isJumpcutBubbleSwitching() { return (this instanceof JumpcutBubbleSwitchTransition); } } /** Loading