/*
 * 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.ActivityManager.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.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.TestApi;
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 java.util.ArrayList;

Helper class for building an options Bundle that can be used with Context.startActivity(Intent, Bundle) and related methods.
/** * 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 requestUsageTimeReport that contains the total time (in ms) the user spent in the app flow.
/** * 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 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).
/** * 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
/** * 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 PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT or PackageManager.FEATURE_PICTURE_IN_PICTURE enabled.
@hide
/** * 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
/** * Type of animation that arguments specify. * @hide */
public static final String KEY_ANIM_TYPE = "android:activity.animType";
Custom enter animation resource ID.
@hide
/** * Custom enter animation resource ID. * @hide */
public static final String KEY_ANIM_ENTER_RES_ID = "android:activity.animEnterRes";
Custom exit animation resource ID.
@hide
/** * 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
/** * 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
/** * Bitmap for thumbnail animation. * @hide */
public static final String KEY_ANIM_THUMBNAIL = "android:activity.animThumbnail";
Start X position of thumbnail animation.
@hide
/** * 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
/** * Start Y position of thumbnail animation. * @hide */
public static final String KEY_ANIM_START_Y = "android:activity.animStartY";
Initial width of the animation.
@hide
/** * Initial width of the animation. * @hide */
public static final String KEY_ANIM_WIDTH = "android:activity.animWidth";
Initial height of the animation.
@hide
/** * Initial height of the animation. * @hide */
public static final String KEY_ANIM_HEIGHT = "android:activity.animHeight";
Callback for when animation is started.
@hide
/** * 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
/** * 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.
/** * 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 Also:
  • setLockTaskEnabled(boolean)
/** * 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 Also:
  • setLaunchDisplayId(int)
@hide
/** * 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 windowing mode the activity should be launched into.
@hide
/** * 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
/** * 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
/** * The task id the activity should be launched into. * @hide */
private static final String KEY_LAUNCH_TASK_ID = "android.activity.launchTaskId";
@hide
/** * See {@link #setTaskOverlay}. * @hide */
private static final String KEY_TASK_OVERLAY = "android.activity.taskOverlay";
@hide
/** * See {@link #setTaskOverlay}. * @hide */
private static final String KEY_TASK_OVERLAY_CAN_RESUME = "android.activity.taskOverlayCanResume";
@hide
/** * See {@link #setAvoidMoveToFront()}. * @hide */
private static final String KEY_AVOID_MOVE_TO_FRONT = "android.activity.avoidMoveToFront";
Where the split-screen-primary stack should be positioned.
@hide
/** * 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
/** * 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";
For Activity transitions, the calling Activity's TransitionListener used to notify the called Activity when the shared element and the exit transitions complete.
/** * 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
/** @hide */
public static final int ANIM_NONE = 0;
@hide
/** @hide */
public static final int ANIM_CUSTOM = 1;
@hide
/** @hide */
public static final int ANIM_SCALE_UP = 2;
@hide
/** @hide */
public static final int ANIM_THUMBNAIL_SCALE_UP = 3;
@hide
/** @hide */
public static final int ANIM_THUMBNAIL_SCALE_DOWN = 4;
@hide
/** @hide */
public static final int ANIM_SCENE_TRANSITION = 5;
@hide
/** @hide */
public static final int ANIM_DEFAULT = 6;
@hide
/** @hide */
public static final int ANIM_LAUNCH_TASK_BEHIND = 7;
@hide
/** @hide */
public static final int ANIM_THUMBNAIL_ASPECT_SCALE_UP = 8;
@hide
/** @hide */
public static final int ANIM_THUMBNAIL_ASPECT_SCALE_DOWN = 9;
@hide
/** @hide */
public static final int ANIM_CUSTOM_IN_PLACE = 10;
@hide
/** @hide */
public static final int ANIM_CLIP_REVEAL = 11;
@hide
/** @hide */
public static final int ANIM_OPEN_CROSS_PROFILE_APPS = 12;
@hide
/** @hide */
public static final int ANIM_REMOTE_ANIMATION = 13; private String mPackageName; private Rect mLaunchBounds; private int mAnimationType = ANIM_NONE; 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 boolean mLockTaskMode = false; private int mLaunchDisplayId = INVALID_DISPLAY; @WindowConfiguration.WindowingMode private int mLaunchWindowingMode = WINDOWING_MODE_UNDEFINED; @WindowConfiguration.ActivityType private int mLaunchActivityType = ACTIVITY_TYPE_UNDEFINED; private int mLaunchTaskId = -1; private int mSplitScreenCreateMode = SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; private boolean mDisallowEnterPictureInPictureWhileLaunching; private boolean mTaskOverlay; private boolean mTaskOverlayCanResume; private boolean mAvoidMoveToFront; 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.
Params:
  • context – Who is defining this. This is the application that the animation resources will be loaded from.
  • enterResId – A resource ID of the animation resource to use for the incoming activity. Use 0 for no animation.
  • exitResId – A resource ID of the animation resource to use for the outgoing activity. Use 0 for no animation.
Returns:Returns a new ActivityOptions object that you can use to supply these options as the options Bundle when starting an activity.
/** * 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); }
Create an ActivityOptions specifying a custom animation to run when the activity is displayed.
Params:
  • context – Who is defining this. This is the application that the animation resources will be loaded from.
  • enterResId – A resource ID of the animation resource to use for the incoming activity. Use 0 for no animation.
  • exitResId – A resource ID of the animation resource to use for the outgoing activity. Use 0 for no animation.
  • handler – If listener is non-null this must be a valid Handler on which to dispatch the callback; otherwise it should be null.
  • 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.
Returns:Returns a new ActivityOptions object that you can use to supply these options as the options Bundle when starting an activity.
@hide
/** * 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 */
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; }
Creates an ActivityOptions specifying a custom animation to run in place on an existing activity.
Params:
  • context – Who is defining this. This is the application that the animation resources will be loaded from.
  • animId – A resource ID of the animation resource to use for the incoming activity.
Returns:Returns a new ActivityOptions object that you can use to supply these options as the options Bundle when running an in-place animation.
@hide
/** * 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 ActivityOptions.makeThumbnailScaleUpAnimation to find out when the given animation has started running.
@hide
/** * Callback for use with {@link ActivityOptions#makeThumbnailScaleUpAnimation} * to find out when the given animation has started running. * @hide */
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 ActivityOptions.makeThumbnailAspectScaleDownAnimation to find out when the given animation has drawn its last frame.
@hide
/** * Callback for use with {@link ActivityOptions#makeThumbnailAspectScaleDownAnimation} * to find out when the given animation has drawn its last frame. * @hide */
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.

If the Intent this is being used with has not set its Intent.setSourceBounds, those bounds will be filled in for you based on the initial bounds passed in here.

Params:
  • source – The View that the new activity is animating from. This defines the coordinate space for startX and startY.
  • startX – The x starting location of the new activity, relative to source.
  • startY – The y starting location of the activity, relative to source.
  • width – The initial width of the new activity.
  • height – The initial height of the new activity.
Returns:Returns a new ActivityOptions object that you can use to supply these options as the options Bundle when starting an activity.
/** * 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.
Params:
  • source – The View that the new activity is animating from. This defines the coordinate space for startX and startY.
  • startX – The x starting location of the new activity, relative to source.
  • startY – The y starting location of the activity, relative to source.
  • width – The initial width of the new activity.
  • height – The initial height of the new activity.
Returns:Returns a new ActivityOptions object that you can use to supply these options as the options Bundle when starting an activity.
/** * 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 ActivityOptions object specifying an animation where the new activity is started in another user profile by calling startMainActivity.startMainActivity(ComponentName, UserHandle).
@hide
/** * 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.

If the Intent this is being used with has not set its Intent.setSourceBounds, those bounds will be filled in for you based on the initial thumbnail location and size provided here.

Params:
  • source – The View that this thumbnail is animating from. This defines the coordinate space for startX and startY.
  • thumbnail – The bitmap that will be shown as the initial thumbnail of the animation.
  • startX – The x starting location of the bitmap, relative to source.
  • startY – The y starting location of the bitmap, relative to source.
Returns:Returns a new ActivityOptions object that you can use to supply these options as the options Bundle when starting an activity.
/** * 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.
Params:
  • source – The View that this thumbnail is animating from. This defines the coordinate space for startX and startY.
  • thumbnail – The bitmap that will be shown as the initial thumbnail of the animation.
  • startX – The x starting location of the bitmap, relative to source.
  • startY – The y starting location of the bitmap, relative to source.
  • 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.
Returns:Returns a new ActivityOptions object that you can use to supply these options as the options Bundle when starting an activity.
/** * 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
/** * Create an ActivityOptions specifying an animation where a list of activity windows and * thumbnails are aspect scaled to/from a new location. * @hide */
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.
Params:
  • source – The View that this thumbnail is animating to. This defines the coordinate space for startX and startY.
  • thumbnail – The bitmap that will be shown as the final thumbnail of the animation.
  • startX – The x end location of the bitmap, relative to source.
  • startY – The y end location of the bitmap, relative to source.
  • handler – If listener is non-null this must be a valid Handler on which to dispatch the callback; otherwise it should be null.
  • 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.
Returns:Returns a new ActivityOptions object that you can use to supply these options as the options Bundle when starting an activity.
@hide
/** * 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
/** @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 sharedElement 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.

This requires 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.

Params:
  • activity – The Activity whose window contains the shared elements.
  • sharedElement – The View to transition to the started Activity.
  • sharedElementName – The shared element name as used in the target Activity. This must not be null.
See Also:
Returns:Returns a new ActivityOptions object that you can use to supply these options as the options Bundle when starting an activity.
/** * 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.

This requires 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.

Params:
  • activity – The Activity whose window contains the shared elements.
  • 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.
See Also:
Returns:Returns a new ActivityOptions object that you can use to supply these options as the options Bundle when starting an activity.
/** * 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.

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
/** * 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 startSharedElementAnimation(Window, Pair<View,String>[]) 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
/** * 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; }
@hide
/** @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.

This behavior is not supported for activities with launchMode values of singleInstance or singleTask.

/** * 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.
/** * 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 ActivityOptions instance that lets the application control the entire animation using a RemoteAnimationAdapter.
@hide
/** * Create an {@link ActivityOptions} instance that lets the application control the entire * animation using a {@link RemoteAnimationAdapter}. * @hide */
@RequiresPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS) public static ActivityOptions makeRemoteAnimation( RemoteAnimationAdapter remoteAnimationAdapter) { final ActivityOptions opts = new ActivityOptions(); opts.mRemoteAnimationAdapter = remoteAnimationAdapter; opts.mAnimationType = ANIM_REMOTE_ANIMATION; return opts; }
@hide
/** @hide */
public boolean getLaunchTaskBehind() { return mAnimationType == ANIM_LAUNCH_TASK_BEHIND; } private ActivityOptions() { }
@hide
/** @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); 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.createHardwareBitmap(buffer); } 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); 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); 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); 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); 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); 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 null to explicitly launch fullscreen.

NOTE: This value is ignored on devices that don't have PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT or PackageManager.FEATURE_PICTURE_IN_PICTURE enabled.

Params:
  • screenSpacePixelRect – launch bounds or null for fullscreen
Returns:this ActivityOptions instance
/** * 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
/** @hide */
public String getPackageName() { return mPackageName; }
Returns the bounds that should be used to launch the activity.
See Also:
  • setLaunchBounds(Rect)
Returns:Bounds used to launch the activity.
/** * 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
/** @hide */
public int getAnimationType() { return mAnimationType; }
@hide
/** @hide */
public int getCustomEnterResId() { return mCustomEnterResId; }
@hide
/** @hide */
public int getCustomExitResId() { return mCustomExitResId; }
@hide
/** @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
/** * 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
/** @hide */
public int getStartX() { return mStartX; }
@hide
/** @hide */
public int getStartY() { return mStartY; }
@hide
/** @hide */
public int getWidth() { return mWidth; }
@hide
/** @hide */
public int getHeight() { return mHeight; }
@hide
/** @hide */
public IRemoteCallback getOnAnimationStartListener() { return mAnimationStartedListener; }
@hide
/** @hide */
public IRemoteCallback getAnimationFinishedListener() { return mAnimationFinishedListener; }
@hide
/** @hide */
public int getExitCoordinatorKey() { return mExitCoordinatorIndex; }
@hide
/** @hide */
public void abort() { if (mAnimationStartedListener != null) { try { mAnimationStartedListener.sendResult(null); } catch (RemoteException e) { } } }
@hide
/** @hide */
public boolean isReturning() { return mIsReturning; }
Returns whether or not the ActivityOptions was created with startSharedElementAnimation(Window, Pair<View,String>[]).
@hide
/** * Returns whether or not the ActivityOptions was created with * {@link #startSharedElementAnimation(Window, Pair[])}. * * @hide */
boolean isCrossTask() { return mExitCoordinatorIndex < 0; }
@hide
/** @hide */
public ArrayList<String> getSharedElementNames() { return mSharedElementNames; }
@hide
/** @hide */
public ResultReceiver getResultReceiver() { return mTransitionReceiver; }
@hide
/** @hide */
public int getResultCode() { return mResultCode; }
@hide
/** @hide */
public Intent getResultData() { return mResultData; }
@hide
/** @hide */
public PendingIntent getUsageTimeReport() { return mUsageTimeReport; }
@hide
/** @hide */
public AppTransitionAnimationSpec[] getAnimSpecs() { return mAnimSpecs; }
@hide
/** @hide */
public IAppTransitionAnimationSpecsFuture getSpecsFuture() { return mSpecsFuture; }
@hide
/** @hide */
public RemoteAnimationAdapter getRemoteAnimationAdapter() { return mRemoteAnimationAdapter; }
@hide
/** @hide */
public void setRemoteAnimationAdapter(RemoteAnimationAdapter remoteAnimationAdapter) { mRemoteAnimationAdapter = remoteAnimationAdapter; }
@hide
/** @hide */
public static ActivityOptions fromBundle(Bundle bOptions) { return bOptions != null ? new ActivityOptions(bOptions) : null; }
@hide
/** @hide */
public static void abort(ActivityOptions options) { if (options != null) { options.abort(); } }
Gets whether the activity is to be launched into LockTask mode.
See Also:
Returns:true if the activity is to be launched into LockTask mode.
/** * 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 DevicePolicyManager can run in LockTask mode. Therefore, if DevicePolicyManager.isLockTaskPermitted(String) returns false for the package of the target activity, a SecurityException will be thrown during 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 false if not set.
Params:
  • lockTaskMode – true if the activity is to be launched into LockTask mode.
See Also:
Returns:this ActivityOptions instance.
/** * 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.
See Also:
Returns:The id of the display where activity should be launched, Display.INVALID_DISPLAY if not set.
/** * 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.

Setting launch display id will be ignored on devices that don't have PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS.

Params:
  • launchDisplayId – The id of the display where the activity should be launched.
Returns:this ActivityOptions instance.
/** * 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
/** @hide */
public int getLaunchWindowingMode() { return mLaunchWindowingMode; }
Sets the windowing mode the activity should launch into. If the input windowing mode is WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY and the device isn't currently in split-screen windowing mode, then the activity will be launched in WindowConfiguration.WINDOWING_MODE_FULLSCREEN windowing mode. For clarity on this you can use WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY
@hide
/** * 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
/** @hide */
public int getLaunchActivityType() { return mLaunchActivityType; }
@hide
/** @hide */
@TestApi public void setLaunchActivityType(int activityType) { mLaunchActivityType = activityType; }
Sets the task the activity will be launched in.
@hide
/** * Sets the task the activity will be launched in. * @hide */
@TestApi public void setLaunchTaskId(int taskId) { mLaunchTaskId = taskId; }
@hide
/** * @hide */
public int getLaunchTaskId() { return mLaunchTaskId; }
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. If {@param canResume} is true, then the task will also not be moved to the front of the stack.
@hide
/** * 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. If {@param canResume} is true, then * 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
/** * @hide */
public boolean getTaskOverlay() { return mTaskOverlay; }
@hide
/** * @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
/** * 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; }
Returns:whether the activity launch should prevent moving the associated activity stack to the front.
@hide
/** * @return whether the activity launch should prevent moving the associated activity stack to * the front. * @hide */
public boolean getAvoidMoveToFront() { return mAvoidMoveToFront; }
@hide
/** @hide */
public int getSplitScreenCreateMode() { return mSplitScreenCreateMode; }
@hide
/** @hide */
public void setSplitScreenCreateMode(int splitScreenCreateMode) { mSplitScreenCreateMode = splitScreenCreateMode; }
@hide
/** @hide */
public void setDisallowEnterPictureInPictureWhileLaunching(boolean disallow) { mDisallowEnterPictureInPictureWhileLaunching = disallow; }
@hide
/** @hide */
public boolean disallowEnterPictureInPictureWhileLaunching() { return mDisallowEnterPictureInPictureWhileLaunching; }
Update the current values in this ActivityOptions from those supplied in otherOptions. Any values defined in otherOptions replace those in the base options.
/** * 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 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.
/** * 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); } 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; } b.putBoolean(KEY_LOCK_TASK_MODE, mLockTaskMode); b.putInt(KEY_LAUNCH_DISPLAY_ID, mLaunchDisplayId); b.putInt(KEY_LAUNCH_WINDOWING_MODE, mLaunchWindowingMode); b.putInt(KEY_LAUNCH_ACTIVITY_TYPE, mLaunchActivityType); b.putInt(KEY_LAUNCH_TASK_ID, mLaunchTaskId); b.putBoolean(KEY_TASK_OVERLAY, mTaskOverlay); b.putBoolean(KEY_TASK_OVERLAY_CAN_RESUME, mTaskOverlayCanResume); b.putBoolean(KEY_AVOID_MOVE_TO_FRONT, mAvoidMoveToFront); b.putInt(KEY_SPLIT_SCREEN_CREATE_MODE, mSplitScreenCreateMode); b.putBoolean(KEY_DISALLOW_ENTER_PICTURE_IN_PICTURE_WHILE_LAUNCHING, mDisallowEnterPictureInPictureWhileLaunching); 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()); } 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 EXTRA_USAGE_TIME_REPORT and EXTRA_USAGE_TIME_REPORT_PACKAGES filled in.

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.

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.

Params:
  • receiver – A broadcast receiver that willl receive the report.
/** * 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
/** * 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 setRotationAnimationHint or -1 if unspecified.
@hide
/** * 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 LayoutParams for rotation animation values.
@hide
/** * 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
/** * 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 Bundle that is provided to the app installer for additional verification if the call to Context.startActivity results in an app being installed. This Bundle is not provided to any other app besides the installer.
/** * 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
/** @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); } } } } }