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