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