diff options
| author | 2023-12-05 18:14:19 -0800 | |
|---|---|---|
| committer | 2023-12-07 16:01:50 -0800 | |
| commit | 89dfc741c4c9386a9da42efe31374c9257894e78 (patch) | |
| tree | a12ce694fe1cbd49825014e45f4a81c89ab88a00 | |
| parent | ca834953e8860043a5ffdb8410538c8791d20191 (diff) | |
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
4 files changed, 50 insertions, 8 deletions
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 37b24e505ade..b7e98daf1dc7 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 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, .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 be685b57f779..449bef5608c9 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 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, 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 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } } + /** 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 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, // 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 ce7fef2d1fdf..d73dc184560a 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.WindowContainerToken; 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 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler, 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 99cd4f391153..855b7ee04702 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 @@ public class SplitScreenControllerTests extends ShellTestCase { 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 @@ public class SplitScreenControllerTests extends ShellTestCase { @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 @@ public class SplitScreenControllerTests extends ShellTestCase { 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()); } |