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

Commit 6b9435a3 authored by Hongwei Wang's avatar Hongwei Wang Committed by Android (Google) Code Review
Browse files

Merge "Add Content PiP support with launch-into-pip API"

parents 1f9bfdb9 54400760
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -4550,6 +4550,7 @@ package android.app {
    method public static android.app.ActivityOptions makeClipRevealAnimation(android.view.View, int, int, int, int);
    method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int);
    method @NonNull public static android.app.ActivityOptions makeCustomAnimation(@NonNull android.content.Context, int, int, int);
    method @NonNull public static android.app.ActivityOptions makeLaunchIntoPip(@NonNull android.app.PictureInPictureParams);
    method public static android.app.ActivityOptions makeScaleUpAnimation(android.view.View, int, int, int, int);
    method public static android.app.ActivityOptions makeSceneTransitionAnimation(android.app.Activity, android.view.View, String);
    method @java.lang.SafeVarargs public static android.app.ActivityOptions makeSceneTransitionAnimation(android.app.Activity, android.util.Pair<android.view.View,java.lang.String>...);
@@ -6635,6 +6636,7 @@ package android.app {
  public static class PictureInPictureParams.Builder {
    ctor public PictureInPictureParams.Builder();
    ctor public PictureInPictureParams.Builder(@NonNull android.app.PictureInPictureParams);
    method public android.app.PictureInPictureParams build();
    method public android.app.PictureInPictureParams.Builder setActions(java.util.List<android.app.RemoteAction>);
    method public android.app.PictureInPictureParams.Builder setAspectRatio(android.util.Rational);
+45 −0
Original line number Diff line number Diff line
@@ -350,6 +350,10 @@ public class ActivityOptions extends ComponentOptions {
    /** See {@link #setTransientLaunch()}. */
    private static final String KEY_TRANSIENT_LAUNCH = "android.activity.transientLaunch";

    /** see {@link #makeLaunchIntoPip(PictureInPictureParams)}. */
    private static final String KEY_LAUNCH_INTO_PIP_PARAMS =
            "android.activity.launchIntoPipParams";

    /**
     * @see #setLaunchCookie
     * @hide
@@ -444,6 +448,7 @@ public class ActivityOptions extends ComponentOptions {
    private boolean mRemoveWithTaskOrganizer;
    private boolean mLaunchedFromBubble;
    private boolean mTransientLaunch;
    private PictureInPictureParams mLaunchIntoPipParams;

    /**
     * Create an ActivityOptions specifying a custom animation to run when
@@ -1106,6 +1111,24 @@ public class ActivityOptions extends ComponentOptions {
        return opts;
    }

    /**
     * Creates an {@link ActivityOptions} instance that launch into picture-in-picture.
     * This is normally used by a Host activity to start another activity that will directly enter
     * picture-in-picture upon its creation.
     * @param pictureInPictureParams {@link PictureInPictureParams} for launching the Activity to
     *                               picture-in-picture mode.
     */
    @NonNull
    public static ActivityOptions makeLaunchIntoPip(
            @NonNull PictureInPictureParams pictureInPictureParams) {
        final ActivityOptions opts = new ActivityOptions();
        opts.mLaunchIntoPipParams = new PictureInPictureParams.Builder(pictureInPictureParams)
                .setIsLaunchIntoPip(true)
                .build();
        opts.mLaunchBounds = new Rect(pictureInPictureParams.getSourceRectHint());
        return opts;
    }

    /** @hide */
    public boolean getLaunchTaskBehind() {
        return mAnimationType == ANIM_LAUNCH_TASK_BEHIND;
@@ -1219,6 +1242,7 @@ public class ActivityOptions extends ComponentOptions {
        mLaunchedFromBubble = opts.getBoolean(KEY_LAUNCHED_FROM_BUBBLE);
        mTransientLaunch = opts.getBoolean(KEY_TRANSIENT_LAUNCH);
        mSplashScreenStyle = opts.getInt(KEY_SPLASH_SCREEN_STYLE);
        mLaunchIntoPipParams = opts.getParcelable(KEY_LAUNCH_INTO_PIP_PARAMS);
    }

    /**
@@ -1556,6 +1580,23 @@ public class ActivityOptions extends ComponentOptions {
        mLaunchWindowingMode = windowingMode;
    }

    /**
     * @return {@link PictureInPictureParams} used to launch into PiP mode.
     * @hide
     */
    public PictureInPictureParams getLaunchIntoPipParams() {
        return mLaunchIntoPipParams;
    }

    /**
     * @return {@code true} if this instance is used to launch into PiP mode.
     * @hide
     */
    public boolean isLaunchIntoPip() {
        return mLaunchIntoPipParams != null
                && mLaunchIntoPipParams.isLaunchIntoPip();
    }

    /** @hide */
    public int getLaunchActivityType() {
        return mLaunchActivityType;
@@ -1867,6 +1908,7 @@ public class ActivityOptions extends ComponentOptions {
        mAnimationFinishedListener = otherOptions.mAnimationFinishedListener;
        mSpecsFuture = otherOptions.mSpecsFuture;
        mRemoteAnimationAdapter = otherOptions.mRemoteAnimationAdapter;
        mLaunchIntoPipParams = otherOptions.mLaunchIntoPipParams;
    }

    /**
@@ -2039,6 +2081,9 @@ public class ActivityOptions extends ComponentOptions {
        if (mSplashScreenStyle != 0) {
            b.putInt(KEY_SPLASH_SCREEN_STYLE, mSplashScreenStyle);
        }
        if (mLaunchIntoPipParams != null) {
            b.putParcelable(KEY_LAUNCH_INTO_PIP_PARAMS, mLaunchIntoPipParams);
        }
        return b;
    }

+76 −9
Original line number Diff line number Diff line
@@ -64,6 +64,27 @@ public final class PictureInPictureParams implements Parcelable {

        private CharSequence mSubtitle;

        private Boolean mIsLaunchIntoPip;

        /** Default constructor */
        public Builder() {}

        /**
         * Copy constructor
         * @param original {@link PictureInPictureParams} instance this builder is built upon.
         */
        public Builder(@NonNull PictureInPictureParams original) {
            mAspectRatio = original.mAspectRatio;
            mUserActions = original.mUserActions;
            mCloseAction = original.mCloseAction;
            mSourceRectHint = original.mSourceRectHint;
            mAutoEnterEnabled = original.mAutoEnterEnabled;
            mSeamlessResizeEnabled = original.mSeamlessResizeEnabled;
            mTitle = original.mTitle;
            mSubtitle = original.mSubtitle;
            mIsLaunchIntoPip = original.mIsLaunchIntoPip;
        }

        /**
         * Sets the aspect ratio.  This aspect ratio is defined as the desired width / height, and
         * does not change upon device rotation.
@@ -221,6 +242,20 @@ public final class PictureInPictureParams implements Parcelable {
            return this;
        }

        /**
         * Sets whether the built {@link PictureInPictureParams} represents a launch into
         * picture-in-picture request.
         *
         * This property is {@code false} by default.
         * @param isLaunchIntoPip {@code true} if the built instance represents a launch into
         *                                 picture-in-picture request
         * @return this builder instance.
         */
        @NonNull
        Builder setIsLaunchIntoPip(boolean isLaunchIntoPip) {
            mIsLaunchIntoPip = isLaunchIntoPip;
            return this;
        }

        /**
         * @return an immutable {@link PictureInPictureParams} to be used when entering or updating
@@ -232,7 +267,8 @@ public final class PictureInPictureParams implements Parcelable {
        public PictureInPictureParams build() {
            PictureInPictureParams params = new PictureInPictureParams(mAspectRatio,
                    mExpandedAspectRatio, mUserActions, mCloseAction, mSourceRectHint,
                    mAutoEnterEnabled, mSeamlessResizeEnabled, mTitle, mSubtitle);
                    mAutoEnterEnabled, mSeamlessResizeEnabled, mTitle, mSubtitle,
                    mIsLaunchIntoPip);
            return params;
        }
    }
@@ -294,6 +330,13 @@ public final class PictureInPictureParams implements Parcelable {
    @Nullable
    private CharSequence mSubtitle;

    /**
     * Whether this {@link PictureInPictureParams} represents a launch into
     * picture-in-picture request.
     * {@link #isLaunchIntoPip()} defaults to {@code false} is this is not set.
     */
    private Boolean mIsLaunchIntoPip;

    /** {@hide} */
    PictureInPictureParams() {
    }
@@ -322,13 +365,16 @@ public final class PictureInPictureParams implements Parcelable {
        if (in.readInt() != 0) {
            mSubtitle = in.readCharSequence();
        }
        if (in.readInt() != 0) {
            mIsLaunchIntoPip = in.readBoolean();
        }
    }

    /** {@hide} */
    PictureInPictureParams(Rational aspectRatio, Rational expandedAspectRatio,
            List<RemoteAction> actions, RemoteAction closeAction, Rect sourceRectHint,
            Boolean autoEnterEnabled, Boolean seamlessResizeEnabled, CharSequence title,
            CharSequence subtitle) {
            CharSequence subtitle, Boolean isLaunchIntoPip) {
        mAspectRatio = aspectRatio;
        mExpandedAspectRatio = expandedAspectRatio;
        mUserActions = actions;
@@ -338,6 +384,7 @@ public final class PictureInPictureParams implements Parcelable {
        mSeamlessResizeEnabled = seamlessResizeEnabled;
        mTitle = title;
        mSubtitle = subtitle;
        mIsLaunchIntoPip = isLaunchIntoPip;
    }

    /**
@@ -347,8 +394,8 @@ public final class PictureInPictureParams implements Parcelable {
    public PictureInPictureParams(PictureInPictureParams other) {
        this(other.mAspectRatio, other.mExpandedAspectRatio, other.mUserActions, other.mCloseAction,
                other.hasSourceBoundsHint() ? new Rect(other.getSourceRectHint()) : null,
                other.mAutoEnterEnabled, other.mSeamlessResizeEnabled, other.mTitle,
                other.mSubtitle);
                other.mAutoEnterEnabled, other.mSeamlessResizeEnabled,
                other.mTitle, other.mSubtitle, other.mIsLaunchIntoPip);
    }

    /**
@@ -384,6 +431,9 @@ public final class PictureInPictureParams implements Parcelable {
        if (otherArgs.hasSetSubtitle()) {
            mSubtitle = otherArgs.mSubtitle;
        }
        if (otherArgs.mIsLaunchIntoPip != null) {
            mIsLaunchIntoPip = otherArgs.mIsLaunchIntoPip;
        }
    }

    /**
@@ -547,15 +597,23 @@ public final class PictureInPictureParams implements Parcelable {
        return mSubtitle;
    }

    /**
     * @return whether this {@link PictureInPictureParams} represents a launch into pip request.
     * @hide
     */
    public boolean isLaunchIntoPip() {
        return mIsLaunchIntoPip == null ? false : mIsLaunchIntoPip;
    }

    /**
     * @return True if no parameters are set
     * @hide
     */
    public boolean empty() {
        return !hasSourceBoundsHint() && !hasSetActions() && !hasSetCloseAction()
                && !hasSetAspectRatio() && !hasSetExpandedAspectRatio() && mAutoEnterEnabled != null
                && mSeamlessResizeEnabled != null && !hasSetTitle()
                && !hasSetSubtitle();
                && !hasSetAspectRatio() && !hasSetExpandedAspectRatio() && mAutoEnterEnabled == null
                && mSeamlessResizeEnabled == null && !hasSetTitle()
                && !hasSetSubtitle() && mIsLaunchIntoPip == null;
    }

    @Override
@@ -571,13 +629,15 @@ public final class PictureInPictureParams implements Parcelable {
                && Objects.equals(mCloseAction, that.mCloseAction)
                && Objects.equals(mSourceRectHint, that.mSourceRectHint)
                && Objects.equals(mTitle, that.mTitle)
                && Objects.equals(mSubtitle, that.mSubtitle);
                && Objects.equals(mSubtitle, that.mSubtitle)
                && Objects.equals(mIsLaunchIntoPip, that.mIsLaunchIntoPip);
    }

    @Override
    public int hashCode() {
        return Objects.hash(mAspectRatio, mExpandedAspectRatio, mUserActions, mCloseAction,
                mSourceRectHint, mAutoEnterEnabled, mSeamlessResizeEnabled, mTitle, mSubtitle);
                mSourceRectHint, mAutoEnterEnabled, mSeamlessResizeEnabled, mTitle, mSubtitle,
                mIsLaunchIntoPip);
    }

    @Override
@@ -628,6 +688,12 @@ public final class PictureInPictureParams implements Parcelable {
        } else {
            out.writeInt(0);
        }
        if (mIsLaunchIntoPip != null) {
            out.writeInt(1);
            out.writeBoolean(mIsLaunchIntoPip);
        } else {
            out.writeInt(0);
        }
    }

    private void writeRationalToParcel(Rational rational, Parcel out) {
@@ -659,6 +725,7 @@ public final class PictureInPictureParams implements Parcelable {
                + " isSeamlessResizeEnabled=" + isSeamlessResizeEnabled()
                + " title=" + getTitle()
                + " subtitle=" + getSubtitle()
                + " isLaunchIntoPip=" + isLaunchIntoPip()
                + ")";
    }

+10 −0
Original line number Diff line number Diff line
@@ -190,6 +190,13 @@ public class TaskInfo {
     */
    public boolean preferDockBigOverlays;

    /**
     * The task id of the host Task of the launch-into-pip Activity, i.e., it points to the Task
     * the launch-into-pip Activity is originated from.
     * @hide
     */
    public int launchIntoPipHostTaskId;

    /**
     * The {@link Rect} copied from {@link DisplayCutout#getSafeInsets()} if the cutout is not of
     * (LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES, LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS),
@@ -516,6 +523,7 @@ public class TaskInfo {
        topActivityType = source.readInt();
        pictureInPictureParams = source.readTypedObject(PictureInPictureParams.CREATOR);
        preferDockBigOverlays = source.readBoolean();
        launchIntoPipHostTaskId = source.readInt();
        displayCutoutInsets = source.readTypedObject(Rect.CREATOR);
        topActivityInfo = source.readTypedObject(ActivityInfo.CREATOR);
        isResizeable = source.readBoolean();
@@ -562,6 +570,7 @@ public class TaskInfo {
        dest.writeInt(topActivityType);
        dest.writeTypedObject(pictureInPictureParams, flags);
        dest.writeBoolean(preferDockBigOverlays);
        dest.writeInt(launchIntoPipHostTaskId);
        dest.writeTypedObject(displayCutoutInsets, flags);
        dest.writeTypedObject(topActivityInfo, flags);
        dest.writeBoolean(isResizeable);
@@ -602,6 +611,7 @@ public class TaskInfo {
                + " topActivityType=" + topActivityType
                + " pictureInPictureParams=" + pictureInPictureParams
                + " preferDockBigOverlays=" + preferDockBigOverlays
                + " launchIntoPipHostTaskId=" + launchIntoPipHostTaskId
                + " displayCutoutSafeInsets=" + displayCutoutInsets
                + " topActivityInfo=" + topActivityInfo
                + " launchCookies=" + launchCookies
+17 −1
Original line number Diff line number Diff line
@@ -310,6 +310,10 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        return mPipTransitionState.isInPip();
    }

    private boolean isLaunchIntoPipTask() {
        return mPictureInPictureParams != null && mPictureInPictureParams.isLaunchIntoPip();
    }

    /**
     * Returns whether the entry animation is waiting to be started.
     */
@@ -397,6 +401,10 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        }

        final WindowContainerTransaction wct = new WindowContainerTransaction();
        if (isLaunchIntoPipTask()) {
            exitLaunchIntoPipTask(wct);
            return;
        }

        if (ENABLE_SHELL_TRANSITIONS) {
            if (requestEnterSplit && mSplitScreenOptional.isPresent()) {
@@ -468,6 +476,14 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        });
    }

    private void exitLaunchIntoPipTask(WindowContainerTransaction wct) {
        wct.startTask(mTaskInfo.launchIntoPipHostTaskId, null /* ActivityOptions */);
        mTaskOrganizer.applyTransaction(wct);

        // Remove the PiP with fade-out animation right after the host Task is brought to front.
        removePip();
    }

    private void applyWindowingModeChangeOnExit(WindowContainerTransaction wct, int direction) {
        // Reset the final windowing mode.
        wct.setWindowingMode(mToken, getOutPipWindowingMode());
@@ -729,7 +745,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
    }

    /**
     * Note that dismissing PiP is now originated from SystemUI, see {@link #exitPip(int)}.
     * Note that dismissing PiP is now originated from SystemUI, see {@link #exitPip(int, boolean)}.
     * Meanwhile this callback is invoked whenever the task is removed. For instance:
     *   - as a result of removeRootTasksInWindowingModes from WM
     *   - activity itself is died
Loading