diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectDataHolder.kt b/quickstep/src/com/android/quickstep/util/SplitSelectDataHolder.kt index 614dfe82d6..8e6415b303 100644 --- a/quickstep/src/com/android/quickstep/util/SplitSelectDataHolder.kt +++ b/quickstep/src/com/android/quickstep/util/SplitSelectDataHolder.kt @@ -61,7 +61,8 @@ class SplitSelectDataHolder( */ companion object { @IntDef(SPLIT_TASK_TASK, SPLIT_TASK_PENDINGINTENT, SPLIT_TASK_SHORTCUT, - SPLIT_PENDINGINTENT_TASK, SPLIT_PENDINGINTENT_PENDINGINTENT, SPLIT_SHORTCUT_TASK) + SPLIT_PENDINGINTENT_TASK, SPLIT_PENDINGINTENT_PENDINGINTENT, SPLIT_SHORTCUT_TASK, + SPLIT_SINGLE_TASK_FULLSCREEN, SPLIT_SINGLE_INTENT_FULLSCREEN) @Retention(AnnotationRetention.SOURCE) annotation class SplitLaunchType @@ -71,6 +72,10 @@ class SplitSelectDataHolder( const val SPLIT_PENDINGINTENT_TASK = 3 const val SPLIT_SHORTCUT_TASK = 4 const val SPLIT_PENDINGINTENT_PENDINGINTENT = 5 + + // Non-split edge case of launching the initial selected task as a fullscreen task + const val SPLIT_SINGLE_TASK_FULLSCREEN = 6 + const val SPLIT_SINGLE_INTENT_FULLSCREEN = 7 } @@ -190,7 +195,7 @@ class SplitSelectDataHolder( /** * @return [SplitLaunchData] with the necessary fields populated as determined by - * [SplitLaunchData.splitLaunchType] + * [SplitLaunchData.splitLaunchType]. This is to be used for launching splitscreen */ fun getSplitLaunchData() : SplitLaunchData { // Convert all intents to shortcut infos to see if determine if we launch shortcut or intent @@ -201,6 +206,24 @@ class SplitSelectDataHolder( initialStagePosition = getOppositeStagePosition(initialStagePosition) } + return generateSplitLaunchData(splitLaunchType) + } + + /** + * @return [SplitLaunchData] with the necessary fields populated as determined by + * [SplitLaunchData.splitLaunchType]. This is to be used for launching an initially selected + * split task in fullscreen + */ + fun getFullscreenLaunchData() : SplitLaunchData { + // Convert all intents to shortcut infos to see if determine if we launch shortcut or intent + convertIntentsToFinalTypes() + val splitLaunchType = if (initialTaskId != INVALID_TASK_ID) SPLIT_SINGLE_TASK_FULLSCREEN + else SPLIT_SINGLE_INTENT_FULLSCREEN + + return generateSplitLaunchData(splitLaunchType) + } + + private fun generateSplitLaunchData(@SplitLaunchType splitLaunchType: Int) : SplitLaunchData { return SplitLaunchData( splitLaunchType, initialTaskId, diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java index ee51af7a5d..ec8be89ecb 100644 --- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java +++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java @@ -27,6 +27,8 @@ import static com.android.launcher3.util.SplitConfigurationOptions.getOppositeSt import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_PENDINGINTENT_PENDINGINTENT; import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_PENDINGINTENT_TASK; import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_SHORTCUT_TASK; +import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_SINGLE_INTENT_FULLSCREEN; +import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_SINGLE_TASK_FULLSCREEN; import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_TASK_PENDINGINTENT; import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_TASK_SHORTCUT; import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_TASK_TASK; @@ -324,11 +326,8 @@ public class SplitSelectStateController { } boolean hasSecondaryPendingIntent = mSecondPendingIntent != null; if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) { - final RemoteSplitLaunchTransitionRunner animationRunner = - new RemoteSplitLaunchTransitionRunner(taskId1, taskId2, callback); - final RemoteTransition remoteTransition = new RemoteTransition(animationRunner, - ActivityThread.currentActivityThread().getApplicationThread(), - "LaunchSplitPair"); + final RemoteTransition remoteTransition = getShellRemoteTransition(taskId1, taskId2, + callback); if (intent1 == null && (intent2 == null && !hasSecondaryPendingIntent)) { mSystemUiProxy.startTasks(taskId1, options1.toBundle(), taskId2, null /* options2 */, stagePosition, splitRatio, remoteTransition, @@ -351,11 +350,8 @@ public class SplitSelectStateController { shellInstanceId); } } else { - final RemoteSplitLaunchAnimationRunner animationRunner = - new RemoteSplitLaunchAnimationRunner(taskId1, taskId2, callback); - final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter( - animationRunner, 300, 150, - ActivityThread.currentActivityThread().getApplicationThread()); + final RemoteAnimationAdapter adapter = getLegacyRemoteAdapter(taskId1, taskId2, + callback); if (intent1 == null && (intent2 == null && !hasSecondaryPendingIntent)) { mSystemUiProxy.startTasksWithLegacyTransition(taskId1, options1.toBundle(), @@ -402,11 +398,8 @@ public class SplitSelectStateController { Bundle optionsBundle = options1.toBundle(); if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) { - final RemoteSplitLaunchTransitionRunner animationRunner = - new RemoteSplitLaunchTransitionRunner(firstTaskId, secondTaskId, callback); - final RemoteTransition remoteTransition = new RemoteTransition(animationRunner, - ActivityThread.currentActivityThread().getApplicationThread(), - "LaunchSplitPair"); + final RemoteTransition remoteTransition = getShellRemoteTransition(firstTaskId, + secondTaskId, callback); switch (launchData.getSplitLaunchType()) { case SPLIT_TASK_TASK -> mSystemUiProxy.startTasks(firstTaskId, optionsBundle, secondTaskId, @@ -440,11 +433,8 @@ public class SplitSelectStateController { remoteTransition, shellInstanceId); } } else { - final RemoteSplitLaunchAnimationRunner animationRunner = - new RemoteSplitLaunchAnimationRunner(firstTaskId, secondTaskId, callback); - final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter( - animationRunner, 300, 150, - ActivityThread.currentActivityThread().getApplicationThread()); + final RemoteAnimationAdapter adapter = getLegacyRemoteAdapter(firstTaskId, secondTaskId, + callback); switch (launchData.getSplitLaunchType()) { case SPLIT_TASK_TASK -> mSystemUiProxy.startTasksWithLegacyTransition(firstTaskId, optionsBundle, @@ -501,26 +491,90 @@ public class SplitSelectStateController { Bundle optionsBundle = options1.toBundle(); if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) { - final RemoteSplitLaunchTransitionRunner animationRunner = - new RemoteSplitLaunchTransitionRunner(firstTaskId, secondTaskId, callback); - final RemoteTransition remoteTransition = new RemoteTransition(animationRunner, - ActivityThread.currentActivityThread().getApplicationThread(), - "LaunchSplitPair"); + final RemoteTransition remoteTransition = getShellRemoteTransition(firstTaskId, + secondTaskId, callback); mSystemUiProxy.startTasks(firstTaskId, optionsBundle, secondTaskId, null /* options2 */, stagePosition, splitRatio, remoteTransition, null /*shellInstanceId*/); } else { - final RemoteSplitLaunchAnimationRunner animationRunner = - new RemoteSplitLaunchAnimationRunner(firstTaskId, secondTaskId, callback); - final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter( - animationRunner, 300, 150, - ActivityThread.currentActivityThread().getApplicationThread()); + final RemoteAnimationAdapter adapter = getLegacyRemoteAdapter(firstTaskId, + secondTaskId, callback); mSystemUiProxy.startTasksWithLegacyTransition(firstTaskId, optionsBundle, secondTaskId, null /* options2 */, stagePosition, splitRatio, adapter, null /*shellInstanceId*/); } } + /** + * Launches the initially selected task/intent in fullscreen (note the same SystemUi APIs are + * used as {@link #launchSplitTasks(Consumer)} because they are overloaded to launch both + * split and fullscreen tasks) + */ + public void launchInitialAppFullscreen(Consumer callback) { + if (!FeatureFlags.ENABLE_SPLIT_LAUNCH_DATA_REFACTOR.get()) { + launchSplitTasks(callback); + return; + } + + final ActivityOptions options1 = ActivityOptions.makeBasic(); + SplitSelectDataHolder.SplitLaunchData launchData = + mSplitSelectDataHolder.getFullscreenLaunchData(); + int firstTaskId = launchData.getInitialTaskId(); + int secondTaskId = launchData.getSecondTaskId(); + PendingIntent firstPI = launchData.getInitialPendingIntent(); + int firstUserId = launchData.getInitialUserId(); + int initialStagePosition = launchData.getInitialStagePosition(); + Bundle optionsBundle = options1.toBundle(); + + final RemoteSplitLaunchTransitionRunner animationRunner = + new RemoteSplitLaunchTransitionRunner(firstTaskId, secondTaskId, callback); + final RemoteTransition remoteTransition = new RemoteTransition(animationRunner, + ActivityThread.currentActivityThread().getApplicationThread(), + "LaunchSplitPair"); + Pair instanceIds = + LogUtils.getShellShareableInstanceId(); + if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) { + switch (launchData.getSplitLaunchType()) { + case SPLIT_SINGLE_TASK_FULLSCREEN -> mSystemUiProxy.startTasks(firstTaskId, + optionsBundle, secondTaskId, null /* options2 */, initialStagePosition, + DEFAULT_SPLIT_RATIO, remoteTransition, instanceIds.first); + case SPLIT_SINGLE_INTENT_FULLSCREEN -> mSystemUiProxy.startIntentAndTask(firstPI, + firstUserId, optionsBundle, secondTaskId, null /*options2*/, + initialStagePosition, DEFAULT_SPLIT_RATIO, remoteTransition, + instanceIds.first); + } + } else { + final RemoteAnimationAdapter adapter = getLegacyRemoteAdapter(firstTaskId, + secondTaskId, callback); + switch (launchData.getSplitLaunchType()) { + case SPLIT_SINGLE_TASK_FULLSCREEN -> mSystemUiProxy.startTasksWithLegacyTransition( + firstTaskId, optionsBundle, secondTaskId, null /* options2 */, + initialStagePosition, DEFAULT_SPLIT_RATIO, adapter, instanceIds.first); + case SPLIT_SINGLE_INTENT_FULLSCREEN -> + mSystemUiProxy.startIntentAndTaskWithLegacyTransition(firstPI, firstUserId, + optionsBundle, secondTaskId, null /*options2*/, + initialStagePosition, DEFAULT_SPLIT_RATIO, adapter, + instanceIds.first); + } + } + } + + private RemoteTransition getShellRemoteTransition(int firstTaskId, int secondTaskId, + Consumer callback) { + final RemoteSplitLaunchTransitionRunner animationRunner = + new RemoteSplitLaunchTransitionRunner(firstTaskId, secondTaskId, callback); + return new RemoteTransition(animationRunner, + ActivityThread.currentActivityThread().getApplicationThread(), "LaunchSplitPair"); + } + + private RemoteAnimationAdapter getLegacyRemoteAdapter(int firstTaskId, int secondTaskId, + Consumer callback) { + final RemoteSplitLaunchAnimationRunner animationRunner = + new RemoteSplitLaunchAnimationRunner(firstTaskId, secondTaskId, callback); + return new RemoteAnimationAdapter(animationRunner, 300, 150, + ActivityThread.currentActivityThread().getApplicationThread()); + } + private void launchIntentOrShortcut(Intent intent, UserHandle user, ActivityOptions options1, int taskId, @StagePosition int stagePosition, float splitRatio, RemoteTransition remoteTransition, @Nullable InstanceId shellInstanceId) { diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index d8fe32db85..f740d9c082 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -3260,7 +3260,7 @@ public abstract class RecentsView - mSplitSelectStateController.launchSplitTasks(launchSuccess -> + mSplitSelectStateController.launchInitialAppFullscreen(launchSuccess -> resetFromSplitSelectionState())); pendingAnimation.buildAnim().start();