summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java16
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitscreenEventLogger.java8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java154
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java18
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java2
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) {