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