Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java +1 −1 Original line number Diff line number Diff line Loading @@ -183,7 +183,7 @@ public class PipAnimationController { return mCurrentAnimator; } PipTransitionAnimator getCurrentAnimator() { public PipTransitionAnimator getCurrentAnimator() { return mCurrentAnimator; } Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +23 −7 Original line number Diff line number Diff line Loading @@ -127,7 +127,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, private final PipBoundsAlgorithm mPipBoundsAlgorithm; private final @NonNull PipMenuController mPipMenuController; private final PipAnimationController mPipAnimationController; private final PipTransitionController mPipTransitionController; protected final PipTransitionController mPipTransitionController; protected final PipParamsChangedForwarder mPipParamsChangedForwarder; private final PipUiEventLogger mPipUiEventLoggerLogger; private final int mEnterAnimationDuration; Loading Loading @@ -196,6 +196,26 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, } }; @VisibleForTesting final PipTransitionController.PipTransitionCallback mPipTransitionCallback = new PipTransitionController.PipTransitionCallback() { @Override public void onPipTransitionStarted(int direction, Rect pipBounds) {} @Override public void onPipTransitionFinished(int direction) { // Apply the deferred RunningTaskInfo if applicable after all proper callbacks // are sent. if (direction == TRANSITION_DIRECTION_TO_PIP && mDeferredTaskInfo != null) { onTaskInfoChanged(mDeferredTaskInfo); mDeferredTaskInfo = null; } } @Override public void onPipTransitionCanceled(int direction) {} }; private final PipAnimationController.PipTransactionHandler mPipTransactionHandler = new PipAnimationController.PipTransactionHandler() { @Override Loading @@ -216,7 +236,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, private ActivityManager.RunningTaskInfo mDeferredTaskInfo; private WindowContainerToken mToken; private SurfaceControl mLeash; private PipTransitionState mPipTransitionState; protected PipTransitionState mPipTransitionState; private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS; private long mLastOneShotAlphaAnimationTime; private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory Loading Loading @@ -296,6 +316,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, mTaskOrganizer.addFocusListener(this); mPipTransitionController.setPipOrganizer(this); displayController.addDisplayWindowListener(this); pipTransitionController.registerPipTransitionCallback(mPipTransitionCallback); } public PipTransitionController getTransitionController() { Loading Loading @@ -773,11 +794,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, mPipTransitionState.setTransitionState(PipTransitionState.ENTERED_PIP); } mPipTransitionController.sendOnPipTransitionFinished(direction); // Apply the deferred RunningTaskInfo if applicable after all proper callbacks are sent. if (direction == TRANSITION_DIRECTION_TO_PIP && mDeferredTaskInfo != null) { onTaskInfoChanged(mDeferredTaskInfo); mDeferredTaskInfo = null; } } private void sendOnPipTransitionCancelled( Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java +49 −29 Original line number Diff line number Diff line Loading @@ -21,13 +21,13 @@ import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTI import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import android.app.ActivityManager; Loading Loading @@ -70,7 +70,7 @@ import java.util.Optional; @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper public class PipTaskOrganizerTest extends ShellTestCase { private PipTaskOrganizer mSpiedPipTaskOrganizer; private PipTaskOrganizer mPipTaskOrganizer; @Mock private DisplayController mMockDisplayController; @Mock private SyncTransactionQueue mMockSyncTransactionQueue; Loading Loading @@ -100,14 +100,15 @@ public class PipTaskOrganizerTest extends ShellTestCase { mPipBoundsAlgorithm = new PipBoundsAlgorithm(mContext, mPipBoundsState, new PipSnapAlgorithm()); mMainExecutor = new TestShellExecutor(); mSpiedPipTaskOrganizer = spy(new PipTaskOrganizer(mContext, mPipTaskOrganizer = new PipTaskOrganizer(mContext, mMockSyncTransactionQueue, mPipTransitionState, mPipBoundsState, mPipBoundsAlgorithm, mMockPhonePipMenuController, mMockPipAnimationController, mMockPipSurfaceTransactionHelper, mMockPipTransitionController, mMockPipParamsChangedForwarder, mMockOptionalSplitScreen, mMockDisplayController, mMockPipUiEventLogger, mMockShellTaskOrganizer, mMainExecutor)); mMockPipUiEventLogger, mMockShellTaskOrganizer, mMainExecutor); mMainExecutor.flushAll(); preparePipTaskOrg(); preparePipSurfaceTransactionHelper(); } @Test Loading @@ -124,14 +125,14 @@ public class PipTaskOrganizerTest extends ShellTestCase { public void startSwipePipToHome_updatesAspectRatio() { final Rational aspectRatio = new Rational(2, 1); mSpiedPipTaskOrganizer.startSwipePipToHome(mComponent1, null, createPipParams(aspectRatio)); mPipTaskOrganizer.startSwipePipToHome(mComponent1, null, createPipParams(aspectRatio)); assertEquals(aspectRatio.floatValue(), mPipBoundsState.getAspectRatio(), 0.01f); } @Test public void startSwipePipToHome_updatesLastPipComponentName() { mSpiedPipTaskOrganizer.startSwipePipToHome(mComponent1, null, createPipParams(null)); mPipTaskOrganizer.startSwipePipToHome(mComponent1, null, createPipParams(null)); assertEquals(mComponent1, mPipBoundsState.getLastPipComponentName()); } Loading @@ -140,7 +141,7 @@ public class PipTaskOrganizerTest extends ShellTestCase { public void startSwipePipToHome_updatesOverrideMinSize() { final Size minSize = new Size(400, 320); mSpiedPipTaskOrganizer.startSwipePipToHome(mComponent1, createActivityInfo(minSize), mPipTaskOrganizer.startSwipePipToHome(mComponent1, createActivityInfo(minSize), createPipParams(null)); assertEquals(minSize, mPipBoundsState.getOverrideMinSize()); Loading @@ -150,7 +151,7 @@ public class PipTaskOrganizerTest extends ShellTestCase { public void onTaskAppeared_updatesAspectRatio() { final Rational aspectRatio = new Rational(2, 1); mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, mPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(aspectRatio)), mock(SurfaceControl.class)); assertEquals(aspectRatio.floatValue(), mPipBoundsState.getAspectRatio(), 0.01f); Loading @@ -158,7 +159,7 @@ public class PipTaskOrganizerTest extends ShellTestCase { @Test public void onTaskAppeared_updatesLastPipComponentName() { mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(null)), mPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(null)), mock(SurfaceControl.class)); assertEquals(mComponent1, mPipBoundsState.getLastPipComponentName()); Loading @@ -168,7 +169,7 @@ public class PipTaskOrganizerTest extends ShellTestCase { public void onTaskAppeared_updatesOverrideMinSize() { final Size minSize = new Size(400, 320); mSpiedPipTaskOrganizer.onTaskAppeared( mPipTaskOrganizer.onTaskAppeared( createTaskInfo(mComponent1, createPipParams(null), minSize), mock(SurfaceControl.class)); Loading @@ -179,16 +180,16 @@ public class PipTaskOrganizerTest extends ShellTestCase { public void onTaskInfoChanged_notInPip_deferUpdatesAspectRatio() { final Rational startAspectRatio = new Rational(2, 1); final Rational newAspectRatio = new Rational(1, 2); mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, mPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(startAspectRatio)), mock(SurfaceControl.class)); // It is in entering transition, should defer onTaskInfoChanged callback in this case. mSpiedPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent1, mPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent1, createPipParams(newAspectRatio))); verify(mMockPipParamsChangedForwarder, never()).notifyAspectRatioChanged(anyFloat()); // Once the entering transition finishes, the new aspect ratio applies in a deferred manner mSpiedPipTaskOrganizer.sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); verify(mMockPipParamsChangedForwarder) .notifyAspectRatioChanged(newAspectRatio.floatValue()); } Loading @@ -197,11 +198,11 @@ public class PipTaskOrganizerTest extends ShellTestCase { public void onTaskInfoChanged_inPip_updatesAspectRatioIfChanged() { final Rational startAspectRatio = new Rational(2, 1); final Rational newAspectRatio = new Rational(1, 2); mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, mPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(startAspectRatio)), mock(SurfaceControl.class)); mSpiedPipTaskOrganizer.sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); mSpiedPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent1, mPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent1, createPipParams(newAspectRatio))); verify(mMockPipParamsChangedForwarder) Loading @@ -210,11 +211,11 @@ public class PipTaskOrganizerTest extends ShellTestCase { @Test public void onTaskInfoChanged_inPip_updatesLastPipComponentName() { mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, mPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(null)), mock(SurfaceControl.class)); mSpiedPipTaskOrganizer.sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); mSpiedPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent2, mPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent2, createPipParams(null))); assertEquals(mComponent2, mPipBoundsState.getLastPipComponentName()); Loading @@ -222,12 +223,12 @@ public class PipTaskOrganizerTest extends ShellTestCase { @Test public void onTaskInfoChanged_inPip_updatesOverrideMinSize() { mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, mPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(null)), mock(SurfaceControl.class)); mSpiedPipTaskOrganizer.sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); final Size minSize = new Size(400, 320); mSpiedPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent2, mPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent2, createPipParams(null), minSize)); assertEquals(minSize, mPipBoundsState.getOverrideMinSize()); Loading @@ -235,23 +236,42 @@ public class PipTaskOrganizerTest extends ShellTestCase { @Test public void onTaskVanished_clearsPipBounds() { mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, mPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(null)), mock(SurfaceControl.class)); mPipBoundsState.setBounds(new Rect(100, 100, 200, 150)); mSpiedPipTaskOrganizer.onTaskVanished(createTaskInfo(mComponent1, createPipParams(null))); mPipTaskOrganizer.onTaskVanished(createTaskInfo(mComponent1, createPipParams(null))); assertTrue(mPipBoundsState.getBounds().isEmpty()); } private void sendOnPipTransitionFinished( @PipAnimationController.TransitionDirection int direction) { mPipTaskOrganizer.sendOnPipTransitionFinished(direction); // PipTransitionController will call back into PipTaskOrganizer. mPipTaskOrganizer.mPipTransitionCallback.onPipTransitionFinished(direction); } private void preparePipTaskOrg() { final DisplayInfo info = new DisplayInfo(); mPipBoundsState.setDisplayLayout(new DisplayLayout(info, mContext.getResources(), true, true)); mSpiedPipTaskOrganizer.setOneShotAnimationType(PipAnimationController.ANIM_TYPE_ALPHA); mSpiedPipTaskOrganizer.setSurfaceControlTransactionFactory( mPipTaskOrganizer.setOneShotAnimationType(PipAnimationController.ANIM_TYPE_ALPHA); mPipTaskOrganizer.setSurfaceControlTransactionFactory( MockSurfaceControlHelper::createMockSurfaceControlTransaction); doNothing().when(mSpiedPipTaskOrganizer).enterPipWithAlphaAnimation(any(), anyLong()); doNothing().when(mSpiedPipTaskOrganizer).scheduleAnimateResizePip(any(), anyInt(), any()); } private void preparePipSurfaceTransactionHelper() { doReturn(mMockPipSurfaceTransactionHelper).when(mMockPipSurfaceTransactionHelper) .crop(any(), any(), any()); doReturn(mMockPipSurfaceTransactionHelper).when(mMockPipSurfaceTransactionHelper) .resetScale(any(), any(), any()); doReturn(mMockPipSurfaceTransactionHelper).when(mMockPipSurfaceTransactionHelper) .round(any(), any(), anyBoolean()); doReturn(mMockPipSurfaceTransactionHelper).when(mMockPipSurfaceTransactionHelper) .scale(any(), any(), any(), any(), anyFloat()); doReturn(mMockPipSurfaceTransactionHelper).when(mMockPipSurfaceTransactionHelper) .alpha(any(), any(), anyFloat()); doNothing().when(mMockPipSurfaceTransactionHelper).onDensityOrFontScaleChanged(any()); } private static ActivityManager.RunningTaskInfo createTaskInfo( Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java +1 −1 Original line number Diff line number Diff line Loading @@ -183,7 +183,7 @@ public class PipAnimationController { return mCurrentAnimator; } PipTransitionAnimator getCurrentAnimator() { public PipTransitionAnimator getCurrentAnimator() { return mCurrentAnimator; } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +23 −7 Original line number Diff line number Diff line Loading @@ -127,7 +127,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, private final PipBoundsAlgorithm mPipBoundsAlgorithm; private final @NonNull PipMenuController mPipMenuController; private final PipAnimationController mPipAnimationController; private final PipTransitionController mPipTransitionController; protected final PipTransitionController mPipTransitionController; protected final PipParamsChangedForwarder mPipParamsChangedForwarder; private final PipUiEventLogger mPipUiEventLoggerLogger; private final int mEnterAnimationDuration; Loading Loading @@ -196,6 +196,26 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, } }; @VisibleForTesting final PipTransitionController.PipTransitionCallback mPipTransitionCallback = new PipTransitionController.PipTransitionCallback() { @Override public void onPipTransitionStarted(int direction, Rect pipBounds) {} @Override public void onPipTransitionFinished(int direction) { // Apply the deferred RunningTaskInfo if applicable after all proper callbacks // are sent. if (direction == TRANSITION_DIRECTION_TO_PIP && mDeferredTaskInfo != null) { onTaskInfoChanged(mDeferredTaskInfo); mDeferredTaskInfo = null; } } @Override public void onPipTransitionCanceled(int direction) {} }; private final PipAnimationController.PipTransactionHandler mPipTransactionHandler = new PipAnimationController.PipTransactionHandler() { @Override Loading @@ -216,7 +236,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, private ActivityManager.RunningTaskInfo mDeferredTaskInfo; private WindowContainerToken mToken; private SurfaceControl mLeash; private PipTransitionState mPipTransitionState; protected PipTransitionState mPipTransitionState; private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS; private long mLastOneShotAlphaAnimationTime; private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory Loading Loading @@ -296,6 +316,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, mTaskOrganizer.addFocusListener(this); mPipTransitionController.setPipOrganizer(this); displayController.addDisplayWindowListener(this); pipTransitionController.registerPipTransitionCallback(mPipTransitionCallback); } public PipTransitionController getTransitionController() { Loading Loading @@ -773,11 +794,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, mPipTransitionState.setTransitionState(PipTransitionState.ENTERED_PIP); } mPipTransitionController.sendOnPipTransitionFinished(direction); // Apply the deferred RunningTaskInfo if applicable after all proper callbacks are sent. if (direction == TRANSITION_DIRECTION_TO_PIP && mDeferredTaskInfo != null) { onTaskInfoChanged(mDeferredTaskInfo); mDeferredTaskInfo = null; } } private void sendOnPipTransitionCancelled( Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java +49 −29 Original line number Diff line number Diff line Loading @@ -21,13 +21,13 @@ import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTI import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import android.app.ActivityManager; Loading Loading @@ -70,7 +70,7 @@ import java.util.Optional; @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper public class PipTaskOrganizerTest extends ShellTestCase { private PipTaskOrganizer mSpiedPipTaskOrganizer; private PipTaskOrganizer mPipTaskOrganizer; @Mock private DisplayController mMockDisplayController; @Mock private SyncTransactionQueue mMockSyncTransactionQueue; Loading Loading @@ -100,14 +100,15 @@ public class PipTaskOrganizerTest extends ShellTestCase { mPipBoundsAlgorithm = new PipBoundsAlgorithm(mContext, mPipBoundsState, new PipSnapAlgorithm()); mMainExecutor = new TestShellExecutor(); mSpiedPipTaskOrganizer = spy(new PipTaskOrganizer(mContext, mPipTaskOrganizer = new PipTaskOrganizer(mContext, mMockSyncTransactionQueue, mPipTransitionState, mPipBoundsState, mPipBoundsAlgorithm, mMockPhonePipMenuController, mMockPipAnimationController, mMockPipSurfaceTransactionHelper, mMockPipTransitionController, mMockPipParamsChangedForwarder, mMockOptionalSplitScreen, mMockDisplayController, mMockPipUiEventLogger, mMockShellTaskOrganizer, mMainExecutor)); mMockPipUiEventLogger, mMockShellTaskOrganizer, mMainExecutor); mMainExecutor.flushAll(); preparePipTaskOrg(); preparePipSurfaceTransactionHelper(); } @Test Loading @@ -124,14 +125,14 @@ public class PipTaskOrganizerTest extends ShellTestCase { public void startSwipePipToHome_updatesAspectRatio() { final Rational aspectRatio = new Rational(2, 1); mSpiedPipTaskOrganizer.startSwipePipToHome(mComponent1, null, createPipParams(aspectRatio)); mPipTaskOrganizer.startSwipePipToHome(mComponent1, null, createPipParams(aspectRatio)); assertEquals(aspectRatio.floatValue(), mPipBoundsState.getAspectRatio(), 0.01f); } @Test public void startSwipePipToHome_updatesLastPipComponentName() { mSpiedPipTaskOrganizer.startSwipePipToHome(mComponent1, null, createPipParams(null)); mPipTaskOrganizer.startSwipePipToHome(mComponent1, null, createPipParams(null)); assertEquals(mComponent1, mPipBoundsState.getLastPipComponentName()); } Loading @@ -140,7 +141,7 @@ public class PipTaskOrganizerTest extends ShellTestCase { public void startSwipePipToHome_updatesOverrideMinSize() { final Size minSize = new Size(400, 320); mSpiedPipTaskOrganizer.startSwipePipToHome(mComponent1, createActivityInfo(minSize), mPipTaskOrganizer.startSwipePipToHome(mComponent1, createActivityInfo(minSize), createPipParams(null)); assertEquals(minSize, mPipBoundsState.getOverrideMinSize()); Loading @@ -150,7 +151,7 @@ public class PipTaskOrganizerTest extends ShellTestCase { public void onTaskAppeared_updatesAspectRatio() { final Rational aspectRatio = new Rational(2, 1); mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, mPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(aspectRatio)), mock(SurfaceControl.class)); assertEquals(aspectRatio.floatValue(), mPipBoundsState.getAspectRatio(), 0.01f); Loading @@ -158,7 +159,7 @@ public class PipTaskOrganizerTest extends ShellTestCase { @Test public void onTaskAppeared_updatesLastPipComponentName() { mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(null)), mPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(null)), mock(SurfaceControl.class)); assertEquals(mComponent1, mPipBoundsState.getLastPipComponentName()); Loading @@ -168,7 +169,7 @@ public class PipTaskOrganizerTest extends ShellTestCase { public void onTaskAppeared_updatesOverrideMinSize() { final Size minSize = new Size(400, 320); mSpiedPipTaskOrganizer.onTaskAppeared( mPipTaskOrganizer.onTaskAppeared( createTaskInfo(mComponent1, createPipParams(null), minSize), mock(SurfaceControl.class)); Loading @@ -179,16 +180,16 @@ public class PipTaskOrganizerTest extends ShellTestCase { public void onTaskInfoChanged_notInPip_deferUpdatesAspectRatio() { final Rational startAspectRatio = new Rational(2, 1); final Rational newAspectRatio = new Rational(1, 2); mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, mPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(startAspectRatio)), mock(SurfaceControl.class)); // It is in entering transition, should defer onTaskInfoChanged callback in this case. mSpiedPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent1, mPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent1, createPipParams(newAspectRatio))); verify(mMockPipParamsChangedForwarder, never()).notifyAspectRatioChanged(anyFloat()); // Once the entering transition finishes, the new aspect ratio applies in a deferred manner mSpiedPipTaskOrganizer.sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); verify(mMockPipParamsChangedForwarder) .notifyAspectRatioChanged(newAspectRatio.floatValue()); } Loading @@ -197,11 +198,11 @@ public class PipTaskOrganizerTest extends ShellTestCase { public void onTaskInfoChanged_inPip_updatesAspectRatioIfChanged() { final Rational startAspectRatio = new Rational(2, 1); final Rational newAspectRatio = new Rational(1, 2); mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, mPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(startAspectRatio)), mock(SurfaceControl.class)); mSpiedPipTaskOrganizer.sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); mSpiedPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent1, mPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent1, createPipParams(newAspectRatio))); verify(mMockPipParamsChangedForwarder) Loading @@ -210,11 +211,11 @@ public class PipTaskOrganizerTest extends ShellTestCase { @Test public void onTaskInfoChanged_inPip_updatesLastPipComponentName() { mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, mPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(null)), mock(SurfaceControl.class)); mSpiedPipTaskOrganizer.sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); mSpiedPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent2, mPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent2, createPipParams(null))); assertEquals(mComponent2, mPipBoundsState.getLastPipComponentName()); Loading @@ -222,12 +223,12 @@ public class PipTaskOrganizerTest extends ShellTestCase { @Test public void onTaskInfoChanged_inPip_updatesOverrideMinSize() { mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, mPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(null)), mock(SurfaceControl.class)); mSpiedPipTaskOrganizer.sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); final Size minSize = new Size(400, 320); mSpiedPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent2, mPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent2, createPipParams(null), minSize)); assertEquals(minSize, mPipBoundsState.getOverrideMinSize()); Loading @@ -235,23 +236,42 @@ public class PipTaskOrganizerTest extends ShellTestCase { @Test public void onTaskVanished_clearsPipBounds() { mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, mPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, createPipParams(null)), mock(SurfaceControl.class)); mPipBoundsState.setBounds(new Rect(100, 100, 200, 150)); mSpiedPipTaskOrganizer.onTaskVanished(createTaskInfo(mComponent1, createPipParams(null))); mPipTaskOrganizer.onTaskVanished(createTaskInfo(mComponent1, createPipParams(null))); assertTrue(mPipBoundsState.getBounds().isEmpty()); } private void sendOnPipTransitionFinished( @PipAnimationController.TransitionDirection int direction) { mPipTaskOrganizer.sendOnPipTransitionFinished(direction); // PipTransitionController will call back into PipTaskOrganizer. mPipTaskOrganizer.mPipTransitionCallback.onPipTransitionFinished(direction); } private void preparePipTaskOrg() { final DisplayInfo info = new DisplayInfo(); mPipBoundsState.setDisplayLayout(new DisplayLayout(info, mContext.getResources(), true, true)); mSpiedPipTaskOrganizer.setOneShotAnimationType(PipAnimationController.ANIM_TYPE_ALPHA); mSpiedPipTaskOrganizer.setSurfaceControlTransactionFactory( mPipTaskOrganizer.setOneShotAnimationType(PipAnimationController.ANIM_TYPE_ALPHA); mPipTaskOrganizer.setSurfaceControlTransactionFactory( MockSurfaceControlHelper::createMockSurfaceControlTransaction); doNothing().when(mSpiedPipTaskOrganizer).enterPipWithAlphaAnimation(any(), anyLong()); doNothing().when(mSpiedPipTaskOrganizer).scheduleAnimateResizePip(any(), anyInt(), any()); } private void preparePipSurfaceTransactionHelper() { doReturn(mMockPipSurfaceTransactionHelper).when(mMockPipSurfaceTransactionHelper) .crop(any(), any(), any()); doReturn(mMockPipSurfaceTransactionHelper).when(mMockPipSurfaceTransactionHelper) .resetScale(any(), any(), any()); doReturn(mMockPipSurfaceTransactionHelper).when(mMockPipSurfaceTransactionHelper) .round(any(), any(), anyBoolean()); doReturn(mMockPipSurfaceTransactionHelper).when(mMockPipSurfaceTransactionHelper) .scale(any(), any(), any(), any(), anyFloat()); doReturn(mMockPipSurfaceTransactionHelper).when(mMockPipSurfaceTransactionHelper) .alpha(any(), any(), anyFloat()); doNothing().when(mMockPipSurfaceTransactionHelper).onDensityOrFontScaleChanged(any()); } private static ActivityManager.RunningTaskInfo createTaskInfo( Loading