1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.app;
18 
19 import static android.Manifest.permission.CONTROL_KEYGUARD;
20 import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
21 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
23 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
24 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
25 import static android.content.Intent.FLAG_RECEIVER_FOREGROUND;
26 import static android.view.Display.INVALID_DISPLAY;
27 import static android.window.DisplayAreaOrganizer.FEATURE_UNDEFINED;
28 
29 import android.annotation.IntDef;
30 import android.annotation.NonNull;
31 import android.annotation.Nullable;
32 import android.annotation.RequiresPermission;
33 import android.annotation.SystemApi;
34 import android.annotation.TestApi;
35 import android.app.ExitTransitionCoordinator.ActivityExitTransitionCallbacks;
36 import android.app.ExitTransitionCoordinator.ExitTransitionCallbacks;
37 import android.compat.annotation.UnsupportedAppUsage;
38 import android.content.ComponentName;
39 import android.content.Context;
40 import android.content.Intent;
41 import android.graphics.Bitmap;
42 import android.graphics.Bitmap.Config;
43 import android.graphics.Rect;
44 import android.hardware.HardwareBuffer;
45 import android.os.Bundle;
46 import android.os.Handler;
47 import android.os.IBinder;
48 import android.os.IRemoteCallback;
49 import android.os.Parcel;
50 import android.os.Parcelable;
51 import android.os.RemoteException;
52 import android.os.ResultReceiver;
53 import android.os.SystemClock;
54 import android.os.UserHandle;
55 import android.transition.TransitionManager;
56 import android.util.Pair;
57 import android.util.Slog;
58 import android.view.AppTransitionAnimationSpec;
59 import android.view.IAppTransitionAnimationSpecsFuture;
60 import android.view.RemoteAnimationAdapter;
61 import android.view.View;
62 import android.view.ViewGroup;
63 import android.view.Window;
64 import android.window.RemoteTransition;
65 import android.window.SplashScreen;
66 import android.window.WindowContainerToken;
67 
68 import java.lang.annotation.Retention;
69 import java.lang.annotation.RetentionPolicy;
70 import java.util.ArrayList;
71 
72 /**
73  * Helper class for building an options Bundle that can be used with
74  * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle)
75  * Context.startActivity(Intent, Bundle)} and related methods.
76  */
77 public class ActivityOptions extends ComponentOptions {
78     private static final String TAG = "ActivityOptions";
79 
80     /**
81      * A long in the extras delivered by {@link #requestUsageTimeReport} that contains
82      * the total time (in ms) the user spent in the app flow.
83      */
84     public static final String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
85 
86     /**
87      * A Bundle in the extras delivered by {@link #requestUsageTimeReport} that contains
88      * detailed information about the time spent in each package associated with the app;
89      * each key is a package name, whose value is a long containing the time (in ms).
90      */
91     public static final String EXTRA_USAGE_TIME_REPORT_PACKAGES = "android.usage_time_packages";
92 
93     /** No explicit value chosen. The system will decide whether to grant privileges. */
94     public static final int MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED =
95             ComponentOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED;
96     /** Allow the {@link PendingIntent} to use the background activity start privileges. */
97     public static final int MODE_BACKGROUND_ACTIVITY_START_ALLOWED =
98             ComponentOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED;
99     /** Deny the {@link PendingIntent} to use the background activity start privileges. */
100     public static final int MODE_BACKGROUND_ACTIVITY_START_DENIED =
101             ComponentOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED;
102 
103     /**
104      * The package name that created the options.
105      * @hide
106      */
107     public static final String KEY_PACKAGE_NAME = "android:activity.packageName";
108 
109     /**
110      * The bounds (window size) that the activity should be launched in. Set to null explicitly for
111      * full screen. If the key is not found, previous bounds will be preserved.
112      * NOTE: This value is ignored on devices that don't have
113      * {@link android.content.pm.PackageManager#FEATURE_FREEFORM_WINDOW_MANAGEMENT} or
114      * {@link android.content.pm.PackageManager#FEATURE_PICTURE_IN_PICTURE} enabled.
115      * @hide
116      */
117     public static final String KEY_LAUNCH_BOUNDS = "android:activity.launchBounds";
118 
119     /**
120      * Type of animation that arguments specify.
121      * @hide
122      */
123     public static final String KEY_ANIM_TYPE = "android:activity.animType";
124 
125     /**
126      * Custom enter animation resource ID.
127      * @hide
128      */
129     public static final String KEY_ANIM_ENTER_RES_ID = "android:activity.animEnterRes";
130 
131     /**
132      * Custom exit animation resource ID.
133      * @hide
134      */
135     public static final String KEY_ANIM_EXIT_RES_ID = "android:activity.animExitRes";
136 
137     /**
138      * Custom in-place animation resource ID.
139      * @hide
140      */
141     public static final String KEY_ANIM_IN_PLACE_RES_ID = "android:activity.animInPlaceRes";
142 
143     /**
144      * Custom background color for animation.
145      * @hide
146      */
147     public static final String KEY_ANIM_BACKGROUND_COLOR = "android:activity.backgroundColor";
148 
149     /**
150      * Bitmap for thumbnail animation.
151      * @hide
152      */
153     public static final String KEY_ANIM_THUMBNAIL = "android:activity.animThumbnail";
154 
155     /**
156      * Start X position of thumbnail animation.
157      * @hide
158      */
159     public static final String KEY_ANIM_START_X = "android:activity.animStartX";
160 
161     /**
162      * Start Y position of thumbnail animation.
163      * @hide
164      */
165     public static final String KEY_ANIM_START_Y = "android:activity.animStartY";
166 
167     /**
168      * Initial width of the animation.
169      * @hide
170      */
171     public static final String KEY_ANIM_WIDTH = "android:activity.animWidth";
172 
173     /**
174      * Initial height of the animation.
175      * @hide
176      */
177     public static final String KEY_ANIM_HEIGHT = "android:activity.animHeight";
178 
179     /**
180      * Callback for when animation is started.
181      * @hide
182      */
183     public static final String KEY_ANIM_START_LISTENER = "android:activity.animStartListener";
184 
185     /**
186      * Specific a theme for a splash screen window.
187      * @hide
188      */
189     public static final String KEY_SPLASH_SCREEN_THEME = "android.activity.splashScreenTheme";
190 
191     /**
192      * Indicates that this activity launch is eligible to show a legacy permission prompt
193      * @hide
194      */
195     public static final String KEY_LEGACY_PERMISSION_PROMPT_ELIGIBLE =
196             "android:activity.legacyPermissionPromptEligible";
197 
198     /**
199      * Callback for when the last frame of the animation is played.
200      * @hide
201      */
202     private static final String KEY_ANIMATION_FINISHED_LISTENER =
203             "android:activity.animationFinishedListener";
204 
205     /**
206      * Descriptions of app transition animations to be played during the activity launch.
207      */
208     private static final String KEY_ANIM_SPECS = "android:activity.animSpecs";
209 
210     /**
211      * Whether the activity should be launched into LockTask mode.
212      * @see #setLockTaskEnabled(boolean)
213      */
214     private static final String KEY_LOCK_TASK_MODE = "android:activity.lockTaskMode";
215 
216     /**
217      * Whether the launching app's identity should be available to the launched activity.
218      * @see #setShareIdentityEnabled(boolean)
219      */
220     private static final String KEY_SHARE_IDENTITY = "android:activity.shareIdentity";
221 
222     /**
223      * The display id the activity should be launched into.
224      * @see #setLaunchDisplayId(int)
225      * @hide
226      */
227     private static final String KEY_LAUNCH_DISPLAY_ID = "android.activity.launchDisplayId";
228 
229     /**
230      * The id of the display where the caller was on.
231      * @see #setCallerDisplayId(int)
232      * @hide
233      */
234     private static final String KEY_CALLER_DISPLAY_ID = "android.activity.callerDisplayId";
235 
236     /**
237      * The task display area token the activity should be launched into.
238      * @see #setLaunchTaskDisplayArea(WindowContainerToken)
239      * @hide
240      */
241     private static final String KEY_LAUNCH_TASK_DISPLAY_AREA_TOKEN =
242             "android.activity.launchTaskDisplayAreaToken";
243 
244     /**
245      * The task display area feature id the activity should be launched into.
246      * @see #setLaunchTaskDisplayAreaFeatureId(int)
247      * @hide
248      */
249     private static final String KEY_LAUNCH_TASK_DISPLAY_AREA_FEATURE_ID =
250             "android.activity.launchTaskDisplayAreaFeatureId";
251 
252     /**
253      * The root task token the activity should be launched into.
254      * @see #setLaunchRootTask(WindowContainerToken)
255      * @hide
256      */
257     public static final String KEY_LAUNCH_ROOT_TASK_TOKEN =
258             "android.activity.launchRootTaskToken";
259 
260     /**
261      * The {@link com.android.server.wm.TaskFragment} token the activity should be launched into.
262      * @see #setLaunchTaskFragmentToken(IBinder)
263      * @hide
264      */
265     public static final String KEY_LAUNCH_TASK_FRAGMENT_TOKEN =
266             "android.activity.launchTaskFragmentToken";
267 
268     /**
269      * The windowing mode the activity should be launched into.
270      * @hide
271      */
272     private static final String KEY_LAUNCH_WINDOWING_MODE = "android.activity.windowingMode";
273 
274     /**
275      * The activity type the activity should be launched as.
276      * @hide
277      */
278     private static final String KEY_LAUNCH_ACTIVITY_TYPE = "android.activity.activityType";
279 
280     /**
281      * The task id the activity should be launched into.
282      * @hide
283      */
284     private static final String KEY_LAUNCH_TASK_ID = "android.activity.launchTaskId";
285 
286     /**
287      * See {@link #setDisableStartingWindow}.
288      * @hide
289      */
290     private static final String KEY_DISABLE_STARTING_WINDOW = "android.activity.disableStarting";
291 
292     /**
293      * See {@link #setPendingIntentLaunchFlags(int)}
294      * @hide
295      */
296     private static final String KEY_PENDING_INTENT_LAUNCH_FLAGS =
297             "android.activity.pendingIntentLaunchFlags";
298 
299     /**
300      * See {@link #setTaskAlwaysOnTop}.
301      * @hide
302      */
303     private static final String KEY_TASK_ALWAYS_ON_TOP = "android.activity.alwaysOnTop";
304 
305     /**
306      * See {@link #setTaskOverlay}.
307      * @hide
308      */
309     private static final String KEY_TASK_OVERLAY = "android.activity.taskOverlay";
310 
311     /**
312      * See {@link #setTaskOverlay}.
313      * @hide
314      */
315     private static final String KEY_TASK_OVERLAY_CAN_RESUME =
316             "android.activity.taskOverlayCanResume";
317 
318     /**
319      * See {@link #setAvoidMoveToFront()}.
320      * @hide
321      */
322     private static final String KEY_AVOID_MOVE_TO_FRONT = "android.activity.avoidMoveToFront";
323 
324     /**
325      * See {@link #setFreezeRecentTasksReordering()}.
326      * @hide
327      */
328     private static final String KEY_FREEZE_RECENT_TASKS_REORDERING =
329             "android.activity.freezeRecentTasksReordering";
330 
331     /**
332      * Determines whether to disallow the outgoing activity from entering picture-in-picture as the
333      * result of a new activity being launched.
334      * @hide
335      */
336     private static final String KEY_DISALLOW_ENTER_PICTURE_IN_PICTURE_WHILE_LAUNCHING =
337             "android:activity.disallowEnterPictureInPictureWhileLaunching";
338 
339     /**
340      * Indicates flags should be applied to the launching activity such that it will behave
341      * correctly in a bubble.
342      * @hide
343      */
344     private static final String KEY_APPLY_ACTIVITY_FLAGS_FOR_BUBBLES =
345             "android:activity.applyActivityFlagsForBubbles";
346 
347     /**
348      * Indicates to apply {@link Intent#FLAG_ACTIVITY_MULTIPLE_TASK} to the launching shortcut.
349      * @hide
350      */
351     private static final String KEY_APPLY_MULTIPLE_TASK_FLAG_FOR_SHORTCUT =
352             "android:activity.applyMultipleTaskFlagForShortcut";
353 
354     /**
355      * Indicates to apply {@link Intent#FLAG_ACTIVITY_NO_USER_ACTION} to the launching shortcut.
356      * @hide
357      */
358     private static final String KEY_APPLY_NO_USER_ACTION_FLAG_FOR_SHORTCUT =
359             "android:activity.applyNoUserActionFlagForShortcut";
360 
361     /**
362      * For Activity transitions, the calling Activity's TransitionListener used to
363      * notify the called Activity when the shared element and the exit transitions
364      * complete.
365      */
366     private static final String KEY_TRANSITION_COMPLETE_LISTENER
367             = "android:activity.transitionCompleteListener";
368 
369     private static final String KEY_TRANSITION_IS_RETURNING
370             = "android:activity.transitionIsReturning";
371     private static final String KEY_TRANSITION_SHARED_ELEMENTS
372             = "android:activity.sharedElementNames";
373     private static final String KEY_RESULT_DATA = "android:activity.resultData";
374     private static final String KEY_RESULT_CODE = "android:activity.resultCode";
375     private static final String KEY_EXIT_COORDINATOR_INDEX
376             = "android:activity.exitCoordinatorIndex";
377 
378     /** See {@link SourceInfo}. */
379     private static final String KEY_SOURCE_INFO = "android.activity.sourceInfo";
380 
381     private static final String KEY_USAGE_TIME_REPORT = "android:activity.usageTimeReport";
382     private static final String KEY_ROTATION_ANIMATION_HINT = "android:activity.rotationAnimationHint";
383 
384     private static final String KEY_INSTANT_APP_VERIFICATION_BUNDLE
385             = "android:instantapps.installerbundle";
386     private static final String KEY_SPECS_FUTURE = "android:activity.specsFuture";
387     private static final String KEY_REMOTE_ANIMATION_ADAPTER
388             = "android:activity.remoteAnimationAdapter";
389     private static final String KEY_REMOTE_TRANSITION =
390             "android:activity.remoteTransition";
391 
392     private static final String KEY_OVERRIDE_TASK_TRANSITION =
393             "android:activity.overrideTaskTransition";
394 
395     /** See {@link #setRemoveWithTaskOrganizer(boolean)}. */
396     private static final String KEY_REMOVE_WITH_TASK_ORGANIZER =
397             "android.activity.removeWithTaskOrganizer";
398     /** See {@link #setLaunchedFromBubble(boolean)}. */
399     private static final String KEY_LAUNCHED_FROM_BUBBLE =
400             "android.activity.launchTypeBubble";
401 
402     /** See {@link #setSplashScreenStyle(int)}. */
403     private static final String KEY_SPLASH_SCREEN_STYLE =
404             "android.activity.splashScreenStyle";
405 
406     /**
407      * See {@link #setTransientLaunch()}.
408      * @hide
409      */
410     public static final String KEY_TRANSIENT_LAUNCH = "android.activity.transientLaunch";
411 
412     /** see {@link #makeLaunchIntoPip(PictureInPictureParams)}. */
413     private static final String KEY_LAUNCH_INTO_PIP_PARAMS =
414             "android.activity.launchIntoPipParams";
415 
416     /** See {@link #setDismissKeyguard()}. */
417     private static final String KEY_DISMISS_KEYGUARD = "android.activity.dismissKeyguard";
418 
419     private static final String KEY_PENDING_INTENT_CREATOR_BACKGROUND_ACTIVITY_START_MODE =
420             "android.activity.pendingIntentCreatorBackgroundActivityStartMode";
421 
422     /**
423      * @see #setLaunchCookie
424      * @hide
425      */
426     public static final String KEY_LAUNCH_COOKIE = "android.activity.launchCookie";
427 
428     /** @hide */
429     public static final int ANIM_UNDEFINED = -1;
430     /** @hide */
431     public static final int ANIM_NONE = 0;
432     /** @hide */
433     public static final int ANIM_CUSTOM = 1;
434     /** @hide */
435     public static final int ANIM_SCALE_UP = 2;
436     /** @hide */
437     public static final int ANIM_THUMBNAIL_SCALE_UP = 3;
438     /** @hide */
439     public static final int ANIM_THUMBNAIL_SCALE_DOWN = 4;
440     /** @hide */
441     public static final int ANIM_SCENE_TRANSITION = 5;
442     /** @hide */
443     public static final int ANIM_DEFAULT = 6;
444     /** @hide */
445     public static final int ANIM_LAUNCH_TASK_BEHIND = 7;
446     /** @hide */
447     public static final int ANIM_THUMBNAIL_ASPECT_SCALE_UP = 8;
448     /** @hide */
449     public static final int ANIM_THUMBNAIL_ASPECT_SCALE_DOWN = 9;
450     /** @hide */
451     public static final int ANIM_CUSTOM_IN_PLACE = 10;
452     /** @hide */
453     public static final int ANIM_CLIP_REVEAL = 11;
454     /** @hide */
455     public static final int ANIM_OPEN_CROSS_PROFILE_APPS = 12;
456     /** @hide */
457     public static final int ANIM_REMOTE_ANIMATION = 13;
458     /** @hide */
459     public static final int ANIM_FROM_STYLE = 14;
460 
461     private String mPackageName;
462     private Rect mLaunchBounds;
463     private int mAnimationType = ANIM_UNDEFINED;
464     private int mCustomEnterResId;
465     private int mCustomExitResId;
466     private int mCustomInPlaceResId;
467     private int mCustomBackgroundColor;
468     private Bitmap mThumbnail;
469     private int mStartX;
470     private int mStartY;
471     private int mWidth;
472     private int mHeight;
473     private IRemoteCallback mAnimationStartedListener;
474     private IRemoteCallback mAnimationFinishedListener;
475     private ResultReceiver mTransitionReceiver;
476     private boolean mIsReturning;
477     private ArrayList<String> mSharedElementNames;
478     private Intent mResultData;
479     private int mResultCode;
480     private int mExitCoordinatorIndex;
481     private PendingIntent mUsageTimeReport;
482     private int mLaunchDisplayId = INVALID_DISPLAY;
483     private int mCallerDisplayId = INVALID_DISPLAY;
484     private WindowContainerToken mLaunchTaskDisplayArea;
485     private int mLaunchTaskDisplayAreaFeatureId = FEATURE_UNDEFINED;
486     private WindowContainerToken mLaunchRootTask;
487     private IBinder mLaunchTaskFragmentToken;
488     @WindowConfiguration.WindowingMode
489     private int mLaunchWindowingMode = WINDOWING_MODE_UNDEFINED;
490     @WindowConfiguration.ActivityType
491     private int mLaunchActivityType = ACTIVITY_TYPE_UNDEFINED;
492     private int mLaunchTaskId = -1;
493     private int mPendingIntentLaunchFlags;
494     private boolean mLockTaskMode = false;
495     private boolean mShareIdentity = false;
496     private boolean mDisallowEnterPictureInPictureWhileLaunching;
497     private boolean mApplyActivityFlagsForBubbles;
498     private boolean mApplyMultipleTaskFlagForShortcut;
499     private boolean mApplyNoUserActionFlagForShortcut;
500     private boolean mTaskAlwaysOnTop;
501     private boolean mTaskOverlay;
502     private boolean mTaskOverlayCanResume;
503     private boolean mAvoidMoveToFront;
504     private boolean mFreezeRecentTasksReordering;
505     private AppTransitionAnimationSpec mAnimSpecs[];
506     private SourceInfo mSourceInfo;
507     private int mRotationAnimationHint = -1;
508     private Bundle mAppVerificationBundle;
509     private IAppTransitionAnimationSpecsFuture mSpecsFuture;
510     private RemoteAnimationAdapter mRemoteAnimationAdapter;
511     private IBinder mLaunchCookie;
512     private RemoteTransition mRemoteTransition;
513     private boolean mOverrideTaskTransition;
514     private String mSplashScreenThemeResName;
515     @SplashScreen.SplashScreenStyle
516     private int mSplashScreenStyle = SplashScreen.SPLASH_SCREEN_STYLE_UNDEFINED;
517     private boolean mIsEligibleForLegacyPermissionPrompt;
518     private boolean mRemoveWithTaskOrganizer;
519     private boolean mLaunchedFromBubble;
520     private boolean mTransientLaunch;
521     private PictureInPictureParams mLaunchIntoPipParams;
522     private boolean mDismissKeyguard;
523     @BackgroundActivityStartMode
524     private int mPendingIntentCreatorBackgroundActivityStartMode =
525             MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED;
526     private boolean mDisableStartingWindow;
527 
528     /**
529      * Create an ActivityOptions specifying a custom animation to run when
530      * the activity is displayed.
531      *
532      * @param context Who is defining this.  This is the application that the
533      * animation resources will be loaded from.
534      * @param enterResId A resource ID of the animation resource to use for
535      * the incoming activity.  Use 0 for no animation.
536      * @param exitResId A resource ID of the animation resource to use for
537      * the outgoing activity.  Use 0 for no animation.
538      * @return Returns a new ActivityOptions object that you can use to
539      * supply these options as the options Bundle when starting an activity.
540      */
makeCustomAnimation(Context context, int enterResId, int exitResId)541     public static ActivityOptions makeCustomAnimation(Context context,
542             int enterResId, int exitResId) {
543         return makeCustomAnimation(context, enterResId, exitResId, 0, null, null);
544     }
545 
546     /**
547      * Create an ActivityOptions specifying a custom animation to run when
548      * the activity is displayed.
549      *
550      * @param context Who is defining this.  This is the application that the
551      * animation resources will be loaded from.
552      * @param enterResId A resource ID of the animation resource to use for
553      * the incoming activity.  Use 0 for no animation.
554      * @param exitResId A resource ID of the animation resource to use for
555      * the outgoing activity.  Use 0 for no animation.
556      * @param backgroundColor The background color to use for the background during the animation if
557      * the animation requires a background. Set to 0 to not override the default color.
558      * @return Returns a new ActivityOptions object that you can use to
559      * supply these options as the options Bundle when starting an activity.
560      */
makeCustomAnimation(@onNull Context context, int enterResId, int exitResId, int backgroundColor)561     public static @NonNull ActivityOptions makeCustomAnimation(@NonNull Context context,
562             int enterResId, int exitResId, int backgroundColor) {
563         return makeCustomAnimation(context, enterResId, exitResId, backgroundColor, null, null);
564     }
565 
566     /**
567      * Create an ActivityOptions specifying a custom animation to run when
568      * the activity is displayed.
569      *
570      * @param context Who is defining this.  This is the application that the
571      * animation resources will be loaded from.
572      * @param enterResId A resource ID of the animation resource to use for
573      * the incoming activity.  Use 0 for no animation.
574      * @param exitResId A resource ID of the animation resource to use for
575      * the outgoing activity.  Use 0 for no animation.
576      * @param handler If <var>listener</var> is non-null this must be a valid
577      * Handler on which to dispatch the callback; otherwise it should be null.
578      * @param listener Optional OnAnimationStartedListener to find out when the
579      * requested animation has started running.  If for some reason the animation
580      * is not executed, the callback will happen immediately.
581      * @return Returns a new ActivityOptions object that you can use to
582      * supply these options as the options Bundle when starting an activity.
583      * @hide
584      */
585     @UnsupportedAppUsage
makeCustomAnimation(Context context, int enterResId, int exitResId, int backgroundColor, Handler handler, OnAnimationStartedListener listener)586     public static ActivityOptions makeCustomAnimation(Context context,
587             int enterResId, int exitResId, int backgroundColor, Handler handler,
588             OnAnimationStartedListener listener) {
589         ActivityOptions opts = new ActivityOptions();
590         opts.mPackageName = context.getPackageName();
591         opts.mAnimationType = ANIM_CUSTOM;
592         opts.mCustomEnterResId = enterResId;
593         opts.mCustomExitResId = exitResId;
594         opts.mCustomBackgroundColor = backgroundColor;
595         opts.setOnAnimationStartedListener(handler, listener);
596         return opts;
597     }
598 
599     /**
600      * Create an ActivityOptions specifying a custom animation to run when
601      * the activity is displayed.
602      *
603      * @param context Who is defining this.  This is the application that the
604      * animation resources will be loaded from.
605      * @param enterResId A resource ID of the animation resource to use for
606      * the incoming activity.  Use 0 for no animation.
607      * @param exitResId A resource ID of the animation resource to use for
608      * the outgoing activity.  Use 0 for no animation.
609      * @param handler If <var>listener</var> is non-null this must be a valid
610      * Handler on which to dispatch the callback; otherwise it should be null.
611      * @param startedListener Optional OnAnimationStartedListener to find out when the
612      * requested animation has started running.  If for some reason the animation
613      * is not executed, the callback will happen immediately.
614      * @param finishedListener Optional OnAnimationFinishedListener when the animation
615      * has finished running.
616      * @return Returns a new ActivityOptions object that you can use to
617      * supply these options as the options Bundle when starting an activity.
618      * @hide
619      */
620     @TestApi
makeCustomAnimation(@onNull Context context, int enterResId, int exitResId, int backgroundColor, @Nullable Handler handler, @Nullable OnAnimationStartedListener startedListener, @Nullable OnAnimationFinishedListener finishedListener)621     public static @NonNull ActivityOptions makeCustomAnimation(@NonNull Context context,
622             int enterResId, int exitResId, int backgroundColor, @Nullable Handler handler,
623             @Nullable OnAnimationStartedListener startedListener,
624             @Nullable OnAnimationFinishedListener finishedListener) {
625         ActivityOptions opts = makeCustomAnimation(context, enterResId, exitResId, backgroundColor,
626                 handler, startedListener);
627         opts.setOnAnimationFinishedListener(handler, finishedListener);
628         return opts;
629     }
630 
631     /**
632      * Create an ActivityOptions specifying a custom animation to run when the activity in the
633      * different task is displayed.
634      *
635      * @param context Who is defining this.  This is the application that the
636      * animation resources will be loaded from.
637      * @param enterResId A resource ID of the animation resource to use for
638      * the incoming activity.  Use 0 for no animation.
639      * @param exitResId A resource ID of the animation resource to use for
640      * the outgoing activity.  Use 0 for no animation.
641      * @param handler If <var>listener</var> is non-null this must be a valid
642      * Handler on which to dispatch the callback; otherwise it should be null.
643      * @param startedListener Optional OnAnimationStartedListener to find out when the
644      * requested animation has started running.  If for some reason the animation
645      * is not executed, the callback will happen immediately.
646      * @param finishedListener Optional OnAnimationFinishedListener when the animation
647      * has finished running.
648      *
649      * @return Returns a new ActivityOptions object that you can use to
650      * supply these options as the options Bundle when starting an activity.
651      * @hide
652      */
653     @RequiresPermission(START_TASKS_FROM_RECENTS)
654     @TestApi
makeCustomTaskAnimation(@onNull Context context, int enterResId, int exitResId, @Nullable Handler handler, @Nullable OnAnimationStartedListener startedListener, @Nullable OnAnimationFinishedListener finishedListener)655     public static @NonNull ActivityOptions makeCustomTaskAnimation(@NonNull Context context,
656             int enterResId, int exitResId, @Nullable Handler handler,
657             @Nullable OnAnimationStartedListener startedListener,
658             @Nullable OnAnimationFinishedListener finishedListener) {
659         ActivityOptions opts = makeCustomAnimation(context, enterResId, exitResId, 0,
660                 handler, startedListener, finishedListener);
661         opts.mOverrideTaskTransition = true;
662         return opts;
663     }
664 
665     /**
666      * Creates an ActivityOptions specifying a custom animation to run in place on an existing
667      * activity.
668      *
669      * @param context Who is defining this.  This is the application that the
670      * animation resources will be loaded from.
671      * @param animId A resource ID of the animation resource to use for
672      * the incoming activity.
673      * @return Returns a new ActivityOptions object that you can use to
674      * supply these options as the options Bundle when running an in-place animation.
675      * @hide
676      */
makeCustomInPlaceAnimation(Context context, int animId)677     public static ActivityOptions makeCustomInPlaceAnimation(Context context, int animId) {
678         if (animId == 0) {
679             throw new RuntimeException("You must specify a valid animation.");
680         }
681 
682         ActivityOptions opts = new ActivityOptions();
683         opts.mPackageName = context.getPackageName();
684         opts.mAnimationType = ANIM_CUSTOM_IN_PLACE;
685         opts.mCustomInPlaceResId = animId;
686         return opts;
687     }
688 
setOnAnimationStartedListener(final Handler handler, final OnAnimationStartedListener listener)689     private void setOnAnimationStartedListener(final Handler handler,
690             final OnAnimationStartedListener listener) {
691         if (listener != null) {
692             mAnimationStartedListener = new IRemoteCallback.Stub() {
693                 @Override
694                 public void sendResult(Bundle data) throws RemoteException {
695                     final long elapsedRealtime = SystemClock.elapsedRealtime();
696                     handler.post(new Runnable() {
697                         @Override public void run() {
698                             listener.onAnimationStarted(elapsedRealtime);
699                         }
700                     });
701                 }
702             };
703         }
704     }
705 
706     /**
707      * Callback for finding out when the given animation has started running.
708      * @hide
709      */
710     @TestApi
711     public interface OnAnimationStartedListener {
712         /**
713          * @param elapsedRealTime {@link SystemClock#elapsedRealTime} when animation started.
714          */
onAnimationStarted(long elapsedRealTime)715         void onAnimationStarted(long elapsedRealTime);
716     }
717 
setOnAnimationFinishedListener(final Handler handler, final OnAnimationFinishedListener listener)718     private void setOnAnimationFinishedListener(final Handler handler,
719             final OnAnimationFinishedListener listener) {
720         if (listener != null) {
721             mAnimationFinishedListener = new IRemoteCallback.Stub() {
722                 @Override
723                 public void sendResult(Bundle data) throws RemoteException {
724                     final long elapsedRealtime = SystemClock.elapsedRealtime();
725                     handler.post(new Runnable() {
726                         @Override
727                         public void run() {
728                             listener.onAnimationFinished(elapsedRealtime);
729                         }
730                     });
731                 }
732             };
733         }
734     }
735 
736     /**
737      * Callback for finding out when the given animation has drawn its last frame.
738      * @hide
739      */
740     @TestApi
741     public interface OnAnimationFinishedListener {
742         /**
743          * @param elapsedRealTime {@link SystemClock#elapsedRealTime} when animation finished.
744          */
onAnimationFinished(long elapsedRealTime)745         void onAnimationFinished(long elapsedRealTime);
746     }
747 
748     /**
749      * Create an ActivityOptions specifying an animation where the new
750      * activity is scaled from a small originating area of the screen to
751      * its final full representation.
752      *
753      * <p>If the Intent this is being used with has not set its
754      * {@link android.content.Intent#setSourceBounds Intent.setSourceBounds},
755      * those bounds will be filled in for you based on the initial
756      * bounds passed in here.
757      *
758      * @param source The View that the new activity is animating from.  This
759      * defines the coordinate space for <var>startX</var> and <var>startY</var>.
760      * @param startX The x starting location of the new activity, relative to <var>source</var>.
761      * @param startY The y starting location of the activity, relative to <var>source</var>.
762      * @param width The initial width of the new activity.
763      * @param height The initial height of the new activity.
764      * @return Returns a new ActivityOptions object that you can use to
765      * supply these options as the options Bundle when starting an activity.
766      */
makeScaleUpAnimation(View source, int startX, int startY, int width, int height)767     public static ActivityOptions makeScaleUpAnimation(View source,
768             int startX, int startY, int width, int height) {
769         ActivityOptions opts = new ActivityOptions();
770         opts.mPackageName = source.getContext().getPackageName();
771         opts.mAnimationType = ANIM_SCALE_UP;
772         int[] pts = new int[2];
773         source.getLocationOnScreen(pts);
774         opts.mStartX = pts[0] + startX;
775         opts.mStartY = pts[1] + startY;
776         opts.mWidth = width;
777         opts.mHeight = height;
778         return opts;
779     }
780 
781     /**
782      * Create an ActivityOptions specifying an animation where the new
783      * activity is revealed from a small originating area of the screen to
784      * its final full representation.
785      *
786      * @param source The View that the new activity is animating from.  This
787      * defines the coordinate space for <var>startX</var> and <var>startY</var>.
788      * @param startX The x starting location of the new activity, relative to <var>source</var>.
789      * @param startY The y starting location of the activity, relative to <var>source</var>.
790      * @param width The initial width of the new activity.
791      * @param height The initial height of the new activity.
792      * @return Returns a new ActivityOptions object that you can use to
793      * supply these options as the options Bundle when starting an activity.
794      */
makeClipRevealAnimation(View source, int startX, int startY, int width, int height)795     public static ActivityOptions makeClipRevealAnimation(View source,
796             int startX, int startY, int width, int height) {
797         ActivityOptions opts = new ActivityOptions();
798         opts.mAnimationType = ANIM_CLIP_REVEAL;
799         int[] pts = new int[2];
800         source.getLocationOnScreen(pts);
801         opts.mStartX = pts[0] + startX;
802         opts.mStartY = pts[1] + startY;
803         opts.mWidth = width;
804         opts.mHeight = height;
805         return opts;
806     }
807 
808     /**
809      * Creates an {@link ActivityOptions} object specifying an animation where the new activity
810      * is started in another user profile by calling {@link
811      * android.content.pm.crossprofile.CrossProfileApps#startMainActivity(ComponentName, UserHandle)
812      * }.
813      * @hide
814      */
makeOpenCrossProfileAppsAnimation()815     public static ActivityOptions makeOpenCrossProfileAppsAnimation() {
816         ActivityOptions options = new ActivityOptions();
817         options.mAnimationType = ANIM_OPEN_CROSS_PROFILE_APPS;
818         return options;
819     }
820 
821     /**
822      * Create an ActivityOptions specifying an animation where a thumbnail
823      * is scaled from a given position to the new activity window that is
824      * being started.
825      *
826      * <p>If the Intent this is being used with has not set its
827      * {@link android.content.Intent#setSourceBounds Intent.setSourceBounds},
828      * those bounds will be filled in for you based on the initial
829      * thumbnail location and size provided here.
830      *
831      * @param source The View that this thumbnail is animating from.  This
832      * defines the coordinate space for <var>startX</var> and <var>startY</var>.
833      * @param thumbnail The bitmap that will be shown as the initial thumbnail
834      * of the animation.
835      * @param startX The x starting location of the bitmap, relative to <var>source</var>.
836      * @param startY The y starting location of the bitmap, relative to <var>source</var>.
837      * @return Returns a new ActivityOptions object that you can use to
838      * supply these options as the options Bundle when starting an activity.
839      */
makeThumbnailScaleUpAnimation(View source, Bitmap thumbnail, int startX, int startY)840     public static ActivityOptions makeThumbnailScaleUpAnimation(View source,
841             Bitmap thumbnail, int startX, int startY) {
842         return makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY, null);
843     }
844 
845     /**
846      * Create an ActivityOptions specifying an animation where a thumbnail
847      * is scaled from a given position to the new activity window that is
848      * being started.
849      *
850      * @param source The View that this thumbnail is animating from.  This
851      * defines the coordinate space for <var>startX</var> and <var>startY</var>.
852      * @param thumbnail The bitmap that will be shown as the initial thumbnail
853      * of the animation.
854      * @param startX The x starting location of the bitmap, relative to <var>source</var>.
855      * @param startY The y starting location of the bitmap, relative to <var>source</var>.
856      * @param listener Optional OnAnimationStartedListener to find out when the
857      * requested animation has started running.  If for some reason the animation
858      * is not executed, the callback will happen immediately.
859      * @return Returns a new ActivityOptions object that you can use to
860      * supply these options as the options Bundle when starting an activity.
861      */
makeThumbnailScaleUpAnimation(View source, Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener)862     private static ActivityOptions makeThumbnailScaleUpAnimation(View source,
863             Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) {
864         return makeThumbnailAnimation(source, thumbnail, startX, startY, listener, true);
865     }
866 
makeThumbnailAnimation(View source, Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener, boolean scaleUp)867     private static ActivityOptions makeThumbnailAnimation(View source,
868             Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener,
869             boolean scaleUp) {
870         ActivityOptions opts = new ActivityOptions();
871         opts.mPackageName = source.getContext().getPackageName();
872         opts.mAnimationType = scaleUp ? ANIM_THUMBNAIL_SCALE_UP : ANIM_THUMBNAIL_SCALE_DOWN;
873         opts.mThumbnail = thumbnail;
874         int[] pts = new int[2];
875         source.getLocationOnScreen(pts);
876         opts.mStartX = pts[0] + startX;
877         opts.mStartY = pts[1] + startY;
878         opts.setOnAnimationStartedListener(source.getHandler(), listener);
879         return opts;
880     }
881 
882     /**
883      * Create an ActivityOptions specifying an animation where a list of activity windows and
884      * thumbnails are aspect scaled to/from a new location.
885      * @hide
886      */
887     @UnsupportedAppUsage
makeMultiThumbFutureAspectScaleAnimation(Context context, Handler handler, IAppTransitionAnimationSpecsFuture specsFuture, OnAnimationStartedListener listener, boolean scaleUp)888     public static ActivityOptions makeMultiThumbFutureAspectScaleAnimation(Context context,
889             Handler handler, IAppTransitionAnimationSpecsFuture specsFuture,
890             OnAnimationStartedListener listener, boolean scaleUp) {
891         ActivityOptions opts = new ActivityOptions();
892         opts.mPackageName = context.getPackageName();
893         opts.mAnimationType = scaleUp
894                 ? ANIM_THUMBNAIL_ASPECT_SCALE_UP
895                 : ANIM_THUMBNAIL_ASPECT_SCALE_DOWN;
896         opts.mSpecsFuture = specsFuture;
897         opts.setOnAnimationStartedListener(handler, listener);
898         return opts;
899     }
900 
901     /**
902      * Create an ActivityOptions specifying an animation where the new activity
903      * window and a thumbnail is aspect-scaled to a new location.
904      *
905      * @param source The View that this thumbnail is animating to.  This
906      * defines the coordinate space for <var>startX</var> and <var>startY</var>.
907      * @param thumbnail The bitmap that will be shown as the final thumbnail
908      * of the animation.
909      * @param startX The x end location of the bitmap, relative to <var>source</var>.
910      * @param startY The y end location of the bitmap, relative to <var>source</var>.
911      * @param handler If <var>listener</var> is non-null this must be a valid
912      * Handler on which to dispatch the callback; otherwise it should be null.
913      * @param listener Optional OnAnimationStartedListener to find out when the
914      * requested animation has started running.  If for some reason the animation
915      * is not executed, the callback will happen immediately.
916      * @return Returns a new ActivityOptions object that you can use to
917      * supply these options as the options Bundle when starting an activity.
918      * @hide
919      */
makeThumbnailAspectScaleDownAnimation(View source, Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight, Handler handler, OnAnimationStartedListener listener)920     public static ActivityOptions makeThumbnailAspectScaleDownAnimation(View source,
921             Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight,
922             Handler handler, OnAnimationStartedListener listener) {
923         return makeAspectScaledThumbnailAnimation(source, thumbnail, startX, startY,
924                 targetWidth, targetHeight, handler, listener, false);
925     }
926 
makeAspectScaledThumbnailAnimation(View source, Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight, Handler handler, OnAnimationStartedListener listener, boolean scaleUp)927     private static ActivityOptions makeAspectScaledThumbnailAnimation(View source, Bitmap thumbnail,
928             int startX, int startY, int targetWidth, int targetHeight,
929             Handler handler, OnAnimationStartedListener listener, boolean scaleUp) {
930         ActivityOptions opts = new ActivityOptions();
931         opts.mPackageName = source.getContext().getPackageName();
932         opts.mAnimationType = scaleUp ? ANIM_THUMBNAIL_ASPECT_SCALE_UP :
933                 ANIM_THUMBNAIL_ASPECT_SCALE_DOWN;
934         opts.mThumbnail = thumbnail;
935         int[] pts = new int[2];
936         source.getLocationOnScreen(pts);
937         opts.mStartX = pts[0] + startX;
938         opts.mStartY = pts[1] + startY;
939         opts.mWidth = targetWidth;
940         opts.mHeight = targetHeight;
941         opts.setOnAnimationStartedListener(handler, listener);
942         return opts;
943     }
944 
945     /** @hide */
makeThumbnailAspectScaleDownAnimation(View source, AppTransitionAnimationSpec[] specs, Handler handler, OnAnimationStartedListener onAnimationStartedListener, OnAnimationFinishedListener onAnimationFinishedListener)946     public static ActivityOptions makeThumbnailAspectScaleDownAnimation(View source,
947             AppTransitionAnimationSpec[] specs, Handler handler,
948             OnAnimationStartedListener onAnimationStartedListener,
949             OnAnimationFinishedListener onAnimationFinishedListener) {
950         ActivityOptions opts = new ActivityOptions();
951         opts.mPackageName = source.getContext().getPackageName();
952         opts.mAnimationType = ANIM_THUMBNAIL_ASPECT_SCALE_DOWN;
953         opts.mAnimSpecs = specs;
954         opts.setOnAnimationStartedListener(handler, onAnimationStartedListener);
955         opts.setOnAnimationFinishedListener(handler, onAnimationFinishedListener);
956         return opts;
957     }
958 
959     /**
960      * Create an ActivityOptions to transition between Activities using cross-Activity scene
961      * animations. This method carries the position of one shared element to the started Activity.
962      * The position of <code>sharedElement</code> will be used as the epicenter for the
963      * exit Transition. The position of the shared element in the launched Activity will be the
964      * epicenter of its entering Transition.
965      *
966      * <p>This requires {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS} to be
967      * enabled on the calling Activity to cause an exit transition. The same must be in
968      * the called Activity to get an entering transition.</p>
969      * @param activity The Activity whose window contains the shared elements.
970      * @param sharedElement The View to transition to the started Activity.
971      * @param sharedElementName The shared element name as used in the target Activity. This
972      *                          must not be null.
973      * @return Returns a new ActivityOptions object that you can use to
974      *         supply these options as the options Bundle when starting an activity.
975      * @see android.transition.Transition#setEpicenterCallback(
976      *          android.transition.Transition.EpicenterCallback)
977      */
makeSceneTransitionAnimation(Activity activity, View sharedElement, String sharedElementName)978     public static ActivityOptions makeSceneTransitionAnimation(Activity activity,
979             View sharedElement, String sharedElementName) {
980         return makeSceneTransitionAnimation(activity, Pair.create(sharedElement, sharedElementName));
981     }
982 
983     /**
984      * Create an ActivityOptions to transition between Activities using cross-Activity scene
985      * animations. This method carries the position of multiple shared elements to the started
986      * Activity. The position of the first element in sharedElements
987      * will be used as the epicenter for the exit Transition. The position of the associated
988      * shared element in the launched Activity will be the epicenter of its entering Transition.
989      *
990      * <p>This requires {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS} to be
991      * enabled on the calling Activity to cause an exit transition. The same must be in
992      * the called Activity to get an entering transition.</p>
993      * @param activity The Activity whose window contains the shared elements.
994      * @param sharedElements The names of the shared elements to transfer to the called
995      *                       Activity and their associated Views. The Views must each have
996      *                       a unique shared element name.
997      * @return Returns a new ActivityOptions object that you can use to
998      *         supply these options as the options Bundle when starting an activity.
999      * @see android.transition.Transition#setEpicenterCallback(
1000      *          android.transition.Transition.EpicenterCallback)
1001      */
1002     @SafeVarargs
makeSceneTransitionAnimation(Activity activity, Pair<View, String>... sharedElements)1003     public static ActivityOptions makeSceneTransitionAnimation(Activity activity,
1004             Pair<View, String>... sharedElements) {
1005         ActivityOptions opts = new ActivityOptions();
1006         ExitTransitionCoordinator exit = makeSceneTransitionAnimation(
1007                 new ActivityExitTransitionCallbacks(activity), activity.mExitTransitionListener,
1008                 activity.getWindow(), opts, sharedElements);
1009         opts.mExitCoordinatorIndex =
1010                 activity.mActivityTransitionState.addExitTransitionCoordinator(exit);
1011         return opts;
1012     }
1013 
1014     /**
1015      * Call this immediately prior to startActivity to begin a shared element transition
1016      * from a non-Activity. The window must support Window.FEATURE_ACTIVITY_TRANSITIONS.
1017      * The exit transition will start immediately and the shared element transition will
1018      * start once the launched Activity's shared element is ready.
1019      * <p>
1020      * When all transitions have completed and the shared element has been transfered,
1021      * the window's decor View will have its visibility set to View.GONE.
1022      *
1023      * @hide
1024      */
1025     @SafeVarargs
startSharedElementAnimation( Window window, ExitTransitionCallbacks exitCallbacks, SharedElementCallback callback, Pair<View, String>... sharedElements)1026     public static Pair<ActivityOptions, ExitTransitionCoordinator> startSharedElementAnimation(
1027             Window window, ExitTransitionCallbacks exitCallbacks, SharedElementCallback callback,
1028             Pair<View, String>... sharedElements) {
1029         ActivityOptions opts = new ActivityOptions();
1030         ExitTransitionCoordinator exit = makeSceneTransitionAnimation(
1031                 exitCallbacks, callback, window, opts, sharedElements);
1032         opts.mExitCoordinatorIndex = -1;
1033         return Pair.create(opts, exit);
1034     }
1035 
1036     /**
1037      * This method should be called when the
1038      * {@link #startSharedElementAnimation(Window, ExitTransitionCallbacks, Pair[])}
1039      * animation must be stopped and the Views reset. This can happen if there was an error
1040      * from startActivity or a springboard activity and the animation should stop and reset.
1041      *
1042      * @hide
1043      */
stopSharedElementAnimation(Window window)1044     public static void stopSharedElementAnimation(Window window) {
1045         final View decorView = window.getDecorView();
1046         if (decorView == null) {
1047             return;
1048         }
1049         final ExitTransitionCoordinator exit = (ExitTransitionCoordinator)
1050                 decorView.getTag(com.android.internal.R.id.cross_task_transition);
1051         if (exit != null) {
1052             exit.cancelPendingTransitions();
1053             decorView.setTagInternal(com.android.internal.R.id.cross_task_transition, null);
1054             TransitionManager.endTransitions((ViewGroup) decorView);
1055             exit.resetViews();
1056             exit.clearState();
1057             decorView.setVisibility(View.VISIBLE);
1058         }
1059     }
1060 
makeSceneTransitionAnimation( ExitTransitionCallbacks exitCallbacks, SharedElementCallback callback, Window window, ActivityOptions opts, Pair<View, String>[] sharedElements)1061     static ExitTransitionCoordinator makeSceneTransitionAnimation(
1062             ExitTransitionCallbacks exitCallbacks, SharedElementCallback callback, Window window,
1063             ActivityOptions opts, Pair<View, String>[] sharedElements) {
1064         if (!window.hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)) {
1065             opts.mAnimationType = ANIM_DEFAULT;
1066             return null;
1067         }
1068         opts.mAnimationType = ANIM_SCENE_TRANSITION;
1069 
1070         ArrayList<String> names = new ArrayList<String>();
1071         ArrayList<View> views = new ArrayList<View>();
1072 
1073         if (sharedElements != null) {
1074             for (int i = 0; i < sharedElements.length; i++) {
1075                 Pair<View, String> sharedElement = sharedElements[i];
1076                 String sharedElementName = sharedElement.second;
1077                 if (sharedElementName == null) {
1078                     throw new IllegalArgumentException("Shared element name must not be null");
1079                 }
1080                 names.add(sharedElementName);
1081                 View view = sharedElement.first;
1082                 if (view == null) {
1083                     throw new IllegalArgumentException("Shared element must not be null");
1084                 }
1085                 views.add(sharedElement.first);
1086             }
1087         }
1088 
1089         ExitTransitionCoordinator exit = new ExitTransitionCoordinator(exitCallbacks, window,
1090                 callback, names, names, views, false);
1091         opts.mTransitionReceiver = exit;
1092         opts.mSharedElementNames = names;
1093         opts.mIsReturning = false;
1094         return exit;
1095     }
1096 
1097     /**
1098      * Needed for virtual devices because they can be slow enough that the 1 second timeout
1099      * triggers when it doesn't on normal devices.
1100      *
1101      * @hide
1102      */
1103     @TestApi
setExitTransitionTimeout(long timeoutMillis)1104     public static void setExitTransitionTimeout(long timeoutMillis) {
1105         ExitTransitionCoordinator.sMaxWaitMillis = timeoutMillis;
1106     }
1107 
1108     /** @hide */
makeSceneTransitionAnimation(Activity activity, ExitTransitionCoordinator exitCoordinator, ArrayList<String> sharedElementNames, int resultCode, Intent resultData)1109     static ActivityOptions makeSceneTransitionAnimation(Activity activity,
1110             ExitTransitionCoordinator exitCoordinator, ArrayList<String> sharedElementNames,
1111             int resultCode, Intent resultData) {
1112         ActivityOptions opts = new ActivityOptions();
1113         opts.mAnimationType = ANIM_SCENE_TRANSITION;
1114         opts.mSharedElementNames = sharedElementNames;
1115         opts.mTransitionReceiver = exitCoordinator;
1116         opts.mIsReturning = true;
1117         opts.mResultCode = resultCode;
1118         opts.mResultData = resultData;
1119         if (activity == null) {
1120             opts.mExitCoordinatorIndex = -1;
1121         } else {
1122             opts.mExitCoordinatorIndex =
1123                     activity.mActivityTransitionState.addExitTransitionCoordinator(exitCoordinator);
1124         }
1125         return opts;
1126     }
1127 
1128     /**
1129      * If set along with Intent.FLAG_ACTIVITY_NEW_DOCUMENT then the task being launched will not be
1130      * presented to the user but will instead be only available through the recents task list.
1131      * In addition, the new task wil be affiliated with the launching activity's task.
1132      * Affiliated tasks are grouped together in the recents task list.
1133      *
1134      * <p>This behavior is not supported for activities with {@link
1135      * android.R.styleable#AndroidManifestActivity_launchMode launchMode} values of
1136      * <code>singleInstance</code> or <code>singleTask</code>.
1137      */
makeTaskLaunchBehind()1138     public static ActivityOptions makeTaskLaunchBehind() {
1139         final ActivityOptions opts = new ActivityOptions();
1140         opts.mAnimationType = ANIM_LAUNCH_TASK_BEHIND;
1141         return opts;
1142     }
1143 
1144     /**
1145      * Create a basic ActivityOptions that has no special animation associated with it.
1146      * Other options can still be set.
1147      */
makeBasic()1148     public static ActivityOptions makeBasic() {
1149         final ActivityOptions opts = new ActivityOptions();
1150         return opts;
1151     }
1152 
1153     /**
1154      * Create an {@link ActivityOptions} instance that lets the application control the entire
1155      * animation using a {@link RemoteAnimationAdapter}.
1156      * @hide
1157      */
1158     @RequiresPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS)
1159     @UnsupportedAppUsage
makeRemoteAnimation( RemoteAnimationAdapter remoteAnimationAdapter)1160     public static ActivityOptions makeRemoteAnimation(
1161             RemoteAnimationAdapter remoteAnimationAdapter) {
1162         final ActivityOptions opts = new ActivityOptions();
1163         opts.mRemoteAnimationAdapter = remoteAnimationAdapter;
1164         opts.mAnimationType = ANIM_REMOTE_ANIMATION;
1165         return opts;
1166     }
1167 
1168     /**
1169      * Create an {@link ActivityOptions} instance that lets the application control the entire
1170      * animation using a {@link RemoteAnimationAdapter}.
1171      * @hide
1172      */
1173     @RequiresPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS)
makeRemoteAnimation(RemoteAnimationAdapter remoteAnimationAdapter, RemoteTransition remoteTransition)1174     public static ActivityOptions makeRemoteAnimation(RemoteAnimationAdapter remoteAnimationAdapter,
1175             RemoteTransition remoteTransition) {
1176         final ActivityOptions opts = new ActivityOptions();
1177         opts.mRemoteAnimationAdapter = remoteAnimationAdapter;
1178         opts.mAnimationType = ANIM_REMOTE_ANIMATION;
1179         opts.mRemoteTransition = remoteTransition;
1180         return opts;
1181     }
1182 
1183     /**
1184      * Create an {@link ActivityOptions} instance that lets the application control the entire
1185      * transition using a {@link RemoteTransition}.
1186      * @hide
1187      */
1188     @RequiresPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS)
makeRemoteTransition(RemoteTransition remoteTransition)1189     public static ActivityOptions makeRemoteTransition(RemoteTransition remoteTransition) {
1190         final ActivityOptions opts = new ActivityOptions();
1191         opts.mRemoteTransition = remoteTransition;
1192         return opts;
1193     }
1194 
1195     /**
1196      * Creates an {@link ActivityOptions} instance that launch into picture-in-picture.
1197      * This is normally used by a Host activity to start another activity that will directly enter
1198      * picture-in-picture upon its creation.
1199      * @param pictureInPictureParams {@link PictureInPictureParams} for launching the Activity to
1200      *                               picture-in-picture mode.
1201      */
1202     @NonNull
makeLaunchIntoPip( @onNull PictureInPictureParams pictureInPictureParams)1203     public static ActivityOptions makeLaunchIntoPip(
1204             @NonNull PictureInPictureParams pictureInPictureParams) {
1205         final ActivityOptions opts = new ActivityOptions();
1206         opts.mLaunchIntoPipParams = new PictureInPictureParams.Builder(pictureInPictureParams)
1207                 .setIsLaunchIntoPip(true)
1208                 .build();
1209         return opts;
1210     }
1211 
1212     /** @hide */
getLaunchTaskBehind()1213     public boolean getLaunchTaskBehind() {
1214         return mAnimationType == ANIM_LAUNCH_TASK_BEHIND;
1215     }
1216 
ActivityOptions()1217     private ActivityOptions() {
1218         super();
1219     }
1220 
1221     /** @hide */
ActivityOptions(Bundle opts)1222     public ActivityOptions(Bundle opts) {
1223         super(opts);
1224 
1225         mPackageName = opts.getString(KEY_PACKAGE_NAME);
1226         try {
1227             mUsageTimeReport = opts.getParcelable(KEY_USAGE_TIME_REPORT, PendingIntent.class);
1228         } catch (RuntimeException e) {
1229             Slog.w(TAG, e);
1230         }
1231         mLaunchBounds = opts.getParcelable(KEY_LAUNCH_BOUNDS, android.graphics.Rect.class);
1232         mAnimationType = opts.getInt(KEY_ANIM_TYPE, ANIM_UNDEFINED);
1233         switch (mAnimationType) {
1234             case ANIM_CUSTOM:
1235                 mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0);
1236                 mCustomExitResId = opts.getInt(KEY_ANIM_EXIT_RES_ID, 0);
1237                 mCustomBackgroundColor = opts.getInt(KEY_ANIM_BACKGROUND_COLOR, 0);
1238                 mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
1239                         opts.getBinder(KEY_ANIM_START_LISTENER));
1240                 break;
1241 
1242             case ANIM_CUSTOM_IN_PLACE:
1243                 mCustomInPlaceResId = opts.getInt(KEY_ANIM_IN_PLACE_RES_ID, 0);
1244                 break;
1245 
1246             case ANIM_SCALE_UP:
1247             case ANIM_CLIP_REVEAL:
1248                 mStartX = opts.getInt(KEY_ANIM_START_X, 0);
1249                 mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
1250                 mWidth = opts.getInt(KEY_ANIM_WIDTH, 0);
1251                 mHeight = opts.getInt(KEY_ANIM_HEIGHT, 0);
1252                 break;
1253 
1254             case ANIM_THUMBNAIL_SCALE_UP:
1255             case ANIM_THUMBNAIL_SCALE_DOWN:
1256             case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
1257             case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
1258                 // Unpackage the HardwareBuffer from the parceled thumbnail
1259                 final HardwareBuffer buffer = opts.getParcelable(KEY_ANIM_THUMBNAIL, android.hardware.HardwareBuffer.class);
1260                 if (buffer != null) {
1261                     mThumbnail = Bitmap.wrapHardwareBuffer(buffer, null);
1262                 }
1263                 mStartX = opts.getInt(KEY_ANIM_START_X, 0);
1264                 mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
1265                 mWidth = opts.getInt(KEY_ANIM_WIDTH, 0);
1266                 mHeight = opts.getInt(KEY_ANIM_HEIGHT, 0);
1267                 mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
1268                         opts.getBinder(KEY_ANIM_START_LISTENER));
1269                 break;
1270 
1271             case ANIM_SCENE_TRANSITION:
1272                 mTransitionReceiver = opts.getParcelable(KEY_TRANSITION_COMPLETE_LISTENER, android.os.ResultReceiver.class);
1273                 mIsReturning = opts.getBoolean(KEY_TRANSITION_IS_RETURNING, false);
1274                 mSharedElementNames = opts.getStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS);
1275                 mResultData = opts.getParcelable(KEY_RESULT_DATA, android.content.Intent.class);
1276                 mResultCode = opts.getInt(KEY_RESULT_CODE);
1277                 mExitCoordinatorIndex = opts.getInt(KEY_EXIT_COORDINATOR_INDEX);
1278                 break;
1279         }
1280         mLockTaskMode = opts.getBoolean(KEY_LOCK_TASK_MODE, false);
1281         mShareIdentity = opts.getBoolean(KEY_SHARE_IDENTITY, false);
1282         mLaunchDisplayId = opts.getInt(KEY_LAUNCH_DISPLAY_ID, INVALID_DISPLAY);
1283         mCallerDisplayId = opts.getInt(KEY_CALLER_DISPLAY_ID, INVALID_DISPLAY);
1284         mLaunchTaskDisplayArea = opts.getParcelable(KEY_LAUNCH_TASK_DISPLAY_AREA_TOKEN, android.window.WindowContainerToken.class);
1285         mLaunchTaskDisplayAreaFeatureId = opts.getInt(KEY_LAUNCH_TASK_DISPLAY_AREA_FEATURE_ID,
1286                 FEATURE_UNDEFINED);
1287         mLaunchRootTask = opts.getParcelable(KEY_LAUNCH_ROOT_TASK_TOKEN, android.window.WindowContainerToken.class);
1288         mLaunchTaskFragmentToken = opts.getBinder(KEY_LAUNCH_TASK_FRAGMENT_TOKEN);
1289         mLaunchWindowingMode = opts.getInt(KEY_LAUNCH_WINDOWING_MODE, WINDOWING_MODE_UNDEFINED);
1290         mLaunchActivityType = opts.getInt(KEY_LAUNCH_ACTIVITY_TYPE, ACTIVITY_TYPE_UNDEFINED);
1291         mLaunchTaskId = opts.getInt(KEY_LAUNCH_TASK_ID, -1);
1292         mPendingIntentLaunchFlags = opts.getInt(KEY_PENDING_INTENT_LAUNCH_FLAGS, 0);
1293         mTaskAlwaysOnTop = opts.getBoolean(KEY_TASK_ALWAYS_ON_TOP, false);
1294         mTaskOverlay = opts.getBoolean(KEY_TASK_OVERLAY, false);
1295         mTaskOverlayCanResume = opts.getBoolean(KEY_TASK_OVERLAY_CAN_RESUME, false);
1296         mAvoidMoveToFront = opts.getBoolean(KEY_AVOID_MOVE_TO_FRONT, false);
1297         mFreezeRecentTasksReordering = opts.getBoolean(KEY_FREEZE_RECENT_TASKS_REORDERING, false);
1298         mDisallowEnterPictureInPictureWhileLaunching = opts.getBoolean(
1299                 KEY_DISALLOW_ENTER_PICTURE_IN_PICTURE_WHILE_LAUNCHING, false);
1300         mApplyActivityFlagsForBubbles = opts.getBoolean(
1301                 KEY_APPLY_ACTIVITY_FLAGS_FOR_BUBBLES, false);
1302         mApplyMultipleTaskFlagForShortcut = opts.getBoolean(
1303                 KEY_APPLY_MULTIPLE_TASK_FLAG_FOR_SHORTCUT, false);
1304         mApplyNoUserActionFlagForShortcut = opts.getBoolean(
1305                 KEY_APPLY_NO_USER_ACTION_FLAG_FOR_SHORTCUT, false);
1306         if (opts.containsKey(KEY_ANIM_SPECS)) {
1307             Parcelable[] specs = opts.getParcelableArray(KEY_ANIM_SPECS);
1308             mAnimSpecs = new AppTransitionAnimationSpec[specs.length];
1309             for (int i = specs.length - 1; i >= 0; i--) {
1310                 mAnimSpecs[i] = (AppTransitionAnimationSpec) specs[i];
1311             }
1312         }
1313         if (opts.containsKey(KEY_ANIMATION_FINISHED_LISTENER)) {
1314             mAnimationFinishedListener = IRemoteCallback.Stub.asInterface(
1315                     opts.getBinder(KEY_ANIMATION_FINISHED_LISTENER));
1316         }
1317         mSourceInfo = opts.getParcelable(KEY_SOURCE_INFO, android.app.ActivityOptions.SourceInfo.class);
1318         mRotationAnimationHint = opts.getInt(KEY_ROTATION_ANIMATION_HINT, -1);
1319         mAppVerificationBundle = opts.getBundle(KEY_INSTANT_APP_VERIFICATION_BUNDLE);
1320         if (opts.containsKey(KEY_SPECS_FUTURE)) {
1321             mSpecsFuture = IAppTransitionAnimationSpecsFuture.Stub.asInterface(opts.getBinder(
1322                     KEY_SPECS_FUTURE));
1323         }
1324         mRemoteAnimationAdapter = opts.getParcelable(KEY_REMOTE_ANIMATION_ADAPTER, android.view.RemoteAnimationAdapter.class);
1325         mLaunchCookie = opts.getBinder(KEY_LAUNCH_COOKIE);
1326         mRemoteTransition = opts.getParcelable(KEY_REMOTE_TRANSITION, android.window.RemoteTransition.class);
1327         mOverrideTaskTransition = opts.getBoolean(KEY_OVERRIDE_TASK_TRANSITION);
1328         mSplashScreenThemeResName = opts.getString(KEY_SPLASH_SCREEN_THEME);
1329         mRemoveWithTaskOrganizer = opts.getBoolean(KEY_REMOVE_WITH_TASK_ORGANIZER);
1330         mLaunchedFromBubble = opts.getBoolean(KEY_LAUNCHED_FROM_BUBBLE);
1331         mTransientLaunch = opts.getBoolean(KEY_TRANSIENT_LAUNCH);
1332         mSplashScreenStyle = opts.getInt(KEY_SPLASH_SCREEN_STYLE);
1333         mLaunchIntoPipParams = opts.getParcelable(KEY_LAUNCH_INTO_PIP_PARAMS, android.app.PictureInPictureParams.class);
1334         mIsEligibleForLegacyPermissionPrompt =
1335                 opts.getBoolean(KEY_LEGACY_PERMISSION_PROMPT_ELIGIBLE);
1336         mDismissKeyguard = opts.getBoolean(KEY_DISMISS_KEYGUARD);
1337         mPendingIntentCreatorBackgroundActivityStartMode = opts.getInt(
1338                 KEY_PENDING_INTENT_CREATOR_BACKGROUND_ACTIVITY_START_MODE,
1339                 MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED);
1340         mDisableStartingWindow = opts.getBoolean(KEY_DISABLE_STARTING_WINDOW);
1341     }
1342 
1343     /**
1344      * Sets the bounds (window size and position) that the activity should be launched in.
1345      * Rect position should be provided in pixels and in screen coordinates.
1346      * Set to {@code null} to explicitly launch fullscreen.
1347      * <p>
1348      * <strong>NOTE:</strong> This value is ignored on devices that don't have
1349      * {@link android.content.pm.PackageManager#FEATURE_FREEFORM_WINDOW_MANAGEMENT} or
1350      * {@link android.content.pm.PackageManager#FEATURE_PICTURE_IN_PICTURE} enabled.
1351      * @param screenSpacePixelRect launch bounds or {@code null} for fullscreen
1352      * @return {@code this} {@link ActivityOptions} instance
1353      */
setLaunchBounds(@ullable Rect screenSpacePixelRect)1354     public ActivityOptions setLaunchBounds(@Nullable Rect screenSpacePixelRect) {
1355         mLaunchBounds = screenSpacePixelRect != null ? new Rect(screenSpacePixelRect) : null;
1356         return this;
1357     }
1358 
1359     /** @hide */
getPackageName()1360     public String getPackageName() {
1361         return mPackageName;
1362     }
1363 
1364     /**
1365      * Returns the bounds that should be used to launch the activity.
1366      * @see #setLaunchBounds(Rect)
1367      * @return Bounds used to launch the activity.
1368      */
1369     @Nullable
getLaunchBounds()1370     public Rect getLaunchBounds() {
1371         return mLaunchBounds;
1372     }
1373 
1374     /** @hide */
getAnimationType()1375     public int getAnimationType() {
1376         return mAnimationType;
1377     }
1378 
1379     /** @hide */
getCustomEnterResId()1380     public int getCustomEnterResId() {
1381         return mCustomEnterResId;
1382     }
1383 
1384     /** @hide */
getCustomExitResId()1385     public int getCustomExitResId() {
1386         return mCustomExitResId;
1387     }
1388 
1389     /** @hide */
getCustomInPlaceResId()1390     public int getCustomInPlaceResId() {
1391         return mCustomInPlaceResId;
1392     }
1393 
1394     /** @hide */
getCustomBackgroundColor()1395     public int getCustomBackgroundColor() {
1396         return mCustomBackgroundColor;
1397     }
1398 
1399     /**
1400      * The thumbnail is copied into a hardware bitmap when it is bundled and sent to the system, so
1401      * it should always be backed by a HardwareBuffer on the other end.
1402      *
1403      * @hide
1404      */
getThumbnail()1405     public HardwareBuffer getThumbnail() {
1406         return mThumbnail != null ? mThumbnail.getHardwareBuffer() : null;
1407     }
1408 
1409     /** @hide */
getStartX()1410     public int getStartX() {
1411         return mStartX;
1412     }
1413 
1414     /** @hide */
getStartY()1415     public int getStartY() {
1416         return mStartY;
1417     }
1418 
1419     /** @hide */
getWidth()1420     public int getWidth() {
1421         return mWidth;
1422     }
1423 
1424     /** @hide */
getHeight()1425     public int getHeight() {
1426         return mHeight;
1427     }
1428 
1429     /** @hide */
getAnimationStartedListener()1430     public IRemoteCallback getAnimationStartedListener() {
1431         return mAnimationStartedListener;
1432     }
1433 
1434     /** @hide */
getAnimationFinishedListener()1435     public IRemoteCallback getAnimationFinishedListener() {
1436         return mAnimationFinishedListener;
1437     }
1438 
1439     /** @hide */
getExitCoordinatorKey()1440     public int getExitCoordinatorKey() { return mExitCoordinatorIndex; }
1441 
1442     /** @hide */
abort()1443     public void abort() {
1444         if (mAnimationStartedListener != null) {
1445             try {
1446                 mAnimationStartedListener.sendResult(null);
1447             } catch (RemoteException e) {
1448             }
1449         }
1450     }
1451 
1452     /** @hide */
isReturning()1453     public boolean isReturning() {
1454         return mIsReturning;
1455     }
1456 
1457     /**
1458      * Returns whether or not the ActivityOptions was created with
1459      * {@link #startSharedElementAnimation(Window, Pair[])}.
1460      *
1461      * @hide
1462      */
isCrossTask()1463     boolean isCrossTask() {
1464         return mExitCoordinatorIndex < 0;
1465     }
1466 
1467     /** @hide */
getSharedElementNames()1468     public ArrayList<String> getSharedElementNames() {
1469         return mSharedElementNames;
1470     }
1471 
1472     /** @hide */
getResultReceiver()1473     public ResultReceiver getResultReceiver() { return mTransitionReceiver; }
1474 
1475     /** @hide */
getResultCode()1476     public int getResultCode() { return mResultCode; }
1477 
1478     /** @hide */
getResultData()1479     public Intent getResultData() { return mResultData; }
1480 
1481     /** @hide */
getUsageTimeReport()1482     public PendingIntent getUsageTimeReport() {
1483         return mUsageTimeReport;
1484     }
1485 
1486     /** @hide */
getAnimSpecs()1487     public AppTransitionAnimationSpec[] getAnimSpecs() { return mAnimSpecs; }
1488 
1489     /** @hide */
getSpecsFuture()1490     public IAppTransitionAnimationSpecsFuture getSpecsFuture() {
1491         return mSpecsFuture;
1492     }
1493 
1494     /** @hide */
getRemoteAnimationAdapter()1495     public RemoteAnimationAdapter getRemoteAnimationAdapter() {
1496         return mRemoteAnimationAdapter;
1497     }
1498 
1499     /** @hide */
setRemoteAnimationAdapter(RemoteAnimationAdapter remoteAnimationAdapter)1500     public void setRemoteAnimationAdapter(RemoteAnimationAdapter remoteAnimationAdapter) {
1501         mRemoteAnimationAdapter = remoteAnimationAdapter;
1502     }
1503 
1504     /** @hide */
getRemoteTransition()1505     public RemoteTransition getRemoteTransition() {
1506         return mRemoteTransition;
1507     }
1508 
1509     /** @hide */
setRemoteTransition(@ullable RemoteTransition remoteTransition)1510     public ActivityOptions setRemoteTransition(@Nullable RemoteTransition remoteTransition) {
1511         mRemoteTransition = remoteTransition;
1512         return this;
1513     }
1514 
1515     /** @hide */
fromBundle(Bundle bOptions)1516     public static ActivityOptions fromBundle(Bundle bOptions) {
1517         return bOptions != null ? new ActivityOptions(bOptions) : null;
1518     }
1519 
1520     /** @hide */
abort(ActivityOptions options)1521     public static void abort(ActivityOptions options) {
1522         if (options != null) {
1523             options.abort();
1524         }
1525     }
1526 
1527     /**
1528      * Gets whether the activity is to be launched into LockTask mode.
1529      * @return {@code true} if the activity is to be launched into LockTask mode.
1530      * @see Activity#startLockTask()
1531      * @see android.app.admin.DevicePolicyManager#setLockTaskPackages(ComponentName, String[])
1532      */
getLockTaskMode()1533     public boolean getLockTaskMode() {
1534         return mLockTaskMode;
1535     }
1536 
1537     /**
1538      * Returns whether the launching app has opted-in to sharing its identity with the launched
1539      * activity.
1540      *
1541      * @return {@code true} if the launching app has opted-in to sharing its identity
1542      *
1543      * @see #setShareIdentityEnabled(boolean)
1544      * @see Activity#getLaunchedFromUid()
1545      * @see Activity#getLaunchedFromPackage()
1546      */
isShareIdentityEnabled()1547     public boolean isShareIdentityEnabled() {
1548         return mShareIdentity;
1549     }
1550 
1551     /**
1552      * Gets whether the activity want to be launched as other theme for the splash screen.
1553      * @hide
1554      */
1555     @Nullable
getSplashScreenThemeResName()1556     public String getSplashScreenThemeResName() {
1557         return mSplashScreenThemeResName;
1558     }
1559 
1560     /**
1561      * Gets the style can be used for cold-launching an activity.
1562      * @see #setSplashScreenStyle(int)
1563      */
getSplashScreenStyle()1564     public @SplashScreen.SplashScreenStyle int getSplashScreenStyle() {
1565         return mSplashScreenStyle;
1566     }
1567 
1568     /**
1569      * Sets the preferred splash screen style of the opening activities. This only applies if the
1570      * Activity or Process is not yet created.
1571      * @param style Can be either {@link SplashScreen#SPLASH_SCREEN_STYLE_ICON} or
1572      *              {@link SplashScreen#SPLASH_SCREEN_STYLE_SOLID_COLOR}
1573      */
1574     @NonNull
setSplashScreenStyle(@plashScreen.SplashScreenStyle int style)1575     public ActivityOptions setSplashScreenStyle(@SplashScreen.SplashScreenStyle int style) {
1576         if (style == SplashScreen.SPLASH_SCREEN_STYLE_ICON
1577                 || style == SplashScreen.SPLASH_SCREEN_STYLE_SOLID_COLOR) {
1578             mSplashScreenStyle = style;
1579         }
1580         return this;
1581     }
1582 
1583     /**
1584      * Whether the activity is eligible to show a legacy permission prompt
1585      * @hide
1586      */
1587     @TestApi
isEligibleForLegacyPermissionPrompt()1588     public boolean isEligibleForLegacyPermissionPrompt() {
1589         return mIsEligibleForLegacyPermissionPrompt;
1590     }
1591 
1592     /**
1593      * Sets whether the activity is eligible to show a legacy permission prompt
1594      * @hide
1595      */
1596     @TestApi
setEligibleForLegacyPermissionPrompt(boolean eligible)1597     public void setEligibleForLegacyPermissionPrompt(boolean eligible) {
1598         mIsEligibleForLegacyPermissionPrompt = eligible;
1599     }
1600 
1601     /**
1602      * Sets whether the activity is to be launched into LockTask mode.
1603      *
1604      * Use this option to start an activity in LockTask mode. Note that only apps permitted by
1605      * {@link android.app.admin.DevicePolicyManager} can run in LockTask mode. Therefore, if
1606      * {@link android.app.admin.DevicePolicyManager#isLockTaskPermitted(String)} returns
1607      * {@code false} for the package of the target activity, a {@link SecurityException} will be
1608      * thrown during {@link Context#startActivity(Intent, Bundle)}. This method doesn't affect
1609      * activities that are already running — relaunch the activity to run in lock task mode.
1610      *
1611      * Defaults to {@code false} if not set.
1612      *
1613      * @param lockTaskMode {@code true} if the activity is to be launched into LockTask mode.
1614      * @return {@code this} {@link ActivityOptions} instance.
1615      * @see Activity#startLockTask()
1616      * @see android.app.admin.DevicePolicyManager#setLockTaskPackages(ComponentName, String[])
1617      */
setLockTaskEnabled(boolean lockTaskMode)1618     public ActivityOptions setLockTaskEnabled(boolean lockTaskMode) {
1619         mLockTaskMode = lockTaskMode;
1620         return this;
1621     }
1622 
1623     /**
1624      * Sets whether the identity of the launching app should be shared with the activity.
1625      *
1626      * <p>Use this option when starting an activity that needs to know the identity of the
1627      * launching app; with this set to {@code true}, the activity will have access to the launching
1628      * app's package name and uid.
1629      *
1630      * <p>Defaults to {@code false} if not set.
1631      *
1632      * <p>Note, even if the launching app does not explicitly enable sharing of its identity, if
1633      * the activity is started with {@code Activity#startActivityForResult}, then {@link
1634      * Activity#getCallingPackage()} will still return the launching app's package name to
1635      * allow validation of the result's recipient. Also, an activity running within a package
1636      * signed by the same key used to sign the platform (some system apps such as Settings will
1637      * be signed with the platform's key) will have access to the launching app's identity.
1638      *
1639      * @param shareIdentity whether the launching app's identity should be shared with the activity
1640      * @return {@code this} {@link ActivityOptions} instance.
1641      * @see Activity#getLaunchedFromPackage()
1642      * @see Activity#getLaunchedFromUid()
1643      */
1644     @NonNull
setShareIdentityEnabled(boolean shareIdentity)1645     public ActivityOptions setShareIdentityEnabled(boolean shareIdentity) {
1646         mShareIdentity = shareIdentity;
1647         return this;
1648     }
1649 
1650     /**
1651      * Gets the id of the display where activity should be launched.
1652      * @return The id of the display where activity should be launched,
1653      *         {@link android.view.Display#INVALID_DISPLAY} if not set.
1654      * @see #setLaunchDisplayId(int)
1655      */
getLaunchDisplayId()1656     public int getLaunchDisplayId() {
1657         return mLaunchDisplayId;
1658     }
1659 
1660     /**
1661      * Sets the id of the display where the activity should be launched.
1662      * An app can launch activities on public displays or displays where the app already has
1663      * activities. Otherwise, trying to launch on a private display or providing an invalid display
1664      * id will result in an exception.
1665      * <p>
1666      * Setting launch display id will be ignored on devices that don't have
1667      * {@link android.content.pm.PackageManager#FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS}.
1668      * @param launchDisplayId The id of the display where the activity should be launched.
1669      * @return {@code this} {@link ActivityOptions} instance.
1670      */
setLaunchDisplayId(int launchDisplayId)1671     public ActivityOptions setLaunchDisplayId(int launchDisplayId) {
1672         mLaunchDisplayId = launchDisplayId;
1673         return this;
1674     }
1675 
1676     /** @hide */
getCallerDisplayId()1677     public int getCallerDisplayId() {
1678         return mCallerDisplayId;
1679     }
1680 
1681     /** @hide */
setCallerDisplayId(int callerDisplayId)1682     public ActivityOptions setCallerDisplayId(int callerDisplayId) {
1683         mCallerDisplayId = callerDisplayId;
1684         return this;
1685     }
1686 
1687     /** @hide */
getLaunchTaskDisplayArea()1688     public WindowContainerToken getLaunchTaskDisplayArea() {
1689         return mLaunchTaskDisplayArea;
1690     }
1691 
1692     /** @hide */
setLaunchTaskDisplayArea( WindowContainerToken windowContainerToken)1693     public ActivityOptions setLaunchTaskDisplayArea(
1694             WindowContainerToken windowContainerToken) {
1695         mLaunchTaskDisplayArea = windowContainerToken;
1696         return this;
1697     }
1698 
1699     /** @hide */
getLaunchTaskDisplayAreaFeatureId()1700     public int getLaunchTaskDisplayAreaFeatureId() {
1701         return mLaunchTaskDisplayAreaFeatureId;
1702     }
1703 
1704     /**
1705      * Sets the TaskDisplayArea feature Id the activity should launch into.
1706      * Note: It is possible to have TaskDisplayAreas with the same featureId on multiple displays.
1707      * If launch display id is not specified, the TaskDisplayArea on the default display will be
1708      * used.
1709      * @hide
1710      */
1711     @TestApi
setLaunchTaskDisplayAreaFeatureId(int launchTaskDisplayAreaFeatureId)1712     public void setLaunchTaskDisplayAreaFeatureId(int launchTaskDisplayAreaFeatureId) {
1713         mLaunchTaskDisplayAreaFeatureId = launchTaskDisplayAreaFeatureId;
1714     }
1715 
1716     /** @hide */
getLaunchRootTask()1717     public WindowContainerToken getLaunchRootTask() {
1718         return mLaunchRootTask;
1719     }
1720 
1721     /** @hide */
setLaunchRootTask(WindowContainerToken windowContainerToken)1722     public ActivityOptions setLaunchRootTask(WindowContainerToken windowContainerToken) {
1723         mLaunchRootTask = windowContainerToken;
1724         return this;
1725     }
1726 
1727     /** @hide */
getLaunchTaskFragmentToken()1728     public IBinder getLaunchTaskFragmentToken() {
1729         return mLaunchTaskFragmentToken;
1730     }
1731 
1732     /** @hide */
setLaunchTaskFragmentToken(IBinder taskFragmentToken)1733     public ActivityOptions setLaunchTaskFragmentToken(IBinder taskFragmentToken) {
1734         mLaunchTaskFragmentToken = taskFragmentToken;
1735         return this;
1736     }
1737 
1738     /** @hide */
getLaunchWindowingMode()1739     public int getLaunchWindowingMode() {
1740         return mLaunchWindowingMode;
1741     }
1742 
1743     /**
1744      * Sets the windowing mode the activity should launch into.
1745      * @hide
1746      */
1747     @TestApi
setLaunchWindowingMode(int windowingMode)1748     public void setLaunchWindowingMode(int windowingMode) {
1749         mLaunchWindowingMode = windowingMode;
1750     }
1751 
1752     /**
1753      * @return {@link PictureInPictureParams} used to launch into PiP mode.
1754      * @hide
1755      */
getLaunchIntoPipParams()1756     public PictureInPictureParams getLaunchIntoPipParams() {
1757         return mLaunchIntoPipParams;
1758     }
1759 
1760     /**
1761      * @return {@code true} if this instance is used to launch into PiP mode.
1762      * @hide
1763      */
isLaunchIntoPip()1764     public boolean isLaunchIntoPip() {
1765         return mLaunchIntoPipParams != null
1766                 && mLaunchIntoPipParams.isLaunchIntoPip();
1767     }
1768 
1769     /** @hide */
getLaunchActivityType()1770     public int getLaunchActivityType() {
1771         return mLaunchActivityType;
1772     }
1773 
1774     /** @hide */
1775     @TestApi
setLaunchActivityType(int activityType)1776     public void setLaunchActivityType(int activityType) {
1777         mLaunchActivityType = activityType;
1778     }
1779 
1780     /**
1781      * Sets the task the activity will be launched in.
1782      * @hide
1783      */
1784     @RequiresPermission(START_TASKS_FROM_RECENTS)
1785     @SystemApi
setLaunchTaskId(int taskId)1786     public void setLaunchTaskId(int taskId) {
1787         mLaunchTaskId = taskId;
1788     }
1789 
1790     /**
1791      * @hide
1792      */
1793     @SystemApi
getLaunchTaskId()1794     public int getLaunchTaskId() {
1795         return mLaunchTaskId;
1796     }
1797 
1798     /**
1799      * Sets whether recents disable showing starting window when activity launch.
1800      * @hide
1801      */
1802     @RequiresPermission(START_TASKS_FROM_RECENTS)
setDisableStartingWindow(boolean disable)1803     public void setDisableStartingWindow(boolean disable) {
1804         mDisableStartingWindow = disable;
1805     }
1806 
1807     /**
1808      * @hide
1809      */
getDisableStartingWindow()1810     public boolean getDisableStartingWindow() {
1811         return mDisableStartingWindow;
1812     }
1813 
1814     /**
1815      * Specifies intent flags to be applied for any activity started from a PendingIntent.
1816      *
1817      * @hide
1818      */
setPendingIntentLaunchFlags(@ndroid.content.Intent.Flags int flags)1819     public void setPendingIntentLaunchFlags(@android.content.Intent.Flags int flags) {
1820         mPendingIntentLaunchFlags = flags;
1821     }
1822 
1823     /**
1824      * @hide
1825      */
getPendingIntentLaunchFlags()1826     public int getPendingIntentLaunchFlags() {
1827         // b/243794108: Ignore all flags except the new task flag, to be reconsidered in b/254490217
1828         return mPendingIntentLaunchFlags &
1829                 (FLAG_ACTIVITY_NEW_TASK | FLAG_RECEIVER_FOREGROUND);
1830     }
1831 
1832     /**
1833      * Set's whether the task for the activity launched with this option should always be on top.
1834      * @hide
1835      */
1836     @TestApi
setTaskAlwaysOnTop(boolean alwaysOnTop)1837     public void setTaskAlwaysOnTop(boolean alwaysOnTop) {
1838         mTaskAlwaysOnTop = alwaysOnTop;
1839     }
1840 
1841     /**
1842      * @hide
1843      */
getTaskAlwaysOnTop()1844     public boolean getTaskAlwaysOnTop() {
1845         return mTaskAlwaysOnTop;
1846     }
1847 
1848     /**
1849      * Set's whether the activity launched with this option should be a task overlay. That is the
1850      * activity will always be the top activity of the task.
1851      * @param canResume {@code false} if the task will also not be moved to the front of the stack.
1852      * @hide
1853      */
1854     @TestApi
setTaskOverlay(boolean taskOverlay, boolean canResume)1855     public void setTaskOverlay(boolean taskOverlay, boolean canResume) {
1856         mTaskOverlay = taskOverlay;
1857         mTaskOverlayCanResume = canResume;
1858     }
1859 
1860     /**
1861      * @hide
1862      */
getTaskOverlay()1863     public boolean getTaskOverlay() {
1864         return mTaskOverlay;
1865     }
1866 
1867     /**
1868      * @hide
1869      */
canTaskOverlayResume()1870     public boolean canTaskOverlayResume() {
1871         return mTaskOverlayCanResume;
1872     }
1873 
1874     /**
1875      * Sets whether the activity launched should not cause the activity stack it is contained in to
1876      * be moved to the front as a part of launching.
1877      *
1878      * @hide
1879      */
setAvoidMoveToFront()1880     public void setAvoidMoveToFront() {
1881         mAvoidMoveToFront = true;
1882     }
1883 
1884     /**
1885      * @return whether the activity launch should prevent moving the associated activity stack to
1886      *         the front.
1887      * @hide
1888      */
getAvoidMoveToFront()1889     public boolean getAvoidMoveToFront() {
1890         return mAvoidMoveToFront;
1891     }
1892 
1893     /**
1894      * Sets whether the launch of this activity should freeze the recent task list reordering until
1895      * the next user interaction or timeout. This flag is only applied when starting an activity
1896      * in recents.
1897      * @hide
1898      */
setFreezeRecentTasksReordering()1899     public void setFreezeRecentTasksReordering() {
1900         mFreezeRecentTasksReordering = true;
1901     }
1902 
1903     /**
1904      * @return whether the launch of this activity should freeze the recent task list reordering
1905      * @hide
1906      */
freezeRecentTasksReordering()1907     public boolean freezeRecentTasksReordering() {
1908         return mFreezeRecentTasksReordering;
1909     }
1910 
1911     /** @hide */
1912     @UnsupportedAppUsage
setSplitScreenCreateMode(int splitScreenCreateMode)1913     public void setSplitScreenCreateMode(int splitScreenCreateMode) {
1914         // Remove this method after @UnsupportedAppUsage can be removed.
1915     }
1916 
1917     /** @hide */
setDisallowEnterPictureInPictureWhileLaunching(boolean disallow)1918     public void setDisallowEnterPictureInPictureWhileLaunching(boolean disallow) {
1919         mDisallowEnterPictureInPictureWhileLaunching = disallow;
1920     }
1921 
1922     /** @hide */
disallowEnterPictureInPictureWhileLaunching()1923     public boolean disallowEnterPictureInPictureWhileLaunching() {
1924         return mDisallowEnterPictureInPictureWhileLaunching;
1925     }
1926 
1927     /** @hide */
setApplyActivityFlagsForBubbles(boolean apply)1928     public void setApplyActivityFlagsForBubbles(boolean apply) {
1929         mApplyActivityFlagsForBubbles = apply;
1930     }
1931 
1932     /**  @hide */
isApplyActivityFlagsForBubbles()1933     public boolean isApplyActivityFlagsForBubbles() {
1934         return mApplyActivityFlagsForBubbles;
1935     }
1936 
1937     /** @hide */
setApplyMultipleTaskFlagForShortcut(boolean apply)1938     public void setApplyMultipleTaskFlagForShortcut(boolean apply) {
1939         mApplyMultipleTaskFlagForShortcut = apply;
1940     }
1941 
1942     /** @hide */
isApplyMultipleTaskFlagForShortcut()1943     public boolean isApplyMultipleTaskFlagForShortcut() {
1944         return mApplyMultipleTaskFlagForShortcut;
1945     }
1946 
1947     /** @hide */
setApplyNoUserActionFlagForShortcut(boolean apply)1948     public void setApplyNoUserActionFlagForShortcut(boolean apply) {
1949         mApplyNoUserActionFlagForShortcut = apply;
1950     }
1951 
1952     /** @hide */
isApplyNoUserActionFlagForShortcut()1953     public boolean isApplyNoUserActionFlagForShortcut() {
1954         return mApplyNoUserActionFlagForShortcut;
1955     }
1956 
1957     /**
1958      * Sets a launch cookie that can be used to track the activity and task that are launch as a
1959      * result of this option. If the launched activity is a trampoline that starts another activity
1960      * immediately, the cookie will be transferred to the next activity.
1961      *
1962      * @hide
1963      */
setLaunchCookie(IBinder launchCookie)1964     public void setLaunchCookie(IBinder launchCookie) {
1965         mLaunchCookie = launchCookie;
1966     }
1967 
1968     /**
1969      * @return The launch tracking cookie if set or {@code null} otherwise.
1970      *
1971      * @hide
1972      */
getLaunchCookie()1973     public IBinder getLaunchCookie() {
1974         return mLaunchCookie;
1975     }
1976 
1977 
1978     /** @hide */
getOverrideTaskTransition()1979     public boolean getOverrideTaskTransition() {
1980         return mOverrideTaskTransition;
1981     }
1982 
1983     /**
1984      * Sets whether to remove the task when TaskOrganizer, which is managing it, is destroyed.
1985      * @hide
1986      */
setRemoveWithTaskOrganizer(boolean remove)1987     public void setRemoveWithTaskOrganizer(boolean remove) {
1988         mRemoveWithTaskOrganizer = remove;
1989     }
1990 
1991     /**
1992      * @return whether to remove the task when TaskOrganizer, which is managing it, is destroyed.
1993      * @hide
1994      */
getRemoveWithTaskOranizer()1995     public boolean getRemoveWithTaskOranizer() {
1996         return mRemoveWithTaskOrganizer;
1997     }
1998 
1999     /**
2000      * Sets whether this activity is launched from a bubble.
2001      * @hide
2002      */
2003     @TestApi
setLaunchedFromBubble(boolean fromBubble)2004     public void setLaunchedFromBubble(boolean fromBubble) {
2005         mLaunchedFromBubble = fromBubble;
2006     }
2007 
2008     /**
2009      * @return whether the activity was launched from a bubble.
2010      * @hide
2011      */
getLaunchedFromBubble()2012     public boolean getLaunchedFromBubble() {
2013         return mLaunchedFromBubble;
2014     }
2015 
2016     /**
2017      * Sets whether the activity launch is part of a transient operation. If it is, it will not
2018      * cause lifecycle changes in existing activities even if it were to occlude them (ie. other
2019      * activities occluded by this one will not be paused or stopped until the launch is committed).
2020      * As a consequence, it will start immediately since it doesn't need to wait for other
2021      * lifecycles to evolve. Current user is recents.
2022      * @hide
2023      */
setTransientLaunch()2024     public ActivityOptions setTransientLaunch() {
2025         mTransientLaunch = true;
2026         return this;
2027     }
2028 
2029     /**
2030      * @see #setTransientLaunch()
2031      * @return whether the activity launch is part of a transient operation.
2032      * @hide
2033      */
getTransientLaunch()2034     public boolean getTransientLaunch() {
2035         return mTransientLaunch;
2036     }
2037 
2038     /**
2039      * Sets whether the keyguard should go away when this activity launches.
2040      *
2041      * @see Activity#setShowWhenLocked(boolean)
2042      * @see android.R.attr#showWhenLocked
2043      * @hide
2044      */
2045     @RequiresPermission(CONTROL_KEYGUARD)
setDismissKeyguard()2046     public void setDismissKeyguard() {
2047         mDismissKeyguard = true;
2048     }
2049 
2050     /**
2051      * @see #setDismissKeyguard()
2052      * @return whether the insecure keyguard should go away when the activity launches.
2053      * @hide
2054      */
getDismissKeyguard()2055     public boolean getDismissKeyguard() {
2056         return mDismissKeyguard;
2057     }
2058 
2059     /**
2060      * Sets background activity launch logic won't use pending intent creator foreground state.
2061      *
2062      * @hide
2063      * @deprecated use {@link #setPendingIntentCreatorBackgroundActivityStartMode(int)} instead
2064      */
2065     @Deprecated
setIgnorePendingIntentCreatorForegroundState(boolean ignore)2066     public ActivityOptions setIgnorePendingIntentCreatorForegroundState(boolean ignore) {
2067         mPendingIntentCreatorBackgroundActivityStartMode = ignore
2068                 ? MODE_BACKGROUND_ACTIVITY_START_DENIED : MODE_BACKGROUND_ACTIVITY_START_ALLOWED;
2069         return this;
2070     }
2071 
2072     /**
2073      * Allow a {@link PendingIntent} to use the privilege of its creator to start background
2074      * activities.
2075      *
2076      * @param mode the {@link android.app.ComponentOptions.BackgroundActivityStartMode} being set
2077      * @throws IllegalArgumentException is the value is not a valid
2078      * {@link android.app.ComponentOptions.BackgroundActivityStartMode}
2079      */
2080     @NonNull
setPendingIntentCreatorBackgroundActivityStartMode( @ackgroundActivityStartMode int mode)2081     public ActivityOptions setPendingIntentCreatorBackgroundActivityStartMode(
2082             @BackgroundActivityStartMode int mode) {
2083         mPendingIntentCreatorBackgroundActivityStartMode = mode;
2084         return this;
2085     }
2086 
2087     /**
2088      * Returns the mode to start background activities granted by the creator of the
2089      * {@link PendingIntent}.
2090      *
2091      * @return the {@link android.app.ComponentOptions.BackgroundActivityStartMode} currently set
2092      */
getPendingIntentCreatorBackgroundActivityStartMode()2093     public @BackgroundActivityStartMode int getPendingIntentCreatorBackgroundActivityStartMode() {
2094         return mPendingIntentCreatorBackgroundActivityStartMode;
2095     }
2096 
2097     /**
2098      * Update the current values in this ActivityOptions from those supplied
2099      * in <var>otherOptions</var>.  Any values
2100      * defined in <var>otherOptions</var> replace those in the base options.
2101      */
update(ActivityOptions otherOptions)2102     public void update(ActivityOptions otherOptions) {
2103         if (otherOptions.mPackageName != null) {
2104             mPackageName = otherOptions.mPackageName;
2105         }
2106         mUsageTimeReport = otherOptions.mUsageTimeReport;
2107         mTransitionReceiver = null;
2108         mSharedElementNames = null;
2109         mIsReturning = false;
2110         mResultData = null;
2111         mResultCode = 0;
2112         mExitCoordinatorIndex = 0;
2113         mAnimationType = otherOptions.mAnimationType;
2114         switch (otherOptions.mAnimationType) {
2115             case ANIM_CUSTOM:
2116                 mCustomEnterResId = otherOptions.mCustomEnterResId;
2117                 mCustomExitResId = otherOptions.mCustomExitResId;
2118                 mCustomBackgroundColor = otherOptions.mCustomBackgroundColor;
2119                 mThumbnail = null;
2120                 if (mAnimationStartedListener != null) {
2121                     try {
2122                         mAnimationStartedListener.sendResult(null);
2123                     } catch (RemoteException e) {
2124                     }
2125                 }
2126                 mAnimationStartedListener = otherOptions.mAnimationStartedListener;
2127                 break;
2128             case ANIM_CUSTOM_IN_PLACE:
2129                 mCustomInPlaceResId = otherOptions.mCustomInPlaceResId;
2130                 break;
2131             case ANIM_SCALE_UP:
2132                 mStartX = otherOptions.mStartX;
2133                 mStartY = otherOptions.mStartY;
2134                 mWidth = otherOptions.mWidth;
2135                 mHeight = otherOptions.mHeight;
2136                 if (mAnimationStartedListener != null) {
2137                     try {
2138                         mAnimationStartedListener.sendResult(null);
2139                     } catch (RemoteException e) {
2140                     }
2141                 }
2142                 mAnimationStartedListener = null;
2143                 break;
2144             case ANIM_THUMBNAIL_SCALE_UP:
2145             case ANIM_THUMBNAIL_SCALE_DOWN:
2146             case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
2147             case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
2148                 mThumbnail = otherOptions.mThumbnail;
2149                 mStartX = otherOptions.mStartX;
2150                 mStartY = otherOptions.mStartY;
2151                 mWidth = otherOptions.mWidth;
2152                 mHeight = otherOptions.mHeight;
2153                 if (mAnimationStartedListener != null) {
2154                     try {
2155                         mAnimationStartedListener.sendResult(null);
2156                     } catch (RemoteException e) {
2157                     }
2158                 }
2159                 mAnimationStartedListener = otherOptions.mAnimationStartedListener;
2160                 break;
2161             case ANIM_SCENE_TRANSITION:
2162                 mTransitionReceiver = otherOptions.mTransitionReceiver;
2163                 mSharedElementNames = otherOptions.mSharedElementNames;
2164                 mIsReturning = otherOptions.mIsReturning;
2165                 mThumbnail = null;
2166                 mAnimationStartedListener = null;
2167                 mResultData = otherOptions.mResultData;
2168                 mResultCode = otherOptions.mResultCode;
2169                 mExitCoordinatorIndex = otherOptions.mExitCoordinatorIndex;
2170                 break;
2171         }
2172         mLockTaskMode = otherOptions.mLockTaskMode;
2173         mShareIdentity = otherOptions.mShareIdentity;
2174         mAnimSpecs = otherOptions.mAnimSpecs;
2175         mAnimationFinishedListener = otherOptions.mAnimationFinishedListener;
2176         mSpecsFuture = otherOptions.mSpecsFuture;
2177         mRemoteAnimationAdapter = otherOptions.mRemoteAnimationAdapter;
2178         mLaunchIntoPipParams = otherOptions.mLaunchIntoPipParams;
2179         mIsEligibleForLegacyPermissionPrompt = otherOptions.mIsEligibleForLegacyPermissionPrompt;
2180     }
2181 
2182     /**
2183      * Returns the created options as a Bundle, which can be passed to
2184      * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle)
2185      * Context.startActivity(Intent, Bundle)} and related methods.
2186      * Note that the returned Bundle is still owned by the ActivityOptions
2187      * object; you must not modify it, but can supply it to the startActivity
2188      * methods that take an options Bundle.
2189      */
2190     @Override
toBundle()2191     public Bundle toBundle() {
2192         Bundle b = super.toBundle();
2193         if (mPackageName != null) {
2194             b.putString(KEY_PACKAGE_NAME, mPackageName);
2195         }
2196         if (mLaunchBounds != null) {
2197             b.putParcelable(KEY_LAUNCH_BOUNDS, mLaunchBounds);
2198         }
2199         if (mAnimationType != ANIM_UNDEFINED) {
2200             b.putInt(KEY_ANIM_TYPE, mAnimationType);
2201         }
2202         if (mUsageTimeReport != null) {
2203             b.putParcelable(KEY_USAGE_TIME_REPORT, mUsageTimeReport);
2204         }
2205         switch (mAnimationType) {
2206             case ANIM_CUSTOM:
2207                 b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId);
2208                 b.putInt(KEY_ANIM_EXIT_RES_ID, mCustomExitResId);
2209                 b.putInt(KEY_ANIM_BACKGROUND_COLOR, mCustomBackgroundColor);
2210                 b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
2211                         != null ? mAnimationStartedListener.asBinder() : null);
2212                 break;
2213             case ANIM_CUSTOM_IN_PLACE:
2214                 b.putInt(KEY_ANIM_IN_PLACE_RES_ID, mCustomInPlaceResId);
2215                 break;
2216             case ANIM_SCALE_UP:
2217             case ANIM_CLIP_REVEAL:
2218                 b.putInt(KEY_ANIM_START_X, mStartX);
2219                 b.putInt(KEY_ANIM_START_Y, mStartY);
2220                 b.putInt(KEY_ANIM_WIDTH, mWidth);
2221                 b.putInt(KEY_ANIM_HEIGHT, mHeight);
2222                 break;
2223             case ANIM_THUMBNAIL_SCALE_UP:
2224             case ANIM_THUMBNAIL_SCALE_DOWN:
2225             case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
2226             case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
2227                 // Once we parcel the thumbnail for transfering over to the system, create a copy of
2228                 // the bitmap to a hardware bitmap and pass through the HardwareBuffer
2229                 if (mThumbnail != null) {
2230                     final Bitmap hwBitmap = mThumbnail.copy(Config.HARDWARE, false /* isMutable */);
2231                     if (hwBitmap != null) {
2232                         b.putParcelable(KEY_ANIM_THUMBNAIL, hwBitmap.getHardwareBuffer());
2233                     } else {
2234                         Slog.w(TAG, "Failed to copy thumbnail");
2235                     }
2236                 }
2237                 b.putInt(KEY_ANIM_START_X, mStartX);
2238                 b.putInt(KEY_ANIM_START_Y, mStartY);
2239                 b.putInt(KEY_ANIM_WIDTH, mWidth);
2240                 b.putInt(KEY_ANIM_HEIGHT, mHeight);
2241                 b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
2242                         != null ? mAnimationStartedListener.asBinder() : null);
2243                 break;
2244             case ANIM_SCENE_TRANSITION:
2245                 if (mTransitionReceiver != null) {
2246                     b.putParcelable(KEY_TRANSITION_COMPLETE_LISTENER, mTransitionReceiver);
2247                 }
2248                 b.putBoolean(KEY_TRANSITION_IS_RETURNING, mIsReturning);
2249                 b.putStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS, mSharedElementNames);
2250                 b.putParcelable(KEY_RESULT_DATA, mResultData);
2251                 b.putInt(KEY_RESULT_CODE, mResultCode);
2252                 b.putInt(KEY_EXIT_COORDINATOR_INDEX, mExitCoordinatorIndex);
2253                 break;
2254         }
2255         if (mLockTaskMode) {
2256             b.putBoolean(KEY_LOCK_TASK_MODE, mLockTaskMode);
2257         }
2258         if (mShareIdentity) {
2259             b.putBoolean(KEY_SHARE_IDENTITY, mShareIdentity);
2260         }
2261         if (mLaunchDisplayId != INVALID_DISPLAY) {
2262             b.putInt(KEY_LAUNCH_DISPLAY_ID, mLaunchDisplayId);
2263         }
2264         if (mCallerDisplayId != INVALID_DISPLAY) {
2265             b.putInt(KEY_CALLER_DISPLAY_ID, mCallerDisplayId);
2266         }
2267         if (mLaunchTaskDisplayArea != null) {
2268             b.putParcelable(KEY_LAUNCH_TASK_DISPLAY_AREA_TOKEN, mLaunchTaskDisplayArea);
2269         }
2270         if (mLaunchTaskDisplayAreaFeatureId != FEATURE_UNDEFINED) {
2271             b.putInt(KEY_LAUNCH_TASK_DISPLAY_AREA_FEATURE_ID, mLaunchTaskDisplayAreaFeatureId);
2272         }
2273         if (mLaunchRootTask != null) {
2274             b.putParcelable(KEY_LAUNCH_ROOT_TASK_TOKEN, mLaunchRootTask);
2275         }
2276         if (mLaunchTaskFragmentToken != null) {
2277             b.putBinder(KEY_LAUNCH_TASK_FRAGMENT_TOKEN, mLaunchTaskFragmentToken);
2278         }
2279         if (mLaunchWindowingMode != WINDOWING_MODE_UNDEFINED) {
2280             b.putInt(KEY_LAUNCH_WINDOWING_MODE, mLaunchWindowingMode);
2281         }
2282         if (mLaunchActivityType != ACTIVITY_TYPE_UNDEFINED) {
2283             b.putInt(KEY_LAUNCH_ACTIVITY_TYPE, mLaunchActivityType);
2284         }
2285         if (mLaunchTaskId != -1) {
2286             b.putInt(KEY_LAUNCH_TASK_ID, mLaunchTaskId);
2287         }
2288         if (mPendingIntentLaunchFlags != 0) {
2289             b.putInt(KEY_PENDING_INTENT_LAUNCH_FLAGS, mPendingIntentLaunchFlags);
2290         }
2291         if (mTaskAlwaysOnTop) {
2292             b.putBoolean(KEY_TASK_ALWAYS_ON_TOP, mTaskAlwaysOnTop);
2293         }
2294         if (mTaskOverlay) {
2295             b.putBoolean(KEY_TASK_OVERLAY, mTaskOverlay);
2296         }
2297         if (mTaskOverlayCanResume) {
2298             b.putBoolean(KEY_TASK_OVERLAY_CAN_RESUME, mTaskOverlayCanResume);
2299         }
2300         if (mAvoidMoveToFront) {
2301             b.putBoolean(KEY_AVOID_MOVE_TO_FRONT, mAvoidMoveToFront);
2302         }
2303         if (mFreezeRecentTasksReordering) {
2304             b.putBoolean(KEY_FREEZE_RECENT_TASKS_REORDERING, mFreezeRecentTasksReordering);
2305         }
2306         if (mDisallowEnterPictureInPictureWhileLaunching) {
2307             b.putBoolean(KEY_DISALLOW_ENTER_PICTURE_IN_PICTURE_WHILE_LAUNCHING,
2308                     mDisallowEnterPictureInPictureWhileLaunching);
2309         }
2310         if (mApplyActivityFlagsForBubbles) {
2311             b.putBoolean(KEY_APPLY_ACTIVITY_FLAGS_FOR_BUBBLES, mApplyActivityFlagsForBubbles);
2312         }
2313         if (mApplyMultipleTaskFlagForShortcut) {
2314             b.putBoolean(KEY_APPLY_MULTIPLE_TASK_FLAG_FOR_SHORTCUT,
2315                     mApplyMultipleTaskFlagForShortcut);
2316         }
2317         if (mApplyNoUserActionFlagForShortcut) {
2318             b.putBoolean(KEY_APPLY_NO_USER_ACTION_FLAG_FOR_SHORTCUT, true);
2319         }
2320         if (mAnimSpecs != null) {
2321             b.putParcelableArray(KEY_ANIM_SPECS, mAnimSpecs);
2322         }
2323         if (mAnimationFinishedListener != null) {
2324             b.putBinder(KEY_ANIMATION_FINISHED_LISTENER, mAnimationFinishedListener.asBinder());
2325         }
2326         if (mSpecsFuture != null) {
2327             b.putBinder(KEY_SPECS_FUTURE, mSpecsFuture.asBinder());
2328         }
2329         if (mSourceInfo != null) {
2330             b.putParcelable(KEY_SOURCE_INFO, mSourceInfo);
2331         }
2332         if (mRotationAnimationHint != -1) {
2333             b.putInt(KEY_ROTATION_ANIMATION_HINT, mRotationAnimationHint);
2334         }
2335         if (mAppVerificationBundle != null) {
2336             b.putBundle(KEY_INSTANT_APP_VERIFICATION_BUNDLE, mAppVerificationBundle);
2337         }
2338         if (mRemoteAnimationAdapter != null) {
2339             b.putParcelable(KEY_REMOTE_ANIMATION_ADAPTER, mRemoteAnimationAdapter);
2340         }
2341         if (mLaunchCookie != null) {
2342             b.putBinder(KEY_LAUNCH_COOKIE, mLaunchCookie);
2343         }
2344         if (mRemoteTransition != null) {
2345             b.putParcelable(KEY_REMOTE_TRANSITION, mRemoteTransition);
2346         }
2347         if (mOverrideTaskTransition) {
2348             b.putBoolean(KEY_OVERRIDE_TASK_TRANSITION, mOverrideTaskTransition);
2349         }
2350         if (mSplashScreenThemeResName != null && !mSplashScreenThemeResName.isEmpty()) {
2351             b.putString(KEY_SPLASH_SCREEN_THEME, mSplashScreenThemeResName);
2352         }
2353         if (mRemoveWithTaskOrganizer) {
2354             b.putBoolean(KEY_REMOVE_WITH_TASK_ORGANIZER, mRemoveWithTaskOrganizer);
2355         }
2356         if (mLaunchedFromBubble) {
2357             b.putBoolean(KEY_LAUNCHED_FROM_BUBBLE, mLaunchedFromBubble);
2358         }
2359         if (mTransientLaunch) {
2360             b.putBoolean(KEY_TRANSIENT_LAUNCH, mTransientLaunch);
2361         }
2362         if (mSplashScreenStyle != 0) {
2363             b.putInt(KEY_SPLASH_SCREEN_STYLE, mSplashScreenStyle);
2364         }
2365         if (mLaunchIntoPipParams != null) {
2366             b.putParcelable(KEY_LAUNCH_INTO_PIP_PARAMS, mLaunchIntoPipParams);
2367         }
2368         if (mIsEligibleForLegacyPermissionPrompt) {
2369             b.putBoolean(KEY_LEGACY_PERMISSION_PROMPT_ELIGIBLE,
2370                     mIsEligibleForLegacyPermissionPrompt);
2371         }
2372         if (mDismissKeyguard) {
2373             b.putBoolean(KEY_DISMISS_KEYGUARD, mDismissKeyguard);
2374         }
2375         if (mPendingIntentCreatorBackgroundActivityStartMode
2376                 != MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED) {
2377             b.putInt(KEY_PENDING_INTENT_CREATOR_BACKGROUND_ACTIVITY_START_MODE,
2378                     mPendingIntentCreatorBackgroundActivityStartMode);
2379         }
2380         if (mDisableStartingWindow) {
2381             b.putBoolean(KEY_DISABLE_STARTING_WINDOW, mDisableStartingWindow);
2382         }
2383         return b;
2384     }
2385 
2386     /**
2387      * Ask the system track that time the user spends in the app being launched, and
2388      * report it back once done.  The report will be sent to the given receiver, with
2389      * the extras {@link #EXTRA_USAGE_TIME_REPORT} and {@link #EXTRA_USAGE_TIME_REPORT_PACKAGES}
2390      * filled in.
2391      *
2392      * <p>The time interval tracked is from launching this activity until the user leaves
2393      * that activity's flow.  They are considered to stay in the flow as long as
2394      * new activities are being launched or returned to from the original flow,
2395      * even if this crosses package or task boundaries.  For example, if the originator
2396      * starts an activity to view an image, and while there the user selects to share,
2397      * which launches their email app in a new task, and they complete the share, the
2398      * time during that entire operation will be included until they finally hit back from
2399      * the original image viewer activity.</p>
2400      *
2401      * <p>The user is considered to complete a flow once they switch to another
2402      * activity that is not part of the tracked flow.  This may happen, for example, by
2403      * using the notification shade, launcher, or recents to launch or switch to another
2404      * app.  Simply going in to these navigation elements does not break the flow (although
2405      * the launcher and recents stops time tracking of the session); it is the act of
2406      * going somewhere else that completes the tracking.</p>
2407      *
2408      * @param receiver A broadcast receiver that willl receive the report.
2409      */
requestUsageTimeReport(PendingIntent receiver)2410     public void requestUsageTimeReport(PendingIntent receiver) {
2411         mUsageTimeReport = receiver;
2412     }
2413 
2414     /**
2415      * Returns the launch source information set by {@link #setSourceInfo}.
2416      * @hide
2417      */
getSourceInfo()2418     public @Nullable SourceInfo getSourceInfo() {
2419         return mSourceInfo;
2420     }
2421 
2422     /**
2423      * Sets the source information of the launch event.
2424      *
2425      * @param type The type of the startup source.
2426      * @param uptimeMillis The event time of startup source in milliseconds since boot, not
2427      *                     including sleep (e.g. from {@link android.view.MotionEvent#getEventTime}
2428      *                     or {@link android.os.SystemClock#uptimeMillis}).
2429      * @see SourceInfo
2430      * @hide
2431      */
setSourceInfo(@ourceInfo.SourceType int type, long uptimeMillis)2432     public void setSourceInfo(@SourceInfo.SourceType int type, long uptimeMillis) {
2433         mSourceInfo = new SourceInfo(type, uptimeMillis);
2434     }
2435 
2436     /**
2437      * Return the filtered options only meant to be seen by the target activity itself
2438      * @hide
2439      */
forTargetActivity()2440     public ActivityOptions forTargetActivity() {
2441         if (mAnimationType == ANIM_SCENE_TRANSITION) {
2442             final ActivityOptions result = new ActivityOptions();
2443             result.update(this);
2444             return result;
2445         }
2446 
2447         return null;
2448     }
2449 
2450     /**
2451      * Returns the rotation animation set by {@link setRotationAnimationHint} or -1
2452      * if unspecified.
2453      * @hide
2454      */
getRotationAnimationHint()2455     public int getRotationAnimationHint() {
2456         return mRotationAnimationHint;
2457     }
2458 
2459 
2460     /**
2461      * Set a rotation animation to be used if launching the activity
2462      * triggers an orientation change, or -1 to clear. See
2463      * {@link android.view.WindowManager.LayoutParams} for rotation
2464      * animation values.
2465      * @hide
2466      */
setRotationAnimationHint(int hint)2467     public void setRotationAnimationHint(int hint) {
2468         mRotationAnimationHint = hint;
2469     }
2470 
2471     /**
2472      * Pop the extra verification bundle for the installer.
2473      * This removes the bundle from the ActivityOptions to make sure the installer bundle
2474      * is only available once.
2475      * @hide
2476      */
popAppVerificationBundle()2477     public Bundle popAppVerificationBundle() {
2478         Bundle out = mAppVerificationBundle;
2479         mAppVerificationBundle = null;
2480         return out;
2481     }
2482 
2483     /**
2484      * Set the {@link Bundle} that is provided to the app installer for additional verification
2485      * if the call to {@link Context#startActivity} results in an app being installed.
2486      *
2487      * This Bundle is not provided to any other app besides the installer.
2488      */
setAppVerificationBundle(Bundle bundle)2489     public ActivityOptions setAppVerificationBundle(Bundle bundle) {
2490         mAppVerificationBundle = bundle;
2491         return this;
2492 
2493     }
2494 
2495     /**
2496      * Sets the mode for allowing or denying the senders privileges to start background activities
2497      * to the PendingIntent.
2498      *
2499      * This is typically used in when executing {@link PendingIntent#send(Context, int, Intent,
2500      * PendingIntent.OnFinished, Handler, String, Bundle)} or similar
2501      * methods. A privileged sender of a PendingIntent should only grant
2502      * {@link #MODE_BACKGROUND_ACTIVITY_START_ALLOWED} if the PendingIntent is from a trusted source
2503      * and/or executed on behalf the user.
2504      */
setPendingIntentBackgroundActivityStartMode( @ackgroundActivityStartMode int state)2505     public @NonNull ActivityOptions setPendingIntentBackgroundActivityStartMode(
2506             @BackgroundActivityStartMode int state) {
2507         super.setPendingIntentBackgroundActivityStartMode(state);
2508         return this;
2509     }
2510 
2511     /**
2512      * Get the mode for allowing or denying the senders privileges to start background activities
2513      * to the PendingIntent.
2514      *
2515      * @see #setPendingIntentBackgroundActivityStartMode(int)
2516      */
getPendingIntentBackgroundActivityStartMode()2517     public @BackgroundActivityStartMode int getPendingIntentBackgroundActivityStartMode() {
2518         return super.getPendingIntentBackgroundActivityStartMode();
2519     }
2520 
2521     /**
2522      * Set PendingIntent activity is allowed to be started in the background if the caller
2523      * can start background activities.
2524      *
2525      * @deprecated use #setPendingIntentBackgroundActivityStartMode(int) to set the full range
2526      * of states
2527      */
2528     @Override
setPendingIntentBackgroundActivityLaunchAllowed(boolean allowed)2529     @Deprecated public void setPendingIntentBackgroundActivityLaunchAllowed(boolean allowed) {
2530         super.setPendingIntentBackgroundActivityLaunchAllowed(allowed);
2531     }
2532 
2533     /**
2534      * Get PendingIntent activity is allowed to be started in the background if the caller can start
2535      * background activities.
2536      *
2537      * @deprecated use {@link #getPendingIntentBackgroundActivityStartMode()} since for apps
2538      * targeting {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} or higher this value might
2539      * not match the actual behavior if the value was not explicitly set.
2540      */
isPendingIntentBackgroundActivityLaunchAllowed()2541     @Deprecated public boolean isPendingIntentBackgroundActivityLaunchAllowed() {
2542         return super.isPendingIntentBackgroundActivityLaunchAllowed();
2543     }
2544 
2545     /** @hide */
2546     @Override
toString()2547     public String toString() {
2548         return "ActivityOptions(" + hashCode() + "), mPackageName=" + mPackageName
2549                 + ", mAnimationType=" + mAnimationType + ", mStartX=" + mStartX + ", mStartY="
2550                 + mStartY + ", mWidth=" + mWidth + ", mHeight=" + mHeight + ", mLaunchDisplayId="
2551                 + mLaunchDisplayId;
2552     }
2553 
2554     /**
2555      * The information about the source of activity launch. E.g. describe an activity is launched
2556      * from launcher by receiving a motion event with a timestamp.
2557      * @hide
2558      */
2559     public static class SourceInfo implements Parcelable {
2560         /** Launched from launcher. */
2561         public static final int TYPE_LAUNCHER = 1;
2562         /** Launched from notification. */
2563         public static final int TYPE_NOTIFICATION = 2;
2564         /** Launched from lockscreen, including notification while the device is locked. */
2565         public static final int TYPE_LOCKSCREEN = 3;
2566         /** Launched from recents gesture handler. */
2567         public static final int TYPE_RECENTS_ANIMATION = 4;
2568 
2569         @IntDef(prefix = { "TYPE_" }, value = {
2570                 TYPE_LAUNCHER,
2571                 TYPE_NOTIFICATION,
2572                 TYPE_LOCKSCREEN,
2573         })
2574         @Retention(RetentionPolicy.SOURCE)
2575         public @interface SourceType {}
2576 
2577         /** The type of the startup source. */
2578         public final @SourceType int type;
2579 
2580         /** The timestamp (uptime based) of the source to launch activity. */
2581         public final long eventTimeMs;
2582 
SourceInfo(@ourceType int srcType, long uptimeMillis)2583         SourceInfo(@SourceType int srcType, long uptimeMillis) {
2584             type = srcType;
2585             eventTimeMs = uptimeMillis;
2586         }
2587 
2588         @Override
writeToParcel(Parcel dest, int flags)2589         public void writeToParcel(Parcel dest, int flags) {
2590             dest.writeInt(type);
2591             dest.writeLong(eventTimeMs);
2592         }
2593 
2594         @Override
describeContents()2595         public int describeContents() {
2596             return 0;
2597         }
2598 
2599         public static final Creator<SourceInfo> CREATOR = new Creator<SourceInfo>() {
2600             public SourceInfo createFromParcel(Parcel in) {
2601                 return new SourceInfo(in.readInt(), in.readLong());
2602             }
2603 
2604             public SourceInfo[] newArray(int size) {
2605                 return new SourceInfo[size];
2606             }
2607         };
2608     }
2609 }
2610