Evict all main stage tasks only for non-drag split starts
* See bug for root cause info.
* Technically we'd want to expand the scope of this
to not only drag n drop but all explicit split starts, but
for QPR2 we'll keep it contained.
* The reason we evict has to do w/ launch-adjacent split
scenarios (highlighted in original bug b/279720005)
Test: Original bug doesn't repro nor does the current one with
drag and drop. Tested Chrome w/ some multi-instance drags and
that also seems to work fine
Fixes: 309905087
Flag: None
Change-Id: I3b4238141d8fadf0cde2ea7fe9fe1161496ce888
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 37b24e5..b7e98da 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
@@ -838,9 +838,12 @@
.map(recentTasks -> recentTasks.findTaskInBackground(component, userId1))
.orElse(null);
if (taskInfo != null) {
- startTask(taskInfo.taskId, position, options);
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
- "Start task in background");
+ if (ENABLE_SHELL_TRANSITIONS) {
+ mStageCoordinator.startTask(taskInfo.taskId, position, options);
+ } else {
+ startTask(taskInfo.taskId, position, options);
+ }
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Start task in background");
return;
}
if (samePackage(packageName1, packageName2, userId1, userId2)) {
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 be685b5..449bef5 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
@@ -263,6 +263,10 @@
mStartIntent2 = startIntent2;
mActivatePosition = position;
}
+ SplitRequest(int taskId1, int position) {
+ mActivateTaskId = taskId1;
+ mActivatePosition = position;
+ }
SplitRequest(int taskId1, int taskId2, int position) {
mActivateTaskId = taskId1;
mActivateTaskId2 = taskId2;
@@ -556,6 +560,27 @@
}
}
+ /** Use this method to launch an existing Task via a taskId */
+ void startTask(int taskId, @SplitPosition int position, @Nullable Bundle options) {
+ mSplitRequest = new SplitRequest(taskId, position);
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+ options = resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, null /* wct */);
+ wct.startTask(taskId, options);
+ // If this should be mixed, send the task to avoid split handle transition directly.
+ if (mMixedHandler != null && mMixedHandler.shouldSplitEnterMixed(taskId, mTaskOrganizer)) {
+ 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, !mIsDropEntering);
+
+ mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct, null, this,
+ extraTransitType, !mIsDropEntering);
+ }
+
/** Launches an activity into split. */
void startIntent(PendingIntent intent, Intent fillInIntent, @SplitPosition int position,
@Nullable Bundle options) {
@@ -1593,7 +1618,9 @@
// Ensure to evict old splitting tasks because the new split pair might be composed by
// one of the splitting tasks, evicting the task when finishing entering transition
// won't guarantee to put the task to the indicated new position.
- mMainStage.evictAllChildren(wct);
+ if (!mIsDropEntering) {
+ mMainStage.evictAllChildren(wct);
+ }
mMainStage.reparentTopTask(wct);
prepareSplitLayout(wct, resizeAnim);
}
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 ce7fef2..d73dc18 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
@@ -48,6 +48,7 @@
import android.window.WindowContainerTransaction;
import com.android.internal.protolog.common.ProtoLog;
+import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.activityembedding.ActivityEmbeddingController;
import com.android.wm.shell.common.split.SplitScreenUtils;
import com.android.wm.shell.desktopmode.DesktopModeStatus;
@@ -902,6 +903,18 @@
return false;
}
+ /** Use to when split use taskId to enter, check if this enter transition should be mixed or
+ * not.*/
+ public boolean shouldSplitEnterMixed(int taskId, ShellTaskOrganizer shellTaskOrganizer) {
+ // Check if this intent package is same as pip one or not, if true we want let the pip
+ // task enter split.
+ if (mPipHandler != null) {
+ return mPipHandler.isInPipPackage(
+ SplitScreenUtils.getPackageName(taskId, shellTaskOrganizer));
+ }
+ return false;
+ }
+
/** @return whether the transition-request represents a pip-entry. */
public boolean requestHasPipEnter(TransitionRequestInfo request) {
return mPipHandler.requestHasPipEnter(request);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
index 99cd4f3..855b7ee 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
@@ -235,7 +235,7 @@
mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
SPLIT_POSITION_TOP_OR_LEFT, null);
- verify(mSplitScreenController).startTask(anyInt(), eq(SPLIT_POSITION_TOP_OR_LEFT),
+ verify(mStageCoordinator).startTask(anyInt(), eq(SPLIT_POSITION_TOP_OR_LEFT),
isNull());
verify(mSplitScreenController, never()).supportMultiInstancesSplit(any());
verify(mStageCoordinator, never()).switchSplitPosition(any());
@@ -243,7 +243,6 @@
@Test
public void startIntent_multiInstancesSupported_startTaskInBackgroundAfterSplitActivated() {
- doReturn(true).when(mSplitScreenController).supportMultiInstancesSplit(any());
doNothing().when(mSplitScreenController).startTask(anyInt(), anyInt(), any());
Intent startIntent = createStartIntent("startActivity");
PendingIntent pendingIntent =
@@ -260,8 +259,8 @@
mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
SPLIT_POSITION_TOP_OR_LEFT, null);
-
- verify(mSplitScreenController).startTask(anyInt(), eq(SPLIT_POSITION_TOP_OR_LEFT),
+ verify(mSplitScreenController, never()).supportMultiInstancesSplit(any());
+ verify(mStageCoordinator).startTask(anyInt(), eq(SPLIT_POSITION_TOP_OR_LEFT),
isNull());
}