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

Commit 9e6e09c0 authored by Tracy Zhou's avatar Tracy Zhou Committed by Android (Google) Code Review
Browse files

Merge "Support launching intent and task in split screen"

parents 80d6ef87 275a1a4b
Loading
Loading
Loading
Loading
+14 −4
Original line number Original line Diff line number Diff line
@@ -93,6 +93,14 @@ interface ISplitScreen {
            int sideTaskId, in Bundle sideOptions, int sidePosition,
            int sideTaskId, in Bundle sideOptions, int sidePosition,
            float splitRatio, in RemoteAnimationAdapter adapter) = 11;
            float splitRatio, in RemoteAnimationAdapter adapter) = 11;


    /**
     * Start a pair of intent and task using legacy transition system.
     */
    oneway void startIntentAndTaskWithLegacyTransition(in PendingIntent pendingIntent,
            in Intent fillInIntent, int taskId, boolean intentFirst, in Bundle mainOptions,
            in Bundle sideOptions, int sidePosition, float splitRatio,
            in RemoteAnimationAdapter adapter) = 12;

    /**
    /**
     * Blocking call that notifies and gets additional split-screen targets when entering
     * Blocking call that notifies and gets additional split-screen targets when entering
     * recents (for example: the dividerBar).
     * recents (for example: the dividerBar).
@@ -100,5 +108,7 @@ interface ISplitScreen {
     * @param appTargets apps that will be re-parented to display area
     * @param appTargets apps that will be re-parented to display area
     */
     */
    RemoteAnimationTarget[] onGoingToRecentsLegacy(boolean cancel,
    RemoteAnimationTarget[] onGoingToRecentsLegacy(boolean cancel,
                                                   in RemoteAnimationTarget[] appTargets) = 12;
                                                   in RemoteAnimationTarget[] appTargets) = 13;


}
}
+12 −0
Original line number Original line Diff line number Diff line
@@ -640,6 +640,18 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
                            splitRatio, adapter));
                            splitRatio, adapter));
        }
        }


        @Override
        public void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent,
                Intent fillInIntent, int taskId, boolean intentFirst, Bundle mainOptions,
                Bundle sideOptions, int sidePosition, float splitRatio,
                RemoteAnimationAdapter adapter) {
            executeRemoteCallWithTaskPermission(mController,
                    "startIntentAndTaskWithLegacyTransition", (controller) ->
                            controller.mStageCoordinator.startIntentAndTaskWithLegacyTransition(
                                    pendingIntent, fillInIntent, taskId, intentFirst, mainOptions,
                                    sideOptions, sidePosition, splitRatio, adapter));
        }

        @Override
        @Override
        public void startTasks(int mainTaskId, @Nullable Bundle mainOptions,
        public void startTasks(int mainTaskId, @Nullable Bundle mainOptions,
                int sideTaskId, @Nullable Bundle sideOptions,
                int sideTaskId, @Nullable Bundle sideOptions,
+112 −0
Original line number Original line Diff line number Diff line
@@ -57,8 +57,10 @@ import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.app.ActivityTaskManager;
import android.app.PendingIntent;
import android.app.WindowConfiguration;
import android.app.WindowConfiguration;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.graphics.Rect;
import android.hardware.devicestate.DeviceStateManager;
import android.hardware.devicestate.DeviceStateManager;
@@ -467,6 +469,116 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        mTaskOrganizer.applyTransaction(wct);
        mTaskOrganizer.applyTransaction(wct);
    }
    }


    /** Start an intent and a task ordered by {@code intentFirst}. */
    void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, Intent fillInIntent,
            int taskId, boolean intentFirst, @Nullable Bundle mainOptions,
            @Nullable Bundle sideOptions, @SplitPosition int sidePosition, float splitRatio,
            RemoteAnimationAdapter adapter) {
        // TODO: try pulling the first chunk of this method into a method so that it can be shared
        // with startTasksWithLegacyTransition. So far attempts to do so result in failure in split.

        // Init divider first to make divider leash for remote animation target.
        mSplitLayout.init();
        // Set false to avoid record new bounds with old task still on top;
        mShouldUpdateRecents = false;
        final WindowContainerTransaction wct = new WindowContainerTransaction();
        final WindowContainerTransaction evictWct = new WindowContainerTransaction();
        prepareEvictChildTasks(SPLIT_POSITION_TOP_OR_LEFT, evictWct);
        prepareEvictChildTasks(SPLIT_POSITION_BOTTOM_OR_RIGHT, evictWct);
        // Need to add another wrapper here in shell so that we can inject the divider bar
        // and also manage the process elevation via setRunningRemote
        IRemoteAnimationRunner wrapper = new IRemoteAnimationRunner.Stub() {
            @Override
            public void onAnimationStart(@WindowManager.TransitionOldType int transit,
                    RemoteAnimationTarget[] apps,
                    RemoteAnimationTarget[] wallpapers,
                    RemoteAnimationTarget[] nonApps,
                    final IRemoteAnimationFinishedCallback finishedCallback) {
                RemoteAnimationTarget[] augmentedNonApps =
                        new RemoteAnimationTarget[nonApps.length + 1];
                for (int i = 0; i < nonApps.length; ++i) {
                    augmentedNonApps[i] = nonApps[i];
                }
                augmentedNonApps[augmentedNonApps.length - 1] = getDividerBarLegacyTarget();

                IRemoteAnimationFinishedCallback wrapCallback =
                        new IRemoteAnimationFinishedCallback.Stub() {
                            @Override
                            public void onAnimationFinished() throws RemoteException {
                                mShouldUpdateRecents = true;
                                mSyncQueue.queue(evictWct);
                                mSyncQueue.runInSync(t -> setDividerVisibility(true, t));
                                finishedCallback.onAnimationFinished();
                            }
                        };
                try {
                    try {
                        ActivityTaskManager.getService().setRunningRemoteTransitionDelegate(
                                adapter.getCallingApplication());
                    } catch (SecurityException e) {
                        Slog.e(TAG, "Unable to boost animation thread. This should only happen"
                                + " during unit tests");
                    }
                    adapter.getRunner().onAnimationStart(transit, apps, wallpapers,
                            augmentedNonApps, wrapCallback);
                } catch (RemoteException e) {
                    Slog.e(TAG, "Error starting remote animation", e);
                }
            }

            @Override
            public void onAnimationCancelled() {
                mShouldUpdateRecents = true;
                mSyncQueue.queue(evictWct);
                mSyncQueue.runInSync(t -> setDividerVisibility(true, t));
                try {
                    adapter.getRunner().onAnimationCancelled();
                } catch (RemoteException e) {
                    Slog.e(TAG, "Error starting remote animation", e);
                }
            }
        };
        RemoteAnimationAdapter wrappedAdapter = new RemoteAnimationAdapter(
                wrapper, adapter.getDuration(), adapter.getStatusBarTransitionDelay());

        if (mainOptions == null) {
            mainOptions = ActivityOptions.makeRemoteAnimation(wrappedAdapter).toBundle();
        } else {
            ActivityOptions mainActivityOptions = ActivityOptions.fromBundle(mainOptions);
            mainActivityOptions.update(ActivityOptions.makeRemoteAnimation(wrappedAdapter));
            mainOptions = mainActivityOptions.toBundle();
        }

        sideOptions = sideOptions != null ? sideOptions : new Bundle();
        setSideStagePosition(sidePosition, wct);

        mSplitLayout.setDivideRatio(splitRatio);
        if (mMainStage.isActive()) {
            mMainStage.moveToTop(getMainStageBounds(), wct);
        } else {
            // Build a request WCT that will launch both apps such that task 0 is on the main stage
            // while task 1 is on the side stage.
            mMainStage.activate(getMainStageBounds(), wct, false /* reparent */);
        }
        mSideStage.moveToTop(getSideStageBounds(), wct);

        // Make sure the launch options will put tasks in the corresponding split roots
        addActivityOptions(mainOptions, mMainStage);
        addActivityOptions(sideOptions, mSideStage);

        // Add task launch requests
        if (intentFirst) {
            wct.sendPendingIntent(pendingIntent, fillInIntent, mainOptions);
            wct.startTask(taskId, sideOptions);
        } else {
            wct.startTask(taskId, mainOptions);
            wct.sendPendingIntent(pendingIntent, fillInIntent, sideOptions);
        }

        // Using legacy transitions, so we can't use blast sync since it conflicts.
        mTaskOrganizer.applyTransaction(wct);
    }

    /**
    /**
     * Collects all the current child tasks of a specific split and prepares transaction to evict
     * Collects all the current child tasks of a specific split and prepares transaction to evict
     * them to display.
     * them to display.