Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java +1 −1 Original line number Diff line number Diff line Loading @@ -350,7 +350,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, } cancelPhysicsAnimation(); mMenuController.hideMenu(ANIM_TYPE_DISMISS, false /* resize */); mPipScheduler.removePipAfterAnimation(); mPipScheduler.scheduleRemovePip(); } /** Sets the movement bounds to use to constrain PIP position animations. */ Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +13 −21 Original line number Diff line number Diff line Loading @@ -122,34 +122,26 @@ public class PipScheduler { * Schedules exit PiP via expand transition. */ public void scheduleExitPipViaExpand() { mMainExecutor.execute(() -> { if (!mPipTransitionState.isInPip()) return; WindowContainerTransaction wct = getExitPipViaExpandTransaction(); if (wct != null) { mMainExecutor.execute(() -> { mPipTransitionController.startExitTransition(TRANSIT_EXIT_PIP, wct, null /* destinationBounds */); }); } } // TODO: Optimize this by running the animation as part of the transition /** Runs remove PiP animation and schedules remove PiP transition after the animation ends. */ public void removePipAfterAnimation() { SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); PipAlphaAnimator animator = mPipAlphaAnimatorSupplier.get(mContext, mPipTransitionState.getPinnedTaskLeash(), tx, PipAlphaAnimator.FADE_OUT); animator.setAnimationEndCallback(this::scheduleRemovePipImmediately); animator.start(); }); } /** Schedules remove PiP transition. */ private void scheduleRemovePipImmediately() { public void scheduleRemovePip() { mMainExecutor.execute(() -> { if (!mPipTransitionState.isInPip()) return; WindowContainerTransaction wct = getRemovePipTransaction(); if (wct != null) { mMainExecutor.execute(() -> { mPipTransitionController.startExitTransition(TRANSIT_REMOVE_PIP, wct, null /* destinationBounds */); }); } }); } /** Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java +11 −5 Original line number Diff line number Diff line Loading @@ -278,7 +278,8 @@ public class PipTransition extends PipTransitionController implements } if (isRemovePipTransition(info)) { return removePipImmediately(info, startTransaction, finishTransaction, finishCallback); mPipTransitionState.setState(PipTransitionState.EXITING_PIP); return startRemoveAnimation(info, startTransaction, finishTransaction, finishCallback); } return false; } Loading Loading @@ -668,13 +669,18 @@ public class PipTransition extends PipTransitionController implements return true; } private boolean removePipImmediately(@NonNull TransitionInfo info, private boolean startRemoveAnimation(@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction, @NonNull SurfaceControl.Transaction finishTransaction, @NonNull Transitions.TransitionFinishCallback finishCallback) { startTransaction.apply(); finishCallback.onTransitionFinished(null); mPipTransitionState.setState(PipTransitionState.EXITED_PIP); TransitionInfo.Change pipChange = getChangeByToken(info, mPipTransitionState.getPipTaskToken()); mFinishCallback = finishCallback; PipAlphaAnimator animator = new PipAlphaAnimator(mContext, pipChange.getLeash(), startTransaction, PipAlphaAnimator.FADE_OUT); finishTransaction.setAlpha(pipChange.getLeash(), 0f); animator.setAnimationEndCallback(this::finishTransition); animator.start(); return true; } Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java +10 −10 Original line number Diff line number Diff line Loading @@ -120,15 +120,22 @@ public class PipSchedulerTest { @Test public void scheduleExitPipViaExpand_nullTaskToken_noop() { setNullPipTaskToken(); when(mMockPipTransitionState.isInPip()).thenReturn(true); mPipScheduler.scheduleExitPipViaExpand(); verify(mMockMainExecutor, never()).execute(any()); verify(mMockMainExecutor, times(1)).execute(mRunnableArgumentCaptor.capture()); assertNotNull(mRunnableArgumentCaptor.getValue()); mRunnableArgumentCaptor.getValue().run(); verify(mMockPipTransitionController, never()) .startExitTransition(eq(TRANSIT_EXIT_PIP), any(), isNull()); } @Test public void scheduleExitPipViaExpand_exitTransitionCalled() { setMockPipTaskToken(); when(mMockPipTransitionState.isInPip()).thenReturn(true); mPipScheduler.scheduleExitPipViaExpand(); Loading @@ -142,20 +149,13 @@ public class PipSchedulerTest { @Test public void removePipAfterAnimation() { //TODO: Update once this is changed to run animation as part of transition setMockPipTaskToken(); when(mMockPipTransitionState.isInPip()).thenReturn(true); mPipScheduler.removePipAfterAnimation(); verify(mMockAlphaAnimator, times(1)) .setAnimationEndCallback(mRunnableArgumentCaptor.capture()); assertNotNull(mRunnableArgumentCaptor.getValue()); verify(mMockAlphaAnimator, times(1)).start(); mRunnableArgumentCaptor.getValue().run(); mPipScheduler.scheduleRemovePip(); verify(mMockMainExecutor, times(1)).execute(mRunnableArgumentCaptor.capture()); assertNotNull(mRunnableArgumentCaptor.getValue()); mRunnableArgumentCaptor.getValue().run(); verify(mMockPipTransitionController, times(1)) Loading services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +3 −2 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLAS import static com.android.server.wm.ActivityTaskManagerService.ANIMATE; import static com.android.server.wm.ActivityTaskManagerService.H.FIRST_SUPERVISOR_TASK_MSG; import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE; import static com.android.server.wm.ActivityTaskManagerService.isPip2ExperimentEnabled; import static com.android.server.wm.ClientLifecycleManager.shouldDispatchLaunchActivityItemIndependently; import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_ALLOWLISTED; import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_LAUNCHABLE; Loading Loading @@ -2525,7 +2526,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { void scheduleUpdatePictureInPictureModeIfNeeded(Task task, Rect targetRootTaskBounds) { task.forAllActivities(r -> { if (!r.attachedToProcess()) return; mPipModeChangedActivities.add(r); if (!isPip2ExperimentEnabled()) mPipModeChangedActivities.add(r); // If we are scheduling pip change, then remove this activity from multi-window // change list as the processing of pip change will make sure multi-window changed // message is processed in the right order relative to pip changed. Loading @@ -2534,7 +2535,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { mPipModeChangedTargetRootTaskBounds = targetRootTaskBounds; if (!mHandler.hasMessages(REPORT_PIP_MODE_CHANGED_MSG)) { if (!isPip2ExperimentEnabled() && !mHandler.hasMessages(REPORT_PIP_MODE_CHANGED_MSG)) { mHandler.sendEmptyMessage(REPORT_PIP_MODE_CHANGED_MSG); } } Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java +1 −1 Original line number Diff line number Diff line Loading @@ -350,7 +350,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, } cancelPhysicsAnimation(); mMenuController.hideMenu(ANIM_TYPE_DISMISS, false /* resize */); mPipScheduler.removePipAfterAnimation(); mPipScheduler.scheduleRemovePip(); } /** Sets the movement bounds to use to constrain PIP position animations. */ Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +13 −21 Original line number Diff line number Diff line Loading @@ -122,34 +122,26 @@ public class PipScheduler { * Schedules exit PiP via expand transition. */ public void scheduleExitPipViaExpand() { mMainExecutor.execute(() -> { if (!mPipTransitionState.isInPip()) return; WindowContainerTransaction wct = getExitPipViaExpandTransaction(); if (wct != null) { mMainExecutor.execute(() -> { mPipTransitionController.startExitTransition(TRANSIT_EXIT_PIP, wct, null /* destinationBounds */); }); } } // TODO: Optimize this by running the animation as part of the transition /** Runs remove PiP animation and schedules remove PiP transition after the animation ends. */ public void removePipAfterAnimation() { SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); PipAlphaAnimator animator = mPipAlphaAnimatorSupplier.get(mContext, mPipTransitionState.getPinnedTaskLeash(), tx, PipAlphaAnimator.FADE_OUT); animator.setAnimationEndCallback(this::scheduleRemovePipImmediately); animator.start(); }); } /** Schedules remove PiP transition. */ private void scheduleRemovePipImmediately() { public void scheduleRemovePip() { mMainExecutor.execute(() -> { if (!mPipTransitionState.isInPip()) return; WindowContainerTransaction wct = getRemovePipTransaction(); if (wct != null) { mMainExecutor.execute(() -> { mPipTransitionController.startExitTransition(TRANSIT_REMOVE_PIP, wct, null /* destinationBounds */); }); } }); } /** Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java +11 −5 Original line number Diff line number Diff line Loading @@ -278,7 +278,8 @@ public class PipTransition extends PipTransitionController implements } if (isRemovePipTransition(info)) { return removePipImmediately(info, startTransaction, finishTransaction, finishCallback); mPipTransitionState.setState(PipTransitionState.EXITING_PIP); return startRemoveAnimation(info, startTransaction, finishTransaction, finishCallback); } return false; } Loading Loading @@ -668,13 +669,18 @@ public class PipTransition extends PipTransitionController implements return true; } private boolean removePipImmediately(@NonNull TransitionInfo info, private boolean startRemoveAnimation(@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction, @NonNull SurfaceControl.Transaction finishTransaction, @NonNull Transitions.TransitionFinishCallback finishCallback) { startTransaction.apply(); finishCallback.onTransitionFinished(null); mPipTransitionState.setState(PipTransitionState.EXITED_PIP); TransitionInfo.Change pipChange = getChangeByToken(info, mPipTransitionState.getPipTaskToken()); mFinishCallback = finishCallback; PipAlphaAnimator animator = new PipAlphaAnimator(mContext, pipChange.getLeash(), startTransaction, PipAlphaAnimator.FADE_OUT); finishTransaction.setAlpha(pipChange.getLeash(), 0f); animator.setAnimationEndCallback(this::finishTransition); animator.start(); return true; } Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipSchedulerTest.java +10 −10 Original line number Diff line number Diff line Loading @@ -120,15 +120,22 @@ public class PipSchedulerTest { @Test public void scheduleExitPipViaExpand_nullTaskToken_noop() { setNullPipTaskToken(); when(mMockPipTransitionState.isInPip()).thenReturn(true); mPipScheduler.scheduleExitPipViaExpand(); verify(mMockMainExecutor, never()).execute(any()); verify(mMockMainExecutor, times(1)).execute(mRunnableArgumentCaptor.capture()); assertNotNull(mRunnableArgumentCaptor.getValue()); mRunnableArgumentCaptor.getValue().run(); verify(mMockPipTransitionController, never()) .startExitTransition(eq(TRANSIT_EXIT_PIP), any(), isNull()); } @Test public void scheduleExitPipViaExpand_exitTransitionCalled() { setMockPipTaskToken(); when(mMockPipTransitionState.isInPip()).thenReturn(true); mPipScheduler.scheduleExitPipViaExpand(); Loading @@ -142,20 +149,13 @@ public class PipSchedulerTest { @Test public void removePipAfterAnimation() { //TODO: Update once this is changed to run animation as part of transition setMockPipTaskToken(); when(mMockPipTransitionState.isInPip()).thenReturn(true); mPipScheduler.removePipAfterAnimation(); verify(mMockAlphaAnimator, times(1)) .setAnimationEndCallback(mRunnableArgumentCaptor.capture()); assertNotNull(mRunnableArgumentCaptor.getValue()); verify(mMockAlphaAnimator, times(1)).start(); mRunnableArgumentCaptor.getValue().run(); mPipScheduler.scheduleRemovePip(); verify(mMockMainExecutor, times(1)).execute(mRunnableArgumentCaptor.capture()); assertNotNull(mRunnableArgumentCaptor.getValue()); mRunnableArgumentCaptor.getValue().run(); verify(mMockPipTransitionController, times(1)) Loading
services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +3 −2 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLAS import static com.android.server.wm.ActivityTaskManagerService.ANIMATE; import static com.android.server.wm.ActivityTaskManagerService.H.FIRST_SUPERVISOR_TASK_MSG; import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE; import static com.android.server.wm.ActivityTaskManagerService.isPip2ExperimentEnabled; import static com.android.server.wm.ClientLifecycleManager.shouldDispatchLaunchActivityItemIndependently; import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_ALLOWLISTED; import static com.android.server.wm.LockTaskController.LOCK_TASK_AUTH_LAUNCHABLE; Loading Loading @@ -2525,7 +2526,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { void scheduleUpdatePictureInPictureModeIfNeeded(Task task, Rect targetRootTaskBounds) { task.forAllActivities(r -> { if (!r.attachedToProcess()) return; mPipModeChangedActivities.add(r); if (!isPip2ExperimentEnabled()) mPipModeChangedActivities.add(r); // If we are scheduling pip change, then remove this activity from multi-window // change list as the processing of pip change will make sure multi-window changed // message is processed in the right order relative to pip changed. Loading @@ -2534,7 +2535,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { mPipModeChangedTargetRootTaskBounds = targetRootTaskBounds; if (!mHandler.hasMessages(REPORT_PIP_MODE_CHANGED_MSG)) { if (!isPip2ExperimentEnabled() && !mHandler.hasMessages(REPORT_PIP_MODE_CHANGED_MSG)) { mHandler.sendEmptyMessage(REPORT_PIP_MODE_CHANGED_MSG); } } Loading