Loading libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java +17 −5 Original line number Diff line number Diff line Loading @@ -222,7 +222,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, RecentsMixedHandler mixer = null; Consumer<IBinder> setTransitionForMixer = null; for (int i = 0; i < mMixers.size(); ++i) { setTransitionForMixer = mMixers.get(i).handleRecentsRequest(wct); setTransitionForMixer = mMixers.get(i).handleRecentsRequest(); if (setTransitionForMixer != null) { mixer = mMixers.get(i); break; Loading Loading @@ -1455,6 +1455,11 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, } } // Notify the mixers of the pending finish for (int i = 0; i < mMixers.size(); ++i) { mMixers.get(i).handleFinishRecents(returningToApp, wct, t); } if (Flags.enableRecentsBookendTransition()) { if (!wct.isEmpty()) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, Loading Loading @@ -1653,15 +1658,22 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, */ public interface RecentsMixedHandler extends Transitions.TransitionHandler { /** * Called when a recents request comes in. The handler can add operations to outWCT. If * the handler wants to "accept" the transition, it should return a Consumer accepting the * IBinder for the transition. If not, it should return `null`. * Called when a recents request comes in. If the handler wants to "accept" the transition, * it should return a Consumer accepting the IBinder for the transition. If not, it should * return `null`. * * If a mixed-handler accepts this recents, it will be the de-facto handler for this * transition and is required to call the associated {@link #startAnimation}, * {@link #mergeAnimation}, and {@link #onTransitionConsumed} methods. */ @Nullable Consumer<IBinder> handleRecentsRequest(WindowContainerTransaction outWCT); Consumer<IBinder> handleRecentsRequest(); /** * Called when a recents transition has finished, with a WCT and SurfaceControl Transaction * that can be used to add to any changes needed to restore the state. */ void handleFinishRecents(boolean returnToApp, @NonNull WindowContainerTransaction finishWct, @NonNull SurfaceControl.Transaction finishT); } } libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +41 −9 Original line number Diff line number Diff line Loading @@ -129,6 +129,7 @@ import com.android.internal.logging.InstanceId; import com.android.internal.policy.FoldLockSettingsObserver; import com.android.internal.protolog.ProtoLog; import com.android.launcher3.icons.IconProvider; import com.android.wm.shell.Flags; import com.android.wm.shell.R; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; Loading Loading @@ -3766,13 +3767,31 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, mTaskOrganizer.applyTransaction(wct); } public void onRecentsInSplitAnimationFinishing(boolean returnToApp, @NonNull WindowContainerTransaction finishWct, @NonNull SurfaceControl.Transaction finishT) { if (!Flags.enableRecentsBookendTransition()) { // The non-bookend recents transition case will be handled by // RecentsMixedTransition wrapping the finish callback and calling // onRecentsInSplitAnimationFinish() return; } onRecentsInSplitAnimationFinishInner(returnToApp, finishWct, finishT); } /** Call this when the recents animation during split-screen finishes. */ public void onRecentsInSplitAnimationFinish(WindowContainerTransaction finishWct, SurfaceControl.Transaction finishT) { ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onRecentsInSplitAnimationFinish"); mPausingTasks.clear(); public void onRecentsInSplitAnimationFinish(@NonNull WindowContainerTransaction finishWct, @NonNull SurfaceControl.Transaction finishT) { if (Flags.enableRecentsBookendTransition()) { // The bookend recents transition case will be handled by // onRecentsInSplitAnimationFinishing above return; } // Check if the recent transition is finished by returning to the current // split, so we can restore the divider bar. boolean returnToApp = false; for (int i = 0; i < finishWct.getHierarchyOps().size(); ++i) { final WindowContainerTransaction.HierarchyOp op = finishWct.getHierarchyOps().get(i); Loading @@ -3787,13 +3806,26 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } if (op.getType() == HIERARCHY_OP_TYPE_REORDER && op.getToTop() && anyStageContainsContainer) { returnToApp = true; } } onRecentsInSplitAnimationFinishInner(returnToApp, finishWct, finishT); } /** Call this when the recents animation during split-screen finishes. */ public void onRecentsInSplitAnimationFinishInner(boolean returnToApp, @NonNull WindowContainerTransaction finishWct, @NonNull SurfaceControl.Transaction finishT) { ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onRecentsInSplitAnimationFinish: returnToApp=%b", returnToApp); mPausingTasks.clear(); if (returnToApp) { updateSurfaceBounds(mSplitLayout, finishT, false /* applyResizingOffset */); finishT.reparent(mSplitLayout.getDividerLeash(), mRootTaskLeash); setDividerVisibility(true, finishT); return; } } setSplitsVisible(false); finishWct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token, Loading libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java +16 −1 Original line number Diff line number Diff line Loading @@ -367,7 +367,7 @@ public class DefaultMixedHandler implements MixedTransitionHandler, } @Override public Consumer<IBinder> handleRecentsRequest(WindowContainerTransaction outWCT) { public Consumer<IBinder> handleRecentsRequest() { if (mRecentsHandler != null) { if (mSplitHandler.isSplitScreenVisible()) { return this::setRecentsTransitionDuringSplit; Loading @@ -383,6 +383,21 @@ public class DefaultMixedHandler implements MixedTransitionHandler, return null; } @Override public void handleFinishRecents(boolean returnToApp, @NonNull WindowContainerTransaction finishWct, @NonNull SurfaceControl.Transaction finishT) { if (mRecentsHandler != null) { for (int i = mActiveTransitions.size() - 1; i >= 0; --i) { final MixedTransition mixed = mActiveTransitions.get(i); if (mixed.mType == MixedTransition.TYPE_RECENTS_DURING_SPLIT) { ((RecentsMixedTransition) mixed).onAnimateRecentsDuringSplitFinishing( returnToApp, finishWct, finishT); } } } } private void setRecentsTransitionDuringSplit(IBinder transition) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Got a recents request while " + "Split-Screen is foreground, so treat it as Mixed."); Loading libs/WindowManager/Shell/src/com/android/wm/shell/transition/RecentsMixedTransition.java +13 −0 Original line number Diff line number Diff line Loading @@ -159,6 +159,8 @@ class RecentsMixedTransition extends DefaultMixedHandler.MixedTransition { // If pair-to-pair switching, the post-recents clean-up isn't needed. wct = wct != null ? wct : new WindowContainerTransaction(); if (mAnimType != ANIM_TYPE_PAIR_TO_PAIR) { // TODO(b/346588978): Only called if !enableRecentsBookendTransition(), can remove // once that rolls out mSplitHandler.onRecentsInSplitAnimationFinish(wct, finishTransaction); } else { // notify pair-to-pair recents animation finish Loading @@ -177,6 +179,17 @@ class RecentsMixedTransition extends DefaultMixedHandler.MixedTransition { return handled; } /** * Called when the recents animation during split is about to finish. */ void onAnimateRecentsDuringSplitFinishing(boolean returnToApp, @NonNull WindowContainerTransaction finishWct, @NonNull SurfaceControl.Transaction finishT) { if (mAnimType != ANIM_TYPE_PAIR_TO_PAIR) { mSplitHandler.onRecentsInSplitAnimationFinishing(returnToApp, finishWct, finishT); } } @Override void mergeAnimation( @NonNull IBinder transition, @NonNull TransitionInfo info, Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java +15 −4 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.launcher3.icons.IconProvider; import com.android.wm.shell.Flags; import com.android.wm.shell.MockToken; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; Loading Loading @@ -355,8 +356,13 @@ public class SplitTransitionTests extends ShellTestCase { // Make sure it cleans-up if recents doesn't restore WindowContainerTransaction commitWCT = new WindowContainerTransaction(); if (Flags.enableRecentsBookendTransition()) { mStageCoordinator.onRecentsInSplitAnimationFinishing(false /* returnToApp */, commitWCT, mock(SurfaceControl.Transaction.class)); } else { mStageCoordinator.onRecentsInSplitAnimationFinish(commitWCT, mock(SurfaceControl.Transaction.class)); } assertFalse(mStageCoordinator.isSplitScreenVisible()); } Loading Loading @@ -420,8 +426,13 @@ public class SplitTransitionTests extends ShellTestCase { // simulate the restoreWCT being applied: mMainStage.onTaskAppeared(mMainChild, mock(SurfaceControl.class)); mSideStage.onTaskAppeared(mSideChild, mock(SurfaceControl.class)); if (Flags.enableRecentsBookendTransition()) { mStageCoordinator.onRecentsInSplitAnimationFinishing(true /* returnToApp */, restoreWCT, mock(SurfaceControl.Transaction.class)); } else { mStageCoordinator.onRecentsInSplitAnimationFinish(restoreWCT, mock(SurfaceControl.Transaction.class)); } assertTrue(mStageCoordinator.isSplitScreenVisible()); } Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java +17 −5 Original line number Diff line number Diff line Loading @@ -222,7 +222,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, RecentsMixedHandler mixer = null; Consumer<IBinder> setTransitionForMixer = null; for (int i = 0; i < mMixers.size(); ++i) { setTransitionForMixer = mMixers.get(i).handleRecentsRequest(wct); setTransitionForMixer = mMixers.get(i).handleRecentsRequest(); if (setTransitionForMixer != null) { mixer = mMixers.get(i); break; Loading Loading @@ -1455,6 +1455,11 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, } } // Notify the mixers of the pending finish for (int i = 0; i < mMixers.size(); ++i) { mMixers.get(i).handleFinishRecents(returningToApp, wct, t); } if (Flags.enableRecentsBookendTransition()) { if (!wct.isEmpty()) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, Loading Loading @@ -1653,15 +1658,22 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, */ public interface RecentsMixedHandler extends Transitions.TransitionHandler { /** * Called when a recents request comes in. The handler can add operations to outWCT. If * the handler wants to "accept" the transition, it should return a Consumer accepting the * IBinder for the transition. If not, it should return `null`. * Called when a recents request comes in. If the handler wants to "accept" the transition, * it should return a Consumer accepting the IBinder for the transition. If not, it should * return `null`. * * If a mixed-handler accepts this recents, it will be the de-facto handler for this * transition and is required to call the associated {@link #startAnimation}, * {@link #mergeAnimation}, and {@link #onTransitionConsumed} methods. */ @Nullable Consumer<IBinder> handleRecentsRequest(WindowContainerTransaction outWCT); Consumer<IBinder> handleRecentsRequest(); /** * Called when a recents transition has finished, with a WCT and SurfaceControl Transaction * that can be used to add to any changes needed to restore the state. */ void handleFinishRecents(boolean returnToApp, @NonNull WindowContainerTransaction finishWct, @NonNull SurfaceControl.Transaction finishT); } }
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +41 −9 Original line number Diff line number Diff line Loading @@ -129,6 +129,7 @@ import com.android.internal.logging.InstanceId; import com.android.internal.policy.FoldLockSettingsObserver; import com.android.internal.protolog.ProtoLog; import com.android.launcher3.icons.IconProvider; import com.android.wm.shell.Flags; import com.android.wm.shell.R; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; Loading Loading @@ -3766,13 +3767,31 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, mTaskOrganizer.applyTransaction(wct); } public void onRecentsInSplitAnimationFinishing(boolean returnToApp, @NonNull WindowContainerTransaction finishWct, @NonNull SurfaceControl.Transaction finishT) { if (!Flags.enableRecentsBookendTransition()) { // The non-bookend recents transition case will be handled by // RecentsMixedTransition wrapping the finish callback and calling // onRecentsInSplitAnimationFinish() return; } onRecentsInSplitAnimationFinishInner(returnToApp, finishWct, finishT); } /** Call this when the recents animation during split-screen finishes. */ public void onRecentsInSplitAnimationFinish(WindowContainerTransaction finishWct, SurfaceControl.Transaction finishT) { ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onRecentsInSplitAnimationFinish"); mPausingTasks.clear(); public void onRecentsInSplitAnimationFinish(@NonNull WindowContainerTransaction finishWct, @NonNull SurfaceControl.Transaction finishT) { if (Flags.enableRecentsBookendTransition()) { // The bookend recents transition case will be handled by // onRecentsInSplitAnimationFinishing above return; } // Check if the recent transition is finished by returning to the current // split, so we can restore the divider bar. boolean returnToApp = false; for (int i = 0; i < finishWct.getHierarchyOps().size(); ++i) { final WindowContainerTransaction.HierarchyOp op = finishWct.getHierarchyOps().get(i); Loading @@ -3787,13 +3806,26 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } if (op.getType() == HIERARCHY_OP_TYPE_REORDER && op.getToTop() && anyStageContainsContainer) { returnToApp = true; } } onRecentsInSplitAnimationFinishInner(returnToApp, finishWct, finishT); } /** Call this when the recents animation during split-screen finishes. */ public void onRecentsInSplitAnimationFinishInner(boolean returnToApp, @NonNull WindowContainerTransaction finishWct, @NonNull SurfaceControl.Transaction finishT) { ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onRecentsInSplitAnimationFinish: returnToApp=%b", returnToApp); mPausingTasks.clear(); if (returnToApp) { updateSurfaceBounds(mSplitLayout, finishT, false /* applyResizingOffset */); finishT.reparent(mSplitLayout.getDividerLeash(), mRootTaskLeash); setDividerVisibility(true, finishT); return; } } setSplitsVisible(false); finishWct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token, Loading
libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java +16 −1 Original line number Diff line number Diff line Loading @@ -367,7 +367,7 @@ public class DefaultMixedHandler implements MixedTransitionHandler, } @Override public Consumer<IBinder> handleRecentsRequest(WindowContainerTransaction outWCT) { public Consumer<IBinder> handleRecentsRequest() { if (mRecentsHandler != null) { if (mSplitHandler.isSplitScreenVisible()) { return this::setRecentsTransitionDuringSplit; Loading @@ -383,6 +383,21 @@ public class DefaultMixedHandler implements MixedTransitionHandler, return null; } @Override public void handleFinishRecents(boolean returnToApp, @NonNull WindowContainerTransaction finishWct, @NonNull SurfaceControl.Transaction finishT) { if (mRecentsHandler != null) { for (int i = mActiveTransitions.size() - 1; i >= 0; --i) { final MixedTransition mixed = mActiveTransitions.get(i); if (mixed.mType == MixedTransition.TYPE_RECENTS_DURING_SPLIT) { ((RecentsMixedTransition) mixed).onAnimateRecentsDuringSplitFinishing( returnToApp, finishWct, finishT); } } } } private void setRecentsTransitionDuringSplit(IBinder transition) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Got a recents request while " + "Split-Screen is foreground, so treat it as Mixed."); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/transition/RecentsMixedTransition.java +13 −0 Original line number Diff line number Diff line Loading @@ -159,6 +159,8 @@ class RecentsMixedTransition extends DefaultMixedHandler.MixedTransition { // If pair-to-pair switching, the post-recents clean-up isn't needed. wct = wct != null ? wct : new WindowContainerTransaction(); if (mAnimType != ANIM_TYPE_PAIR_TO_PAIR) { // TODO(b/346588978): Only called if !enableRecentsBookendTransition(), can remove // once that rolls out mSplitHandler.onRecentsInSplitAnimationFinish(wct, finishTransaction); } else { // notify pair-to-pair recents animation finish Loading @@ -177,6 +179,17 @@ class RecentsMixedTransition extends DefaultMixedHandler.MixedTransition { return handled; } /** * Called when the recents animation during split is about to finish. */ void onAnimateRecentsDuringSplitFinishing(boolean returnToApp, @NonNull WindowContainerTransaction finishWct, @NonNull SurfaceControl.Transaction finishT) { if (mAnimType != ANIM_TYPE_PAIR_TO_PAIR) { mSplitHandler.onRecentsInSplitAnimationFinishing(returnToApp, finishWct, finishT); } } @Override void mergeAnimation( @NonNull IBinder transition, @NonNull TransitionInfo info, Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java +15 −4 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.launcher3.icons.IconProvider; import com.android.wm.shell.Flags; import com.android.wm.shell.MockToken; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; Loading Loading @@ -355,8 +356,13 @@ public class SplitTransitionTests extends ShellTestCase { // Make sure it cleans-up if recents doesn't restore WindowContainerTransaction commitWCT = new WindowContainerTransaction(); if (Flags.enableRecentsBookendTransition()) { mStageCoordinator.onRecentsInSplitAnimationFinishing(false /* returnToApp */, commitWCT, mock(SurfaceControl.Transaction.class)); } else { mStageCoordinator.onRecentsInSplitAnimationFinish(commitWCT, mock(SurfaceControl.Transaction.class)); } assertFalse(mStageCoordinator.isSplitScreenVisible()); } Loading Loading @@ -420,8 +426,13 @@ public class SplitTransitionTests extends ShellTestCase { // simulate the restoreWCT being applied: mMainStage.onTaskAppeared(mMainChild, mock(SurfaceControl.class)); mSideStage.onTaskAppeared(mSideChild, mock(SurfaceControl.class)); if (Flags.enableRecentsBookendTransition()) { mStageCoordinator.onRecentsInSplitAnimationFinishing(true /* returnToApp */, restoreWCT, mock(SurfaceControl.Transaction.class)); } else { mStageCoordinator.onRecentsInSplitAnimationFinish(restoreWCT, mock(SurfaceControl.Transaction.class)); } assertTrue(mStageCoordinator.isSplitScreenVisible()); } Loading