Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ed7b50ef authored by Vinit Nayak's avatar Vinit Nayak Committed by Android (Google) Code Review
Browse files

Merge "Handle fullscreen app launchs in split init flow for SplitSelectDataHolder" into udc-dev

parents b4e91b14 69ee1b9c
Loading
Loading
Loading
Loading
+25 −2
Original line number Diff line number Diff line
@@ -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,
+84 −30
Original line number Diff line number Diff line
@@ -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,24 +491,88 @@ public class SplitSelectStateController {
        Bundle optionsBundle = options1.toBundle();

        if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
            final RemoteTransition remoteTransition = getShellRemoteTransition(firstTaskId,
                    secondTaskId, callback);
            mSystemUiProxy.startTasks(firstTaskId, optionsBundle, secondTaskId,
                    null /* options2 */, stagePosition, splitRatio,
                    remoteTransition, null /*shellInstanceId*/);
        } else {
            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<Boolean> 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");
            mSystemUiProxy.startTasks(firstTaskId, optionsBundle, secondTaskId,
                    null /* options2 */, stagePosition, splitRatio,
                    remoteTransition, null /*shellInstanceId*/);
        Pair<InstanceId, com.android.launcher3.logging.InstanceId> 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<Boolean> 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<Boolean> callback) {
        final RemoteSplitLaunchAnimationRunner animationRunner =
                new RemoteSplitLaunchAnimationRunner(firstTaskId, secondTaskId, callback);
            final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter(
                    animationRunner, 300, 150,
        return new RemoteAnimationAdapter(animationRunner, 300, 150,
                ActivityThread.currentActivityThread().getApplicationThread());
            mSystemUiProxy.startTasksWithLegacyTransition(firstTaskId, optionsBundle,
                    secondTaskId, null /* options2 */, stagePosition,
                    splitRatio, adapter, null /*shellInstanceId*/);
        }
    }

    private void launchIntentOrShortcut(Intent intent, UserHandle user, ActivityOptions options1,
+1 −1
Original line number Diff line number Diff line
@@ -3260,7 +3260,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
                true /* isStagedTask */);

        pendingAnimation.addEndListener(animationSuccess ->
                mSplitSelectStateController.launchSplitTasks(launchSuccess ->
                mSplitSelectStateController.launchInitialAppFullscreen(launchSuccess ->
                        resetFromSplitSelectionState()));

        pendingAnimation.buildAnim().start();