Loading libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java +6 −3 Original line number Diff line number Diff line Loading @@ -847,9 +847,12 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, .map(recentTasks -> recentTasks.findTaskInBackground(component, userId1)) .orElse(null); if (taskInfo != null) { 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"); } ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Start task in background"); return; } if (samePackage(packageName1, packageName2, userId1, userId2)) { Loading libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +28 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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. if (!mIsDropEntering) { mMainStage.evictAllChildren(wct); } mMainStage.reparentTopTask(wct); prepareSplitLayout(wct, resizeAnim); } Loading libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java +13 −0 Original line number Diff line number Diff line Loading @@ -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.DesktopTasksController; Loading Loading @@ -901,6 +902,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); Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java +3 −4 Original line number Diff line number Diff line Loading @@ -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()); Loading @@ -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 = Loading @@ -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()); } Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java +6 −3 Original line number Diff line number Diff line Loading @@ -847,9 +847,12 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, .map(recentTasks -> recentTasks.findTaskInBackground(component, userId1)) .orElse(null); if (taskInfo != null) { 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"); } ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Start task in background"); return; } if (samePackage(packageName1, packageName2, userId1, userId2)) { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +28 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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. if (!mIsDropEntering) { mMainStage.evictAllChildren(wct); } mMainStage.reparentTopTask(wct); prepareSplitLayout(wct, resizeAnim); } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java +13 −0 Original line number Diff line number Diff line Loading @@ -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.DesktopTasksController; Loading Loading @@ -901,6 +902,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); Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java +3 −4 Original line number Diff line number Diff line Loading @@ -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()); Loading @@ -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 = Loading @@ -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()); } Loading