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.scheduleRemovePip(); mPipScheduler.removePipAfterAnimation(); } /** Sets the movement bounds to use to constrain PIP position animations. */ Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +21 −13 Original line number Diff line number Diff line Loading @@ -122,27 +122,35 @@ 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. */ public void scheduleRemovePip() { mMainExecutor.execute(() -> { if (!mPipTransitionState.isInPip()) return; private void scheduleRemovePipImmediately() { WindowContainerTransaction wct = getRemovePipTransaction(); if (wct != null) { mMainExecutor.execute(() -> { mPipTransitionController.startExitTransition(TRANSIT_REMOVE_PIP, wct, null /* destinationBounds */); } }); } } /** * Animates resizing of the pinned stack given the duration. Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java +5 −11 Original line number Diff line number Diff line Loading @@ -276,8 +276,7 @@ public class PipTransition extends PipTransitionController implements } if (isRemovePipTransition(info)) { mPipTransitionState.setState(PipTransitionState.EXITING_PIP); return startRemoveAnimation(info, startTransaction, finishTransaction, finishCallback); return removePipImmediately(info, startTransaction, finishTransaction, finishCallback); } return false; } Loading Loading @@ -667,18 +666,13 @@ public class PipTransition extends PipTransitionController implements return true; } private boolean startRemoveAnimation(@NonNull TransitionInfo info, private boolean removePipImmediately(@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction, @NonNull SurfaceControl.Transaction finishTransaction, @NonNull Transitions.TransitionFinishCallback finishCallback) { 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(); startTransaction.apply(); finishCallback.onTransitionFinished(null); mPipTransitionState.setState(PipTransitionState.EXITED_PIP); 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,22 +120,15 @@ public class PipSchedulerTest { @Test public void scheduleExitPipViaExpand_nullTaskToken_noop() { setNullPipTaskToken(); when(mMockPipTransitionState.isInPip()).thenReturn(true); mPipScheduler.scheduleExitPipViaExpand(); verify(mMockMainExecutor, times(1)).execute(mRunnableArgumentCaptor.capture()); assertNotNull(mRunnableArgumentCaptor.getValue()); mRunnableArgumentCaptor.getValue().run(); verify(mMockPipTransitionController, never()) .startExitTransition(eq(TRANSIT_EXIT_PIP), any(), isNull()); verify(mMockMainExecutor, never()).execute(any()); } @Test public void scheduleExitPipViaExpand_exitTransitionCalled() { setMockPipTaskToken(); when(mMockPipTransitionState.isInPip()).thenReturn(true); mPipScheduler.scheduleExitPipViaExpand(); Loading @@ -149,13 +142,20 @@ 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.scheduleRemovePip(); mPipScheduler.removePipAfterAnimation(); verify(mMockAlphaAnimator, times(1)) .setAnimationEndCallback(mRunnableArgumentCaptor.capture()); assertNotNull(mRunnableArgumentCaptor.getValue()); verify(mMockAlphaAnimator, times(1)).start(); mRunnableArgumentCaptor.getValue().run(); 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 +2 −3 Original line number Diff line number Diff line Loading @@ -76,7 +76,6 @@ 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 @@ -2524,7 +2523,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { void scheduleUpdatePictureInPictureModeIfNeeded(Task task, Rect targetRootTaskBounds) { task.forAllActivities(r -> { if (!r.attachedToProcess()) return; if (!isPip2ExperimentEnabled()) mPipModeChangedActivities.add(r); 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 @@ -2533,7 +2532,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { mPipModeChangedTargetRootTaskBounds = targetRootTaskBounds; if (!isPip2ExperimentEnabled() && !mHandler.hasMessages(REPORT_PIP_MODE_CHANGED_MSG)) { if (!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.scheduleRemovePip(); mPipScheduler.removePipAfterAnimation(); } /** Sets the movement bounds to use to constrain PIP position animations. */ Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +21 −13 Original line number Diff line number Diff line Loading @@ -122,27 +122,35 @@ 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. */ public void scheduleRemovePip() { mMainExecutor.execute(() -> { if (!mPipTransitionState.isInPip()) return; private void scheduleRemovePipImmediately() { WindowContainerTransaction wct = getRemovePipTransaction(); if (wct != null) { mMainExecutor.execute(() -> { mPipTransitionController.startExitTransition(TRANSIT_REMOVE_PIP, wct, null /* destinationBounds */); } }); } } /** * Animates resizing of the pinned stack given the duration. Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java +5 −11 Original line number Diff line number Diff line Loading @@ -276,8 +276,7 @@ public class PipTransition extends PipTransitionController implements } if (isRemovePipTransition(info)) { mPipTransitionState.setState(PipTransitionState.EXITING_PIP); return startRemoveAnimation(info, startTransaction, finishTransaction, finishCallback); return removePipImmediately(info, startTransaction, finishTransaction, finishCallback); } return false; } Loading Loading @@ -667,18 +666,13 @@ public class PipTransition extends PipTransitionController implements return true; } private boolean startRemoveAnimation(@NonNull TransitionInfo info, private boolean removePipImmediately(@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction, @NonNull SurfaceControl.Transaction finishTransaction, @NonNull Transitions.TransitionFinishCallback finishCallback) { 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(); startTransaction.apply(); finishCallback.onTransitionFinished(null); mPipTransitionState.setState(PipTransitionState.EXITED_PIP); 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,22 +120,15 @@ public class PipSchedulerTest { @Test public void scheduleExitPipViaExpand_nullTaskToken_noop() { setNullPipTaskToken(); when(mMockPipTransitionState.isInPip()).thenReturn(true); mPipScheduler.scheduleExitPipViaExpand(); verify(mMockMainExecutor, times(1)).execute(mRunnableArgumentCaptor.capture()); assertNotNull(mRunnableArgumentCaptor.getValue()); mRunnableArgumentCaptor.getValue().run(); verify(mMockPipTransitionController, never()) .startExitTransition(eq(TRANSIT_EXIT_PIP), any(), isNull()); verify(mMockMainExecutor, never()).execute(any()); } @Test public void scheduleExitPipViaExpand_exitTransitionCalled() { setMockPipTaskToken(); when(mMockPipTransitionState.isInPip()).thenReturn(true); mPipScheduler.scheduleExitPipViaExpand(); Loading @@ -149,13 +142,20 @@ 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.scheduleRemovePip(); mPipScheduler.removePipAfterAnimation(); verify(mMockAlphaAnimator, times(1)) .setAnimationEndCallback(mRunnableArgumentCaptor.capture()); assertNotNull(mRunnableArgumentCaptor.getValue()); verify(mMockAlphaAnimator, times(1)).start(); mRunnableArgumentCaptor.getValue().run(); 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 +2 −3 Original line number Diff line number Diff line Loading @@ -76,7 +76,6 @@ 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 @@ -2524,7 +2523,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { void scheduleUpdatePictureInPictureModeIfNeeded(Task task, Rect targetRootTaskBounds) { task.forAllActivities(r -> { if (!r.attachedToProcess()) return; if (!isPip2ExperimentEnabled()) mPipModeChangedActivities.add(r); 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 @@ -2533,7 +2532,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { mPipModeChangedTargetRootTaskBounds = targetRootTaskBounds; if (!isPip2ExperimentEnabled() && !mHandler.hasMessages(REPORT_PIP_MODE_CHANGED_MSG)) { if (!mHandler.hasMessages(REPORT_PIP_MODE_CHANGED_MSG)) { mHandler.sendEmptyMessage(REPORT_PIP_MODE_CHANGED_MSG); } } Loading