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.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT; 20 import static android.app.ActivityManager.StackId.INVALID_STACK_ID; 21 22 import android.annotation.Nullable; 23 import android.annotation.TestApi; 24 import android.content.Context; 25 import android.content.Intent; 26 import android.graphics.Bitmap; 27 import android.graphics.Rect; 28 import android.os.Bundle; 29 import android.os.Handler; 30 import android.os.IRemoteCallback; 31 import android.os.Parcelable; 32 import android.os.RemoteException; 33 import android.os.ResultReceiver; 34 import android.util.Pair; 35 import android.util.Slog; 36 import android.view.AppTransitionAnimationSpec; 37 import android.view.View; 38 import android.view.Window; 39 40 import java.util.ArrayList; 41 42 /** 43 * Helper class for building an options Bundle that can be used with 44 * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle) 45 * Context.startActivity(Intent, Bundle)} and related methods. 46 */ 47 public class ActivityOptions { 48 private static final String TAG = "ActivityOptions"; 49 50 /** 51 * A long in the extras delivered by {@link #requestUsageTimeReport} that contains 52 * the total time (in ms) the user spent in the app flow. 53 */ 54 public static final String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time"; 55 56 /** 57 * A Bundle in the extras delivered by {@link #requestUsageTimeReport} that contains 58 * detailed information about the time spent in each package associated with the app; 59 * each key is a package name, whose value is a long containing the time (in ms). 60 */ 61 public static final String EXTRA_USAGE_TIME_REPORT_PACKAGES = "android.usage_time_packages"; 62 63 /** 64 * The package name that created the options. 65 * @hide 66 */ 67 public static final String KEY_PACKAGE_NAME = "android:activity.packageName"; 68 69 /** 70 * The bounds (window size) that the activity should be launched in. Set to null explicitly for 71 * full screen. If the key is not found, previous bounds will be preserved. 72 * NOTE: This value is ignored on devices that don't have 73 * {@link android.content.pm.PackageManager#FEATURE_FREEFORM_WINDOW_MANAGEMENT} or 74 * {@link android.content.pm.PackageManager#FEATURE_PICTURE_IN_PICTURE} enabled. 75 * @hide 76 */ 77 public static final String KEY_LAUNCH_BOUNDS = "android:activity.launchBounds"; 78 79 /** 80 * Type of animation that arguments specify. 81 * @hide 82 */ 83 public static final String KEY_ANIM_TYPE = "android:activity.animType"; 84 85 /** 86 * Custom enter animation resource ID. 87 * @hide 88 */ 89 public static final String KEY_ANIM_ENTER_RES_ID = "android:activity.animEnterRes"; 90 91 /** 92 * Custom exit animation resource ID. 93 * @hide 94 */ 95 public static final String KEY_ANIM_EXIT_RES_ID = "android:activity.animExitRes"; 96 97 /** 98 * Custom in-place animation resource ID. 99 * @hide 100 */ 101 public static final String KEY_ANIM_IN_PLACE_RES_ID = "android:activity.animInPlaceRes"; 102 103 /** 104 * Bitmap for thumbnail animation. 105 * @hide 106 */ 107 public static final String KEY_ANIM_THUMBNAIL = "android:activity.animThumbnail"; 108 109 /** 110 * Start X position of thumbnail animation. 111 * @hide 112 */ 113 public static final String KEY_ANIM_START_X = "android:activity.animStartX"; 114 115 /** 116 * Start Y position of thumbnail animation. 117 * @hide 118 */ 119 public static final String KEY_ANIM_START_Y = "android:activity.animStartY"; 120 121 /** 122 * Initial width of the animation. 123 * @hide 124 */ 125 public static final String KEY_ANIM_WIDTH = "android:activity.animWidth"; 126 127 /** 128 * Initial height of the animation. 129 * @hide 130 */ 131 public static final String KEY_ANIM_HEIGHT = "android:activity.animHeight"; 132 133 /** 134 * Callback for when animation is started. 135 * @hide 136 */ 137 public static final String KEY_ANIM_START_LISTENER = "android:activity.animStartListener"; 138 139 /** 140 * Callback for when the last frame of the animation is played. 141 * @hide 142 */ 143 private static final String KEY_ANIMATION_FINISHED_LISTENER = 144 "android:activity.animationFinishedListener"; 145 146 /** 147 * Descriptions of app transition animations to be played during the activity launch. 148 */ 149 private static final String KEY_ANIM_SPECS = "android:activity.animSpecs"; 150 151 /** 152 * The stack id the activity should be launched into. 153 * @hide 154 */ 155 private static final String KEY_LAUNCH_STACK_ID = "android.activity.launchStackId"; 156 157 /** 158 * The task id the activity should be launched into. 159 * @hide 160 */ 161 private static final String KEY_LAUNCH_TASK_ID = "android.activity.launchTaskId"; 162 163 /** 164 * See {@link #setTaskOverlay}. 165 * @hide 166 */ 167 private static final String KEY_TASK_OVERLAY = "android.activity.taskOverlay"; 168 169 /** 170 * Where the docked stack should be positioned. 171 * @hide 172 */ 173 private static final String KEY_DOCK_CREATE_MODE = "android:activity.dockCreateMode"; 174 175 /** 176 * For Activity transitions, the calling Activity's TransitionListener used to 177 * notify the called Activity when the shared element and the exit transitions 178 * complete. 179 */ 180 private static final String KEY_TRANSITION_COMPLETE_LISTENER 181 = "android:activity.transitionCompleteListener"; 182 183 private static final String KEY_TRANSITION_IS_RETURNING 184 = "android:activity.transitionIsReturning"; 185 private static final String KEY_TRANSITION_SHARED_ELEMENTS 186 = "android:activity.sharedElementNames"; 187 private static final String KEY_RESULT_DATA = "android:activity.resultData"; 188 private static final String KEY_RESULT_CODE = "android:activity.resultCode"; 189 private static final String KEY_EXIT_COORDINATOR_INDEX 190 = "android:activity.exitCoordinatorIndex"; 191 192 private static final String KEY_USAGE_TIME_REPORT = "android:activity.usageTimeReport"; 193 194 /** @hide */ 195 public static final int ANIM_NONE = 0; 196 /** @hide */ 197 public static final int ANIM_CUSTOM = 1; 198 /** @hide */ 199 public static final int ANIM_SCALE_UP = 2; 200 /** @hide */ 201 public static final int ANIM_THUMBNAIL_SCALE_UP = 3; 202 /** @hide */ 203 public static final int ANIM_THUMBNAIL_SCALE_DOWN = 4; 204 /** @hide */ 205 public static final int ANIM_SCENE_TRANSITION = 5; 206 /** @hide */ 207 public static final int ANIM_DEFAULT = 6; 208 /** @hide */ 209 public static final int ANIM_LAUNCH_TASK_BEHIND = 7; 210 /** @hide */ 211 public static final int ANIM_THUMBNAIL_ASPECT_SCALE_UP = 8; 212 /** @hide */ 213 public static final int ANIM_THUMBNAIL_ASPECT_SCALE_DOWN = 9; 214 /** @hide */ 215 public static final int ANIM_CUSTOM_IN_PLACE = 10; 216 /** @hide */ 217 public static final int ANIM_CLIP_REVEAL = 11; 218 219 private String mPackageName; 220 private Rect mLaunchBounds; 221 private int mAnimationType = ANIM_NONE; 222 private int mCustomEnterResId; 223 private int mCustomExitResId; 224 private int mCustomInPlaceResId; 225 private Bitmap mThumbnail; 226 private int mStartX; 227 private int mStartY; 228 private int mWidth; 229 private int mHeight; 230 private IRemoteCallback mAnimationStartedListener; 231 private IRemoteCallback mAnimationFinishedListener; 232 private ResultReceiver mTransitionReceiver; 233 private boolean mIsReturning; 234 private ArrayList<String> mSharedElementNames; 235 private Intent mResultData; 236 private int mResultCode; 237 private int mExitCoordinatorIndex; 238 private PendingIntent mUsageTimeReport; 239 private int mLaunchStackId = INVALID_STACK_ID; 240 private int mLaunchTaskId = -1; 241 private int mDockCreateMode = DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT; 242 private boolean mTaskOverlay; 243 private AppTransitionAnimationSpec mAnimSpecs[]; 244 245 /** 246 * Create an ActivityOptions specifying a custom animation to run when 247 * the activity is displayed. 248 * 249 * @param context Who is defining this. This is the application that the 250 * animation resources will be loaded from. 251 * @param enterResId A resource ID of the animation resource to use for 252 * the incoming activity. Use 0 for no animation. 253 * @param exitResId A resource ID of the animation resource to use for 254 * the outgoing activity. Use 0 for no animation. 255 * @return Returns a new ActivityOptions object that you can use to 256 * supply these options as the options Bundle when starting an activity. 257 */ makeCustomAnimation(Context context, int enterResId, int exitResId)258 public static ActivityOptions makeCustomAnimation(Context context, 259 int enterResId, int exitResId) { 260 return makeCustomAnimation(context, enterResId, exitResId, null, null); 261 } 262 263 /** 264 * Create an ActivityOptions specifying a custom animation to run when 265 * the activity is displayed. 266 * 267 * @param context Who is defining this. This is the application that the 268 * animation resources will be loaded from. 269 * @param enterResId A resource ID of the animation resource to use for 270 * the incoming activity. Use 0 for no animation. 271 * @param exitResId A resource ID of the animation resource to use for 272 * the outgoing activity. Use 0 for no animation. 273 * @param handler If <var>listener</var> is non-null this must be a valid 274 * Handler on which to dispatch the callback; otherwise it should be null. 275 * @param listener Optional OnAnimationStartedListener to find out when the 276 * requested animation has started running. If for some reason the animation 277 * is not executed, the callback will happen immediately. 278 * @return Returns a new ActivityOptions object that you can use to 279 * supply these options as the options Bundle when starting an activity. 280 * @hide 281 */ makeCustomAnimation(Context context, int enterResId, int exitResId, Handler handler, OnAnimationStartedListener listener)282 public static ActivityOptions makeCustomAnimation(Context context, 283 int enterResId, int exitResId, Handler handler, OnAnimationStartedListener listener) { 284 ActivityOptions opts = new ActivityOptions(); 285 opts.mPackageName = context.getPackageName(); 286 opts.mAnimationType = ANIM_CUSTOM; 287 opts.mCustomEnterResId = enterResId; 288 opts.mCustomExitResId = exitResId; 289 opts.setOnAnimationStartedListener(handler, listener); 290 return opts; 291 } 292 293 /** 294 * Creates an ActivityOptions specifying a custom animation to run in place on an existing 295 * activity. 296 * 297 * @param context Who is defining this. This is the application that the 298 * animation resources will be loaded from. 299 * @param animId A resource ID of the animation resource to use for 300 * the incoming activity. 301 * @return Returns a new ActivityOptions object that you can use to 302 * supply these options as the options Bundle when running an in-place animation. 303 * @hide 304 */ makeCustomInPlaceAnimation(Context context, int animId)305 public static ActivityOptions makeCustomInPlaceAnimation(Context context, int animId) { 306 if (animId == 0) { 307 throw new RuntimeException("You must specify a valid animation."); 308 } 309 310 ActivityOptions opts = new ActivityOptions(); 311 opts.mPackageName = context.getPackageName(); 312 opts.mAnimationType = ANIM_CUSTOM_IN_PLACE; 313 opts.mCustomInPlaceResId = animId; 314 return opts; 315 } 316 setOnAnimationStartedListener(final Handler handler, final OnAnimationStartedListener listener)317 private void setOnAnimationStartedListener(final Handler handler, 318 final OnAnimationStartedListener listener) { 319 if (listener != null) { 320 mAnimationStartedListener = new IRemoteCallback.Stub() { 321 @Override 322 public void sendResult(Bundle data) throws RemoteException { 323 handler.post(new Runnable() { 324 @Override public void run() { 325 listener.onAnimationStarted(); 326 } 327 }); 328 } 329 }; 330 } 331 } 332 333 /** 334 * Callback for use with {@link ActivityOptions#makeThumbnailScaleUpAnimation} 335 * to find out when the given animation has started running. 336 * @hide 337 */ 338 public interface OnAnimationStartedListener { onAnimationStarted()339 void onAnimationStarted(); 340 } 341 setOnAnimationFinishedListener(final Handler handler, final OnAnimationFinishedListener listener)342 private void setOnAnimationFinishedListener(final Handler handler, 343 final OnAnimationFinishedListener listener) { 344 if (listener != null) { 345 mAnimationFinishedListener = new IRemoteCallback.Stub() { 346 @Override 347 public void sendResult(Bundle data) throws RemoteException { 348 handler.post(new Runnable() { 349 @Override 350 public void run() { 351 listener.onAnimationFinished(); 352 } 353 }); 354 } 355 }; 356 } 357 } 358 359 /** 360 * Callback for use with {@link ActivityOptions#makeThumbnailAspectScaleDownAnimation} 361 * to find out when the given animation has drawn its last frame. 362 * @hide 363 */ 364 public interface OnAnimationFinishedListener { onAnimationFinished()365 void onAnimationFinished(); 366 } 367 368 /** 369 * Create an ActivityOptions specifying an animation where the new 370 * activity is scaled from a small originating area of the screen to 371 * its final full representation. 372 * 373 * <p>If the Intent this is being used with has not set its 374 * {@link android.content.Intent#setSourceBounds Intent.setSourceBounds}, 375 * those bounds will be filled in for you based on the initial 376 * bounds passed in here. 377 * 378 * @param source The View that the new activity is animating from. This 379 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 380 * @param startX The x starting location of the new activity, relative to <var>source</var>. 381 * @param startY The y starting location of the activity, relative to <var>source</var>. 382 * @param width The initial width of the new activity. 383 * @param height The initial height of the new activity. 384 * @return Returns a new ActivityOptions object that you can use to 385 * supply these options as the options Bundle when starting an activity. 386 */ makeScaleUpAnimation(View source, int startX, int startY, int width, int height)387 public static ActivityOptions makeScaleUpAnimation(View source, 388 int startX, int startY, int width, int height) { 389 ActivityOptions opts = new ActivityOptions(); 390 opts.mPackageName = source.getContext().getPackageName(); 391 opts.mAnimationType = ANIM_SCALE_UP; 392 int[] pts = new int[2]; 393 source.getLocationOnScreen(pts); 394 opts.mStartX = pts[0] + startX; 395 opts.mStartY = pts[1] + startY; 396 opts.mWidth = width; 397 opts.mHeight = height; 398 return opts; 399 } 400 401 /** 402 * Create an ActivityOptions specifying an animation where the new 403 * activity is revealed from a small originating area of the screen to 404 * its final full representation. 405 * 406 * @param source The View that the new activity is animating from. This 407 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 408 * @param startX The x starting location of the new activity, relative to <var>source</var>. 409 * @param startY The y starting location of the activity, relative to <var>source</var>. 410 * @param width The initial width of the new activity. 411 * @param height The initial height of the new activity. 412 * @return Returns a new ActivityOptions object that you can use to 413 * supply these options as the options Bundle when starting an activity. 414 */ makeClipRevealAnimation(View source, int startX, int startY, int width, int height)415 public static ActivityOptions makeClipRevealAnimation(View source, 416 int startX, int startY, int width, int height) { 417 ActivityOptions opts = new ActivityOptions(); 418 opts.mAnimationType = ANIM_CLIP_REVEAL; 419 int[] pts = new int[2]; 420 source.getLocationOnScreen(pts); 421 opts.mStartX = pts[0] + startX; 422 opts.mStartY = pts[1] + startY; 423 opts.mWidth = width; 424 opts.mHeight = height; 425 return opts; 426 } 427 428 /** 429 * Create an ActivityOptions specifying an animation where a thumbnail 430 * is scaled from a given position to the new activity window that is 431 * being started. 432 * 433 * <p>If the Intent this is being used with has not set its 434 * {@link android.content.Intent#setSourceBounds Intent.setSourceBounds}, 435 * those bounds will be filled in for you based on the initial 436 * thumbnail location and size provided here. 437 * 438 * @param source The View that this thumbnail is animating from. This 439 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 440 * @param thumbnail The bitmap that will be shown as the initial thumbnail 441 * of the animation. 442 * @param startX The x starting location of the bitmap, relative to <var>source</var>. 443 * @param startY The y starting location of the bitmap, relative to <var>source</var>. 444 * @return Returns a new ActivityOptions object that you can use to 445 * supply these options as the options Bundle when starting an activity. 446 */ makeThumbnailScaleUpAnimation(View source, Bitmap thumbnail, int startX, int startY)447 public static ActivityOptions makeThumbnailScaleUpAnimation(View source, 448 Bitmap thumbnail, int startX, int startY) { 449 return makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY, null); 450 } 451 452 /** 453 * Create an ActivityOptions specifying an animation where a thumbnail 454 * is scaled from a given position to the new activity window that is 455 * being started. 456 * 457 * @param source The View that this thumbnail is animating from. This 458 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 459 * @param thumbnail The bitmap that will be shown as the initial thumbnail 460 * of the animation. 461 * @param startX The x starting location of the bitmap, relative to <var>source</var>. 462 * @param startY The y starting location of the bitmap, relative to <var>source</var>. 463 * @param listener Optional OnAnimationStartedListener to find out when the 464 * requested animation has started running. If for some reason the animation 465 * is not executed, the callback will happen immediately. 466 * @return Returns a new ActivityOptions object that you can use to 467 * supply these options as the options Bundle when starting an activity. 468 * @hide 469 */ makeThumbnailScaleUpAnimation(View source, Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener)470 public static ActivityOptions makeThumbnailScaleUpAnimation(View source, 471 Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) { 472 return makeThumbnailAnimation(source, thumbnail, startX, startY, listener, true); 473 } 474 475 /** 476 * Create an ActivityOptions specifying an animation where an activity window 477 * is scaled from a given position to a thumbnail at a specified location. 478 * 479 * @param source The View that this thumbnail is animating to. This 480 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 481 * @param thumbnail The bitmap that will be shown as the final thumbnail 482 * of the animation. 483 * @param startX The x end location of the bitmap, relative to <var>source</var>. 484 * @param startY The y end location of the bitmap, relative to <var>source</var>. 485 * @param listener Optional OnAnimationStartedListener to find out when the 486 * requested animation has started running. If for some reason the animation 487 * is not executed, the callback will happen immediately. 488 * @return Returns a new ActivityOptions object that you can use to 489 * supply these options as the options Bundle when starting an activity. 490 * @hide 491 */ makeThumbnailScaleDownAnimation(View source, Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener)492 public static ActivityOptions makeThumbnailScaleDownAnimation(View source, 493 Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) { 494 return makeThumbnailAnimation(source, thumbnail, startX, startY, listener, false); 495 } 496 makeThumbnailAnimation(View source, Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener, boolean scaleUp)497 private static ActivityOptions makeThumbnailAnimation(View source, 498 Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener, 499 boolean scaleUp) { 500 ActivityOptions opts = new ActivityOptions(); 501 opts.mPackageName = source.getContext().getPackageName(); 502 opts.mAnimationType = scaleUp ? ANIM_THUMBNAIL_SCALE_UP : ANIM_THUMBNAIL_SCALE_DOWN; 503 opts.mThumbnail = thumbnail; 504 int[] pts = new int[2]; 505 source.getLocationOnScreen(pts); 506 opts.mStartX = pts[0] + startX; 507 opts.mStartY = pts[1] + startY; 508 opts.setOnAnimationStartedListener(source.getHandler(), listener); 509 return opts; 510 } 511 512 /** 513 * Create an ActivityOptions specifying an animation where the new activity 514 * window and a thumbnail is aspect-scaled to a new location. 515 * 516 * @param source The View that this thumbnail is animating from. This 517 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 518 * @param thumbnail The bitmap that will be shown as the initial thumbnail 519 * of the animation. 520 * @param startX The x starting location of the bitmap, relative to <var>source</var>. 521 * @param startY The y starting location of the bitmap, relative to <var>source</var>. 522 * @param handler If <var>listener</var> is non-null this must be a valid 523 * Handler on which to dispatch the callback; otherwise it should be null. 524 * @param listener Optional OnAnimationStartedListener to find out when the 525 * requested animation has started running. If for some reason the animation 526 * is not executed, the callback will happen immediately. 527 * @return Returns a new ActivityOptions object that you can use to 528 * supply these options as the options Bundle when starting an activity. 529 * @hide 530 */ makeThumbnailAspectScaleUpAnimation(View source, Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight, Handler handler, OnAnimationStartedListener listener)531 public static ActivityOptions makeThumbnailAspectScaleUpAnimation(View source, 532 Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight, 533 Handler handler, OnAnimationStartedListener listener) { 534 return makeAspectScaledThumbnailAnimation(source, thumbnail, startX, startY, 535 targetWidth, targetHeight, handler, listener, true); 536 } 537 538 /** 539 * Create an ActivityOptions specifying an animation where the new activity 540 * window and a thumbnail is aspect-scaled to a new location. 541 * 542 * @param source The View that this thumbnail is animating to. This 543 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 544 * @param thumbnail The bitmap that will be shown as the final thumbnail 545 * of the animation. 546 * @param startX The x end location of the bitmap, relative to <var>source</var>. 547 * @param startY The y end location of the bitmap, relative to <var>source</var>. 548 * @param handler If <var>listener</var> is non-null this must be a valid 549 * Handler on which to dispatch the callback; otherwise it should be null. 550 * @param listener Optional OnAnimationStartedListener to find out when the 551 * requested animation has started running. If for some reason the animation 552 * is not executed, the callback will happen immediately. 553 * @return Returns a new ActivityOptions object that you can use to 554 * supply these options as the options Bundle when starting an activity. 555 * @hide 556 */ makeThumbnailAspectScaleDownAnimation(View source, Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight, Handler handler, OnAnimationStartedListener listener)557 public static ActivityOptions makeThumbnailAspectScaleDownAnimation(View source, 558 Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight, 559 Handler handler, OnAnimationStartedListener listener) { 560 return makeAspectScaledThumbnailAnimation(source, thumbnail, startX, startY, 561 targetWidth, targetHeight, handler, listener, false); 562 } 563 makeAspectScaledThumbnailAnimation(View source, Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight, Handler handler, OnAnimationStartedListener listener, boolean scaleUp)564 private static ActivityOptions makeAspectScaledThumbnailAnimation(View source, Bitmap thumbnail, 565 int startX, int startY, int targetWidth, int targetHeight, 566 Handler handler, OnAnimationStartedListener listener, boolean scaleUp) { 567 ActivityOptions opts = new ActivityOptions(); 568 opts.mPackageName = source.getContext().getPackageName(); 569 opts.mAnimationType = scaleUp ? ANIM_THUMBNAIL_ASPECT_SCALE_UP : 570 ANIM_THUMBNAIL_ASPECT_SCALE_DOWN; 571 opts.mThumbnail = thumbnail; 572 int[] pts = new int[2]; 573 source.getLocationOnScreen(pts); 574 opts.mStartX = pts[0] + startX; 575 opts.mStartY = pts[1] + startY; 576 opts.mWidth = targetWidth; 577 opts.mHeight = targetHeight; 578 opts.setOnAnimationStartedListener(handler, listener); 579 return opts; 580 } 581 582 /** @hide */ makeThumbnailAspectScaleDownAnimation(View source, AppTransitionAnimationSpec[] specs, Handler handler, OnAnimationStartedListener onAnimationStartedListener, OnAnimationFinishedListener onAnimationFinishedListener)583 public static ActivityOptions makeThumbnailAspectScaleDownAnimation(View source, 584 AppTransitionAnimationSpec[] specs, Handler handler, 585 OnAnimationStartedListener onAnimationStartedListener, 586 OnAnimationFinishedListener onAnimationFinishedListener) { 587 ActivityOptions opts = new ActivityOptions(); 588 opts.mPackageName = source.getContext().getPackageName(); 589 opts.mAnimationType = ANIM_THUMBNAIL_ASPECT_SCALE_DOWN; 590 opts.mAnimSpecs = specs; 591 opts.setOnAnimationStartedListener(handler, onAnimationStartedListener); 592 opts.setOnAnimationFinishedListener(handler, onAnimationFinishedListener); 593 return opts; 594 } 595 596 /** 597 * Create an ActivityOptions to transition between Activities using cross-Activity scene 598 * animations. This method carries the position of one shared element to the started Activity. 599 * The position of <code>sharedElement</code> will be used as the epicenter for the 600 * exit Transition. The position of the shared element in the launched Activity will be the 601 * epicenter of its entering Transition. 602 * 603 * <p>This requires {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS} to be 604 * enabled on the calling Activity to cause an exit transition. The same must be in 605 * the called Activity to get an entering transition.</p> 606 * @param activity The Activity whose window contains the shared elements. 607 * @param sharedElement The View to transition to the started Activity. 608 * @param sharedElementName The shared element name as used in the target Activity. This 609 * must not be null. 610 * @return Returns a new ActivityOptions object that you can use to 611 * supply these options as the options Bundle when starting an activity. 612 * @see android.transition.Transition#setEpicenterCallback( 613 * android.transition.Transition.EpicenterCallback) 614 */ makeSceneTransitionAnimation(Activity activity, View sharedElement, String sharedElementName)615 public static ActivityOptions makeSceneTransitionAnimation(Activity activity, 616 View sharedElement, String sharedElementName) { 617 return makeSceneTransitionAnimation(activity, Pair.create(sharedElement, sharedElementName)); 618 } 619 620 /** 621 * Create an ActivityOptions to transition between Activities using cross-Activity scene 622 * animations. This method carries the position of multiple shared elements to the started 623 * Activity. The position of the first element in sharedElements 624 * will be used as the epicenter for the exit Transition. The position of the associated 625 * shared element in the launched Activity will be the epicenter of its entering Transition. 626 * 627 * <p>This requires {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS} to be 628 * enabled on the calling Activity to cause an exit transition. The same must be in 629 * the called Activity to get an entering transition.</p> 630 * @param activity The Activity whose window contains the shared elements. 631 * @param sharedElements The names of the shared elements to transfer to the called 632 * Activity and their associated Views. The Views must each have 633 * a unique shared element name. 634 * @return Returns a new ActivityOptions object that you can use to 635 * supply these options as the options Bundle when starting an activity. 636 * @see android.transition.Transition#setEpicenterCallback( 637 * android.transition.Transition.EpicenterCallback) 638 */ 639 @SafeVarargs makeSceneTransitionAnimation(Activity activity, Pair<View, String>... sharedElements)640 public static ActivityOptions makeSceneTransitionAnimation(Activity activity, 641 Pair<View, String>... sharedElements) { 642 ActivityOptions opts = new ActivityOptions(); 643 if (!activity.getWindow().hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)) { 644 opts.mAnimationType = ANIM_DEFAULT; 645 return opts; 646 } 647 opts.mAnimationType = ANIM_SCENE_TRANSITION; 648 649 ArrayList<String> names = new ArrayList<String>(); 650 ArrayList<View> views = new ArrayList<View>(); 651 652 if (sharedElements != null) { 653 for (int i = 0; i < sharedElements.length; i++) { 654 Pair<View, String> sharedElement = sharedElements[i]; 655 String sharedElementName = sharedElement.second; 656 if (sharedElementName == null) { 657 throw new IllegalArgumentException("Shared element name must not be null"); 658 } 659 names.add(sharedElementName); 660 View view = sharedElement.first; 661 if (view == null) { 662 throw new IllegalArgumentException("Shared element must not be null"); 663 } 664 views.add(sharedElement.first); 665 } 666 } 667 668 ExitTransitionCoordinator exit = new ExitTransitionCoordinator(activity, names, names, 669 views, false); 670 opts.mTransitionReceiver = exit; 671 opts.mSharedElementNames = names; 672 opts.mIsReturning = false; 673 opts.mExitCoordinatorIndex = 674 activity.mActivityTransitionState.addExitTransitionCoordinator(exit); 675 return opts; 676 } 677 678 /** @hide */ makeSceneTransitionAnimation(Activity activity, ExitTransitionCoordinator exitCoordinator, ArrayList<String> sharedElementNames, int resultCode, Intent resultData)679 public static ActivityOptions makeSceneTransitionAnimation(Activity activity, 680 ExitTransitionCoordinator exitCoordinator, ArrayList<String> sharedElementNames, 681 int resultCode, Intent resultData) { 682 ActivityOptions opts = new ActivityOptions(); 683 opts.mAnimationType = ANIM_SCENE_TRANSITION; 684 opts.mSharedElementNames = sharedElementNames; 685 opts.mTransitionReceiver = exitCoordinator; 686 opts.mIsReturning = true; 687 opts.mResultCode = resultCode; 688 opts.mResultData = resultData; 689 opts.mExitCoordinatorIndex = 690 activity.mActivityTransitionState.addExitTransitionCoordinator(exitCoordinator); 691 return opts; 692 } 693 694 /** 695 * If set along with Intent.FLAG_ACTIVITY_NEW_DOCUMENT then the task being launched will not be 696 * presented to the user but will instead be only available through the recents task list. 697 * In addition, the new task wil be affiliated with the launching activity's task. 698 * Affiliated tasks are grouped together in the recents task list. 699 * 700 * <p>This behavior is not supported for activities with {@link 701 * android.R.styleable#AndroidManifestActivity_launchMode launchMode} values of 702 * <code>singleInstance</code> or <code>singleTask</code>. 703 */ makeTaskLaunchBehind()704 public static ActivityOptions makeTaskLaunchBehind() { 705 final ActivityOptions opts = new ActivityOptions(); 706 opts.mAnimationType = ANIM_LAUNCH_TASK_BEHIND; 707 return opts; 708 } 709 710 /** 711 * Create a basic ActivityOptions that has no special animation associated with it. 712 * Other options can still be set. 713 */ makeBasic()714 public static ActivityOptions makeBasic() { 715 final ActivityOptions opts = new ActivityOptions(); 716 return opts; 717 } 718 719 /** @hide */ getLaunchTaskBehind()720 public boolean getLaunchTaskBehind() { 721 return mAnimationType == ANIM_LAUNCH_TASK_BEHIND; 722 } 723 ActivityOptions()724 private ActivityOptions() { 725 } 726 727 /** @hide */ ActivityOptions(Bundle opts)728 public ActivityOptions(Bundle opts) { 729 // If the remote side sent us bad parcelables, they won't get the 730 // results they want, which is their loss. 731 opts.setDefusable(true); 732 733 mPackageName = opts.getString(KEY_PACKAGE_NAME); 734 try { 735 mUsageTimeReport = opts.getParcelable(KEY_USAGE_TIME_REPORT); 736 } catch (RuntimeException e) { 737 Slog.w(TAG, e); 738 } 739 mLaunchBounds = opts.getParcelable(KEY_LAUNCH_BOUNDS); 740 mAnimationType = opts.getInt(KEY_ANIM_TYPE); 741 switch (mAnimationType) { 742 case ANIM_CUSTOM: 743 mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0); 744 mCustomExitResId = opts.getInt(KEY_ANIM_EXIT_RES_ID, 0); 745 mAnimationStartedListener = IRemoteCallback.Stub.asInterface( 746 opts.getBinder(KEY_ANIM_START_LISTENER)); 747 break; 748 749 case ANIM_CUSTOM_IN_PLACE: 750 mCustomInPlaceResId = opts.getInt(KEY_ANIM_IN_PLACE_RES_ID, 0); 751 break; 752 753 case ANIM_SCALE_UP: 754 case ANIM_CLIP_REVEAL: 755 mStartX = opts.getInt(KEY_ANIM_START_X, 0); 756 mStartY = opts.getInt(KEY_ANIM_START_Y, 0); 757 mWidth = opts.getInt(KEY_ANIM_WIDTH, 0); 758 mHeight = opts.getInt(KEY_ANIM_HEIGHT, 0); 759 break; 760 761 case ANIM_THUMBNAIL_SCALE_UP: 762 case ANIM_THUMBNAIL_SCALE_DOWN: 763 case ANIM_THUMBNAIL_ASPECT_SCALE_UP: 764 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN: 765 mThumbnail = (Bitmap) opts.getParcelable(KEY_ANIM_THUMBNAIL); 766 mStartX = opts.getInt(KEY_ANIM_START_X, 0); 767 mStartY = opts.getInt(KEY_ANIM_START_Y, 0); 768 mWidth = opts.getInt(KEY_ANIM_WIDTH, 0); 769 mHeight = opts.getInt(KEY_ANIM_HEIGHT, 0); 770 mAnimationStartedListener = IRemoteCallback.Stub.asInterface( 771 opts.getBinder(KEY_ANIM_START_LISTENER)); 772 break; 773 774 case ANIM_SCENE_TRANSITION: 775 mTransitionReceiver = opts.getParcelable(KEY_TRANSITION_COMPLETE_LISTENER); 776 mIsReturning = opts.getBoolean(KEY_TRANSITION_IS_RETURNING, false); 777 mSharedElementNames = opts.getStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS); 778 mResultData = opts.getParcelable(KEY_RESULT_DATA); 779 mResultCode = opts.getInt(KEY_RESULT_CODE); 780 mExitCoordinatorIndex = opts.getInt(KEY_EXIT_COORDINATOR_INDEX); 781 break; 782 } 783 mLaunchStackId = opts.getInt(KEY_LAUNCH_STACK_ID, INVALID_STACK_ID); 784 mLaunchTaskId = opts.getInt(KEY_LAUNCH_TASK_ID, -1); 785 mTaskOverlay = opts.getBoolean(KEY_TASK_OVERLAY, false); 786 mDockCreateMode = opts.getInt(KEY_DOCK_CREATE_MODE, DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT); 787 if (opts.containsKey(KEY_ANIM_SPECS)) { 788 Parcelable[] specs = opts.getParcelableArray(KEY_ANIM_SPECS); 789 mAnimSpecs = new AppTransitionAnimationSpec[specs.length]; 790 for (int i = specs.length - 1; i >= 0; i--) { 791 mAnimSpecs[i] = (AppTransitionAnimationSpec) specs[i]; 792 } 793 } 794 if (opts.containsKey(KEY_ANIMATION_FINISHED_LISTENER)) { 795 mAnimationFinishedListener = IRemoteCallback.Stub.asInterface( 796 opts.getBinder(KEY_ANIMATION_FINISHED_LISTENER)); 797 } 798 } 799 800 /** 801 * Sets the bounds (window size) that the activity should be launched in. 802 * Rect position should be provided in pixels and in screen coordinates. 803 * Set to null explicitly for fullscreen. 804 * <p> 805 * <strong>NOTE:<strong/> This value is ignored on devices that don't have 806 * {@link android.content.pm.PackageManager#FEATURE_FREEFORM_WINDOW_MANAGEMENT} or 807 * {@link android.content.pm.PackageManager#FEATURE_PICTURE_IN_PICTURE} enabled. 808 * @param screenSpacePixelRect Launch bounds to use for the activity or null for fullscreen. 809 */ setLaunchBounds(@ullable Rect screenSpacePixelRect)810 public ActivityOptions setLaunchBounds(@Nullable Rect screenSpacePixelRect) { 811 mLaunchBounds = screenSpacePixelRect != null ? new Rect(screenSpacePixelRect) : null; 812 return this; 813 } 814 815 /** @hide */ getPackageName()816 public String getPackageName() { 817 return mPackageName; 818 } 819 820 /** 821 * Returns the bounds that should be used to launch the activity. 822 * @see #setLaunchBounds(Rect) 823 * @return Bounds used to launch the activity. 824 */ 825 @Nullable getLaunchBounds()826 public Rect getLaunchBounds() { 827 return mLaunchBounds; 828 } 829 830 /** @hide */ getAnimationType()831 public int getAnimationType() { 832 return mAnimationType; 833 } 834 835 /** @hide */ getCustomEnterResId()836 public int getCustomEnterResId() { 837 return mCustomEnterResId; 838 } 839 840 /** @hide */ getCustomExitResId()841 public int getCustomExitResId() { 842 return mCustomExitResId; 843 } 844 845 /** @hide */ getCustomInPlaceResId()846 public int getCustomInPlaceResId() { 847 return mCustomInPlaceResId; 848 } 849 850 /** @hide */ getThumbnail()851 public Bitmap getThumbnail() { 852 return mThumbnail; 853 } 854 855 /** @hide */ getStartX()856 public int getStartX() { 857 return mStartX; 858 } 859 860 /** @hide */ getStartY()861 public int getStartY() { 862 return mStartY; 863 } 864 865 /** @hide */ getWidth()866 public int getWidth() { 867 return mWidth; 868 } 869 870 /** @hide */ getHeight()871 public int getHeight() { 872 return mHeight; 873 } 874 875 /** @hide */ getOnAnimationStartListener()876 public IRemoteCallback getOnAnimationStartListener() { 877 return mAnimationStartedListener; 878 } 879 880 /** @hide */ getAnimationFinishedListener()881 public IRemoteCallback getAnimationFinishedListener() { 882 return mAnimationFinishedListener; 883 } 884 885 /** @hide */ getExitCoordinatorKey()886 public int getExitCoordinatorKey() { return mExitCoordinatorIndex; } 887 888 /** @hide */ abort()889 public void abort() { 890 if (mAnimationStartedListener != null) { 891 try { 892 mAnimationStartedListener.sendResult(null); 893 } catch (RemoteException e) { 894 } 895 } 896 } 897 898 /** @hide */ isReturning()899 public boolean isReturning() { 900 return mIsReturning; 901 } 902 903 /** @hide */ getSharedElementNames()904 public ArrayList<String> getSharedElementNames() { 905 return mSharedElementNames; 906 } 907 908 /** @hide */ getResultReceiver()909 public ResultReceiver getResultReceiver() { return mTransitionReceiver; } 910 911 /** @hide */ getResultCode()912 public int getResultCode() { return mResultCode; } 913 914 /** @hide */ getResultData()915 public Intent getResultData() { return mResultData; } 916 917 /** @hide */ getUsageTimeReport()918 public PendingIntent getUsageTimeReport() { 919 return mUsageTimeReport; 920 } 921 922 /** @hide */ getAnimSpecs()923 public AppTransitionAnimationSpec[] getAnimSpecs() { return mAnimSpecs; } 924 925 /** @hide */ fromBundle(Bundle bOptions)926 public static ActivityOptions fromBundle(Bundle bOptions) { 927 return bOptions != null ? new ActivityOptions(bOptions) : null; 928 } 929 930 /** @hide */ abort(ActivityOptions options)931 public static void abort(ActivityOptions options) { 932 if (options != null) { 933 options.abort(); 934 } 935 } 936 937 /** @hide */ getLaunchStackId()938 public int getLaunchStackId() { 939 return mLaunchStackId; 940 } 941 942 /** @hide */ 943 @TestApi setLaunchStackId(int launchStackId)944 public void setLaunchStackId(int launchStackId) { 945 mLaunchStackId = launchStackId; 946 } 947 948 /** 949 * Sets the task the activity will be launched in. 950 * @hide 951 */ setLaunchTaskId(int taskId)952 public void setLaunchTaskId(int taskId) { 953 mLaunchTaskId = taskId; 954 } 955 956 /** 957 * @hide 958 */ getLaunchTaskId()959 public int getLaunchTaskId() { 960 return mLaunchTaskId; 961 } 962 963 /** 964 * Set's whether the activity launched with this option should be a task overlay. That is the 965 * activity will always be the top activity of the task and doesn't cause the task to be moved 966 * to the front when it is added. 967 * @hide 968 */ setTaskOverlay(boolean taskOverlay)969 public void setTaskOverlay(boolean taskOverlay) { 970 mTaskOverlay = taskOverlay; 971 } 972 973 /** 974 * @hide 975 */ getTaskOverlay()976 public boolean getTaskOverlay() { 977 return mTaskOverlay; 978 } 979 980 /** @hide */ getDockCreateMode()981 public int getDockCreateMode() { 982 return mDockCreateMode; 983 } 984 985 /** @hide */ setDockCreateMode(int dockCreateMode)986 public void setDockCreateMode(int dockCreateMode) { 987 mDockCreateMode = dockCreateMode; 988 } 989 990 /** 991 * Update the current values in this ActivityOptions from those supplied 992 * in <var>otherOptions</var>. Any values 993 * defined in <var>otherOptions</var> replace those in the base options. 994 */ update(ActivityOptions otherOptions)995 public void update(ActivityOptions otherOptions) { 996 if (otherOptions.mPackageName != null) { 997 mPackageName = otherOptions.mPackageName; 998 } 999 mUsageTimeReport = otherOptions.mUsageTimeReport; 1000 mTransitionReceiver = null; 1001 mSharedElementNames = null; 1002 mIsReturning = false; 1003 mResultData = null; 1004 mResultCode = 0; 1005 mExitCoordinatorIndex = 0; 1006 mAnimationType = otherOptions.mAnimationType; 1007 switch (otherOptions.mAnimationType) { 1008 case ANIM_CUSTOM: 1009 mCustomEnterResId = otherOptions.mCustomEnterResId; 1010 mCustomExitResId = otherOptions.mCustomExitResId; 1011 mThumbnail = null; 1012 if (mAnimationStartedListener != null) { 1013 try { 1014 mAnimationStartedListener.sendResult(null); 1015 } catch (RemoteException e) { 1016 } 1017 } 1018 mAnimationStartedListener = otherOptions.mAnimationStartedListener; 1019 break; 1020 case ANIM_CUSTOM_IN_PLACE: 1021 mCustomInPlaceResId = otherOptions.mCustomInPlaceResId; 1022 break; 1023 case ANIM_SCALE_UP: 1024 mStartX = otherOptions.mStartX; 1025 mStartY = otherOptions.mStartY; 1026 mWidth = otherOptions.mWidth; 1027 mHeight = otherOptions.mHeight; 1028 if (mAnimationStartedListener != null) { 1029 try { 1030 mAnimationStartedListener.sendResult(null); 1031 } catch (RemoteException e) { 1032 } 1033 } 1034 mAnimationStartedListener = null; 1035 break; 1036 case ANIM_THUMBNAIL_SCALE_UP: 1037 case ANIM_THUMBNAIL_SCALE_DOWN: 1038 case ANIM_THUMBNAIL_ASPECT_SCALE_UP: 1039 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN: 1040 mThumbnail = otherOptions.mThumbnail; 1041 mStartX = otherOptions.mStartX; 1042 mStartY = otherOptions.mStartY; 1043 mWidth = otherOptions.mWidth; 1044 mHeight = otherOptions.mHeight; 1045 if (mAnimationStartedListener != null) { 1046 try { 1047 mAnimationStartedListener.sendResult(null); 1048 } catch (RemoteException e) { 1049 } 1050 } 1051 mAnimationStartedListener = otherOptions.mAnimationStartedListener; 1052 break; 1053 case ANIM_SCENE_TRANSITION: 1054 mTransitionReceiver = otherOptions.mTransitionReceiver; 1055 mSharedElementNames = otherOptions.mSharedElementNames; 1056 mIsReturning = otherOptions.mIsReturning; 1057 mThumbnail = null; 1058 mAnimationStartedListener = null; 1059 mResultData = otherOptions.mResultData; 1060 mResultCode = otherOptions.mResultCode; 1061 mExitCoordinatorIndex = otherOptions.mExitCoordinatorIndex; 1062 break; 1063 } 1064 mAnimSpecs = otherOptions.mAnimSpecs; 1065 mAnimationFinishedListener = otherOptions.mAnimationFinishedListener; 1066 } 1067 1068 /** 1069 * Returns the created options as a Bundle, which can be passed to 1070 * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle) 1071 * Context.startActivity(Intent, Bundle)} and related methods. 1072 * Note that the returned Bundle is still owned by the ActivityOptions 1073 * object; you must not modify it, but can supply it to the startActivity 1074 * methods that take an options Bundle. 1075 */ toBundle()1076 public Bundle toBundle() { 1077 if (mAnimationType == ANIM_DEFAULT) { 1078 return null; 1079 } 1080 Bundle b = new Bundle(); 1081 if (mPackageName != null) { 1082 b.putString(KEY_PACKAGE_NAME, mPackageName); 1083 } 1084 if (mLaunchBounds != null) { 1085 b.putParcelable(KEY_LAUNCH_BOUNDS, mLaunchBounds); 1086 } 1087 b.putInt(KEY_ANIM_TYPE, mAnimationType); 1088 if (mUsageTimeReport != null) { 1089 b.putParcelable(KEY_USAGE_TIME_REPORT, mUsageTimeReport); 1090 } 1091 switch (mAnimationType) { 1092 case ANIM_CUSTOM: 1093 b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId); 1094 b.putInt(KEY_ANIM_EXIT_RES_ID, mCustomExitResId); 1095 b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener 1096 != null ? mAnimationStartedListener.asBinder() : null); 1097 break; 1098 case ANIM_CUSTOM_IN_PLACE: 1099 b.putInt(KEY_ANIM_IN_PLACE_RES_ID, mCustomInPlaceResId); 1100 break; 1101 case ANIM_SCALE_UP: 1102 case ANIM_CLIP_REVEAL: 1103 b.putInt(KEY_ANIM_START_X, mStartX); 1104 b.putInt(KEY_ANIM_START_Y, mStartY); 1105 b.putInt(KEY_ANIM_WIDTH, mWidth); 1106 b.putInt(KEY_ANIM_HEIGHT, mHeight); 1107 break; 1108 case ANIM_THUMBNAIL_SCALE_UP: 1109 case ANIM_THUMBNAIL_SCALE_DOWN: 1110 case ANIM_THUMBNAIL_ASPECT_SCALE_UP: 1111 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN: 1112 b.putParcelable(KEY_ANIM_THUMBNAIL, mThumbnail); 1113 b.putInt(KEY_ANIM_START_X, mStartX); 1114 b.putInt(KEY_ANIM_START_Y, mStartY); 1115 b.putInt(KEY_ANIM_WIDTH, mWidth); 1116 b.putInt(KEY_ANIM_HEIGHT, mHeight); 1117 b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener 1118 != null ? mAnimationStartedListener.asBinder() : null); 1119 break; 1120 case ANIM_SCENE_TRANSITION: 1121 if (mTransitionReceiver != null) { 1122 b.putParcelable(KEY_TRANSITION_COMPLETE_LISTENER, mTransitionReceiver); 1123 } 1124 b.putBoolean(KEY_TRANSITION_IS_RETURNING, mIsReturning); 1125 b.putStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS, mSharedElementNames); 1126 b.putParcelable(KEY_RESULT_DATA, mResultData); 1127 b.putInt(KEY_RESULT_CODE, mResultCode); 1128 b.putInt(KEY_EXIT_COORDINATOR_INDEX, mExitCoordinatorIndex); 1129 break; 1130 } 1131 b.putInt(KEY_LAUNCH_STACK_ID, mLaunchStackId); 1132 b.putInt(KEY_LAUNCH_TASK_ID, mLaunchTaskId); 1133 b.putBoolean(KEY_TASK_OVERLAY, mTaskOverlay); 1134 b.putInt(KEY_DOCK_CREATE_MODE, mDockCreateMode); 1135 if (mAnimSpecs != null) { 1136 b.putParcelableArray(KEY_ANIM_SPECS, mAnimSpecs); 1137 } 1138 if (mAnimationFinishedListener != null) { 1139 b.putBinder(KEY_ANIMATION_FINISHED_LISTENER, mAnimationFinishedListener.asBinder()); 1140 } 1141 1142 return b; 1143 } 1144 1145 /** 1146 * Ask the the system track that time the user spends in the app being launched, and 1147 * report it back once done. The report will be sent to the given receiver, with 1148 * the extras {@link #EXTRA_USAGE_TIME_REPORT} and {@link #EXTRA_USAGE_TIME_REPORT_PACKAGES} 1149 * filled in. 1150 * 1151 * <p>The time interval tracked is from launching this activity until the user leaves 1152 * that activity's flow. They are considered to stay in the flow as long as 1153 * new activities are being launched or returned to from the original flow, 1154 * even if this crosses package or task boundaries. For example, if the originator 1155 * starts an activity to view an image, and while there the user selects to share, 1156 * which launches their email app in a new task, and they complete the share, the 1157 * time during that entire operation will be included until they finally hit back from 1158 * the original image viewer activity.</p> 1159 * 1160 * <p>The user is considered to complete a flow once they switch to another 1161 * activity that is not part of the tracked flow. This may happen, for example, by 1162 * using the notification shade, launcher, or recents to launch or switch to another 1163 * app. Simply going in to these navigation elements does not break the flow (although 1164 * the launcher and recents stops time tracking of the session); it is the act of 1165 * going somewhere else that completes the tracking.</p> 1166 * 1167 * @param receiver A broadcast receiver that willl receive the report. 1168 */ requestUsageTimeReport(PendingIntent receiver)1169 public void requestUsageTimeReport(PendingIntent receiver) { 1170 mUsageTimeReport = receiver; 1171 } 1172 1173 /** 1174 * Return the filtered options only meant to be seen by the target activity itself 1175 * @hide 1176 */ forTargetActivity()1177 public ActivityOptions forTargetActivity() { 1178 if (mAnimationType == ANIM_SCENE_TRANSITION) { 1179 final ActivityOptions result = new ActivityOptions(); 1180 result.update(this); 1181 return result; 1182 } 1183 1184 return null; 1185 } 1186 1187 /** @hide */ 1188 @Override toString()1189 public String toString() { 1190 return "ActivityOptions(" + hashCode() + "), mPackageName=" + mPackageName 1191 + ", mAnimationType=" + mAnimationType + ", mStartX=" + mStartX + ", mStartY=" 1192 + mStartY + ", mWidth=" + mWidth + ", mHeight=" + mHeight; 1193 } 1194 } 1195