Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +21 −25 Original line number Diff line number Diff line Loading @@ -534,17 +534,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, return; } if (ENABLE_SHELL_TRANSITIONS) { if (requestEnterSplit && mSplitScreenOptional.isPresent()) { mSplitScreenOptional.get().prepareEnterSplitScreen(wct, mTaskInfo, isPipTopLeft() ? SPLIT_POSITION_TOP_OR_LEFT : SPLIT_POSITION_BOTTOM_OR_RIGHT); mPipTransitionController.startExitTransition( TRANSIT_EXIT_PIP_TO_SPLIT, wct, null /* destinationBounds */); return; } } final Rect displayBounds = mPipBoundsState.getDisplayBounds(); final Rect destinationBounds = new Rect(displayBounds); final int direction = syncWithSplitScreenBounds(destinationBounds, requestEnterSplit) Loading @@ -553,10 +542,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, // For exiting to fullscreen, the windowing mode of task will be changed to fullscreen // until the animation is finished. Otherwise if the activity is resumed and focused at the // begin of aniamtion, the app may do something too early to distub the animation. final boolean toFullscreen = destinationBounds.equals(displayBounds); if (Transitions.SHELL_TRANSITIONS_ROTATION || (Transitions.ENABLE_SHELL_TRANSITIONS && !toFullscreen)) { if (Transitions.SHELL_TRANSITIONS_ROTATION) { // When exit to fullscreen with Shell transition enabled, we update the Task windowing // mode directly so that it can also trigger display rotation and visibility update in // the same transition if there will be any. Loading Loading @@ -588,9 +575,29 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, mPipTransitionState.setTransitionState(PipTransitionState.EXITING_PIP); if (Transitions.ENABLE_SHELL_TRANSITIONS) { if (requestEnterSplit && mSplitScreenOptional.isPresent()) { wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED); mSplitScreenOptional.get().prepareEnterSplitScreen(wct, mTaskInfo, isPipToTopLeft() ? SPLIT_POSITION_TOP_OR_LEFT : SPLIT_POSITION_BOTTOM_OR_RIGHT); mPipTransitionController.startExitTransition( TRANSIT_EXIT_PIP_TO_SPLIT, wct, destinationBounds); return; } if (mSplitScreenOptional.isPresent()) { // If pip activity will reparent to origin task case and if the origin task still // under split root, apply exit split transaction to make it expand to fullscreen. SplitScreenController split = mSplitScreenOptional.get(); if (split.isTaskInSplitScreen(mTaskInfo.lastParentTaskIdBeforePip)) { split.prepareExitSplitScreen(wct, split.getStageOfTask( mTaskInfo.lastParentTaskIdBeforePip)); } } mPipTransitionController.startExitTransition(TRANSIT_EXIT_PIP, wct, destinationBounds); return; } if (mSplitScreenOptional.isPresent()) { // If pip activity will reparent to origin task case and if the origin task still under // split root, just exit split screen here to ensure it could expand to fullscreen. Loading Loading @@ -1666,17 +1673,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, } } private boolean isPipTopLeft() { if (!mSplitScreenOptional.isPresent()) { return false; } final Rect topLeft = new Rect(); final Rect bottomRight = new Rect(); mSplitScreenOptional.get().getStageBounds(topLeft, bottomRight); return topLeft.contains(mPipBoundsState.getBounds()); } private boolean isPipToTopLeft() { if (!mSplitScreenOptional.isPresent()) { return false; Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java +1 −6 Original line number Diff line number Diff line Loading @@ -989,12 +989,7 @@ public class PipTransition extends PipTransitionController { @NonNull SurfaceControl.Transaction finishTransaction, @NonNull Transitions.TransitionFinishCallback finishCallback, @NonNull TaskInfo taskInfo) { final int changeSize = info.getChanges().size(); if (changeSize < 4) { throw new RuntimeException( "Got an exit-pip-to-split transition with unexpected change-list"); } for (int i = changeSize - 1; i >= 0; i--) { for (int i = info.getChanges().size() - 1; i >= 0; i--) { final TransitionInfo.Change change = info.getChanges().get(i); final int mode = change.getMode(); Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java +8 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import android.window.WindowContainerTransaction; import androidx.annotation.NonNull; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.split.SplitScreenUtils; import com.android.wm.shell.sysui.ShellInit; import com.android.wm.shell.transition.Transitions; Loading Loading @@ -223,6 +224,13 @@ public abstract class PipTransitionController implements Transitions.TransitionH return false; } /** Whether a particular package is same as current pip package. */ public boolean isInPipPackage(String packageName) { final TaskInfo inPipTask = mPipOrganizer.getTaskInfo(); return packageName != null && inPipTask != null && packageName.equals(SplitScreenUtils.getPackageName(inPipTask.baseIntent)); } /** Add PiP-related changes to `outWCT` for the given request. */ public void augmentRequest(@NonNull IBinder transition, @NonNull TransitionRequestInfo request, @NonNull WindowContainerTransaction outWCT) { Loading libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java +31 −7 Original line number Diff line number Diff line Loading @@ -88,6 +88,7 @@ import com.android.wm.shell.draganddrop.DragAndDropController; import com.android.wm.shell.draganddrop.DragAndDropPolicy; import com.android.wm.shell.protolog.ShellProtoLogGroup; import com.android.wm.shell.recents.RecentTasksController; import com.android.wm.shell.splitscreen.SplitScreen.StageType; import com.android.wm.shell.sysui.KeyguardChangeListener; import com.android.wm.shell.sysui.ShellCommandHandler; import com.android.wm.shell.sysui.ShellController; Loading Loading @@ -332,6 +333,11 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, return mStageCoordinator.getStageOfTask(taskId) != STAGE_TYPE_UNDEFINED; } /** Get the split stage of task is under it. */ public @StageType int getStageOfTask(int taskId) { return mStageCoordinator.getStageOfTask(taskId); } /** Check split is foreground and task is under split or not by taskId. */ public boolean isTaskInSplitScreenForeground(int taskId) { return isTaskInSplitScreen(taskId) && isSplitScreenVisible(); Loading Loading @@ -378,17 +384,35 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, mStageCoordinator.setSideStagePosition(sideStagePosition, null /* wct */); } public void enterSplitScreen(int taskId, boolean leftOrTop) { enterSplitScreen(taskId, leftOrTop, new WindowContainerTransaction()); } /** * Doing necessary window transaction for other transition handler need to enter split in * transition. */ public void prepareEnterSplitScreen(WindowContainerTransaction wct, ActivityManager.RunningTaskInfo taskInfo, int startPosition) { mStageCoordinator.prepareEnterSplitScreen(wct, taskInfo, startPosition); mStageCoordinator.prepareEnterSplitScreen(wct, taskInfo, startPosition, false /* resizeAnim */); } /** * Doing necessary surface transaction for other transition handler need to enter split in * transition when finished. */ public void finishEnterSplitScreen(SurfaceControl.Transaction finishT) { mStageCoordinator.finishEnterSplitScreen(finishT); } public void finishEnterSplitScreen(SurfaceControl.Transaction t) { mStageCoordinator.finishEnterSplitScreen(t); /** * Doing necessary window transaction for other transition handler need to exit split in * transition. */ public void prepareExitSplitScreen(WindowContainerTransaction wct, @StageType int stageToTop) { mStageCoordinator.prepareExitSplitScreen(stageToTop, wct); } public void enterSplitScreen(int taskId, boolean leftOrTop) { enterSplitScreen(taskId, leftOrTop, new WindowContainerTransaction()); } public void enterSplitScreen(int taskId, boolean leftOrTop, WindowContainerTransaction wct) { Loading libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +34 −24 Original line number Diff line number Diff line Loading @@ -389,7 +389,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, boolean moveToStage(ActivityManager.RunningTaskInfo task, @SplitPosition int stagePosition, WindowContainerTransaction wct) { prepareEnterSplitScreen(wct, task, stagePosition); prepareEnterSplitScreen(wct, task, stagePosition, false /* resizeAnim */); if (ENABLE_SHELL_TRANSITIONS) { mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct, null, this, Loading Loading @@ -487,20 +487,26 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, /** Launches an activity into split. */ void startIntent(PendingIntent intent, Intent fillInIntent, @SplitPosition int position, @Nullable Bundle options) { mSplitRequest = new SplitRequest(intent.getIntent(), position); if (!ENABLE_SHELL_TRANSITIONS) { startIntentLegacy(intent, fillInIntent, position, options); return; } final WindowContainerTransaction wct = new WindowContainerTransaction(); options = resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, null /* wct */); wct.sendPendingIntent(intent, fillInIntent, options); // If this should be mixed, just send the intent to avoid split handle transition directly. if (mMixedHandler != null && mMixedHandler.shouldSplitEnterMixed(intent)) { mTaskOrganizer.applyTransaction(wct); return; } // If split screen is not activated, we're expecting to open a pair of apps to split. final int extraTransitType = mMainStage.isActive() ? TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE : TRANSIT_SPLIT_SCREEN_PAIR_OPEN; prepareEnterSplitScreen(wct, null /* taskInfo */, position); prepareEnterSplitScreen(wct, null /* taskInfo */, position, !mIsDropEntering); mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct, null, this, extraTransitType, !mIsDropEntering); Loading Loading @@ -557,7 +563,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, if (isEnteringSplit && mLogger.isEnterRequestedByDrag()) { updateWindowBounds(mSplitLayout, wct); } mSplitRequest = new SplitRequest(intent.getIntent(), position); wct.sendPendingIntent(intent, fillInIntent, options); mSyncQueue.queue(transition, WindowManager.TRANSIT_OPEN, wct); } Loading Loading @@ -1445,7 +1450,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, * an existing WindowContainerTransaction (rather than applying immediately). This is intended * to be used when exiting split might be bundled with other window operations. */ private void prepareExitSplitScreen(@StageType int stageToTop, void prepareExitSplitScreen(@StageType int stageToTop, @NonNull WindowContainerTransaction wct) { if (!mMainStage.isActive()) return; mSideStage.removeAllTasks(wct, stageToTop == STAGE_TYPE_SIDE); Loading @@ -1453,7 +1458,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } private void prepareEnterSplitScreen(WindowContainerTransaction wct) { prepareEnterSplitScreen(wct, null /* taskInfo */, SPLIT_POSITION_UNDEFINED); prepareEnterSplitScreen(wct, null /* taskInfo */, SPLIT_POSITION_UNDEFINED, !mIsDropEntering); } /** Loading @@ -1461,17 +1467,19 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, * into side stage. */ void prepareEnterSplitScreen(WindowContainerTransaction wct, @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition) { @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition, boolean resizeAnim) { onSplitScreenEnter(); if (isSplitActive()) { prepareBringSplit(wct, taskInfo, startPosition); prepareBringSplit(wct, taskInfo, startPosition, resizeAnim); } else { prepareActiveSplit(wct, taskInfo, startPosition); prepareActiveSplit(wct, taskInfo, startPosition, resizeAnim); } } private void prepareBringSplit(WindowContainerTransaction wct, @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition) { @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition, boolean resizeAnim) { if (taskInfo != null) { wct.startTask(taskInfo.taskId, resolveStartStage(STAGE_TYPE_UNDEFINED, startPosition, null, wct)); Loading @@ -1483,12 +1491,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, // won't guarantee to put the task to the indicated new position. mMainStage.evictAllChildren(wct); mMainStage.reparentTopTask(wct); prepareSplitLayout(wct); prepareSplitLayout(wct, resizeAnim); } } private void prepareActiveSplit(WindowContainerTransaction wct, @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition) { @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition, boolean resizeAnim) { if (!ENABLE_SHELL_TRANSITIONS) { // Legacy transition we need to create divider here, shell transition case we will // create it on #finishEnterSplitScreen Loading @@ -1499,17 +1508,17 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, mSideStage.addTask(taskInfo, wct); } mMainStage.activate(wct, true /* includingTopTask */); prepareSplitLayout(wct); prepareSplitLayout(wct, resizeAnim); } private void prepareSplitLayout(WindowContainerTransaction wct) { if (mIsDropEntering) { mSplitLayout.resetDividerPosition(); } else { private void prepareSplitLayout(WindowContainerTransaction wct, boolean resizeAnim) { if (resizeAnim) { mSplitLayout.setDividerAtBorder(mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT); } else { mSplitLayout.resetDividerPosition(); } updateWindowBounds(mSplitLayout, wct); if (!mIsDropEntering) { if (resizeAnim) { // Reset its smallest width dp to avoid is change layout before it actually resized to // split bounds. wct.setSmallestScreenWidthDp(mMainStage.mRootTaskInfo.token, Loading @@ -1519,21 +1528,22 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, setRootForceTranslucent(false, wct); } void finishEnterSplitScreen(SurfaceControl.Transaction t) { mSplitLayout.update(t); void finishEnterSplitScreen(SurfaceControl.Transaction finishT) { mSplitLayout.update(finishT); mMainStage.getSplitDecorManager().inflate(mContext, mMainStage.mRootLeash, getMainStageBounds()); mSideStage.getSplitDecorManager().inflate(mContext, mSideStage.mRootLeash, getSideStageBounds()); setDividerVisibility(true, t); setDividerVisibility(true, finishT); // Ensure divider surface are re-parented back into the hierarchy at the end of the // transition. See Transition#buildFinishTransaction for more detail. t.reparent(mSplitLayout.getDividerLeash(), mRootTaskLeash); finishT.reparent(mSplitLayout.getDividerLeash(), mRootTaskLeash); updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */); t.show(mRootTaskLeash); updateSurfaceBounds(mSplitLayout, finishT, false /* applyResizingOffset */); finishT.show(mRootTaskLeash); setSplitsVisible(true); mIsDropEntering = false; mSplitRequest = null; updateRecentTasksSplitPair(); if (!mLogger.hasStartedSession()) { mLogger.logEnter(mSplitLayout.getDividerPositionAsFraction(), Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +21 −25 Original line number Diff line number Diff line Loading @@ -534,17 +534,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, return; } if (ENABLE_SHELL_TRANSITIONS) { if (requestEnterSplit && mSplitScreenOptional.isPresent()) { mSplitScreenOptional.get().prepareEnterSplitScreen(wct, mTaskInfo, isPipTopLeft() ? SPLIT_POSITION_TOP_OR_LEFT : SPLIT_POSITION_BOTTOM_OR_RIGHT); mPipTransitionController.startExitTransition( TRANSIT_EXIT_PIP_TO_SPLIT, wct, null /* destinationBounds */); return; } } final Rect displayBounds = mPipBoundsState.getDisplayBounds(); final Rect destinationBounds = new Rect(displayBounds); final int direction = syncWithSplitScreenBounds(destinationBounds, requestEnterSplit) Loading @@ -553,10 +542,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, // For exiting to fullscreen, the windowing mode of task will be changed to fullscreen // until the animation is finished. Otherwise if the activity is resumed and focused at the // begin of aniamtion, the app may do something too early to distub the animation. final boolean toFullscreen = destinationBounds.equals(displayBounds); if (Transitions.SHELL_TRANSITIONS_ROTATION || (Transitions.ENABLE_SHELL_TRANSITIONS && !toFullscreen)) { if (Transitions.SHELL_TRANSITIONS_ROTATION) { // When exit to fullscreen with Shell transition enabled, we update the Task windowing // mode directly so that it can also trigger display rotation and visibility update in // the same transition if there will be any. Loading Loading @@ -588,9 +575,29 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, mPipTransitionState.setTransitionState(PipTransitionState.EXITING_PIP); if (Transitions.ENABLE_SHELL_TRANSITIONS) { if (requestEnterSplit && mSplitScreenOptional.isPresent()) { wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED); mSplitScreenOptional.get().prepareEnterSplitScreen(wct, mTaskInfo, isPipToTopLeft() ? SPLIT_POSITION_TOP_OR_LEFT : SPLIT_POSITION_BOTTOM_OR_RIGHT); mPipTransitionController.startExitTransition( TRANSIT_EXIT_PIP_TO_SPLIT, wct, destinationBounds); return; } if (mSplitScreenOptional.isPresent()) { // If pip activity will reparent to origin task case and if the origin task still // under split root, apply exit split transaction to make it expand to fullscreen. SplitScreenController split = mSplitScreenOptional.get(); if (split.isTaskInSplitScreen(mTaskInfo.lastParentTaskIdBeforePip)) { split.prepareExitSplitScreen(wct, split.getStageOfTask( mTaskInfo.lastParentTaskIdBeforePip)); } } mPipTransitionController.startExitTransition(TRANSIT_EXIT_PIP, wct, destinationBounds); return; } if (mSplitScreenOptional.isPresent()) { // If pip activity will reparent to origin task case and if the origin task still under // split root, just exit split screen here to ensure it could expand to fullscreen. Loading Loading @@ -1666,17 +1673,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, } } private boolean isPipTopLeft() { if (!mSplitScreenOptional.isPresent()) { return false; } final Rect topLeft = new Rect(); final Rect bottomRight = new Rect(); mSplitScreenOptional.get().getStageBounds(topLeft, bottomRight); return topLeft.contains(mPipBoundsState.getBounds()); } private boolean isPipToTopLeft() { if (!mSplitScreenOptional.isPresent()) { return false; Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java +1 −6 Original line number Diff line number Diff line Loading @@ -989,12 +989,7 @@ public class PipTransition extends PipTransitionController { @NonNull SurfaceControl.Transaction finishTransaction, @NonNull Transitions.TransitionFinishCallback finishCallback, @NonNull TaskInfo taskInfo) { final int changeSize = info.getChanges().size(); if (changeSize < 4) { throw new RuntimeException( "Got an exit-pip-to-split transition with unexpected change-list"); } for (int i = changeSize - 1; i >= 0; i--) { for (int i = info.getChanges().size() - 1; i >= 0; i--) { final TransitionInfo.Change change = info.getChanges().get(i); final int mode = change.getMode(); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java +8 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import android.window.WindowContainerTransaction; import androidx.annotation.NonNull; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.split.SplitScreenUtils; import com.android.wm.shell.sysui.ShellInit; import com.android.wm.shell.transition.Transitions; Loading Loading @@ -223,6 +224,13 @@ public abstract class PipTransitionController implements Transitions.TransitionH return false; } /** Whether a particular package is same as current pip package. */ public boolean isInPipPackage(String packageName) { final TaskInfo inPipTask = mPipOrganizer.getTaskInfo(); return packageName != null && inPipTask != null && packageName.equals(SplitScreenUtils.getPackageName(inPipTask.baseIntent)); } /** Add PiP-related changes to `outWCT` for the given request. */ public void augmentRequest(@NonNull IBinder transition, @NonNull TransitionRequestInfo request, @NonNull WindowContainerTransaction outWCT) { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java +31 −7 Original line number Diff line number Diff line Loading @@ -88,6 +88,7 @@ import com.android.wm.shell.draganddrop.DragAndDropController; import com.android.wm.shell.draganddrop.DragAndDropPolicy; import com.android.wm.shell.protolog.ShellProtoLogGroup; import com.android.wm.shell.recents.RecentTasksController; import com.android.wm.shell.splitscreen.SplitScreen.StageType; import com.android.wm.shell.sysui.KeyguardChangeListener; import com.android.wm.shell.sysui.ShellCommandHandler; import com.android.wm.shell.sysui.ShellController; Loading Loading @@ -332,6 +333,11 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, return mStageCoordinator.getStageOfTask(taskId) != STAGE_TYPE_UNDEFINED; } /** Get the split stage of task is under it. */ public @StageType int getStageOfTask(int taskId) { return mStageCoordinator.getStageOfTask(taskId); } /** Check split is foreground and task is under split or not by taskId. */ public boolean isTaskInSplitScreenForeground(int taskId) { return isTaskInSplitScreen(taskId) && isSplitScreenVisible(); Loading Loading @@ -378,17 +384,35 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, mStageCoordinator.setSideStagePosition(sideStagePosition, null /* wct */); } public void enterSplitScreen(int taskId, boolean leftOrTop) { enterSplitScreen(taskId, leftOrTop, new WindowContainerTransaction()); } /** * Doing necessary window transaction for other transition handler need to enter split in * transition. */ public void prepareEnterSplitScreen(WindowContainerTransaction wct, ActivityManager.RunningTaskInfo taskInfo, int startPosition) { mStageCoordinator.prepareEnterSplitScreen(wct, taskInfo, startPosition); mStageCoordinator.prepareEnterSplitScreen(wct, taskInfo, startPosition, false /* resizeAnim */); } /** * Doing necessary surface transaction for other transition handler need to enter split in * transition when finished. */ public void finishEnterSplitScreen(SurfaceControl.Transaction finishT) { mStageCoordinator.finishEnterSplitScreen(finishT); } public void finishEnterSplitScreen(SurfaceControl.Transaction t) { mStageCoordinator.finishEnterSplitScreen(t); /** * Doing necessary window transaction for other transition handler need to exit split in * transition. */ public void prepareExitSplitScreen(WindowContainerTransaction wct, @StageType int stageToTop) { mStageCoordinator.prepareExitSplitScreen(stageToTop, wct); } public void enterSplitScreen(int taskId, boolean leftOrTop) { enterSplitScreen(taskId, leftOrTop, new WindowContainerTransaction()); } public void enterSplitScreen(int taskId, boolean leftOrTop, WindowContainerTransaction wct) { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +34 −24 Original line number Diff line number Diff line Loading @@ -389,7 +389,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, boolean moveToStage(ActivityManager.RunningTaskInfo task, @SplitPosition int stagePosition, WindowContainerTransaction wct) { prepareEnterSplitScreen(wct, task, stagePosition); prepareEnterSplitScreen(wct, task, stagePosition, false /* resizeAnim */); if (ENABLE_SHELL_TRANSITIONS) { mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct, null, this, Loading Loading @@ -487,20 +487,26 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, /** Launches an activity into split. */ void startIntent(PendingIntent intent, Intent fillInIntent, @SplitPosition int position, @Nullable Bundle options) { mSplitRequest = new SplitRequest(intent.getIntent(), position); if (!ENABLE_SHELL_TRANSITIONS) { startIntentLegacy(intent, fillInIntent, position, options); return; } final WindowContainerTransaction wct = new WindowContainerTransaction(); options = resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, null /* wct */); wct.sendPendingIntent(intent, fillInIntent, options); // If this should be mixed, just send the intent to avoid split handle transition directly. if (mMixedHandler != null && mMixedHandler.shouldSplitEnterMixed(intent)) { mTaskOrganizer.applyTransaction(wct); return; } // If split screen is not activated, we're expecting to open a pair of apps to split. final int extraTransitType = mMainStage.isActive() ? TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE : TRANSIT_SPLIT_SCREEN_PAIR_OPEN; prepareEnterSplitScreen(wct, null /* taskInfo */, position); prepareEnterSplitScreen(wct, null /* taskInfo */, position, !mIsDropEntering); mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct, null, this, extraTransitType, !mIsDropEntering); Loading Loading @@ -557,7 +563,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, if (isEnteringSplit && mLogger.isEnterRequestedByDrag()) { updateWindowBounds(mSplitLayout, wct); } mSplitRequest = new SplitRequest(intent.getIntent(), position); wct.sendPendingIntent(intent, fillInIntent, options); mSyncQueue.queue(transition, WindowManager.TRANSIT_OPEN, wct); } Loading Loading @@ -1445,7 +1450,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, * an existing WindowContainerTransaction (rather than applying immediately). This is intended * to be used when exiting split might be bundled with other window operations. */ private void prepareExitSplitScreen(@StageType int stageToTop, void prepareExitSplitScreen(@StageType int stageToTop, @NonNull WindowContainerTransaction wct) { if (!mMainStage.isActive()) return; mSideStage.removeAllTasks(wct, stageToTop == STAGE_TYPE_SIDE); Loading @@ -1453,7 +1458,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } private void prepareEnterSplitScreen(WindowContainerTransaction wct) { prepareEnterSplitScreen(wct, null /* taskInfo */, SPLIT_POSITION_UNDEFINED); prepareEnterSplitScreen(wct, null /* taskInfo */, SPLIT_POSITION_UNDEFINED, !mIsDropEntering); } /** Loading @@ -1461,17 +1467,19 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, * into side stage. */ void prepareEnterSplitScreen(WindowContainerTransaction wct, @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition) { @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition, boolean resizeAnim) { onSplitScreenEnter(); if (isSplitActive()) { prepareBringSplit(wct, taskInfo, startPosition); prepareBringSplit(wct, taskInfo, startPosition, resizeAnim); } else { prepareActiveSplit(wct, taskInfo, startPosition); prepareActiveSplit(wct, taskInfo, startPosition, resizeAnim); } } private void prepareBringSplit(WindowContainerTransaction wct, @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition) { @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition, boolean resizeAnim) { if (taskInfo != null) { wct.startTask(taskInfo.taskId, resolveStartStage(STAGE_TYPE_UNDEFINED, startPosition, null, wct)); Loading @@ -1483,12 +1491,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, // won't guarantee to put the task to the indicated new position. mMainStage.evictAllChildren(wct); mMainStage.reparentTopTask(wct); prepareSplitLayout(wct); prepareSplitLayout(wct, resizeAnim); } } private void prepareActiveSplit(WindowContainerTransaction wct, @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition) { @Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition, boolean resizeAnim) { if (!ENABLE_SHELL_TRANSITIONS) { // Legacy transition we need to create divider here, shell transition case we will // create it on #finishEnterSplitScreen Loading @@ -1499,17 +1508,17 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, mSideStage.addTask(taskInfo, wct); } mMainStage.activate(wct, true /* includingTopTask */); prepareSplitLayout(wct); prepareSplitLayout(wct, resizeAnim); } private void prepareSplitLayout(WindowContainerTransaction wct) { if (mIsDropEntering) { mSplitLayout.resetDividerPosition(); } else { private void prepareSplitLayout(WindowContainerTransaction wct, boolean resizeAnim) { if (resizeAnim) { mSplitLayout.setDividerAtBorder(mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT); } else { mSplitLayout.resetDividerPosition(); } updateWindowBounds(mSplitLayout, wct); if (!mIsDropEntering) { if (resizeAnim) { // Reset its smallest width dp to avoid is change layout before it actually resized to // split bounds. wct.setSmallestScreenWidthDp(mMainStage.mRootTaskInfo.token, Loading @@ -1519,21 +1528,22 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, setRootForceTranslucent(false, wct); } void finishEnterSplitScreen(SurfaceControl.Transaction t) { mSplitLayout.update(t); void finishEnterSplitScreen(SurfaceControl.Transaction finishT) { mSplitLayout.update(finishT); mMainStage.getSplitDecorManager().inflate(mContext, mMainStage.mRootLeash, getMainStageBounds()); mSideStage.getSplitDecorManager().inflate(mContext, mSideStage.mRootLeash, getSideStageBounds()); setDividerVisibility(true, t); setDividerVisibility(true, finishT); // Ensure divider surface are re-parented back into the hierarchy at the end of the // transition. See Transition#buildFinishTransaction for more detail. t.reparent(mSplitLayout.getDividerLeash(), mRootTaskLeash); finishT.reparent(mSplitLayout.getDividerLeash(), mRootTaskLeash); updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */); t.show(mRootTaskLeash); updateSurfaceBounds(mSplitLayout, finishT, false /* applyResizingOffset */); finishT.show(mRootTaskLeash); setSplitsVisible(true); mIsDropEntering = false; mSplitRequest = null; updateRecentTasksSplitPair(); if (!mLogger.hasStartedSession()) { mLogger.logEnter(mSplitLayout.getDividerPositionAsFraction(), Loading