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 android.content.Context; 20 import android.content.Intent; 21 import android.graphics.Bitmap; 22 import android.os.Bundle; 23 import android.os.Handler; 24 import android.os.IRemoteCallback; 25 import android.os.RemoteException; 26 import android.os.ResultReceiver; 27 import android.util.Pair; 28 import android.view.View; 29 import android.view.Window; 30 31 import java.util.ArrayList; 32 33 /** 34 * Helper class for building an options Bundle that can be used with 35 * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle) 36 * Context.startActivity(Intent, Bundle)} and related methods. 37 */ 38 public class ActivityOptions { 39 private static final String TAG = "ActivityOptions"; 40 41 /** 42 * The package name that created the options. 43 * @hide 44 */ 45 public static final String KEY_PACKAGE_NAME = "android:packageName"; 46 47 /** 48 * Type of animation that arguments specify. 49 * @hide 50 */ 51 public static final String KEY_ANIM_TYPE = "android:animType"; 52 53 /** 54 * Custom enter animation resource ID. 55 * @hide 56 */ 57 public static final String KEY_ANIM_ENTER_RES_ID = "android:animEnterRes"; 58 59 /** 60 * Custom exit animation resource ID. 61 * @hide 62 */ 63 public static final String KEY_ANIM_EXIT_RES_ID = "android:animExitRes"; 64 65 /** 66 * Bitmap for thumbnail animation. 67 * @hide 68 */ 69 public static final String KEY_ANIM_THUMBNAIL = "android:animThumbnail"; 70 71 /** 72 * Start X position of thumbnail animation. 73 * @hide 74 */ 75 public static final String KEY_ANIM_START_X = "android:animStartX"; 76 77 /** 78 * Start Y position of thumbnail animation. 79 * @hide 80 */ 81 public static final String KEY_ANIM_START_Y = "android:animStartY"; 82 83 /** 84 * Initial width of the animation. 85 * @hide 86 */ 87 public static final String KEY_ANIM_WIDTH = "android:animWidth"; 88 89 /** 90 * Initial height of the animation. 91 * @hide 92 */ 93 public static final String KEY_ANIM_HEIGHT = "android:animHeight"; 94 95 /** 96 * Callback for when animation is started. 97 * @hide 98 */ 99 public static final String KEY_ANIM_START_LISTENER = "android:animStartListener"; 100 101 /** 102 * For Activity transitions, the calling Activity's TransitionListener used to 103 * notify the called Activity when the shared element and the exit transitions 104 * complete. 105 */ 106 private static final String KEY_TRANSITION_COMPLETE_LISTENER 107 = "android:transitionCompleteListener"; 108 109 private static final String KEY_TRANSITION_IS_RETURNING = "android:transitionIsReturning"; 110 private static final String KEY_TRANSITION_SHARED_ELEMENTS = "android:sharedElementNames"; 111 private static final String KEY_RESULT_DATA = "android:resultData"; 112 private static final String KEY_RESULT_CODE = "android:resultCode"; 113 private static final String KEY_EXIT_COORDINATOR_INDEX = "android:exitCoordinatorIndex"; 114 115 /** @hide */ 116 public static final int ANIM_NONE = 0; 117 /** @hide */ 118 public static final int ANIM_CUSTOM = 1; 119 /** @hide */ 120 public static final int ANIM_SCALE_UP = 2; 121 /** @hide */ 122 public static final int ANIM_THUMBNAIL_SCALE_UP = 3; 123 /** @hide */ 124 public static final int ANIM_THUMBNAIL_SCALE_DOWN = 4; 125 /** @hide */ 126 public static final int ANIM_SCENE_TRANSITION = 5; 127 /** @hide */ 128 public static final int ANIM_DEFAULT = 6; 129 /** @hide */ 130 public static final int ANIM_LAUNCH_TASK_BEHIND = 7; 131 /** @hide */ 132 public static final int ANIM_THUMBNAIL_ASPECT_SCALE_UP = 8; 133 /** @hide */ 134 public static final int ANIM_THUMBNAIL_ASPECT_SCALE_DOWN = 9; 135 136 private String mPackageName; 137 private int mAnimationType = ANIM_NONE; 138 private int mCustomEnterResId; 139 private int mCustomExitResId; 140 private Bitmap mThumbnail; 141 private int mStartX; 142 private int mStartY; 143 private int mWidth; 144 private int mHeight; 145 private IRemoteCallback mAnimationStartedListener; 146 private ResultReceiver mTransitionReceiver; 147 private boolean mIsReturning; 148 private ArrayList<String> mSharedElementNames; 149 private Intent mResultData; 150 private int mResultCode; 151 private int mExitCoordinatorIndex; 152 153 /** 154 * Create an ActivityOptions specifying a custom animation to run when 155 * the activity is displayed. 156 * 157 * @param context Who is defining this. This is the application that the 158 * animation resources will be loaded from. 159 * @param enterResId A resource ID of the animation resource to use for 160 * the incoming activity. Use 0 for no animation. 161 * @param exitResId A resource ID of the animation resource to use for 162 * the outgoing activity. Use 0 for no animation. 163 * @return Returns a new ActivityOptions object that you can use to 164 * supply these options as the options Bundle when starting an activity. 165 */ makeCustomAnimation(Context context, int enterResId, int exitResId)166 public static ActivityOptions makeCustomAnimation(Context context, 167 int enterResId, int exitResId) { 168 return makeCustomAnimation(context, enterResId, exitResId, null, null); 169 } 170 171 /** 172 * Create an ActivityOptions specifying a custom animation to run when 173 * the activity is displayed. 174 * 175 * @param context Who is defining this. This is the application that the 176 * animation resources will be loaded from. 177 * @param enterResId A resource ID of the animation resource to use for 178 * the incoming activity. Use 0 for no animation. 179 * @param exitResId A resource ID of the animation resource to use for 180 * the outgoing activity. Use 0 for no animation. 181 * @param handler If <var>listener</var> is non-null this must be a valid 182 * Handler on which to dispatch the callback; otherwise it should be null. 183 * @param listener Optional OnAnimationStartedListener to find out when the 184 * requested animation has started running. If for some reason the animation 185 * is not executed, the callback will happen immediately. 186 * @return Returns a new ActivityOptions object that you can use to 187 * supply these options as the options Bundle when starting an activity. 188 * @hide 189 */ makeCustomAnimation(Context context, int enterResId, int exitResId, Handler handler, OnAnimationStartedListener listener)190 public static ActivityOptions makeCustomAnimation(Context context, 191 int enterResId, int exitResId, Handler handler, OnAnimationStartedListener listener) { 192 ActivityOptions opts = new ActivityOptions(); 193 opts.mPackageName = context.getPackageName(); 194 opts.mAnimationType = ANIM_CUSTOM; 195 opts.mCustomEnterResId = enterResId; 196 opts.mCustomExitResId = exitResId; 197 opts.setOnAnimationStartedListener(handler, listener); 198 return opts; 199 } 200 setOnAnimationStartedListener(Handler handler, OnAnimationStartedListener listener)201 private void setOnAnimationStartedListener(Handler handler, 202 OnAnimationStartedListener listener) { 203 if (listener != null) { 204 final Handler h = handler; 205 final OnAnimationStartedListener finalListener = listener; 206 mAnimationStartedListener = new IRemoteCallback.Stub() { 207 @Override public void sendResult(Bundle data) throws RemoteException { 208 h.post(new Runnable() { 209 @Override public void run() { 210 finalListener.onAnimationStarted(); 211 } 212 }); 213 } 214 }; 215 } 216 } 217 218 /** 219 * Callback for use with {@link ActivityOptions#makeThumbnailScaleUpAnimation} 220 * to find out when the given animation has started running. 221 * @hide 222 */ 223 public interface OnAnimationStartedListener { onAnimationStarted()224 void onAnimationStarted(); 225 } 226 227 /** 228 * Create an ActivityOptions specifying an animation where the new 229 * activity is scaled from a small originating area of the screen to 230 * its final full representation. 231 * 232 * <p>If the Intent this is being used with has not set its 233 * {@link android.content.Intent#setSourceBounds Intent.setSourceBounds}, 234 * those bounds will be filled in for you based on the initial 235 * bounds passed in here. 236 * 237 * @param source The View that the new activity is animating from. This 238 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 239 * @param startX The x starting location of the new activity, relative to <var>source</var>. 240 * @param startY The y starting location of the activity, relative to <var>source</var>. 241 * @param width The initial width of the new activity. 242 * @param height The initial height of the new activity. 243 * @return Returns a new ActivityOptions object that you can use to 244 * supply these options as the options Bundle when starting an activity. 245 */ makeScaleUpAnimation(View source, int startX, int startY, int width, int height)246 public static ActivityOptions makeScaleUpAnimation(View source, 247 int startX, int startY, int width, int height) { 248 ActivityOptions opts = new ActivityOptions(); 249 opts.mPackageName = source.getContext().getPackageName(); 250 opts.mAnimationType = ANIM_SCALE_UP; 251 int[] pts = new int[2]; 252 source.getLocationOnScreen(pts); 253 opts.mStartX = pts[0] + startX; 254 opts.mStartY = pts[1] + startY; 255 opts.mWidth = width; 256 opts.mHeight = height; 257 return opts; 258 } 259 260 /** 261 * Create an ActivityOptions specifying an animation where a thumbnail 262 * is scaled from a given position to the new activity window that is 263 * being started. 264 * 265 * <p>If the Intent this is being used with has not set its 266 * {@link android.content.Intent#setSourceBounds Intent.setSourceBounds}, 267 * those bounds will be filled in for you based on the initial 268 * thumbnail location and size provided here. 269 * 270 * @param source The View that this thumbnail is animating from. This 271 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 272 * @param thumbnail The bitmap that will be shown as the initial thumbnail 273 * of the animation. 274 * @param startX The x starting location of the bitmap, relative to <var>source</var>. 275 * @param startY The y starting location of the bitmap, relative to <var>source</var>. 276 * @return Returns a new ActivityOptions object that you can use to 277 * supply these options as the options Bundle when starting an activity. 278 */ makeThumbnailScaleUpAnimation(View source, Bitmap thumbnail, int startX, int startY)279 public static ActivityOptions makeThumbnailScaleUpAnimation(View source, 280 Bitmap thumbnail, int startX, int startY) { 281 return makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY, null); 282 } 283 284 /** 285 * Create an ActivityOptions specifying an animation where a thumbnail 286 * is scaled from a given position to the new activity window that is 287 * being started. 288 * 289 * @param source The View that this thumbnail is animating from. This 290 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 291 * @param thumbnail The bitmap that will be shown as the initial thumbnail 292 * of the animation. 293 * @param startX The x starting location of the bitmap, relative to <var>source</var>. 294 * @param startY The y starting location of the bitmap, relative to <var>source</var>. 295 * @param listener Optional OnAnimationStartedListener to find out when the 296 * requested animation has started running. If for some reason the animation 297 * is not executed, the callback will happen immediately. 298 * @return Returns a new ActivityOptions object that you can use to 299 * supply these options as the options Bundle when starting an activity. 300 * @hide 301 */ makeThumbnailScaleUpAnimation(View source, Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener)302 public static ActivityOptions makeThumbnailScaleUpAnimation(View source, 303 Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) { 304 return makeThumbnailAnimation(source, thumbnail, startX, startY, listener, true); 305 } 306 307 /** 308 * Create an ActivityOptions specifying an animation where an activity window 309 * is scaled from a given position to a thumbnail at a specified location. 310 * 311 * @param source The View that this thumbnail is animating to. This 312 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 313 * @param thumbnail The bitmap that will be shown as the final thumbnail 314 * of the animation. 315 * @param startX The x end location of the bitmap, relative to <var>source</var>. 316 * @param startY The y end location of the bitmap, relative to <var>source</var>. 317 * @param listener Optional OnAnimationStartedListener to find out when the 318 * requested animation has started running. If for some reason the animation 319 * is not executed, the callback will happen immediately. 320 * @return Returns a new ActivityOptions object that you can use to 321 * supply these options as the options Bundle when starting an activity. 322 * @hide 323 */ makeThumbnailScaleDownAnimation(View source, Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener)324 public static ActivityOptions makeThumbnailScaleDownAnimation(View source, 325 Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) { 326 return makeThumbnailAnimation(source, thumbnail, startX, startY, listener, false); 327 } 328 makeThumbnailAnimation(View source, Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener, boolean scaleUp)329 private static ActivityOptions makeThumbnailAnimation(View source, 330 Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener, 331 boolean scaleUp) { 332 ActivityOptions opts = new ActivityOptions(); 333 opts.mPackageName = source.getContext().getPackageName(); 334 opts.mAnimationType = scaleUp ? ANIM_THUMBNAIL_SCALE_UP : ANIM_THUMBNAIL_SCALE_DOWN; 335 opts.mThumbnail = thumbnail; 336 int[] pts = new int[2]; 337 source.getLocationOnScreen(pts); 338 opts.mStartX = pts[0] + startX; 339 opts.mStartY = pts[1] + startY; 340 opts.setOnAnimationStartedListener(source.getHandler(), listener); 341 return opts; 342 } 343 344 /** 345 * Create an ActivityOptions specifying an animation where the new activity 346 * window and a thumbnail is aspect-scaled to a new location. 347 * 348 * @param source The View that this thumbnail is animating from. This 349 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 350 * @param thumbnail The bitmap that will be shown as the initial thumbnail 351 * of the animation. 352 * @param startX The x starting location of the bitmap, relative to <var>source</var>. 353 * @param startY The y starting location of the bitmap, relative to <var>source</var>. 354 * @param listener Optional OnAnimationStartedListener to find out when the 355 * requested animation has started running. If for some reason the animation 356 * is not executed, the callback will happen immediately. 357 * @return Returns a new ActivityOptions object that you can use to 358 * supply these options as the options Bundle when starting an activity. 359 * @hide 360 */ makeThumbnailAspectScaleUpAnimation(View source, Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight, OnAnimationStartedListener listener)361 public static ActivityOptions makeThumbnailAspectScaleUpAnimation(View source, 362 Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight, 363 OnAnimationStartedListener listener) { 364 return makeAspectScaledThumbnailAnimation(source, thumbnail, startX, startY, 365 targetWidth, targetHeight, listener, true); 366 } 367 368 /** 369 * Create an ActivityOptions specifying an animation where the new activity 370 * window and a thumbnail is aspect-scaled to a new location. 371 * 372 * @param source The View that this thumbnail is animating to. This 373 * defines the coordinate space for <var>startX</var> and <var>startY</var>. 374 * @param thumbnail The bitmap that will be shown as the final thumbnail 375 * of the animation. 376 * @param startX The x end location of the bitmap, relative to <var>source</var>. 377 * @param startY The y end location of the bitmap, relative to <var>source</var>. 378 * @param listener Optional OnAnimationStartedListener to find out when the 379 * requested animation has started running. If for some reason the animation 380 * is not executed, the callback will happen immediately. 381 * @return Returns a new ActivityOptions object that you can use to 382 * supply these options as the options Bundle when starting an activity. 383 * @hide 384 */ makeThumbnailAspectScaleDownAnimation(View source, Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight, OnAnimationStartedListener listener)385 public static ActivityOptions makeThumbnailAspectScaleDownAnimation(View source, 386 Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight, 387 OnAnimationStartedListener listener) { 388 return makeAspectScaledThumbnailAnimation(source, thumbnail, startX, startY, 389 targetWidth, targetHeight, listener, false); 390 } 391 makeAspectScaledThumbnailAnimation(View source, Bitmap thumbnail, int startX, int startY, int targetWidth, int targetHeight, OnAnimationStartedListener listener, boolean scaleUp)392 private static ActivityOptions makeAspectScaledThumbnailAnimation(View source, Bitmap thumbnail, 393 int startX, int startY, int targetWidth, int targetHeight, 394 OnAnimationStartedListener listener, boolean scaleUp) { 395 ActivityOptions opts = new ActivityOptions(); 396 opts.mPackageName = source.getContext().getPackageName(); 397 opts.mAnimationType = scaleUp ? ANIM_THUMBNAIL_ASPECT_SCALE_UP : 398 ANIM_THUMBNAIL_ASPECT_SCALE_DOWN; 399 opts.mThumbnail = thumbnail; 400 int[] pts = new int[2]; 401 source.getLocationOnScreen(pts); 402 opts.mStartX = pts[0] + startX; 403 opts.mStartY = pts[1] + startY; 404 opts.mWidth = targetWidth; 405 opts.mHeight = targetHeight; 406 opts.setOnAnimationStartedListener(source.getHandler(), listener); 407 return opts; 408 } 409 410 /** 411 * Create an ActivityOptions to transition between Activities using cross-Activity scene 412 * animations. This method carries the position of one shared element to the started Activity. 413 * The position of <code>sharedElement</code> will be used as the epicenter for the 414 * exit Transition. The position of the shared element in the launched Activity will be the 415 * epicenter of its entering Transition. 416 * 417 * <p>This requires {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS} to be 418 * enabled on the calling Activity to cause an exit transition. The same must be in 419 * the called Activity to get an entering transition.</p> 420 * @param activity The Activity whose window contains the shared elements. 421 * @param sharedElement The View to transition to the started Activity. 422 * @param sharedElementName The shared element name as used in the target Activity. This 423 * must not be null. 424 * @return Returns a new ActivityOptions object that you can use to 425 * supply these options as the options Bundle when starting an activity. 426 * @see android.transition.Transition#setEpicenterCallback( 427 * android.transition.Transition.EpicenterCallback) 428 */ makeSceneTransitionAnimation(Activity activity, View sharedElement, String sharedElementName)429 public static ActivityOptions makeSceneTransitionAnimation(Activity activity, 430 View sharedElement, String sharedElementName) { 431 return makeSceneTransitionAnimation(activity, Pair.create(sharedElement, sharedElementName)); 432 } 433 434 /** 435 * Create an ActivityOptions to transition between Activities using cross-Activity scene 436 * animations. This method carries the position of multiple shared elements to the started 437 * Activity. The position of the first element in sharedElements 438 * will be used as the epicenter for the exit Transition. The position of the associated 439 * shared element in the launched Activity will be the epicenter of its entering Transition. 440 * 441 * <p>This requires {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS} to be 442 * enabled on the calling Activity to cause an exit transition. The same must be in 443 * the called Activity to get an entering transition.</p> 444 * @param activity The Activity whose window contains the shared elements. 445 * @param sharedElements The names of the shared elements to transfer to the called 446 * Activity and their associated Views. The Views must each have 447 * a unique shared element name. 448 * @return Returns a new ActivityOptions object that you can use to 449 * supply these options as the options Bundle when starting an activity. 450 * @see android.transition.Transition#setEpicenterCallback( 451 * android.transition.Transition.EpicenterCallback) 452 */ makeSceneTransitionAnimation(Activity activity, Pair<View, String>... sharedElements)453 public static ActivityOptions makeSceneTransitionAnimation(Activity activity, 454 Pair<View, String>... sharedElements) { 455 ActivityOptions opts = new ActivityOptions(); 456 if (!activity.getWindow().hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)) { 457 opts.mAnimationType = ANIM_DEFAULT; 458 return opts; 459 } 460 opts.mAnimationType = ANIM_SCENE_TRANSITION; 461 462 ArrayList<String> names = new ArrayList<String>(); 463 ArrayList<View> views = new ArrayList<View>(); 464 465 if (sharedElements != null) { 466 for (int i = 0; i < sharedElements.length; i++) { 467 Pair<View, String> sharedElement = sharedElements[i]; 468 String sharedElementName = sharedElement.second; 469 if (sharedElementName == null) { 470 throw new IllegalArgumentException("Shared element name must not be null"); 471 } 472 names.add(sharedElementName); 473 View view = sharedElement.first; 474 if (view == null) { 475 throw new IllegalArgumentException("Shared element must not be null"); 476 } 477 views.add(sharedElement.first); 478 } 479 } 480 481 ExitTransitionCoordinator exit = new ExitTransitionCoordinator(activity, names, names, 482 views, false); 483 opts.mTransitionReceiver = exit; 484 opts.mSharedElementNames = names; 485 opts.mIsReturning = false; 486 opts.mExitCoordinatorIndex = 487 activity.mActivityTransitionState.addExitTransitionCoordinator(exit); 488 return opts; 489 } 490 491 /** @hide */ makeSceneTransitionAnimation(Activity activity, ExitTransitionCoordinator exitCoordinator, ArrayList<String> sharedElementNames, int resultCode, Intent resultData)492 public static ActivityOptions makeSceneTransitionAnimation(Activity activity, 493 ExitTransitionCoordinator exitCoordinator, ArrayList<String> sharedElementNames, 494 int resultCode, Intent resultData) { 495 ActivityOptions opts = new ActivityOptions(); 496 opts.mAnimationType = ANIM_SCENE_TRANSITION; 497 opts.mSharedElementNames = sharedElementNames; 498 opts.mTransitionReceiver = exitCoordinator; 499 opts.mIsReturning = true; 500 opts.mResultCode = resultCode; 501 opts.mResultData = resultData; 502 opts.mExitCoordinatorIndex = 503 activity.mActivityTransitionState.addExitTransitionCoordinator(exitCoordinator); 504 return opts; 505 } 506 507 /** 508 * If set along with Intent.FLAG_ACTIVITY_NEW_DOCUMENT then the task being launched will not be 509 * presented to the user but will instead be only available through the recents task list. 510 * In addition, the new task wil be affiliated with the launching activity's task. 511 * Affiliated tasks are grouped together in the recents task list. 512 * 513 * <p>This behavior is not supported for activities with {@link 514 * android.R.styleable#AndroidManifestActivity_launchMode launchMode} values of 515 * <code>singleInstance</code> or <code>singleTask</code>. 516 */ makeTaskLaunchBehind()517 public static ActivityOptions makeTaskLaunchBehind() { 518 final ActivityOptions opts = new ActivityOptions(); 519 opts.mAnimationType = ANIM_LAUNCH_TASK_BEHIND; 520 return opts; 521 } 522 523 /** @hide */ getLaunchTaskBehind()524 public boolean getLaunchTaskBehind() { 525 return mAnimationType == ANIM_LAUNCH_TASK_BEHIND; 526 } 527 ActivityOptions()528 private ActivityOptions() { 529 } 530 531 /** @hide */ ActivityOptions(Bundle opts)532 public ActivityOptions(Bundle opts) { 533 mPackageName = opts.getString(KEY_PACKAGE_NAME); 534 mAnimationType = opts.getInt(KEY_ANIM_TYPE); 535 switch (mAnimationType) { 536 case ANIM_CUSTOM: 537 mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0); 538 mCustomExitResId = opts.getInt(KEY_ANIM_EXIT_RES_ID, 0); 539 mAnimationStartedListener = IRemoteCallback.Stub.asInterface( 540 opts.getBinder(KEY_ANIM_START_LISTENER)); 541 break; 542 543 case ANIM_SCALE_UP: 544 mStartX = opts.getInt(KEY_ANIM_START_X, 0); 545 mStartY = opts.getInt(KEY_ANIM_START_Y, 0); 546 mWidth = opts.getInt(KEY_ANIM_WIDTH, 0); 547 mHeight = opts.getInt(KEY_ANIM_HEIGHT, 0); 548 break; 549 550 case ANIM_THUMBNAIL_SCALE_UP: 551 case ANIM_THUMBNAIL_SCALE_DOWN: 552 case ANIM_THUMBNAIL_ASPECT_SCALE_UP: 553 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN: 554 mThumbnail = (Bitmap) opts.getParcelable(KEY_ANIM_THUMBNAIL); 555 mStartX = opts.getInt(KEY_ANIM_START_X, 0); 556 mStartY = opts.getInt(KEY_ANIM_START_Y, 0); 557 mWidth = opts.getInt(KEY_ANIM_WIDTH, 0); 558 mHeight = opts.getInt(KEY_ANIM_HEIGHT, 0); 559 mAnimationStartedListener = IRemoteCallback.Stub.asInterface( 560 opts.getBinder(KEY_ANIM_START_LISTENER)); 561 break; 562 563 case ANIM_SCENE_TRANSITION: 564 mTransitionReceiver = opts.getParcelable(KEY_TRANSITION_COMPLETE_LISTENER); 565 mIsReturning = opts.getBoolean(KEY_TRANSITION_IS_RETURNING, false); 566 mSharedElementNames = opts.getStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS); 567 mResultData = opts.getParcelable(KEY_RESULT_DATA); 568 mResultCode = opts.getInt(KEY_RESULT_CODE); 569 mExitCoordinatorIndex = opts.getInt(KEY_EXIT_COORDINATOR_INDEX); 570 break; 571 } 572 } 573 574 /** @hide */ getPackageName()575 public String getPackageName() { 576 return mPackageName; 577 } 578 579 /** @hide */ getAnimationType()580 public int getAnimationType() { 581 return mAnimationType; 582 } 583 584 /** @hide */ getCustomEnterResId()585 public int getCustomEnterResId() { 586 return mCustomEnterResId; 587 } 588 589 /** @hide */ getCustomExitResId()590 public int getCustomExitResId() { 591 return mCustomExitResId; 592 } 593 594 /** @hide */ getThumbnail()595 public Bitmap getThumbnail() { 596 return mThumbnail; 597 } 598 599 /** @hide */ getStartX()600 public int getStartX() { 601 return mStartX; 602 } 603 604 /** @hide */ getStartY()605 public int getStartY() { 606 return mStartY; 607 } 608 609 /** @hide */ getWidth()610 public int getWidth() { 611 return mWidth; 612 } 613 614 /** @hide */ getHeight()615 public int getHeight() { 616 return mHeight; 617 } 618 619 /** @hide */ getOnAnimationStartListener()620 public IRemoteCallback getOnAnimationStartListener() { 621 return mAnimationStartedListener; 622 } 623 624 /** @hide */ getExitCoordinatorKey()625 public int getExitCoordinatorKey() { return mExitCoordinatorIndex; } 626 627 /** @hide */ abort()628 public void abort() { 629 if (mAnimationStartedListener != null) { 630 try { 631 mAnimationStartedListener.sendResult(null); 632 } catch (RemoteException e) { 633 } 634 } 635 } 636 637 /** @hide */ isReturning()638 public boolean isReturning() { 639 return mIsReturning; 640 } 641 642 /** @hide */ getSharedElementNames()643 public ArrayList<String> getSharedElementNames() { 644 return mSharedElementNames; 645 } 646 647 /** @hide */ getResultReceiver()648 public ResultReceiver getResultReceiver() { return mTransitionReceiver; } 649 650 /** @hide */ getResultCode()651 public int getResultCode() { return mResultCode; } 652 653 /** @hide */ getResultData()654 public Intent getResultData() { return mResultData; } 655 656 /** @hide */ abort(Bundle options)657 public static void abort(Bundle options) { 658 if (options != null) { 659 (new ActivityOptions(options)).abort(); 660 } 661 } 662 663 /** 664 * Update the current values in this ActivityOptions from those supplied 665 * in <var>otherOptions</var>. Any values 666 * defined in <var>otherOptions</var> replace those in the base options. 667 */ update(ActivityOptions otherOptions)668 public void update(ActivityOptions otherOptions) { 669 if (otherOptions.mPackageName != null) { 670 mPackageName = otherOptions.mPackageName; 671 } 672 mTransitionReceiver = null; 673 mSharedElementNames = null; 674 mIsReturning = false; 675 mResultData = null; 676 mResultCode = 0; 677 mExitCoordinatorIndex = 0; 678 mAnimationType = otherOptions.mAnimationType; 679 switch (otherOptions.mAnimationType) { 680 case ANIM_CUSTOM: 681 mCustomEnterResId = otherOptions.mCustomEnterResId; 682 mCustomExitResId = otherOptions.mCustomExitResId; 683 mThumbnail = null; 684 if (mAnimationStartedListener != null) { 685 try { 686 mAnimationStartedListener.sendResult(null); 687 } catch (RemoteException e) { 688 } 689 } 690 mAnimationStartedListener = otherOptions.mAnimationStartedListener; 691 break; 692 case ANIM_SCALE_UP: 693 mStartX = otherOptions.mStartX; 694 mStartY = otherOptions.mStartY; 695 mWidth = otherOptions.mWidth; 696 mHeight = otherOptions.mHeight; 697 if (mAnimationStartedListener != null) { 698 try { 699 mAnimationStartedListener.sendResult(null); 700 } catch (RemoteException e) { 701 } 702 } 703 mAnimationStartedListener = null; 704 break; 705 case ANIM_THUMBNAIL_SCALE_UP: 706 case ANIM_THUMBNAIL_SCALE_DOWN: 707 case ANIM_THUMBNAIL_ASPECT_SCALE_UP: 708 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN: 709 mThumbnail = otherOptions.mThumbnail; 710 mStartX = otherOptions.mStartX; 711 mStartY = otherOptions.mStartY; 712 mWidth = otherOptions.mWidth; 713 mHeight = otherOptions.mHeight; 714 if (mAnimationStartedListener != null) { 715 try { 716 mAnimationStartedListener.sendResult(null); 717 } catch (RemoteException e) { 718 } 719 } 720 mAnimationStartedListener = otherOptions.mAnimationStartedListener; 721 break; 722 case ANIM_SCENE_TRANSITION: 723 mTransitionReceiver = otherOptions.mTransitionReceiver; 724 mSharedElementNames = otherOptions.mSharedElementNames; 725 mIsReturning = otherOptions.mIsReturning; 726 mThumbnail = null; 727 mAnimationStartedListener = null; 728 mResultData = otherOptions.mResultData; 729 mResultCode = otherOptions.mResultCode; 730 mExitCoordinatorIndex = otherOptions.mExitCoordinatorIndex; 731 break; 732 } 733 } 734 735 /** 736 * Returns the created options as a Bundle, which can be passed to 737 * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle) 738 * Context.startActivity(Intent, Bundle)} and related methods. 739 * Note that the returned Bundle is still owned by the ActivityOptions 740 * object; you must not modify it, but can supply it to the startActivity 741 * methods that take an options Bundle. 742 */ toBundle()743 public Bundle toBundle() { 744 if (mAnimationType == ANIM_DEFAULT) { 745 return null; 746 } 747 Bundle b = new Bundle(); 748 if (mPackageName != null) { 749 b.putString(KEY_PACKAGE_NAME, mPackageName); 750 } 751 b.putInt(KEY_ANIM_TYPE, mAnimationType); 752 switch (mAnimationType) { 753 case ANIM_CUSTOM: 754 b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId); 755 b.putInt(KEY_ANIM_EXIT_RES_ID, mCustomExitResId); 756 b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener 757 != null ? mAnimationStartedListener.asBinder() : null); 758 break; 759 case ANIM_SCALE_UP: 760 b.putInt(KEY_ANIM_START_X, mStartX); 761 b.putInt(KEY_ANIM_START_Y, mStartY); 762 b.putInt(KEY_ANIM_WIDTH, mWidth); 763 b.putInt(KEY_ANIM_HEIGHT, mHeight); 764 break; 765 case ANIM_THUMBNAIL_SCALE_UP: 766 case ANIM_THUMBNAIL_SCALE_DOWN: 767 case ANIM_THUMBNAIL_ASPECT_SCALE_UP: 768 case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN: 769 b.putParcelable(KEY_ANIM_THUMBNAIL, mThumbnail); 770 b.putInt(KEY_ANIM_START_X, mStartX); 771 b.putInt(KEY_ANIM_START_Y, mStartY); 772 b.putInt(KEY_ANIM_WIDTH, mWidth); 773 b.putInt(KEY_ANIM_HEIGHT, mHeight); 774 b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener 775 != null ? mAnimationStartedListener.asBinder() : null); 776 break; 777 case ANIM_SCENE_TRANSITION: 778 if (mTransitionReceiver != null) { 779 b.putParcelable(KEY_TRANSITION_COMPLETE_LISTENER, mTransitionReceiver); 780 } 781 b.putBoolean(KEY_TRANSITION_IS_RETURNING, mIsReturning); 782 b.putStringArrayList(KEY_TRANSITION_SHARED_ELEMENTS, mSharedElementNames); 783 b.putParcelable(KEY_RESULT_DATA, mResultData); 784 b.putInt(KEY_RESULT_CODE, mResultCode); 785 b.putInt(KEY_EXIT_COORDINATOR_INDEX, mExitCoordinatorIndex); 786 break; 787 } 788 789 return b; 790 } 791 792 /** 793 * Return the filtered options only meant to be seen by the target activity itself 794 * @hide 795 */ forTargetActivity()796 public ActivityOptions forTargetActivity() { 797 if (mAnimationType == ANIM_SCENE_TRANSITION) { 798 final ActivityOptions result = new ActivityOptions(); 799 result.update(this); 800 return result; 801 } 802 803 return null; 804 } 805 806 } 807