Automatic sources dropoff on 2020-06-10 18:32:38.095721

The change is generated with prebuilt drop tool.

Change-Id: I24cbf6ba6db262a1ae1445db1427a08fee35b3b4
diff --git a/android/app/ActivityOptions.java b/android/app/ActivityOptions.java
new file mode 100644
index 0000000..80d2e6c
--- /dev/null
+++ b/android/app/ActivityOptions.java
@@ -0,0 +1,1866 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
+import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.view.Display.INVALID_DISPLAY;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.TestApi;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.graphics.GraphicBuffer;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IRemoteCallback;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.UserHandle;
+import android.transition.Transition;
+import android.transition.TransitionListenerAdapter;
+import android.transition.TransitionManager;
+import android.util.Pair;
+import android.util.Slog;
+import android.view.AppTransitionAnimationSpec;
+import android.view.IAppTransitionAnimationSpecsFuture;
+import android.view.RemoteAnimationAdapter;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.window.WindowContainerToken;
+
+import java.util.ArrayList;
+
+/**
+ * Helper class for building an options Bundle that can be used with
+ * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle)
+ * Context.startActivity(Intent, Bundle)} and related methods.
+ */
+public class ActivityOptions {
+    private static final String TAG = "ActivityOptions";
+
+    /**
+     * A long in the extras delivered by {@link #requestUsageTimeReport} that contains
+     * the total time (in ms) the user spent in the app flow.
+     */
+    public static final String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
+
+    /**
+     * A Bundle in the extras delivered by {@link #requestUsageTimeReport} that contains
+     * detailed information about the time spent in each package associated with the app;
+     * each key is a package name, whose value is a long containing the time (in ms).
+     */
+    public static final String EXTRA_USAGE_TIME_REPORT_PACKAGES = "android.usage_time_packages";
+
+    /**
+     * The package name that created the options.
+     * @hide
+     */
+    public static final String KEY_PACKAGE_NAME = "android:activity.packageName";
+
+    /**
+     * The bounds (window size) that the activity should be launched in. Set to null explicitly for
+     * full screen. If the key is not found, previous bounds will be preserved.
+     * NOTE: This value is ignored on devices that don't have
+     * {@link android.content.pm.PackageManager#FEATURE_FREEFORM_WINDOW_MANAGEMENT} or
+     * {@link android.content.pm.PackageManager#FEATURE_PICTURE_IN_PICTURE} enabled.
+     * @hide
+     */
+    public static final String KEY_LAUNCH_BOUNDS = "android:activity.launchBounds";
+
+    /**
+     * Type of animation that arguments specify.
+     * @hide
+     */
+    public static final String KEY_ANIM_TYPE = "android:activity.animType";
+
+    /**
+     * Custom enter animation resource ID.
+     * @hide
+     */
+    public static final String KEY_ANIM_ENTER_RES_ID = "android:activity.animEnterRes";
+
+    /**
+     * Custom exit animation resource ID.
+     * @hide
+     */
+    public static final String KEY_ANIM_EXIT_RES_ID = "android:activity.animExitRes";
+
+    /**
+     * Custom in-place animation resource ID.
+     * @hide
+     */
+    public static final String KEY_ANIM_IN_PLACE_RES_ID = "android:activity.animInPlaceRes";
+
+    /**
+     * Bitmap for thumbnail animation.
+     * @hide
+     */
+    public static final String KEY_ANIM_THUMBNAIL = "android:activity.animThumbnail";
+
+    /**
+     * Start X position of thumbnail animation.
+     * @hide
+     */
+    public static final String KEY_ANIM_START_X = "android:activity.animStartX";
+
+    /**
+     * Start Y position of thumbnail animation.
+     * @hide
+     */
+    public static final String KEY_ANIM_START_Y = "android:activity.animStartY";
+
+    /**
+     * Initial width of the animation.
+     * @hide
+     */
+    public static final String KEY_ANIM_WIDTH = "android:activity.animWidth";
+
+    /**
+     * Initial height of the animation.
+     * @hide
+     */
+    public static final String KEY_ANIM_HEIGHT = "android:activity.animHeight";
+
+    /**
+     * Callback for when animation is started.
+     * @hide
+     */
+    public static final String KEY_ANIM_START_LISTENER = "android:activity.animStartListener";
+
+    /**
+     * Callback for when the last frame of the animation is played.
+     * @hide
+     */
+    private static final String KEY_ANIMATION_FINISHED_LISTENER =
+            "android:activity.animationFinishedListener";
+
+    /**
+     * Descriptions of app transition animations to be played during the activity launch.
+     */
+    private static final String KEY_ANIM_SPECS = "android:activity.animSpecs";
+
+    /**
+     * Whether the activity should be launched into LockTask mode.
+     * @see #setLockTaskEnabled(boolean)
+     */
+    private static final String KEY_LOCK_TASK_MODE = "android:activity.lockTaskMode";
+
+    /**
+     * The display id the activity should be launched into.
+     * @see #setLaunchDisplayId(int)
+     * @hide
+     */
+    private static final String KEY_LAUNCH_DISPLAY_ID = "android.activity.launchDisplayId";
+
+    /**
+     * The id of the display where the caller was on.
+     * @see #setCallerDisplayId(int)
+     * @hide
+     */
+    private static final String KEY_CALLER_DISPLAY_ID = "android.activity.callerDisplayId";
+
+    /**
+     * The task display area token the activity should be launched into.
+     * @see #setLaunchTaskDisplayArea(WindowContainerToken)
+     * @hide
+     */
+    private static final String KEY_LAUNCH_TASK_DISPLAY_AREA_TOKEN =
+            "android.activity.launchTaskDisplayAreaToken";
+
+    /**
+     * The windowing mode the activity should be launched into.
+     * @hide
+     */
+    private static final String KEY_LAUNCH_WINDOWING_MODE = "android.activity.windowingMode";
+
+    /**
+     * The activity type the activity should be launched as.
+     * @hide
+     */
+    private static final String KEY_LAUNCH_ACTIVITY_TYPE = "android.activity.activityType";
+
+    /**
+     * The task id the activity should be launched into.
+     * @hide
+     */
+    private static final String KEY_LAUNCH_TASK_ID = "android.activity.launchTaskId";
+
+    /**
+     * See {@link #setPendingIntentLaunchFlags(int)}
+     * @hide
+     */
+    private static final String KEY_PENDING_INTENT_LAUNCH_FLAGS =
+            "android.activity.pendingIntentLaunchFlags";
+
+    /**
+     * See {@link #setTaskAlwaysOnTop}.
+     * @hide
+     */
+    private static final String KEY_TASK_ALWAYS_ON_TOP = "android.activity.alwaysOnTop";
+
+    /**
+     * See {@link #setTaskOverlay}.
+     * @hide
+     */
+    private static final String KEY_TASK_OVERLAY = "android.activity.taskOverlay";
+
+    /**
+     * See {@link #setTaskOverlay}.
+     * @hide
+     */
+    private static final String KEY_TASK_OVERLAY_CAN_RESUME =
+            "android.activity.taskOverlayCanResume";
+
+    /**
+     * See {@link #setAvoidMoveToFront()}.
+     * @hide
+     */
+    private static final String KEY_AVOID_MOVE_TO_FRONT = "android.activity.avoidMoveToFront";
+
+    /**
+     * See {@link #setFreezeRecentTasksReordering()}.
+     * @hide
+     */
+    private static final String KEY_FREEZE_RECENT_TASKS_REORDERING =
+            "android.activity.freezeRecentTasksReordering";
+
+    /**
+     * Where the split-screen-primary stack should be positioned.
+     * @hide
+     */
+    private static final String KEY_SPLIT_SCREEN_CREATE_MODE =
+            "android:activity.splitScreenCreateMode";
+
+    /**
+     * Determines whether to disallow the outgoing activity from entering picture-in-picture as the
+     * result of a new activity being launched.
+     * @hide
+     */
+    private static final String KEY_DISALLOW_ENTER_PICTURE_IN_PICTURE_WHILE_LAUNCHING =
+            "android:activity.disallowEnterPictureInPictureWhileLaunching";
+
+    /**
+     * Indicates flags should be applied to the launching activity such that it will behave
+     * correctly in a bubble.
+     * @hide
+     */
+    private static final String KEY_APPLY_ACTIVITY_FLAGS_FOR_BUBBLES =
+            "android:activity.applyActivityFlagsForBubbles";
+
+    /**
+     * For Activity transitions, the calling Activity's TransitionListener used to
+     * notify the called Activity when the shared element and the exit transitions
+     * complete.
+     */
+    private static final String KEY_TRANSITION_COMPLETE_LISTENER
+            = "android:activity.transitionCompleteListener";
+
+    private static final String KEY_TRANSITION_IS_RETURNING
+            = "android:activity.transitionIsReturning";
+    private static final String KEY_TRANSITION_SHARED_ELEMENTS
+            = "android:activity.sharedElementNames";
+    private static final String KEY_RESULT_DATA = "android:activity.resultData";
+    private static final String KEY_RESULT_CODE = "android:activity.resultCode";
+    private static final String KEY_EXIT_COORDINATOR_INDEX
+            = "android:activity.exitCoordinatorIndex";
+
+    private static final String KEY_USAGE_TIME_REPORT = "android:activity.usageTimeReport";
+    private static final String KEY_ROTATION_ANIMATION_HINT = "android:activity.rotationAnimationHint";
+
+    private static final String KEY_INSTANT_APP_VERIFICATION_BUNDLE
+            = "android:instantapps.installerbundle";
+    private static final String KEY_SPECS_FUTURE = "android:activity.specsFuture";
+    private static final String KEY_REMOTE_ANIMATION_ADAPTER
+            = "android:activity.remoteAnimationAdapter";
+
+    /** @hide */
+    public static final int ANIM_UNDEFINED = -1;
+    /** @hide */
+    public static final int ANIM_NONE = 0;
+    /** @hide */
+    public static final int ANIM_CUSTOM = 1;
+    /** @hide */
+    public static final int ANIM_SCALE_UP = 2;
+    /** @hide */
+    public static final int ANIM_THUMBNAIL_SCALE_UP = 3;
+    /** @hide */
+    public static final int ANIM_THUMBNAIL_SCALE_DOWN = 4;
+    /** @hide */
+    public static final int ANIM_SCENE_TRANSITION = 5;
+    /** @hide */
+    public static final int ANIM_DEFAULT = 6;
+    /** @hide */
+    public static final int ANIM_LAUNCH_TASK_BEHIND = 7;
+    /** @hide */
+    public static final int ANIM_THUMBNAIL_ASPECT_SCALE_UP = 8;
+    /** @hide */
+    public static final int ANIM_THUMBNAIL_ASPECT_SCALE_DOWN = 9;
+    /** @hide */
+    public static final int ANIM_CUSTOM_IN_PLACE = 10;
+    /** @hide */
+    public static final int ANIM_CLIP_REVEAL = 11;
+    /** @hide */
+    public static final int ANIM_OPEN_CROSS_PROFILE_APPS = 12;
+    /** @hide */
+    public static final int ANIM_REMOTE_ANIMATION = 13;
+
+    private String mPackageName;
+    private Rect mLaunchBounds;
+    private int mAnimationType = ANIM_UNDEFINED;
+    private int mCustomEnterResId;
+    private int mCustomExitResId;
+    private int mCustomInPlaceResId;
+    private Bitmap mThumbnail;
+    private int mStartX;
+    private int mStartY;
+    private int mWidth;
+    private int mHeight;
+    private IRemoteCallback mAnimationStartedListener;
+    private IRemoteCallback mAnimationFinishedListener;
+    private ResultReceiver mTransitionReceiver;
+    private boolean mIsReturning;
+    private ArrayList<String> mSharedElementNames;
+    private Intent mResultData;
+    private int mResultCode;
+    private int mExitCoordinatorIndex;
+    private PendingIntent mUsageTimeReport;
+    private int mLaunchDisplayId = INVALID_DISPLAY;
+    private int mCallerDisplayId = INVALID_DISPLAY;
+    private WindowContainerToken mLaunchTaskDisplayArea;
+    @WindowConfiguration.WindowingMode
+    private int mLaunchWindowingMode = WINDOWING_MODE_UNDEFINED;
+    @WindowConfiguration.ActivityType
+    private int mLaunchActivityType = ACTIVITY_TYPE_UNDEFINED;
+    private int mLaunchTaskId = -1;
+    private int mPendingIntentLaunchFlags;
+    private int mSplitScreenCreateMode = SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
+    private boolean mLockTaskMode = false;
+    private boolean mDisallowEnterPictureInPictureWhileLaunching;
+    private boolean mApplyActivityFlagsForBubbles;
+    private boolean mTaskAlwaysOnTop;
+    private boolean mTaskOverlay;
+    private boolean mTaskOverlayCanResume;
+    private boolean mAvoidMoveToFront;
+    private boolean mFreezeRecentTasksReordering;
+    private AppTransitionAnimationSpec mAnimSpecs[];
+    private int mRotationAnimationHint = -1;
+    private Bundle mAppVerificationBundle;
+    private IAppTransitionAnimationSpecsFuture mSpecsFuture;
+    private RemoteAnimationAdapter mRemoteAnimationAdapter;
+
+    /**
+     * Create an ActivityOptions specifying a custom animation to run when
+     * the activity is displayed.
+     *
+     * @param context Who is defining this.  This is the application that the
+     * animation resources will be loaded from.
+     * @param enterResId A resource ID of the animation resource to use for
+     * the incoming activity.  Use 0 for no animation.
+     * @param exitResId A resource ID of the animation resource to use for
+     * the outgoing activity.  Use 0 for no animation.
+     * @return Returns a new ActivityOptions object that you can use to
+     * supply these options as the options Bundle when starting an activity.
+     */
+    public static ActivityOptions makeCustomAnimation(Context context,
+            int enterResId, int exitResId) {
+        return makeCustomAnimation(context, enterResId, exitResId, null, null, null);
+    }
+
+    /**
+     * Create an ActivityOptions specifying a custom animation to run when
+     * the activity is displayed.
+     *
+     * @param context Who is defining this.  This is the application that the
+     * animation resources will be loaded from.
+     * @param enterResId A resource ID of the animation resource to use for
+     * the incoming activity.  Use 0 for no animation.
+     * @param exitResId A resource ID of the animation resource to use for
+     * the outgoing activity.  Use 0 for no animation.
+     * @param handler If <var>listener</var> is non-null this must be a valid
+     * Handler on which to dispatch the callback; otherwise it should be null.
+     * @param listener Optional OnAnimationStartedListener to find out when the
+     * requested animation has started running.  If for some reason the animation
+     * is not executed, the callback will happen immediately.
+     * @return Returns a new ActivityOptions object that you can use to
+     * supply these options as the options Bundle when starting an activity.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public static ActivityOptions makeCustomAnimation(Context context,
+            int enterResId, int exitResId, Handler handler, OnAnimationStartedListener listener) {
+        ActivityOptions opts = new ActivityOptions();
+        opts.mPackageName = context.getPackageName();
+        opts.mAnimationType = ANIM_CUSTOM;
+        opts.mCustomEnterResId = enterResId;
+        opts.mCustomExitResId = exitResId;
+        opts.setOnAnimationStartedListener(handler, listener);
+        return opts;
+    }
+
+    /**
+     * Create an ActivityOptions specifying a custom animation to run when
+     * the activity is displayed.
+     *
+     * @param context Who is defining this.  This is the application that the
+     * animation resources will be loaded from.
+     * @param enterResId A resource ID of the animation resource to use for
+     * the incoming activity.  Use 0 for no animation.
+     * @param exitResId A resource ID of the animation resource to use for
+     * the outgoing activity.  Use 0 for no animation.
+     * @param handler If <var>listener</var> is non-null this must be a valid
+     * Handler on which to dispatch the callback; otherwise it should be null.
+     * @param startedListener Optional OnAnimationStartedListener to find out when the
+     * requested animation has started running.  If for some reason the animation
+     * is not executed, the callback will happen immediately.
+     * @param finishedListener Optional OnAnimationFinishedListener when the animation
+     * has finished running.
+     * @return Returns a new ActivityOptions object that you can use to
+     * supply these options as the options Bundle when starting an activity.
+     * @hide
+     */
+    @TestApi
+    public static @NonNull ActivityOptions makeCustomAnimation(@NonNull Context context,
+            int enterResId, int exitResId, @Nullable Handler handler,
+            @Nullable OnAnimationStartedListener startedListener,
+            @Nullable OnAnimationFinishedListener finishedListener) {
+        ActivityOptions opts = makeCustomAnimation(context, enterResId, exitResId, handler,
+                startedListener);
+        opts.setOnAnimationFinishedListener(handler, finishedListener);
+        return opts;
+    }
+
+    /**
+     * Creates an ActivityOptions specifying a custom animation to run in place on an existing
+     * activity.
+     *
+     * @param context Who is defining this.  This is the application that the
+     * animation resources will be loaded from.
+     * @param animId A resource ID of the animation resource to use for
+     * the incoming activity.
+     * @return Returns a new ActivityOptions object that you can use to
+     * supply these options as the options Bundle when running an in-place animation.
+     * @hide
+     */
+    public static ActivityOptions makeCustomInPlaceAnimation(Context context, int animId) {
+        if (animId == 0) {
+            throw new RuntimeException("You must specify a valid animation.");
+        }
+
+        ActivityOptions opts = new ActivityOptions();
+        opts.mPackageName = context.getPackageName();
+        opts.mAnimationType = ANIM_CUSTOM_IN_PLACE;
+        opts.mCustomInPlaceResId = animId;
+        return opts;
+    }
+
+    private void setOnAnimationStartedListener(final Handler handler,
+            final OnAnimationStartedListener listener) {
+        if (listener != null) {
+            mAnimationStartedListener = new IRemoteCallback.Stub() {
+                @Override
+                public void sendResult(Bundle data) throws RemoteException {
+                    handler.post(new Runnable() {
+                        @Override public void run() {
+                            listener.onAnimationStarted();
+                        }
+                    });
+                }
+            };
+        }
+    }
+
+    /**
+     * Callback for use with {@link ActivityOptions#makeThumbnailScaleUpAnimation}
+     * to find out when the given animation has started running.
+     * @hide
+     */
+    @TestApi
+    public interface OnAnimationStartedListener {
+        void onAnimationStarted();
+    }
+
+    private void setOnAnimationFinishedListener(final Handler handler,
+            final OnAnimationFinishedListener listener) {
+        if (listener != null) {
+            mAnimationFinishedListener = new IRemoteCallback.Stub() {
+                @Override
+                public void sendResult(Bundle data) throws RemoteException {
+                    handler.post(new Runnable() {
+                        @Override
+                        public void run() {
+                            listener.onAnimationFinished();
+                        }
+                    });
+                }
+            };
+        }
+    }
+
+    /**
+     * Callback for use with {@link ActivityOptions#makeThumbnailAspectScaleDownAnimation}
+     * to find out when the given animation has drawn its last frame.
+     * @hide
+     */
+    @TestApi
+    public interface OnAnimationFinishedListener {
+        void onAnimationFinished();
+    }
+
+    /**
+     * Create an ActivityOptions specifying an animation where the new
+     * activity is scaled from a small originating area of the screen to
+     * its final full representation.
+     *
+     * <p>If the Intent this is being used with has not set its
+     * {@link android.content.Intent#setSourceBounds Intent.setSourceBounds},
+     * those bounds will be filled in for you based on the initial
+     * bounds passed in here.
+     *
+     * @param source The View that the new activity is animating from.  This
+     * defines the coordinate space for <var>startX</var> and <var>startY</var>.
+     * @param startX The x starting location of the new activity, relative to <var>source</var>.
+     * @param startY The y starting location of the activity, relative to <var>source</var>.
+     * @param width The initial width of the new activity.
+     * @param height The initial height of the new activity.
+     * @return Returns a new ActivityOptions object that you can use to
+     * supply these options as the options Bundle when starting an activity.
+     */
+    public static ActivityOptions makeScaleUpAnimation(View source,
+            int startX, int startY, int width, int height) {
+        ActivityOptions opts = new ActivityOptions();
+        opts.mPackageName = source.getContext().getPackageName();
+        opts.mAnimationType = ANIM_SCALE_UP;
+        int[] pts = new int[2];
+        source.getLocationOnScreen(pts);
+        opts.mStartX = pts[0] + startX;
+        opts.mStartY = pts[1] + startY;
+        opts.mWidth = width;
+        opts.mHeight = height;
+        return opts;
+    }
+
+    /**
+     * Create an ActivityOptions specifying an animation where the new
+     * activity is revealed from a small originating area of the screen to
+     * its final full representation.
+     *
+     * @param source The View that the new activity is animating from.  This
+     * defines the coordinate space for <var>startX</var> and <var>startY</var>.
+     * @param startX The x starting location of the new activity, relative to <var>source</var>.
+     * @param startY The y starting location of the activity, relative to <var>source</var>.
+     * @param width The initial width of the new activity.
+     * @param height The initial height of the new activity.
+     * @return Returns a new ActivityOptions object that you can use to
+     * supply these options as the options Bundle when starting an activity.
+     */
+    public static ActivityOptions makeClipRevealAnimation(View source,
+            int startX, int startY, int width, int height) {
+        ActivityOptions opts = new ActivityOptions();
+        opts.mAnimationType = ANIM_CLIP_REVEAL;
+        int[] pts = new int[2];
+        source.getLocationOnScreen(pts);
+        opts.mStartX = pts[0] + startX;
+        opts.mStartY = pts[1] + startY;
+        opts.mWidth = width;
+        opts.mHeight = height;
+        return opts;
+    }
+
+    /**
+     * Creates an {@link ActivityOptions} object specifying an animation where the new activity
+     * is started in another user profile by calling {@link
+     * android.content.pm.crossprofile.CrossProfileApps#startMainActivity(ComponentName, UserHandle)
+     * }.
+     * @hide
+     */
+    public static ActivityOptions makeOpenCrossProfileAppsAnimation() {
+        ActivityOptions options = new ActivityOptions();
+        options.mAnimationType = ANIM_OPEN_CROSS_PROFILE_APPS;
+        return options;
+    }
+
+    /**
+     * Create an ActivityOptions specifying an animation where a thumbnail
+     * is scaled from a given position to the new activity window that is
+     * being started.
+     *
+     * <p>If the Intent this is being used with has not set its
+     * {@link android.content.Intent#setSourceBounds Intent.setSourceBounds},
+     * those bounds will be filled in for you based on the initial
+     * thumbnail location and size provided here.
+     *
+     * @param source The View that this thumbnail is animating from.  This
+     * defines the coordinate space for <var>startX</var> and <var>startY</var>.
+     * @param thumbnail The bitmap that will be shown as the initial thumbnail
+     * of the animation.
+     * @param startX The x starting location of the bitmap, relative to <var>source</var>.
+     * @param startY The y starting location of the bitmap, relative to <var>source</var>.
+     * @return Returns a new ActivityOptions object that you can use to
+     * supply these options as the options Bundle when starting an activity.
+     */
+    public static ActivityOptions makeThumbnailScaleUpAnimation(View source,
+            Bitmap thumbnail, int startX, int startY) {
+        return makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY, null);
+    }
+
+    /**
+     * Create an ActivityOptions specifying an animation where a thumbnail
+     * is scaled from a given position to the new activity window that is
+     * being started.
+     *
+     * @param source The View that this thumbnail is animating from.  This
+     * defines the coordinate space for <var>startX</var> and <var>startY</var>.
+     * @param thumbnail The bitmap that will be shown as the initial thumbnail
+     * of the animation.
+     * @param startX The x starting location of the bitmap, relative to <var>source</var>.
+     * @param startY The y starting location of the bitmap, relative to <var>source</var>.
+     * @param listener Optional OnAnimationStartedListener to find out when the
+     * requested animation has started running.  If for some reason the animation
+     * is not executed, the callback will happen immediately.
+     * @return Returns a new ActivityOptions object that you can use to
+     * supply these options as the options Bundle when starting an activity.
+     */
+    private static ActivityOptions makeThumbnailScaleUpAnimation(View source,
+            Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) {
+        return makeThumbnailAnimation(source, thumbnail, startX, startY, listener, true);
+    }
+
+    private static ActivityOptions makeThumbnailAnimation(View source,
+            Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener,
+            boolean scaleUp) {
+        ActivityOptions opts = new ActivityOptions();
+        opts.mPackageName = source.getContext().getPackageName();
+        opts.mAnimationType = scaleUp ? ANIM_THUMBNAIL_SCALE_UP : ANIM_THUMBNAIL_SCALE_DOWN;
+        opts.mThumbnail = thumbnail;
+        int[] pts = new int[2];
+        source.getLocationOnScreen(pts);
+        opts.mStartX = pts[0] + startX;
+        opts.mStartY = pts[1] + startY;
+        opts.setOnAnimationStartedListener(source.getHandler(), listener);
+        return opts;
+    }
+
+    /**
+     * Create an ActivityOptions specifying an animation where a list of activity windows and
+     * thumbnails are aspect scaled to/from a new location.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public static ActivityOptions makeMultiThumbFutureAspectScaleAnimation(Context context,
+            Handler handler, IAppTransitionAnimationSpecsFuture specsFuture,
+            OnAnimationStartedListener listener, boolean scaleUp) {
+        ActivityOptions opts = new ActivityOptions();
+        opts.mPackageName = context.getPackageName();
+        opts.mAnimationType = scaleUp
+                ? ANIM_THUMBNAIL_ASPECT_SCALE_UP
+                : ANIM_THUMBNAIL_ASPECT_SCALE_DOWN;
+        opts.mSpecsFuture = specsFuture;
+        opts.setOnAnimationStartedListener(handler, listener);
+        return opts;
+    }
+
+    /**
+     * Create an ActivityOptions specifying an animation where the new activity
+     * window and a thumbnail is aspect-scaled to a new location.
+     *
+     * @param source The View that this thumbnail is animating to.  This
+     * defines the coordinate space for <var>startX</var> and <var>startY</var>.
+     * @param thumbnail The bitmap that will be shown as the final thumbnail
+     * of the animation.
+     * @param startX The x end location of the bitmap, relative to <var>source</var>.
+     * @param startY The y end location of the bitmap, relative to <var>source</var>.
+     * @param handler If <var>listener</var> is non-null this must be a valid
+     * Handler on which to dispatch the callback; otherwise it should be null.
+     * @param listener Optional OnAnimationStartedListener to find out when the
+     * requested animation has started running.  If for some reason the animation
+     * is not executed, the callback will happen immediately.
+     * @return Returns a new ActivityOptions object that you can use to
+     * supply these options as the options Bundle when starting an activity.
+     * @hide
+     */
+    public static ActivityOptions makeThumbnailAspectScaleDownAnimation(View source,
+            Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight,
+            Handler handler, OnAnimationStartedListener listener) {
+        return makeAspectScaledThumbnailAnimation(source, thumbnail, startX, startY,
+                targetWidth, targetHeight, handler, listener, false);
+    }
+
+    private static ActivityOptions makeAspectScaledThumbnailAnimation(View source, Bitmap thumbnail,
+            int startX, int startY, int targetWidth, int targetHeight,
+            Handler handler, OnAnimationStartedListener listener, boolean scaleUp) {
+        ActivityOptions opts = new ActivityOptions();
+        opts.mPackageName = source.getContext().getPackageName();
+        opts.mAnimationType = scaleUp ? ANIM_THUMBNAIL_ASPECT_SCALE_UP :
+                ANIM_THUMBNAIL_ASPECT_SCALE_DOWN;
+        opts.mThumbnail = thumbnail;
+        int[] pts = new int[2];
+        source.getLocationOnScreen(pts);
+        opts.mStartX = pts[0] + startX;
+        opts.mStartY = pts[1] + startY;
+        opts.mWidth = targetWidth;
+        opts.mHeight = targetHeight;
+        opts.setOnAnimationStartedListener(handler, listener);
+        return opts;
+    }
+
+    /** @hide */
+    public static ActivityOptions makeThumbnailAspectScaleDownAnimation(View source,
+            AppTransitionAnimationSpec[] specs, Handler handler,
+            OnAnimationStartedListener onAnimationStartedListener,
+            OnAnimationFinishedListener onAnimationFinishedListener) {
+        ActivityOptions opts = new ActivityOptions();
+        opts.mPackageName = source.getContext().getPackageName();
+        opts.mAnimationType = ANIM_THUMBNAIL_ASPECT_SCALE_DOWN;
+        opts.mAnimSpecs = specs;
+        opts.setOnAnimationStartedListener(handler, onAnimationStartedListener);
+        opts.setOnAnimationFinishedListener(handler, onAnimationFinishedListener);
+        return opts;
+    }
+
+    /**
+     * Create an ActivityOptions to transition between Activities using cross-Activity scene
+     * animations. This method carries the position of one shared element to the started Activity.
+     * The position of <code>sharedElement</code> will be used as the epicenter for the
+     * exit Transition. The position of the shared element in the launched Activity will be the
+     * epicenter of its entering Transition.
+     *
+     * <p>This requires {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS} to be
+     * enabled on the calling Activity to cause an exit transition. The same must be in
+     * the called Activity to get an entering transition.</p>
+     * @param activity The Activity whose window contains the shared elements.
+     * @param sharedElement The View to transition to the started Activity.
+     * @param sharedElementName The shared element name as used in the target Activity. This
+     *                          must not be null.
+     * @return Returns a new ActivityOptions object that you can use to
+     *         supply these options as the options Bundle when starting an activity.
+     * @see android.transition.Transition#setEpicenterCallback(
+     *          android.transition.Transition.EpicenterCallback)
+     */
+    public static ActivityOptions makeSceneTransitionAnimation(Activity activity,
+            View sharedElement, String sharedElementName) {
+        return makeSceneTransitionAnimation(activity, Pair.create(sharedElement, sharedElementName));
+    }
+
+    /**
+     * Create an ActivityOptions to transition between Activities using cross-Activity scene
+     * animations. This method carries the position of multiple shared elements to the started
+     * Activity. The position of the first element in sharedElements
+     * will be used as the epicenter for the exit Transition. The position of the associated
+     * shared element in the launched Activity will be the epicenter of its entering Transition.
+     *
+     * <p>This requires {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS} to be
+     * enabled on the calling Activity to cause an exit transition. The same must be in
+     * the called Activity to get an entering transition.</p>
+     * @param activity The Activity whose window contains the shared elements.
+     * @param sharedElements The names of the shared elements to transfer to the called
+     *                       Activity and their associated Views. The Views must each have
+     *                       a unique shared element name.
+     * @return Returns a new ActivityOptions object that you can use to
+     *         supply these options as the options Bundle when starting an activity.
+     * @see android.transition.Transition#setEpicenterCallback(
+     *          android.transition.Transition.EpicenterCallback)
+     */
+    @SafeVarargs
+    public static ActivityOptions makeSceneTransitionAnimation(Activity activity,
+            Pair<View, String>... sharedElements) {
+        ActivityOptions opts = new ActivityOptions();
+        makeSceneTransitionAnimation(activity, activity.getWindow(), opts,
+                activity.mExitTransitionListener, sharedElements);
+        return opts;
+    }
+
+    /**
+     * Call this immediately prior to startActivity to begin a shared element transition
+     * from a non-Activity. The window must support Window.FEATURE_ACTIVITY_TRANSITIONS.
+     * The exit transition will start immediately and the shared element transition will
+     * start once the launched Activity's shared element is ready.
+     * <p>
+     * When all transitions have completed and the shared element has been transfered,
+     * the window's decor View will have its visibility set to View.GONE.
+     *
+     * @hide
+     */
+    @SafeVarargs
+    public static ActivityOptions startSharedElementAnimation(Window window,
+            Pair<View, String>... sharedElements) {
+        ActivityOptions opts = new ActivityOptions();
+        final View decorView = window.getDecorView();
+        if (decorView == null) {
+            return opts;
+        }
+        final ExitTransitionCoordinator exit =
+                makeSceneTransitionAnimation(null, window, opts, null, sharedElements);
+        if (exit != null) {
+            HideWindowListener listener = new HideWindowListener(window, exit);
+            exit.setHideSharedElementsCallback(listener);
+            exit.startExit();
+        }
+        return opts;
+    }
+
+    /**
+     * This method should be called when the {@link #startSharedElementAnimation(Window, Pair[])}
+     * animation must be stopped and the Views reset. This can happen if there was an error
+     * from startActivity or a springboard activity and the animation should stop and reset.
+     *
+     * @hide
+     */
+    public static void stopSharedElementAnimation(Window window) {
+        final View decorView = window.getDecorView();
+        if (decorView == null) {
+            return;
+        }
+        final ExitTransitionCoordinator exit = (ExitTransitionCoordinator)
+                decorView.getTag(com.android.internal.R.id.cross_task_transition);
+        if (exit != null) {
+            exit.cancelPendingTransitions();
+            decorView.setTagInternal(com.android.internal.R.id.cross_task_transition, null);
+            TransitionManager.endTransitions((ViewGroup) decorView);
+            exit.resetViews();
+            exit.clearState();
+            decorView.setVisibility(View.VISIBLE);
+        }
+    }
+
+    static ExitTransitionCoordinator makeSceneTransitionAnimation(Activity activity, Window window,
+            ActivityOptions opts, SharedElementCallback callback,
+            Pair<View, String>[] sharedElements) {
+        if (!window.hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)) {
+            opts.mAnimationType = ANIM_DEFAULT;
+            return null;
+        }
+        opts.mAnimationType = ANIM_SCENE_TRANSITION;
+
+        ArrayList<String> names = new ArrayList<String>();
+        ArrayList<View> views = new ArrayList<View>();
+
+        if (sharedElements != null) {
+            for (int i = 0; i < sharedElements.length; i++) {
+                Pair<View, String> sharedElement = sharedElements[i];
+                String sharedElementName = sharedElement.second;
+                if (sharedElementName == null) {
+                    throw new IllegalArgumentException("Shared element name must not be null");
+                }
+                names.add(sharedElementName);
+                View view = sharedElement.first;
+                if (view == null) {
+                    throw new IllegalArgumentException("Shared element must not be null");
+                }
+                views.add(sharedElement.first);
+            }
+        }
+
+        ExitTransitionCoordinator exit = new ExitTransitionCoordinator(activity, window,
+                callback, names, names, views, false);
+        opts.mTransitionReceiver = exit;
+        opts.mSharedElementNames = names;
+        opts.mIsReturning = (activity == null);
+        if (activity == null) {
+            opts.mExitCoordinatorIndex = -1;
+        } else {
+            opts.mExitCoordinatorIndex =
+                    activity.mActivityTransitionState.addExitTransitionCoordinator(exit);
+        }
+        return exit;
+    }
+
+    /**
+     * Needed for virtual devices because they can be slow enough that the 1 second timeout
+     * triggers when it doesn't on normal devices.
+     *
+     * @hide
+     */
+    @TestApi
+    public static void setExitTransitionTimeout(long timeoutMillis) {
+        ExitTransitionCoordinator.sMaxWaitMillis = timeoutMillis;
+    }
+
+    /** @hide */
+    static ActivityOptions makeSceneTransitionAnimation(Activity activity,
+            ExitTransitionCoordinator exitCoordinator, ArrayList<String> sharedElementNames,
+            int resultCode, Intent resultData) {
+        ActivityOptions opts = new ActivityOptions();
+        opts.mAnimationType = ANIM_SCENE_TRANSITION;
+        opts.mSharedElementNames = sharedElementNames;
+        opts.mTransitionReceiver = exitCoordinator;
+        opts.mIsReturning = true;
+        opts.mResultCode = resultCode;
+        opts.mResultData = resultData;
+        opts.mExitCoordinatorIndex =
+                activity.mActivityTransitionState.addExitTransitionCoordinator(exitCoordinator);
+        return opts;
+    }
+
+    /**
+     * If set along with Intent.FLAG_ACTIVITY_NEW_DOCUMENT then the task being launched will not be
+     * presented to the user but will instead be only available through the recents task list.
+     * In addition, the new task wil be affiliated with the launching activity's task.
+     * Affiliated tasks are grouped together in the recents task list.
+     *
+     * <p>This behavior is not supported for activities with {@link
+     * android.R.styleable#AndroidManifestActivity_launchMode launchMode} values of
+     * <code>singleInstance</code> or <code>singleTask</code>.
+     */
+    public static ActivityOptions makeTaskLaunchBehind() {
+        final ActivityOptions opts = new ActivityOptions();
+        opts.mAnimationType = ANIM_LAUNCH_TASK_BEHIND;
+        return opts;
+    }
+
+    /**
+     * Create a basic ActivityOptions that has no special animation associated with it.
+     * Other options can still be set.
+     */
+    public static ActivityOptions makeBasic() {
+        final ActivityOptions opts = new ActivityOptions();
+        return opts;
+    }
+
+    /**
+     * Create an {@link ActivityOptions} instance that lets the application control the entire
+     * animation using a {@link RemoteAnimationAdapter}.
+     * @hide
+     */
+    @RequiresPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS)
+    @UnsupportedAppUsage
+    public static ActivityOptions makeRemoteAnimation(
+            RemoteAnimationAdapter remoteAnimationAdapter) {
+        final ActivityOptions opts = new ActivityOptions();
+        opts.mRemoteAnimationAdapter = remoteAnimationAdapter;
+        opts.mAnimationType = ANIM_REMOTE_ANIMATION;
+        return opts;
+    }
+
+    /** @hide */
+    public boolean getLaunchTaskBehind() {
+        return mAnimationType == ANIM_LAUNCH_TASK_BEHIND;
+    }
+
+    private ActivityOptions() {
+    }
+
+    /** @hide */
+    public ActivityOptions(Bundle opts) {
+        // If the remote side sent us bad parcelables, they won't get the
+        // results they want, which is their loss.
+        opts.setDefusable(true);
+
+        mPackageName = opts.getString(KEY_PACKAGE_NAME);
+        try {
+            mUsageTimeReport = opts.getParcelable(KEY_USAGE_TIME_REPORT);
+        } catch (RuntimeException e) {
+            Slog.w(TAG, e);
+        }
+        mLaunchBounds = opts.getParcelable(KEY_LAUNCH_BOUNDS);
+        mAnimationType = opts.getInt(KEY_ANIM_TYPE, ANIM_UNDEFINED);
+        switch (mAnimationType) {
+            case ANIM_CUSTOM:
+                mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0);
+                mCustomExitResId = opts.getInt(KEY_ANIM_EXIT_RES_ID, 0);
+                mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
+                        opts.getBinder(KEY_ANIM_START_LISTENER));
+                break;
+
+            case ANIM_CUSTOM_IN_PLACE:
+                mCustomInPlaceResId = opts.getInt(KEY_ANIM_IN_PLACE_RES_ID, 0);
+                break;
+
+            case ANIM_SCALE_UP:
+            case ANIM_CLIP_REVEAL:
+                mStartX = opts.getInt(KEY_ANIM_START_X, 0);
+                mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
+                mWidth = opts.getInt(KEY_ANIM_WIDTH, 0);
+                mHeight = opts.getInt(KEY_ANIM_HEIGHT, 0);
+                break;
+
+            case ANIM_THUMBNAIL_SCALE_UP:
+            case ANIM_THUMBNAIL_SCALE_DOWN:
+            case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
+            case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
+                // Unpackage the GraphicBuffer from the parceled thumbnail
+                final GraphicBuffer buffer = opts.getParcelable(KEY_ANIM_THUMBNAIL);
+                if (buffer != null) {
+                    mThumbnail = Bitmap.wrapHardwareBuffer(buffer, null);
+                }
+                mStartX = opts.getInt(KEY_ANIM_START_X, 0);
+                mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
+                mWidth = opts.getInt(KEY_ANIM_WIDTH, 0);
+                mHeight = opts.getInt(KEY_ANIM_HEIGHT, 0);
+                mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
+                        opts.getBinder(KEY_ANIM_START_LISTENER));
+                break;
+
+            case ANIM_SCENE_TRANSITION:
+                mTransitionReceiver = opts.getParcelable(KEY_TRANSITION_COMPLETE_LISTENER);
+                mIsReturning = opts.getBoolean(KEY_TRANSITION_IS_RETURNING, false);
+                mSharedElementNames = opts.getStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS);
+                mResultData = opts.getParcelable(KEY_RESULT_DATA);
+                mResultCode = opts.getInt(KEY_RESULT_CODE);
+                mExitCoordinatorIndex = opts.getInt(KEY_EXIT_COORDINATOR_INDEX);
+                break;
+        }
+        mLockTaskMode = opts.getBoolean(KEY_LOCK_TASK_MODE, false);
+        mLaunchDisplayId = opts.getInt(KEY_LAUNCH_DISPLAY_ID, INVALID_DISPLAY);
+        mCallerDisplayId = opts.getInt(KEY_CALLER_DISPLAY_ID, INVALID_DISPLAY);
+        mLaunchTaskDisplayArea = opts.getParcelable(KEY_LAUNCH_TASK_DISPLAY_AREA_TOKEN);
+        mLaunchWindowingMode = opts.getInt(KEY_LAUNCH_WINDOWING_MODE, WINDOWING_MODE_UNDEFINED);
+        mLaunchActivityType = opts.getInt(KEY_LAUNCH_ACTIVITY_TYPE, ACTIVITY_TYPE_UNDEFINED);
+        mLaunchTaskId = opts.getInt(KEY_LAUNCH_TASK_ID, -1);
+        mPendingIntentLaunchFlags = opts.getInt(KEY_PENDING_INTENT_LAUNCH_FLAGS, 0);
+        mTaskAlwaysOnTop = opts.getBoolean(KEY_TASK_ALWAYS_ON_TOP, false);
+        mTaskOverlay = opts.getBoolean(KEY_TASK_OVERLAY, false);
+        mTaskOverlayCanResume = opts.getBoolean(KEY_TASK_OVERLAY_CAN_RESUME, false);
+        mAvoidMoveToFront = opts.getBoolean(KEY_AVOID_MOVE_TO_FRONT, false);
+        mFreezeRecentTasksReordering = opts.getBoolean(KEY_FREEZE_RECENT_TASKS_REORDERING, false);
+        mSplitScreenCreateMode = opts.getInt(KEY_SPLIT_SCREEN_CREATE_MODE,
+                SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT);
+        mDisallowEnterPictureInPictureWhileLaunching = opts.getBoolean(
+                KEY_DISALLOW_ENTER_PICTURE_IN_PICTURE_WHILE_LAUNCHING, false);
+        mApplyActivityFlagsForBubbles = opts.getBoolean(
+                KEY_APPLY_ACTIVITY_FLAGS_FOR_BUBBLES, false);
+        if (opts.containsKey(KEY_ANIM_SPECS)) {
+            Parcelable[] specs = opts.getParcelableArray(KEY_ANIM_SPECS);
+            mAnimSpecs = new AppTransitionAnimationSpec[specs.length];
+            for (int i = specs.length - 1; i >= 0; i--) {
+                mAnimSpecs[i] = (AppTransitionAnimationSpec) specs[i];
+            }
+        }
+        if (opts.containsKey(KEY_ANIMATION_FINISHED_LISTENER)) {
+            mAnimationFinishedListener = IRemoteCallback.Stub.asInterface(
+                    opts.getBinder(KEY_ANIMATION_FINISHED_LISTENER));
+        }
+        mRotationAnimationHint = opts.getInt(KEY_ROTATION_ANIMATION_HINT, -1);
+        mAppVerificationBundle = opts.getBundle(KEY_INSTANT_APP_VERIFICATION_BUNDLE);
+        if (opts.containsKey(KEY_SPECS_FUTURE)) {
+            mSpecsFuture = IAppTransitionAnimationSpecsFuture.Stub.asInterface(opts.getBinder(
+                    KEY_SPECS_FUTURE));
+        }
+        mRemoteAnimationAdapter = opts.getParcelable(KEY_REMOTE_ANIMATION_ADAPTER);
+    }
+
+    /**
+     * Sets the bounds (window size and position) that the activity should be launched in.
+     * Rect position should be provided in pixels and in screen coordinates.
+     * Set to {@code null} to explicitly launch fullscreen.
+     * <p>
+     * <strong>NOTE:</strong> This value is ignored on devices that don't have
+     * {@link android.content.pm.PackageManager#FEATURE_FREEFORM_WINDOW_MANAGEMENT} or
+     * {@link android.content.pm.PackageManager#FEATURE_PICTURE_IN_PICTURE} enabled.
+     * @param screenSpacePixelRect launch bounds or {@code null} for fullscreen
+     * @return {@code this} {@link ActivityOptions} instance
+     */
+    public ActivityOptions setLaunchBounds(@Nullable Rect screenSpacePixelRect) {
+        mLaunchBounds = screenSpacePixelRect != null ? new Rect(screenSpacePixelRect) : null;
+        return this;
+    }
+
+    /** @hide */
+    public String getPackageName() {
+        return mPackageName;
+    }
+
+    /**
+     * Returns the bounds that should be used to launch the activity.
+     * @see #setLaunchBounds(Rect)
+     * @return Bounds used to launch the activity.
+     */
+    @Nullable
+    public Rect getLaunchBounds() {
+        return mLaunchBounds;
+    }
+
+    /** @hide */
+    public int getAnimationType() {
+        return mAnimationType;
+    }
+
+    /** @hide */
+    public int getCustomEnterResId() {
+        return mCustomEnterResId;
+    }
+
+    /** @hide */
+    public int getCustomExitResId() {
+        return mCustomExitResId;
+    }
+
+    /** @hide */
+    public int getCustomInPlaceResId() {
+        return mCustomInPlaceResId;
+    }
+
+    /**
+     * The thumbnail is copied into a hardware bitmap when it is bundled and sent to the system, so
+     * it should always be backed by a GraphicBuffer on the other end.
+     *
+     * @hide
+     */
+    public GraphicBuffer getThumbnail() {
+        return mThumbnail != null ? mThumbnail.createGraphicBufferHandle() : null;
+    }
+
+    /** @hide */
+    public int getStartX() {
+        return mStartX;
+    }
+
+    /** @hide */
+    public int getStartY() {
+        return mStartY;
+    }
+
+    /** @hide */
+    public int getWidth() {
+        return mWidth;
+    }
+
+    /** @hide */
+    public int getHeight() {
+        return mHeight;
+    }
+
+    /** @hide */
+    public IRemoteCallback getAnimationStartedListener() {
+        return mAnimationStartedListener;
+    }
+
+    /** @hide */
+    public IRemoteCallback getAnimationFinishedListener() {
+        return mAnimationFinishedListener;
+    }
+
+    /** @hide */
+    public int getExitCoordinatorKey() { return mExitCoordinatorIndex; }
+
+    /** @hide */
+    public void abort() {
+        if (mAnimationStartedListener != null) {
+            try {
+                mAnimationStartedListener.sendResult(null);
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    /** @hide */
+    public boolean isReturning() {
+        return mIsReturning;
+    }
+
+    /**
+     * Returns whether or not the ActivityOptions was created with
+     * {@link #startSharedElementAnimation(Window, Pair[])}.
+     *
+     * @hide
+     */
+    boolean isCrossTask() {
+        return mExitCoordinatorIndex < 0;
+    }
+
+    /** @hide */
+    public ArrayList<String> getSharedElementNames() {
+        return mSharedElementNames;
+    }
+
+    /** @hide */
+    public ResultReceiver getResultReceiver() { return mTransitionReceiver; }
+
+    /** @hide */
+    public int getResultCode() { return mResultCode; }
+
+    /** @hide */
+    public Intent getResultData() { return mResultData; }
+
+    /** @hide */
+    public PendingIntent getUsageTimeReport() {
+        return mUsageTimeReport;
+    }
+
+    /** @hide */
+    public AppTransitionAnimationSpec[] getAnimSpecs() { return mAnimSpecs; }
+
+    /** @hide */
+    public IAppTransitionAnimationSpecsFuture getSpecsFuture() {
+        return mSpecsFuture;
+    }
+
+    /** @hide */
+    public RemoteAnimationAdapter getRemoteAnimationAdapter() {
+        return mRemoteAnimationAdapter;
+    }
+
+    /** @hide */
+    public void setRemoteAnimationAdapter(RemoteAnimationAdapter remoteAnimationAdapter) {
+        mRemoteAnimationAdapter = remoteAnimationAdapter;
+    }
+
+    /** @hide */
+    public static ActivityOptions fromBundle(Bundle bOptions) {
+        return bOptions != null ? new ActivityOptions(bOptions) : null;
+    }
+
+    /** @hide */
+    public static void abort(ActivityOptions options) {
+        if (options != null) {
+            options.abort();
+        }
+    }
+
+    /**
+     * Gets whether the activity is to be launched into LockTask mode.
+     * @return {@code true} if the activity is to be launched into LockTask mode.
+     * @see Activity#startLockTask()
+     * @see android.app.admin.DevicePolicyManager#setLockTaskPackages(ComponentName, String[])
+     */
+    public boolean getLockTaskMode() {
+        return mLockTaskMode;
+    }
+
+    /**
+     * Sets whether the activity is to be launched into LockTask mode.
+     *
+     * Use this option to start an activity in LockTask mode. Note that only apps permitted by
+     * {@link android.app.admin.DevicePolicyManager} can run in LockTask mode. Therefore, if
+     * {@link android.app.admin.DevicePolicyManager#isLockTaskPermitted(String)} returns
+     * {@code false} for the package of the target activity, a {@link SecurityException} will be
+     * thrown during {@link Context#startActivity(Intent, Bundle)}. This method doesn't affect
+     * activities that are already running — relaunch the activity to run in lock task mode.
+     *
+     * Defaults to {@code false} if not set.
+     *
+     * @param lockTaskMode {@code true} if the activity is to be launched into LockTask mode.
+     * @return {@code this} {@link ActivityOptions} instance.
+     * @see Activity#startLockTask()
+     * @see android.app.admin.DevicePolicyManager#setLockTaskPackages(ComponentName, String[])
+     */
+    public ActivityOptions setLockTaskEnabled(boolean lockTaskMode) {
+        mLockTaskMode = lockTaskMode;
+        return this;
+    }
+
+    /**
+     * Gets the id of the display where activity should be launched.
+     * @return The id of the display where activity should be launched,
+     *         {@link android.view.Display#INVALID_DISPLAY} if not set.
+     * @see #setLaunchDisplayId(int)
+     */
+    public int getLaunchDisplayId() {
+        return mLaunchDisplayId;
+    }
+
+    /**
+     * Sets the id of the display where activity should be launched.
+     * An app can launch activities on public displays or private displays that are owned by the app
+     * or where an app already has activities. Otherwise, trying to launch on a private display
+     * or providing an invalid display id will result in an exception.
+     * <p>
+     * Setting launch display id will be ignored on devices that don't have
+     * {@link android.content.pm.PackageManager#FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS}.
+     * @param launchDisplayId The id of the display where the activity should be launched.
+     * @return {@code this} {@link ActivityOptions} instance.
+     */
+    public ActivityOptions setLaunchDisplayId(int launchDisplayId) {
+        mLaunchDisplayId = launchDisplayId;
+        return this;
+    }
+
+    /** @hide */
+    public int getCallerDisplayId() {
+        return mCallerDisplayId;
+    }
+
+    /** @hide */
+    public ActivityOptions setCallerDisplayId(int callerDisplayId) {
+        mCallerDisplayId = callerDisplayId;
+        return this;
+    }
+
+    /** @hide */
+    public WindowContainerToken getLaunchTaskDisplayArea() {
+        return mLaunchTaskDisplayArea;
+    }
+
+    /** @hide */
+    public ActivityOptions setLaunchTaskDisplayArea(
+            WindowContainerToken windowContainerToken) {
+        mLaunchTaskDisplayArea = windowContainerToken;
+        return this;
+    }
+
+    /** @hide */
+    public int getLaunchWindowingMode() {
+        return mLaunchWindowingMode;
+    }
+
+    /**
+     * Sets the windowing mode the activity should launch into. If the input windowing mode is
+     * {@link android.app.WindowConfiguration#WINDOWING_MODE_SPLIT_SCREEN_SECONDARY} and the device
+     * isn't currently in split-screen windowing mode, then the activity will be launched in
+     * {@link android.app.WindowConfiguration#WINDOWING_MODE_FULLSCREEN} windowing mode. For clarity
+     * on this you can use
+     * {@link android.app.WindowConfiguration#WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY}
+     *
+     * @hide
+     */
+    @TestApi
+    public void setLaunchWindowingMode(int windowingMode) {
+        mLaunchWindowingMode = windowingMode;
+    }
+
+    /** @hide */
+    public int getLaunchActivityType() {
+        return mLaunchActivityType;
+    }
+
+    /** @hide */
+    @TestApi
+    public void setLaunchActivityType(int activityType) {
+        mLaunchActivityType = activityType;
+    }
+
+    /**
+     * Sets the task the activity will be launched in.
+     * @hide
+     */
+    @TestApi
+    public void setLaunchTaskId(int taskId) {
+        mLaunchTaskId = taskId;
+    }
+
+    /**
+     * @hide
+     */
+    public int getLaunchTaskId() {
+        return mLaunchTaskId;
+    }
+
+    /**
+     * Specifies intent flags to be applied for any activity started from a PendingIntent.
+     *
+     * @hide
+     */
+    public void setPendingIntentLaunchFlags(@android.content.Intent.Flags int flags) {
+        mPendingIntentLaunchFlags = flags;
+    }
+
+    /**
+     * @hide
+     */
+    public int getPendingIntentLaunchFlags() {
+        return mPendingIntentLaunchFlags;
+    }
+
+    /**
+     * Set's whether the task for the activity launched with this option should always be on top.
+     * @hide
+     */
+    @TestApi
+    public void setTaskAlwaysOnTop(boolean alwaysOnTop) {
+        mTaskAlwaysOnTop = alwaysOnTop;
+    }
+
+    /**
+     * @hide
+     */
+    public boolean getTaskAlwaysOnTop() {
+        return mTaskAlwaysOnTop;
+    }
+
+    /**
+     * Set's whether the activity launched with this option should be a task overlay. That is the
+     * activity will always be the top activity of the task.
+     * @param canResume {@code false} if the task will also not be moved to the front of the stack.
+     * @hide
+     */
+    @TestApi
+    public void setTaskOverlay(boolean taskOverlay, boolean canResume) {
+        mTaskOverlay = taskOverlay;
+        mTaskOverlayCanResume = canResume;
+    }
+
+    /**
+     * @hide
+     */
+    public boolean getTaskOverlay() {
+        return mTaskOverlay;
+    }
+
+    /**
+     * @hide
+     */
+    public boolean canTaskOverlayResume() {
+        return mTaskOverlayCanResume;
+    }
+
+    /**
+     * Sets whether the activity launched should not cause the activity stack it is contained in to
+     * be moved to the front as a part of launching.
+     *
+     * @hide
+     */
+    public void setAvoidMoveToFront() {
+        mAvoidMoveToFront = true;
+    }
+
+    /**
+     * @return whether the activity launch should prevent moving the associated activity stack to
+     *         the front.
+     * @hide
+     */
+    public boolean getAvoidMoveToFront() {
+        return mAvoidMoveToFront;
+    }
+
+    /**
+     * Sets whether the launch of this activity should freeze the recent task list reordering until
+     * the next user interaction or timeout. This flag is only applied when starting an activity
+     * in recents.
+     * @hide
+     */
+    public void setFreezeRecentTasksReordering() {
+        mFreezeRecentTasksReordering = true;
+    }
+
+    /**
+     * @return whether the launch of this activity should freeze the recent task list reordering
+     * @hide
+     */
+    public boolean freezeRecentTasksReordering() {
+        return mFreezeRecentTasksReordering;
+    }
+
+    /** @hide */
+    public int getSplitScreenCreateMode() {
+        return mSplitScreenCreateMode;
+    }
+
+    /** @hide */
+    @UnsupportedAppUsage
+    public void setSplitScreenCreateMode(int splitScreenCreateMode) {
+        mSplitScreenCreateMode = splitScreenCreateMode;
+    }
+
+    /** @hide */
+    public void setDisallowEnterPictureInPictureWhileLaunching(boolean disallow) {
+        mDisallowEnterPictureInPictureWhileLaunching = disallow;
+    }
+
+    /** @hide */
+    public boolean disallowEnterPictureInPictureWhileLaunching() {
+        return mDisallowEnterPictureInPictureWhileLaunching;
+    }
+
+    /** @hide */
+    public void setApplyActivityFlagsForBubbles(boolean apply) {
+        mApplyActivityFlagsForBubbles = apply;
+    }
+
+    /**  @hide */
+    public boolean isApplyActivityFlagsForBubbles() {
+        return mApplyActivityFlagsForBubbles;
+    }
+
+    /**
+     * Update the current values in this ActivityOptions from those supplied
+     * in <var>otherOptions</var>.  Any values
+     * defined in <var>otherOptions</var> replace those in the base options.
+     */
+    public void update(ActivityOptions otherOptions) {
+        if (otherOptions.mPackageName != null) {
+            mPackageName = otherOptions.mPackageName;
+        }
+        mUsageTimeReport = otherOptions.mUsageTimeReport;
+        mTransitionReceiver = null;
+        mSharedElementNames = null;
+        mIsReturning = false;
+        mResultData = null;
+        mResultCode = 0;
+        mExitCoordinatorIndex = 0;
+        mAnimationType = otherOptions.mAnimationType;
+        switch (otherOptions.mAnimationType) {
+            case ANIM_CUSTOM:
+                mCustomEnterResId = otherOptions.mCustomEnterResId;
+                mCustomExitResId = otherOptions.mCustomExitResId;
+                mThumbnail = null;
+                if (mAnimationStartedListener != null) {
+                    try {
+                        mAnimationStartedListener.sendResult(null);
+                    } catch (RemoteException e) {
+                    }
+                }
+                mAnimationStartedListener = otherOptions.mAnimationStartedListener;
+                break;
+            case ANIM_CUSTOM_IN_PLACE:
+                mCustomInPlaceResId = otherOptions.mCustomInPlaceResId;
+                break;
+            case ANIM_SCALE_UP:
+                mStartX = otherOptions.mStartX;
+                mStartY = otherOptions.mStartY;
+                mWidth = otherOptions.mWidth;
+                mHeight = otherOptions.mHeight;
+                if (mAnimationStartedListener != null) {
+                    try {
+                        mAnimationStartedListener.sendResult(null);
+                    } catch (RemoteException e) {
+                    }
+                }
+                mAnimationStartedListener = null;
+                break;
+            case ANIM_THUMBNAIL_SCALE_UP:
+            case ANIM_THUMBNAIL_SCALE_DOWN:
+            case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
+            case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
+                mThumbnail = otherOptions.mThumbnail;
+                mStartX = otherOptions.mStartX;
+                mStartY = otherOptions.mStartY;
+                mWidth = otherOptions.mWidth;
+                mHeight = otherOptions.mHeight;
+                if (mAnimationStartedListener != null) {
+                    try {
+                        mAnimationStartedListener.sendResult(null);
+                    } catch (RemoteException e) {
+                    }
+                }
+                mAnimationStartedListener = otherOptions.mAnimationStartedListener;
+                break;
+            case ANIM_SCENE_TRANSITION:
+                mTransitionReceiver = otherOptions.mTransitionReceiver;
+                mSharedElementNames = otherOptions.mSharedElementNames;
+                mIsReturning = otherOptions.mIsReturning;
+                mThumbnail = null;
+                mAnimationStartedListener = null;
+                mResultData = otherOptions.mResultData;
+                mResultCode = otherOptions.mResultCode;
+                mExitCoordinatorIndex = otherOptions.mExitCoordinatorIndex;
+                break;
+        }
+        mLockTaskMode = otherOptions.mLockTaskMode;
+        mAnimSpecs = otherOptions.mAnimSpecs;
+        mAnimationFinishedListener = otherOptions.mAnimationFinishedListener;
+        mSpecsFuture = otherOptions.mSpecsFuture;
+        mRemoteAnimationAdapter = otherOptions.mRemoteAnimationAdapter;
+    }
+
+    /**
+     * Returns the created options as a Bundle, which can be passed to
+     * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle)
+     * Context.startActivity(Intent, Bundle)} and related methods.
+     * Note that the returned Bundle is still owned by the ActivityOptions
+     * object; you must not modify it, but can supply it to the startActivity
+     * methods that take an options Bundle.
+     */
+    public Bundle toBundle() {
+        Bundle b = new Bundle();
+        if (mPackageName != null) {
+            b.putString(KEY_PACKAGE_NAME, mPackageName);
+        }
+        if (mLaunchBounds != null) {
+            b.putParcelable(KEY_LAUNCH_BOUNDS, mLaunchBounds);
+        }
+        if (mAnimationType != ANIM_UNDEFINED) {
+            b.putInt(KEY_ANIM_TYPE, mAnimationType);
+        }
+        if (mUsageTimeReport != null) {
+            b.putParcelable(KEY_USAGE_TIME_REPORT, mUsageTimeReport);
+        }
+        switch (mAnimationType) {
+            case ANIM_CUSTOM:
+                b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId);
+                b.putInt(KEY_ANIM_EXIT_RES_ID, mCustomExitResId);
+                b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
+                        != null ? mAnimationStartedListener.asBinder() : null);
+                break;
+            case ANIM_CUSTOM_IN_PLACE:
+                b.putInt(KEY_ANIM_IN_PLACE_RES_ID, mCustomInPlaceResId);
+                break;
+            case ANIM_SCALE_UP:
+            case ANIM_CLIP_REVEAL:
+                b.putInt(KEY_ANIM_START_X, mStartX);
+                b.putInt(KEY_ANIM_START_Y, mStartY);
+                b.putInt(KEY_ANIM_WIDTH, mWidth);
+                b.putInt(KEY_ANIM_HEIGHT, mHeight);
+                break;
+            case ANIM_THUMBNAIL_SCALE_UP:
+            case ANIM_THUMBNAIL_SCALE_DOWN:
+            case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
+            case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
+                // Once we parcel the thumbnail for transfering over to the system, create a copy of
+                // the bitmap to a hardware bitmap and pass through the GraphicBuffer
+                if (mThumbnail != null) {
+                    final Bitmap hwBitmap = mThumbnail.copy(Config.HARDWARE, false /* isMutable */);
+                    if (hwBitmap != null) {
+                        b.putParcelable(KEY_ANIM_THUMBNAIL, hwBitmap.createGraphicBufferHandle());
+                    } else {
+                        Slog.w(TAG, "Failed to copy thumbnail");
+                    }
+                }
+                b.putInt(KEY_ANIM_START_X, mStartX);
+                b.putInt(KEY_ANIM_START_Y, mStartY);
+                b.putInt(KEY_ANIM_WIDTH, mWidth);
+                b.putInt(KEY_ANIM_HEIGHT, mHeight);
+                b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
+                        != null ? mAnimationStartedListener.asBinder() : null);
+                break;
+            case ANIM_SCENE_TRANSITION:
+                if (mTransitionReceiver != null) {
+                    b.putParcelable(KEY_TRANSITION_COMPLETE_LISTENER, mTransitionReceiver);
+                }
+                b.putBoolean(KEY_TRANSITION_IS_RETURNING, mIsReturning);
+                b.putStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS, mSharedElementNames);
+                b.putParcelable(KEY_RESULT_DATA, mResultData);
+                b.putInt(KEY_RESULT_CODE, mResultCode);
+                b.putInt(KEY_EXIT_COORDINATOR_INDEX, mExitCoordinatorIndex);
+                break;
+        }
+        if (mLockTaskMode) {
+            b.putBoolean(KEY_LOCK_TASK_MODE, mLockTaskMode);
+        }
+        if (mLaunchDisplayId != INVALID_DISPLAY) {
+            b.putInt(KEY_LAUNCH_DISPLAY_ID, mLaunchDisplayId);
+        }
+        if (mCallerDisplayId != INVALID_DISPLAY) {
+            b.putInt(KEY_CALLER_DISPLAY_ID, mCallerDisplayId);
+        }
+        if (mLaunchTaskDisplayArea != null) {
+            b.putParcelable(KEY_LAUNCH_TASK_DISPLAY_AREA_TOKEN, mLaunchTaskDisplayArea);
+        }
+        if (mLaunchWindowingMode != WINDOWING_MODE_UNDEFINED) {
+            b.putInt(KEY_LAUNCH_WINDOWING_MODE, mLaunchWindowingMode);
+        }
+        if (mLaunchActivityType != ACTIVITY_TYPE_UNDEFINED) {
+            b.putInt(KEY_LAUNCH_ACTIVITY_TYPE, mLaunchActivityType);
+        }
+        if (mLaunchTaskId != -1) {
+            b.putInt(KEY_LAUNCH_TASK_ID, mLaunchTaskId);
+        }
+        if (mPendingIntentLaunchFlags != 0) {
+            b.putInt(KEY_PENDING_INTENT_LAUNCH_FLAGS, mPendingIntentLaunchFlags);
+        }
+        if (mTaskAlwaysOnTop) {
+            b.putBoolean(KEY_TASK_ALWAYS_ON_TOP, mTaskAlwaysOnTop);
+        }
+        if (mTaskOverlay) {
+            b.putBoolean(KEY_TASK_OVERLAY, mTaskOverlay);
+        }
+        if (mTaskOverlayCanResume) {
+            b.putBoolean(KEY_TASK_OVERLAY_CAN_RESUME, mTaskOverlayCanResume);
+        }
+        if (mAvoidMoveToFront) {
+            b.putBoolean(KEY_AVOID_MOVE_TO_FRONT, mAvoidMoveToFront);
+        }
+        if (mFreezeRecentTasksReordering) {
+            b.putBoolean(KEY_FREEZE_RECENT_TASKS_REORDERING, mFreezeRecentTasksReordering);
+        }
+        if (mSplitScreenCreateMode != SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT) {
+            b.putInt(KEY_SPLIT_SCREEN_CREATE_MODE, mSplitScreenCreateMode);
+        }
+        if (mDisallowEnterPictureInPictureWhileLaunching) {
+            b.putBoolean(KEY_DISALLOW_ENTER_PICTURE_IN_PICTURE_WHILE_LAUNCHING,
+                    mDisallowEnterPictureInPictureWhileLaunching);
+        }
+        if (mApplyActivityFlagsForBubbles) {
+            b.putBoolean(KEY_APPLY_ACTIVITY_FLAGS_FOR_BUBBLES, mApplyActivityFlagsForBubbles);
+        }
+        if (mAnimSpecs != null) {
+            b.putParcelableArray(KEY_ANIM_SPECS, mAnimSpecs);
+        }
+        if (mAnimationFinishedListener != null) {
+            b.putBinder(KEY_ANIMATION_FINISHED_LISTENER, mAnimationFinishedListener.asBinder());
+        }
+        if (mSpecsFuture != null) {
+            b.putBinder(KEY_SPECS_FUTURE, mSpecsFuture.asBinder());
+        }
+        if (mRotationAnimationHint != -1) {
+            b.putInt(KEY_ROTATION_ANIMATION_HINT, mRotationAnimationHint);
+        }
+        if (mAppVerificationBundle != null) {
+            b.putBundle(KEY_INSTANT_APP_VERIFICATION_BUNDLE, mAppVerificationBundle);
+        }
+        if (mRemoteAnimationAdapter != null) {
+            b.putParcelable(KEY_REMOTE_ANIMATION_ADAPTER, mRemoteAnimationAdapter);
+        }
+        return b;
+    }
+
+    /**
+     * Ask the system track that time the user spends in the app being launched, and
+     * report it back once done.  The report will be sent to the given receiver, with
+     * the extras {@link #EXTRA_USAGE_TIME_REPORT} and {@link #EXTRA_USAGE_TIME_REPORT_PACKAGES}
+     * filled in.
+     *
+     * <p>The time interval tracked is from launching this activity until the user leaves
+     * that activity's flow.  They are considered to stay in the flow as long as
+     * new activities are being launched or returned to from the original flow,
+     * even if this crosses package or task boundaries.  For example, if the originator
+     * starts an activity to view an image, and while there the user selects to share,
+     * which launches their email app in a new task, and they complete the share, the
+     * time during that entire operation will be included until they finally hit back from
+     * the original image viewer activity.</p>
+     *
+     * <p>The user is considered to complete a flow once they switch to another
+     * activity that is not part of the tracked flow.  This may happen, for example, by
+     * using the notification shade, launcher, or recents to launch or switch to another
+     * app.  Simply going in to these navigation elements does not break the flow (although
+     * the launcher and recents stops time tracking of the session); it is the act of
+     * going somewhere else that completes the tracking.</p>
+     *
+     * @param receiver A broadcast receiver that willl receive the report.
+     */
+    public void requestUsageTimeReport(PendingIntent receiver) {
+        mUsageTimeReport = receiver;
+    }
+
+    /**
+     * Return the filtered options only meant to be seen by the target activity itself
+     * @hide
+     */
+    public ActivityOptions forTargetActivity() {
+        if (mAnimationType == ANIM_SCENE_TRANSITION) {
+            final ActivityOptions result = new ActivityOptions();
+            result.update(this);
+            return result;
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the rotation animation set by {@link setRotationAnimationHint} or -1
+     * if unspecified.
+     * @hide
+     */
+    public int getRotationAnimationHint() {
+        return mRotationAnimationHint;
+    }
+
+
+    /**
+     * Set a rotation animation to be used if launching the activity
+     * triggers an orientation change, or -1 to clear. See
+     * {@link android.view.WindowManager.LayoutParams} for rotation
+     * animation values.
+     * @hide
+     */
+    public void setRotationAnimationHint(int hint) {
+        mRotationAnimationHint = hint;
+    }
+
+    /**
+     * Pop the extra verification bundle for the installer.
+     * This removes the bundle from the ActivityOptions to make sure the installer bundle
+     * is only available once.
+     * @hide
+     */
+    public Bundle popAppVerificationBundle() {
+        Bundle out = mAppVerificationBundle;
+        mAppVerificationBundle = null;
+        return out;
+    }
+
+    /**
+     * Set the {@link Bundle} that is provided to the app installer for additional verification
+     * if the call to {@link Context#startActivity} results in an app being installed.
+     *
+     * This Bundle is not provided to any other app besides the installer.
+     */
+    public ActivityOptions setAppVerificationBundle(Bundle bundle) {
+        mAppVerificationBundle = bundle;
+        return this;
+
+    }
+
+    /** @hide */
+    @Override
+    public String toString() {
+        return "ActivityOptions(" + hashCode() + "), mPackageName=" + mPackageName
+                + ", mAnimationType=" + mAnimationType + ", mStartX=" + mStartX + ", mStartY="
+                + mStartY + ", mWidth=" + mWidth + ", mHeight=" + mHeight;
+    }
+
+    private static class HideWindowListener extends TransitionListenerAdapter
+        implements ExitTransitionCoordinator.HideSharedElementsCallback {
+        private final Window mWindow;
+        private final ExitTransitionCoordinator mExit;
+        private final boolean mWaitingForTransition;
+        private boolean mTransitionEnded;
+        private boolean mSharedElementHidden;
+        private ArrayList<View> mSharedElements;
+
+        public HideWindowListener(Window window, ExitTransitionCoordinator exit) {
+            mWindow = window;
+            mExit = exit;
+            mSharedElements = new ArrayList<>(exit.mSharedElements);
+            Transition transition = mWindow.getExitTransition();
+            if (transition != null) {
+                transition.addListener(this);
+                mWaitingForTransition = true;
+            } else {
+                mWaitingForTransition = false;
+            }
+            View decorView = mWindow.getDecorView();
+            if (decorView != null) {
+                if (decorView.getTag(com.android.internal.R.id.cross_task_transition) != null) {
+                    throw new IllegalStateException(
+                            "Cannot start a transition while one is running");
+                }
+                decorView.setTagInternal(com.android.internal.R.id.cross_task_transition, exit);
+            }
+        }
+
+        @Override
+        public void onTransitionEnd(Transition transition) {
+            mTransitionEnded = true;
+            hideWhenDone();
+            transition.removeListener(this);
+        }
+
+        @Override
+        public void hideSharedElements() {
+            mSharedElementHidden = true;
+            hideWhenDone();
+        }
+
+        private void hideWhenDone() {
+            if (mSharedElementHidden && (!mWaitingForTransition || mTransitionEnded)) {
+                mExit.resetViews();
+                int numSharedElements = mSharedElements.size();
+                for (int i = 0; i < numSharedElements; i++) {
+                    View view = mSharedElements.get(i);
+                    view.requestLayout();
+                }
+                View decorView = mWindow.getDecorView();
+                if (decorView != null) {
+                    decorView.setTagInternal(
+                            com.android.internal.R.id.cross_task_transition, null);
+                    decorView.setVisibility(View.GONE);
+                }
+            }
+        }
+    }
+}