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