diff options
7 files changed, 151 insertions, 63 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java index 62bf5172e106..d93a9012c8f1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java @@ -240,7 +240,7 @@ public class DragAndDropPolicy { // Update launch options for the split side we are targeting. position = leftOrTop ? SPLIT_POSITION_TOP_OR_LEFT : SPLIT_POSITION_BOTTOM_OR_RIGHT; // Add some data for logging splitscreen once it is invoked - mSplitScreen.logOnDroppedToSplit(position, mLoggerSessionId); + mSplitScreen.onDroppedToSplit(position, mLoggerSessionId); } final ClipDescription description = data.getDescription(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java index e7ec15e70c11..89538cb394d4 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java @@ -16,9 +16,6 @@ package com.android.wm.shell.splitscreen; -import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES; -import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES; - import android.content.Context; import android.view.SurfaceSession; import android.window.WindowContainerToken; @@ -34,8 +31,6 @@ import com.android.wm.shell.common.SyncTransactionQueue; * @see StageCoordinator */ class MainStage extends StageTaskListener { - private static final String TAG = MainStage.class.getSimpleName(); - private boolean mIsActive = false; MainStage(Context context, ShellTaskOrganizer taskOrganizer, int displayId, @@ -52,15 +47,8 @@ class MainStage extends StageTaskListener { void activate(WindowContainerTransaction wct, boolean includingTopTask) { if (mIsActive) return; - final WindowContainerToken rootToken = mRootTaskInfo.token; if (includingTopTask) { - wct.reparentTasks( - null /* currentParent */, - rootToken, - CONTROLLED_WINDOWING_MODES, - CONTROLLED_ACTIVITY_TYPES, - true /* onTop */, - true /* reparentTopOnly */); + reparentTopTask(wct); } mIsActive = true; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java index b26bc9cd7f9c..ef70d9bd84ee 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java @@ -121,7 +121,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, public static final int EXIT_REASON_SCREEN_LOCKED = 7; public static final int EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP = 8; public static final int EXIT_REASON_CHILD_TASK_ENTER_PIP = 9; - public static final int EXIT_REASON_FULLSCREEN_SHORTCUT = 10; + public static final int EXIT_REASON_RECREATE_SPLIT = 10; + public static final int EXIT_REASON_FULLSCREEN_SHORTCUT = 11; @IntDef(value = { EXIT_REASON_UNKNOWN, EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW, @@ -133,6 +134,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, EXIT_REASON_SCREEN_LOCKED, EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP, EXIT_REASON_CHILD_TASK_ENTER_PIP, + EXIT_REASON_RECREATE_SPLIT, EXIT_REASON_FULLSCREEN_SHORTCUT, }) @Retention(RetentionPolicy.SOURCE) @@ -470,7 +472,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, */ public void startShortcut(String packageName, String shortcutId, @SplitPosition int position, @Nullable Bundle options, UserHandle user, @NonNull InstanceId instanceId) { - mStageCoordinator.getLogger().enterRequested(instanceId, ENTER_REASON_LAUNCHER); + mStageCoordinator.onRequestToSplit(instanceId, ENTER_REASON_LAUNCHER); startShortcut(packageName, shortcutId, position, options, user); } @@ -518,7 +520,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, */ public void startIntent(PendingIntent intent, @Nullable Intent fillInIntent, @SplitPosition int position, @Nullable Bundle options, @NonNull InstanceId instanceId) { - mStageCoordinator.getLogger().enterRequested(instanceId, ENTER_REASON_LAUNCHER); + mStageCoordinator.onRequestToSplit(instanceId, ENTER_REASON_LAUNCHER); startIntent(intent, fillInIntent, position, options); } @@ -784,10 +786,10 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, return splitTasksLayer; } /** - * Sets drag info to be logged when splitscreen is entered. + * Drop callback when splitscreen is entered. */ - public void logOnDroppedToSplit(@SplitPosition int position, InstanceId dragSessionId) { - mStageCoordinator.logOnDroppedToSplit(position, dragSessionId); + public void onDroppedToSplit(@SplitPosition int position, InstanceId dragSessionId) { + mStageCoordinator.onDroppedToSplit(position, dragSessionId); } /** @@ -815,6 +817,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, return "APP_DOES_NOT_SUPPORT_MULTIWINDOW"; case EXIT_REASON_CHILD_TASK_ENTER_PIP: return "CHILD_TASK_ENTER_PIP"; + case EXIT_REASON_RECREATE_SPLIT: + return "RECREATE_SPLIT"; default: return "unknown reason, reason int = " + exitReason; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitscreenEventLogger.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitscreenEventLogger.java index 1016e1bcd66f..5483fa5d29f6 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitscreenEventLogger.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitscreenEventLogger.java @@ -21,9 +21,11 @@ import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED_ import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__ENTER_REASON__UNKNOWN_ENTER; import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__APP_DOES_NOT_SUPPORT_MULTIWINDOW; import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__APP_FINISHED; +import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__CHILD_TASK_ENTER_PIP; import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__DEVICE_FOLDED; import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__DRAG_DIVIDER; import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__FULLSCREEN_SHORTCUT; +import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__RECREATE_SPLIT; import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__RETURN_HOME; import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__ROOT_TASK_VANISHED; import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__SCREEN_LOCKED; @@ -37,9 +39,11 @@ import static com.android.wm.shell.splitscreen.SplitScreenController.ENTER_REASO import static com.android.wm.shell.splitscreen.SplitScreenController.ENTER_REASON_UNKNOWN; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_APP_FINISHED; +import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_CHILD_TASK_ENTER_PIP; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DEVICE_FOLDED; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DRAG_DIVIDER; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_FULLSCREEN_SHORTCUT; +import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_RECREATE_SPLIT; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_RETURN_HOME; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_ROOT_TASK_VANISHED; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_SCREEN_LOCKED; @@ -182,6 +186,10 @@ public class SplitscreenEventLogger { return SPLITSCREEN_UICHANGED__EXIT_REASON__SCREEN_LOCKED; case EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP: return SPLITSCREEN_UICHANGED__EXIT_REASON__SCREEN_LOCKED_SHOW_ON_TOP; + case EXIT_REASON_CHILD_TASK_ENTER_PIP: + return SPLITSCREEN_UICHANGED__EXIT_REASON__CHILD_TASK_ENTER_PIP; + case EXIT_REASON_RECREATE_SPLIT: + return SPLITSCREEN_UICHANGED__EXIT_REASON__RECREATE_SPLIT; case EXIT_REASON_FULLSCREEN_SHORTCUT: return SPLITSCREEN_UICHANGED__EXIT_REASON__FULLSCREEN_SHORTCUT; case EXIT_REASON_UNKNOWN: diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index da8dc8733ef5..602d0e6c0201 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -49,10 +49,11 @@ import static com.android.wm.shell.splitscreen.SplitScreenController.ENTER_REASO import static com.android.wm.shell.splitscreen.SplitScreenController.ENTER_REASON_MULTI_INSTANCE; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_APP_FINISHED; -import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_FULLSCREEN_SHORTCUT; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_CHILD_TASK_ENTER_PIP; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DEVICE_FOLDED; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DRAG_DIVIDER; +import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_FULLSCREEN_SHORTCUT; +import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_RECREATE_SPLIT; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_RETURN_HOME; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_ROOT_TASK_VANISHED; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP; @@ -199,7 +200,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, // and exit, since exit itself can trigger a number of changes that update the stages. private boolean mShouldUpdateRecents; private boolean mExitSplitScreenOnHide; - private boolean mIsDividerRemoteAnimating; + private boolean mIsSplitEntering; + private boolean mIsDropEntering; private boolean mIsExiting; /** The target stage to dismiss to when unlock after folded. */ @@ -347,10 +349,19 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, return mSplitTransitions; } - boolean isSplitScreenVisible() { + public boolean isSplitScreenVisible() { return mSideStageListener.mVisible && mMainStageListener.mVisible; } + public boolean isSplitActive() { + return mMainStage.isActive(); + } + + boolean isSplitScreenRunningBackground() { + return !isSplitScreenVisible() && mMainStageListener.mHasChildren + && mSideStageListener.mHasChildren; + } + @StageType int getStageOfTask(int taskId) { if (mMainStage.containsTask(taskId)) { @@ -373,11 +384,12 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, targetStage = mSideStage; sideStagePosition = stagePosition; } else { - if (mMainStage.isActive()) { + if (isSplitScreenVisible()) { // If the split screen is activated, retrieves target stage based on position. targetStage = stagePosition == mSideStagePosition ? mSideStage : mMainStage; sideStagePosition = mSideStagePosition; } else { + exitSplitIfBackground(); targetStage = mSideStage; sideStagePosition = stagePosition; } @@ -673,6 +685,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, @Nullable PendingIntent mainPendingIntent, @Nullable Intent mainFillInIntent, @Nullable Bundle mainOptions, @SplitPosition int sidePosition, float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) { + exitSplitIfBackground(); // Init divider first to make divider leash for remote animation target. mSplitLayout.init(); mSplitLayout.setDivideRatio(splitRatio); @@ -685,11 +698,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, // Set false to avoid record new bounds with old task still on top; mShouldUpdateRecents = false; - mIsDividerRemoteAnimating = true; + mIsSplitEntering = true; final WindowContainerTransaction evictWct = new WindowContainerTransaction(); - prepareEvictChildTasks(SPLIT_POSITION_TOP_OR_LEFT, evictWct); - prepareEvictChildTasks(SPLIT_POSITION_BOTTOM_OR_RIGHT, evictWct); + if (isSplitScreenVisible()) { + mMainStage.evictAllChildren(evictWct); + mSideStage.evictAllChildren(evictWct); + } IRemoteAnimationRunner wrapper = new IRemoteAnimationRunner.Stub() { @Override @@ -769,7 +784,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, private void onRemoteAnimationFinishedOrCancelled(boolean cancel, WindowContainerTransaction evictWct) { - mIsDividerRemoteAnimating = false; + mIsSplitEntering = false; mShouldUpdateRecents = true; // If any stage has no child after animation finished, it means that split will display // nothing, such status will happen if task and intent is same app but not support @@ -781,6 +796,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, mSplitUnsupportedToast.show(); } else { mSyncQueue.queue(evictWct); + mSyncQueue.runInSync(t -> { + updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */); + }); } } @@ -815,7 +833,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, switch (stage) { case STAGE_TYPE_UNDEFINED: { if (position != SPLIT_POSITION_UNDEFINED) { - if (mMainStage.isActive()) { + if (isSplitScreenVisible()) { // Use the stage of the specified position options = resolveStartStage( position == mSideStagePosition ? STAGE_TYPE_SIDE : STAGE_TYPE_MAIN, @@ -1045,7 +1063,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } }); mShouldUpdateRecents = false; - mIsDividerRemoteAnimating = false; + mIsSplitEntering = false; mSplitLayout.getInvisibleBounds(mTempRect1); if (childrenToTop == null || childrenToTop.getTopVisibleChildTaskId() == INVALID_TASK_ID) { @@ -1064,6 +1082,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, wct.setSmallestScreenWidthDp(childrenToTop.mRootTaskInfo.token, SMALLEST_SCREEN_WIDTH_DP_UNDEFINED); } + wct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token, + false /* reparentLeafTaskIfRelaunch */); mSyncQueue.queue(wct); mSyncQueue.runInSync(t -> { t.setWindowCrop(mMainStage.mRootLeash, null) @@ -1102,6 +1122,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } } + /** Exit split screen if it still running background */ + public void exitSplitIfBackground() { + if (!isSplitScreenRunningBackground()) return; + + exitSplitScreen(null /* childrenToTop */, EXIT_REASON_RECREATE_SPLIT); + } + /** * Overridden by child classes. */ @@ -1374,7 +1401,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, && !ENABLE_SHELL_TRANSITIONS) { // Clear the divider remote animating flag as the divider will be re-rendered to apply // the new rotation config. - mIsDividerRemoteAnimating = false; + mIsSplitEntering = false; mSplitLayout.update(null /* t */); onLayoutSizeChanged(mSplitLayout); } @@ -1423,6 +1450,33 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, }); } + void onChildTaskAppeared(StageListenerImpl stageListener, int taskId) { + if (stageListener == mSideStageListener && isSplitScreenRunningBackground()) { + // Handle entring split case here if split already running background. + if (mIsDropEntering) { + mSplitLayout.resetDividerPosition(); + } else { + mSplitLayout.setDividerAtBorder(mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT); + } + final WindowContainerTransaction wct = new WindowContainerTransaction(); + mMainStage.evictAllChildren(wct); + mSideStage.evictOtherChildren(wct, taskId); + mMainStage.reparentTopTask(wct); + updateWindowBounds(mSplitLayout, wct); + wct.reorder(mRootTaskInfo.token, true); + + mSyncQueue.queue(wct); + mSyncQueue.runInSync(t -> { + if (mIsDropEntering) { + updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */); + mIsDropEntering = false; + } else { + mSplitLayout.flingDividerToCenter(); + } + }); + } + } + private void onRootTaskVanished() { final WindowContainerTransaction wct = new WindowContainerTransaction(); if (mRootTaskInfo != null) { @@ -1441,20 +1495,20 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, return; } + final WindowContainerTransaction wct = new WindowContainerTransaction(); if (!mainStageVisible) { + wct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token, + true /* setReparentLeafTaskIfRelaunch */); // Both stages are not visible, check if it needs to dismiss split screen. - if (mExitSplitScreenOnHide - // Don't dismiss split screen when both stages are not visible due to sleeping - // display. - || (!mMainStage.mRootTaskInfo.isSleeping - && !mSideStage.mRootTaskInfo.isSleeping)) { + if (mExitSplitScreenOnHide) { exitSplitScreen(null /* childrenToTop */, EXIT_REASON_RETURN_HOME); } + } else { + wct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token, + false /* setReparentLeafTaskIfRelaunch */); } - + mSyncQueue.queue(wct); mSyncQueue.runInSync(t -> { - t.setVisibility(mSideStage.mRootLeash, sideStageVisible) - .setVisibility(mMainStage.mRootLeash, mainStageVisible); setDividerVisibility(mainStageVisible, t); }); } @@ -1479,7 +1533,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, mDividerVisible = visible; sendSplitVisibilityChanged(); - if (mIsDividerRemoteAnimating) { + if (mIsSplitEntering) { ProtoLog.d(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, " Skip animating divider bar due to it's remote animating."); return; @@ -1499,7 +1553,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, " Skip animating divider bar due to divider leash not ready."); return; } - if (mIsDividerRemoteAnimating) { + if (mIsSplitEntering) { ProtoLog.d(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, " Skip animating divider bar due to it's remote animating."); return; @@ -1555,26 +1609,22 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, if (!hasChildren && !mIsExiting && mMainStage.isActive()) { if (isSideStage && mMainStageListener.mVisible) { // Exit to main stage if side stage no longer has children. - if (ENABLE_SHELL_TRANSITIONS) { - exitSplitScreen(mMainStage, EXIT_REASON_APP_FINISHED); - } else { - mSplitLayout.flingDividerToDismiss( - mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT, - EXIT_REASON_APP_FINISHED); - } + mSplitLayout.flingDividerToDismiss( + mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT, + EXIT_REASON_APP_FINISHED); } else if (!isSideStage && mSideStageListener.mVisible) { // Exit to side stage if main stage no longer has children. - if (ENABLE_SHELL_TRANSITIONS) { - exitSplitScreen(mSideStage, EXIT_REASON_APP_FINISHED); - } else { - mSplitLayout.flingDividerToDismiss( - mSideStagePosition != SPLIT_POSITION_BOTTOM_OR_RIGHT, - EXIT_REASON_APP_FINISHED); - } + mSplitLayout.flingDividerToDismiss( + mSideStagePosition != SPLIT_POSITION_BOTTOM_OR_RIGHT, + EXIT_REASON_APP_FINISHED); + } else if (isSplitScreenRunningBackground()) { + // Do not exit to any stage due to running background. + exitSplitScreen(null /* childrenToTop */, EXIT_REASON_APP_FINISHED); } } else if (isSideStage && hasChildren && !mMainStage.isActive()) { - final WindowContainerTransaction wct = new WindowContainerTransaction(); mSplitLayout.init(); + + final WindowContainerTransaction wct = new WindowContainerTransaction(); if (mLogger.isEnterRequestedByDrag()) { prepareEnterSplitScreen(wct); } else { @@ -1589,8 +1639,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, mSyncQueue.queue(wct); mSyncQueue.runInSync(t -> { - if (mLogger.isEnterRequestedByDrag()) { + if (mIsDropEntering) { updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */); + mIsDropEntering = false; } else { mShowDecorImmediately = true; mSplitLayout.flingDividerToCenter(); @@ -1945,10 +1996,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } } - public boolean isSplitActive() { - return mMainStage.isActive(); - } - @Override public void mergeAnimation(IBinder transition, TransitionInfo info, SurfaceControl.Transaction t, IBinder mergeTarget, @@ -2304,11 +2351,29 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, /** * Sets drag info to be logged when splitscreen is next entered. */ - public void logOnDroppedToSplit(@SplitPosition int position, InstanceId dragSessionId) { + public void onDroppedToSplit(@SplitPosition int position, InstanceId dragSessionId) { + if (!isSplitScreenVisible()) { + mIsDropEntering = true; + } + if (isSplitScreenRunningBackground()) { + // Split running background, log exit first and start new enter request. + logExit(EXIT_REASON_RECREATE_SPLIT); + } mLogger.enterRequestedByDrag(position, dragSessionId); } /** + * Sets info to be logged when splitscreen is next entered. + */ + public void onRequestToSplit(InstanceId sessionId, int enterReason) { + if (isSplitScreenRunningBackground()) { + // Split running background, log exit first and start new enter request. + logExit(EXIT_REASON_RECREATE_SPLIT); + } + mLogger.enterRequested(sessionId, enterReason); + } + + /** * Logs the exit of splitscreen. */ private void logExit(@ExitReason int exitReason) { @@ -2343,6 +2408,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } @Override + public void onChildTaskAppeared(int taskId) { + StageCoordinator.this.onChildTaskAppeared(this, taskId); + } + + @Override public void onStatusChanged(boolean visible, boolean hasChildren) { if (!mHasRootTask) return; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java index 8a52c8750ba6..a841b7f96d3c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java @@ -22,6 +22,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.view.RemoteAnimationTarget.MODE_OPENING; import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES; +import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES; import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES_WHEN_ACTIVE; import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS; @@ -69,6 +70,8 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { public interface StageListenerCallbacks { void onRootTaskAppeared(); + void onChildTaskAppeared(int taskId); + void onStatusChanged(boolean visible, boolean hasChildren); void onChildTaskStatusChanged(int taskId, boolean present, boolean visible); @@ -185,6 +188,7 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { // Status is managed/synchronized by the transition lifecycle. return; } + mCallbacks.onChildTaskAppeared(taskId); sendStatusChanged(); } else { throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo @@ -338,6 +342,14 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { } } + void evictOtherChildren(WindowContainerTransaction wct, int taskId) { + for (int i = mChildrenTaskInfo.size() - 1; i >= 0; i--) { + final ActivityManager.RunningTaskInfo taskInfo = mChildrenTaskInfo.valueAt(i); + if (taskId == taskInfo.taskId) continue; + wct.reparent(taskInfo.token, null /* parent */, false /* onTop */); + } + } + void evictNonOpeningChildren(RemoteAnimationTarget[] apps, WindowContainerTransaction wct) { final SparseArray<ActivityManager.RunningTaskInfo> toBeEvict = mChildrenTaskInfo.clone(); for (int i = 0; i < apps.length; i++) { @@ -360,6 +372,12 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { } } + void reparentTopTask(WindowContainerTransaction wct) { + wct.reparentTasks(null /* currentParent */, mRootTaskInfo.token, + CONTROLLED_WINDOWING_MODES, CONTROLLED_ACTIVITY_TYPES, + true /* onTop */, true /* reparentTopOnly */); + } + void resetBounds(WindowContainerTransaction wct) { wct.setBounds(mRootTaskInfo.token, null); wct.setAppBounds(mRootTaskInfo.token, null); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java index 3cba92956f95..a2d7bc43653a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java @@ -111,7 +111,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler { @Override public WindowContainerTransaction handleRequest(@NonNull IBinder transition, @NonNull TransitionRequestInfo request) { - if (mPipHandler.requestHasPipEnter(request) && mSplitHandler.isSplitActive()) { + if (mPipHandler.requestHasPipEnter(request) && mSplitHandler.isSplitScreenVisible()) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Got a PiP-enter request while " + "Split-Screen is active, so treat it as Mixed."); if (request.getRemoteTransition() != null) { |