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

Commit 884bd51e authored by Evan Rosky's avatar Evan Rosky Committed by Automerger Merge Worker
Browse files

Merge "Hook up split-launch to legacy transition system" into sc-v2-dev am: 5b003d97

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15138014

Change-Id: Iba00e82284ae6e4f6dd4a6ba46c4af4147591be4
parents 26fcf8c5 5b003d97
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -336,4 +336,12 @@ interface IActivityTaskManager {
     * TODO(188595497): Remove this once navbar attachment is in shell.
     */
    void detachNavigationBarFromApp(in IBinder transition);

    /**
     * Marks a process as a delegate for the currently playing remote transition animation. This
     * must be called from a process that is already a remote transition player or delegate. Any
     * marked delegates are cleaned-up automatically at the end of the transition.
     * @param caller is the IApplicationThread representing the calling process.
     */
    void setRunningRemoteTransitionDelegate(in IApplicationThread caller);
}
+22 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.view;

import android.app.ActivityOptions;
import android.app.IApplicationThread;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build;
import android.os.Parcel;
@@ -58,6 +59,9 @@ public class RemoteAnimationAdapter implements Parcelable {
    private int mCallingPid;
    private int mCallingUid;

    /** @see #getCallingApplication */
    private IApplicationThread mCallingApplication;

    /**
     * @param runner The interface that gets notified when we actually need to start the animation.
     * @param duration The duration of the animation.
@@ -81,11 +85,19 @@ public class RemoteAnimationAdapter implements Parcelable {
        this(runner, duration, statusBarTransitionDelay, false /* changeNeedsSnapshot */);
    }

    @UnsupportedAppUsage
    public RemoteAnimationAdapter(IRemoteAnimationRunner runner, long duration,
            long statusBarTransitionDelay, IApplicationThread callingApplication) {
        this(runner, duration, statusBarTransitionDelay, false /* changeNeedsSnapshot */);
        mCallingApplication = callingApplication;
    }

    public RemoteAnimationAdapter(Parcel in) {
        mRunner = IRemoteAnimationRunner.Stub.asInterface(in.readStrongBinder());
        mDuration = in.readLong();
        mStatusBarTransitionDelay = in.readLong();
        mChangeNeedsSnapshot = in.readBoolean();
        mCallingApplication = IApplicationThread.Stub.asInterface(in.readStrongBinder());
    }

    public IRemoteAnimationRunner getRunner() {
@@ -126,6 +138,15 @@ public class RemoteAnimationAdapter implements Parcelable {
        return mCallingUid;
    }

    /**
     * Gets the ApplicationThread that will run the animation. Instead it is intended to pass the
     * calling information among client processes (eg. shell + launcher) through one-way binder
     * calls (where binder itself doesn't track calling information).
     */
    public IApplicationThread getCallingApplication() {
        return mCallingApplication;
    }

    @Override
    public int describeContents() {
        return 0;
@@ -137,6 +158,7 @@ public class RemoteAnimationAdapter implements Parcelable {
        dest.writeLong(mDuration);
        dest.writeLong(mStatusBarTransitionDelay);
        dest.writeBoolean(mChangeNeedsSnapshot);
        dest.writeStrongInterface(mCallingApplication);
    }

    public static final @android.annotation.NonNull Creator<RemoteAnimationAdapter> CREATOR
+10 −2
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.os.UserHandle;
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationTarget;
import android.window.IRemoteTransition;

import com.android.wm.shell.splitscreen.ISplitScreenListener;
@@ -77,9 +79,15 @@ interface ISplitScreen {
            int position, in Bundle options) = 9;

    /**
     * Starts tasks simultaneously in one transition. The first task in the list will be in the
     * main-stage and on the left/top.
     * Starts tasks simultaneously in one transition.
     */
    oneway void startTasks(int mainTaskId, in Bundle mainOptions, int sideTaskId,
            in Bundle sideOptions, int sidePosition, in IRemoteTransition remoteTransition) = 10;

    /**
     * Version of startTasks using legacy transition system.
     */
     oneway void startTasksWithLegacyTransition(int mainTaskId, in Bundle mainOptions,
                            int sideTaskId, in Bundle sideOptions, int sidePosition,
                            in RemoteAnimationAdapter adapter) = 11;
}
+11 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Slog;
import android.view.RemoteAnimationAdapter;
import android.window.IRemoteTransition;

import androidx.annotation.BinderThread;
@@ -427,6 +428,16 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
                    });
        }

        @Override
        public void startTasksWithLegacyTransition(int mainTaskId, @Nullable Bundle mainOptions,
                int sideTaskId, @Nullable Bundle sideOptions, @SplitPosition int sidePosition,
                RemoteAnimationAdapter adapter) {
            executeRemoteCallWithTaskPermission(mController, "startTasks",
                    (controller) -> controller.mStageCoordinator.startTasksWithLegacyTransition(
                            mainTaskId, mainOptions, sideTaskId, sideOptions, sidePosition,
                            adapter));
        }

        @Override
        public void startTasks(int mainTaskId, @Nullable Bundle mainOptions,
                int sideTaskId, @Nullable Bundle sideOptions,
+89 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.app.ActivityOptions.KEY_LAUNCH_ROOT_TASK_TOKEN;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
@@ -42,12 +43,21 @@ import static com.android.wm.shell.transition.Transitions.isOpeningType;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.app.WindowConfiguration;
import android.content.Context;
import android.graphics.Rect;
import android.hardware.devicestate.DeviceStateManager;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.util.Slog;
import android.view.IRemoteAnimationFinishedCallback;
import android.view.IRemoteAnimationRunner;
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.view.WindowManager;
@@ -248,6 +258,75 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
                TRANSIT_SPLIT_SCREEN_PAIR_OPEN, wct, remoteTransition, this);
    }

    /** Starts 2 tasks in one legacy transition. */
    void startTasksWithLegacyTransition(int mainTaskId, @Nullable Bundle mainOptions,
            int sideTaskId, @Nullable Bundle sideOptions, @SplitPosition int sidePosition,
            RemoteAnimationAdapter adapter) {
        final WindowContainerTransaction wct = new WindowContainerTransaction();
        // 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();
                try {
                    ActivityTaskManager.getService().setRunningRemoteTransitionDelegate(
                            adapter.getCallingApplication());
                    adapter.getRunner().onAnimationStart(transit, apps, wallpapers, nonApps,
                            finishedCallback);
                } catch (RemoteException e) {
                    Slog.e(TAG, "Error starting remote animation", e);
                }
            }

            @Override
            public void onAnimationCancelled() {
                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));
        }

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

        // 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);
        mSideStage.setBounds(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
        wct.startTask(mainTaskId, mainOptions);
        wct.startTask(sideTaskId, sideOptions);

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

    @SplitLayout.SplitPosition
    int getSideStagePosition() {
        return mSideStagePosition;
@@ -891,6 +970,16 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        }
    }

    private RemoteAnimationTarget getDividerBarLegacyTarget() {
        final Rect bounds = mSplitLayout.getDividerBounds();
        return new RemoteAnimationTarget(-1 /* taskId */, -1 /* mode */,
                mSplitLayout.getDividerLeash(), false /* isTranslucent */, null /* clipRect */,
                null /* contentInsets */, Integer.MAX_VALUE /* prefixOrderIndex */,
                new android.graphics.Point(0, 0) /* position */, bounds, bounds,
                new WindowConfiguration(), true, null /* startLeash */, null /* startBounds */,
                null /* taskInfo */, TYPE_DOCK_DIVIDER);
    }

    @Override
    public void dump(@NonNull PrintWriter pw, String prefix) {
        final String innerPrefix = prefix + "  ";
Loading