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