AppTransition.java revision 164d4bb4c3eeba1488d9b4994980d24c1f6ec961
1/* 2 * Copyright (C) 2011 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 17package com.android.server.wm; 18 19import android.app.ActivityOptions; 20import android.content.Context; 21import android.graphics.Bitmap; 22import android.graphics.Point; 23import android.os.Debug; 24import android.os.Handler; 25import android.os.IRemoteCallback; 26import android.util.Slog; 27import android.view.WindowManager; 28import android.view.WindowManagerPolicy; 29import android.view.animation.AlphaAnimation; 30import android.view.animation.Animation; 31import android.view.animation.AnimationSet; 32import android.view.animation.AnimationUtils; 33import android.view.animation.DecelerateInterpolator; 34import android.view.animation.Interpolator; 35import android.view.animation.ScaleAnimation; 36 37import com.android.internal.util.DumpUtils.Dump; 38import com.android.server.AttributeCache; 39import com.android.server.wm.WindowManagerService.H; 40 41import java.io.PrintWriter; 42 43import static android.view.WindowManagerPolicy.TRANSIT_NONE; 44import static android.view.WindowManagerPolicy.TRANSIT_UNSET; 45 46// State management of app transitions. When we are preparing for a 47// transition, mNextAppTransition will be the kind of transition to 48// perform or TRANSIT_NONE if we are not waiting. If we are waiting, 49// mOpeningApps and mClosingApps are the lists of tokens that will be 50// made visible or hidden at the next transition. 51public class AppTransition implements Dump { 52 private static final String TAG = "AppTransition"; 53 private static final float THUMBNAIL_ANIMATION_DECELERATE_FACTOR = 1.5f; 54 private static final boolean DEBUG_APP_TRANSITIONS = WindowManagerService.DEBUG_APP_TRANSITIONS; 55 private static final boolean DEBUG_ANIM = WindowManagerService.DEBUG_APP_TRANSITIONS; 56 57 final Context mContext; 58 final Handler mH; 59 60 int mNextAppTransition = TRANSIT_UNSET; 61 int mNextAppTransitionType = ActivityOptions.ANIM_NONE; 62 String mNextAppTransitionPackage; 63 Bitmap mNextAppTransitionThumbnail; 64 // Used for thumbnail transitions. True if we're scaling up, false if scaling down 65 boolean mNextAppTransitionScaleUp; 66 IRemoteCallback mNextAppTransitionCallback; 67 int mNextAppTransitionEnter; 68 int mNextAppTransitionExit; 69 int mNextAppTransitionStartX; 70 int mNextAppTransitionStartY; 71 int mNextAppTransitionStartWidth; 72 int mNextAppTransitionStartHeight; 73 boolean mAppTransitionReady = false; 74 boolean mAppTransitionRunning = false; 75 boolean mAppTransitionTimeout = false; 76 77 final int mConfigShortAnimTime; 78 final Interpolator mInterpolator; 79 80 AppTransition(Context context, Handler h) { 81 mContext = context; 82 mH = h; 83 mConfigShortAnimTime = context.getResources().getInteger( 84 com.android.internal.R.integer.config_shortAnimTime); 85 mInterpolator = AnimationUtils.loadInterpolator(context, 86 com.android.internal.R.interpolator.decelerate_quad); 87 } 88 89 boolean isTransitionSet() { 90 return mNextAppTransition != TRANSIT_UNSET; 91 } 92 93 boolean isTransitionNone() { 94 return mNextAppTransition == TRANSIT_NONE; 95 } 96 97 boolean isTransitionEqual(int transit) { 98 return mNextAppTransition == transit; 99 } 100 101 int getAppTransition() { 102 return mNextAppTransition; 103 } 104 105 void setAppTransition(int transit) { 106 mNextAppTransition = transit; 107 } 108 109 boolean isReady() { 110 return mAppTransitionReady; 111 } 112 113 void setReady(boolean ready) { 114 mAppTransitionReady = ready; 115 } 116 117 boolean isRunning() { 118 return mAppTransitionRunning; 119 } 120 121 void setRunning(boolean running) { 122 mAppTransitionRunning = running; 123 } 124 125 boolean isTimeout() { 126 return mAppTransitionTimeout; 127 } 128 129 void setTimeout(boolean timeout) { 130 mAppTransitionTimeout = timeout; 131 } 132 133 Bitmap getNextAppTransitionThumbnail() { 134 return mNextAppTransitionThumbnail; 135 } 136 137 void getStartingPoint(Point outPoint) { 138 outPoint.x = mNextAppTransitionStartX; 139 outPoint.y = mNextAppTransitionStartY; 140 } 141 142 int getType() { 143 return mNextAppTransitionType; 144 } 145 146 void prepare() { 147 mAppTransitionReady = false; 148 mAppTransitionTimeout = false; 149 } 150 151 void goodToGo() { 152 mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET; 153 mAppTransitionReady = false; 154 mAppTransitionRunning = true; 155 mAppTransitionTimeout = false; 156 } 157 158 void clear() { 159 mNextAppTransitionType = ActivityOptions.ANIM_NONE; 160 mNextAppTransitionPackage = null; 161 mNextAppTransitionThumbnail = null; 162 } 163 164 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) { 165 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: layout params pkg=" 166 + (lp != null ? lp.packageName : null) 167 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null)); 168 if (lp != null && lp.windowAnimations != 0) { 169 // If this is a system resource, don't try to load it from the 170 // application resources. It is nice to avoid loading application 171 // resources if we can. 172 String packageName = lp.packageName != null ? lp.packageName : "android"; 173 int resId = lp.windowAnimations; 174 if ((resId&0xFF000000) == 0x01000000) { 175 packageName = "android"; 176 } 177 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package=" 178 + packageName); 179 return AttributeCache.instance().get(packageName, resId, 180 com.android.internal.R.styleable.WindowAnimation); 181 } 182 return null; 183 } 184 185 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) { 186 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: package=" 187 + packageName + " resId=0x" + Integer.toHexString(resId)); 188 if (packageName != null) { 189 if ((resId&0xFF000000) == 0x01000000) { 190 packageName = "android"; 191 } 192 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package=" 193 + packageName); 194 return AttributeCache.instance().get(packageName, resId, 195 com.android.internal.R.styleable.WindowAnimation); 196 } 197 return null; 198 } 199 200 Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) { 201 int anim = 0; 202 Context context = mContext; 203 if (animAttr >= 0) { 204 AttributeCache.Entry ent = getCachedAnimations(lp); 205 if (ent != null) { 206 context = ent.context; 207 anim = ent.array.getResourceId(animAttr, 0); 208 } 209 } 210 if (anim != 0) { 211 return AnimationUtils.loadAnimation(context, anim); 212 } 213 return null; 214 } 215 216 private Animation loadAnimation(String packageName, int resId) { 217 int anim = 0; 218 Context context = mContext; 219 if (resId >= 0) { 220 AttributeCache.Entry ent = getCachedAnimations(packageName, resId); 221 if (ent != null) { 222 context = ent.context; 223 anim = resId; 224 } 225 } 226 if (anim != 0) { 227 return AnimationUtils.loadAnimation(context, anim); 228 } 229 return null; 230 } 231 232 private Animation createExitAnimationLocked(int transit, int duration) { 233 if (transit == WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN || 234 transit == WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE) { 235 // If we are on top of the wallpaper, we need an animation that 236 // correctly handles the wallpaper staying static behind all of 237 // the animated elements. To do this, will just have the existing 238 // element fade out. 239 Animation a = new AlphaAnimation(1, 0); 240 a.setDetachWallpaper(true); 241 a.setDuration(duration); 242 return a; 243 } 244 // For normal animations, the exiting element just holds in place. 245 Animation a = new AlphaAnimation(1, 1); 246 a.setDuration(duration); 247 return a; 248 } 249 250 /** 251 * Compute the pivot point for an animation that is scaling from a small 252 * rect on screen to a larger rect. The pivot point varies depending on 253 * the distance between the inner and outer edges on both sides. This 254 * function computes the pivot point for one dimension. 255 * @param startPos Offset from left/top edge of outer rectangle to 256 * left/top edge of inner rectangle. 257 * @param finalScale The scaling factor between the size of the outer 258 * and inner rectangles. 259 */ 260 private static float computePivot(int startPos, float finalScale) { 261 final float denom = finalScale-1; 262 if (Math.abs(denom) < .0001f) { 263 return startPos; 264 } 265 return -startPos / denom; 266 } 267 268 private Animation createScaleUpAnimationLocked(int transit, boolean enter, 269 int appWidth, int appHeight) { 270 Animation a = null; 271 // Pick the desired duration. If this is an inter-activity transition, 272 // it is the standard duration for that. Otherwise we use the longer 273 // task transition duration. 274 int duration; 275 switch (transit) { 276 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN: 277 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE: 278 duration = mContext.getResources().getInteger( 279 com.android.internal.R.integer.config_shortAnimTime); 280 break; 281 default: 282 duration = 300; 283 break; 284 } 285 if (enter) { 286 // Entering app zooms out from the center of the initial rect. 287 float scaleW = mNextAppTransitionStartWidth / (float) appWidth; 288 float scaleH = mNextAppTransitionStartHeight / (float) appHeight; 289 Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1, 290 computePivot(mNextAppTransitionStartX, scaleW), 291 computePivot(mNextAppTransitionStartY, scaleH)); 292 scale.setDuration(duration); 293 AnimationSet set = new AnimationSet(true); 294 Animation alpha = new AlphaAnimation(0, 1); 295 scale.setDuration(duration); 296 set.addAnimation(scale); 297 alpha.setDuration(duration); 298 set.addAnimation(alpha); 299 set.setDetachWallpaper(true); 300 a = set; 301 } else { 302 a = createExitAnimationLocked(transit, duration); 303 } 304 a.setFillAfter(true); 305 final Interpolator interpolator = AnimationUtils.loadInterpolator(mContext, 306 com.android.internal.R.interpolator.decelerate_cubic); 307 a.setInterpolator(interpolator); 308 a.initialize(appWidth, appHeight, appWidth, appHeight); 309 return a; 310 } 311 312 Animation createThumbnailAnimationLocked(int transit, boolean enter, boolean thumb, 313 int appWidth, int appHeight) { 314 Animation a; 315 final int thumbWidthI = mNextAppTransitionThumbnail.getWidth(); 316 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1; 317 final int thumbHeightI = mNextAppTransitionThumbnail.getHeight(); 318 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1; 319 // Pick the desired duration. If this is an inter-activity transition, 320 // it is the standard duration for that. Otherwise we use the longer 321 // task transition duration. 322 int duration; 323 switch (transit) { 324 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN: 325 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE: 326 duration = mConfigShortAnimTime; 327 break; 328 default: 329 duration = 250; 330 break; 331 } 332 if (thumb) { 333 // Animation for zooming thumbnail from its initial size to 334 // filling the screen. 335 if (mNextAppTransitionScaleUp) { 336 float scaleW = appWidth / thumbWidth; 337 float scaleH = appHeight / thumbHeight; 338 339 Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH, 340 computePivot(mNextAppTransitionStartX, 1 / scaleW), 341 computePivot(mNextAppTransitionStartY, 1 / scaleH)); 342 AnimationSet set = new AnimationSet(true); 343 Animation alpha = new AlphaAnimation(1, 0); 344 scale.setDuration(duration); 345 scale.setInterpolator( 346 new DecelerateInterpolator(THUMBNAIL_ANIMATION_DECELERATE_FACTOR)); 347 set.addAnimation(scale); 348 alpha.setDuration(duration); 349 set.addAnimation(alpha); 350 set.setFillBefore(true); 351 a = set; 352 } else { 353 float scaleW = appWidth / thumbWidth; 354 float scaleH = appHeight / thumbHeight; 355 356 Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1, 357 computePivot(mNextAppTransitionStartX, 1 / scaleW), 358 computePivot(mNextAppTransitionStartY, 1 / scaleH)); 359 AnimationSet set = new AnimationSet(true); 360 Animation alpha = new AlphaAnimation(1, 1); 361 scale.setDuration(duration); 362 scale.setInterpolator( 363 new DecelerateInterpolator(THUMBNAIL_ANIMATION_DECELERATE_FACTOR)); 364 set.addAnimation(scale); 365 alpha.setDuration(duration); 366 set.addAnimation(alpha); 367 set.setFillBefore(true); 368 369 a = set; 370 } 371 } else if (enter) { 372 // Entering app zooms out from the center of the thumbnail. 373 if (mNextAppTransitionScaleUp) { 374 float scaleW = thumbWidth / appWidth; 375 float scaleH = thumbHeight / appHeight; 376 Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1, 377 computePivot(mNextAppTransitionStartX, scaleW), 378 computePivot(mNextAppTransitionStartY, scaleH)); 379 scale.setDuration(duration); 380 scale.setInterpolator( 381 new DecelerateInterpolator(THUMBNAIL_ANIMATION_DECELERATE_FACTOR)); 382 scale.setFillBefore(true); 383 a = scale; 384 } else { 385 // noop animation 386 a = new AlphaAnimation(1, 1); 387 a.setDuration(duration); 388 } 389 } else { 390 // Exiting app 391 if (mNextAppTransitionScaleUp) { 392 if (transit == WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN) { 393 // Fade out while bringing up selected activity. This keeps the 394 // current activity from showing through a launching wallpaper 395 // activity. 396 a = new AlphaAnimation(1, 0); 397 } else { 398 // noop animation 399 a = new AlphaAnimation(1, 1); 400 } 401 a.setDuration(duration); 402 } else { 403 float scaleW = thumbWidth / appWidth; 404 float scaleH = thumbHeight / appHeight; 405 Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH, 406 computePivot(mNextAppTransitionStartX, scaleW), 407 computePivot(mNextAppTransitionStartY, scaleH)); 408 scale.setDuration(duration); 409 scale.setInterpolator( 410 new DecelerateInterpolator(THUMBNAIL_ANIMATION_DECELERATE_FACTOR)); 411 scale.setFillBefore(true); 412 AnimationSet set = new AnimationSet(true); 413 Animation alpha = new AlphaAnimation(1, 0); 414 set.addAnimation(scale); 415 alpha.setDuration(duration); 416 alpha.setInterpolator(new DecelerateInterpolator( 417 THUMBNAIL_ANIMATION_DECELERATE_FACTOR)); 418 set.addAnimation(alpha); 419 set.setFillBefore(true); 420 set.setZAdjustment(Animation.ZORDER_TOP); 421 a = set; 422 } 423 } 424 a.setFillAfter(true); 425 a.setInterpolator(mInterpolator); 426 a.initialize(appWidth, appHeight, appWidth, appHeight); 427 return a; 428 } 429 430 431 Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter, 432 int appWidth, int appHeight) { 433 Animation a; 434 if (mNextAppTransitionType == ActivityOptions.ANIM_CUSTOM) { 435 a = loadAnimation(mNextAppTransitionPackage, enter ? 436 mNextAppTransitionEnter : mNextAppTransitionExit); 437 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, 438 "applyAnimation:" 439 + " anim=" + a + " nextAppTransition=ANIM_CUSTOM" 440 + " transit=" + transit + " isEntrance=" + enter 441 + " Callers=" + Debug.getCallers(3)); 442 } else if (mNextAppTransitionType == ActivityOptions.ANIM_SCALE_UP) { 443 a = createScaleUpAnimationLocked(transit, enter, appWidth, appHeight); 444 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, 445 "applyAnimation:" 446 + " anim=" + a + " nextAppTransition=ANIM_SCALE_UP" 447 + " transit=" + transit + " isEntrance=" + enter 448 + " Callers=" + Debug.getCallers(3)); 449 } else if (mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL_SCALE_UP || 450 mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN) { 451 mNextAppTransitionScaleUp = 452 (mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL_SCALE_UP); 453 a = createThumbnailAnimationLocked(transit, enter, false, appWidth, appHeight); 454 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) { 455 String animName = mNextAppTransitionScaleUp ? 456 "ANIM_THUMBNAIL_SCALE_UP" : "ANIM_THUMBNAIL_SCALE_DOWN"; 457 Slog.v(TAG, "applyAnimation:" 458 + " anim=" + a + " nextAppTransition=" + animName 459 + " transit=" + transit + " isEntrance=" + enter 460 + " Callers=" + Debug.getCallers(3)); 461 } 462 } else { 463 int animAttr = 0; 464 switch (transit) { 465 case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN: 466 animAttr = enter 467 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation 468 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation; 469 break; 470 case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE: 471 animAttr = enter 472 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation 473 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation; 474 break; 475 case WindowManagerPolicy.TRANSIT_TASK_OPEN: 476 animAttr = enter 477 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation 478 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation; 479 break; 480 case WindowManagerPolicy.TRANSIT_TASK_CLOSE: 481 animAttr = enter 482 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation 483 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation; 484 break; 485 case WindowManagerPolicy.TRANSIT_TASK_TO_FRONT: 486 animAttr = enter 487 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation 488 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation; 489 break; 490 case WindowManagerPolicy.TRANSIT_TASK_TO_BACK: 491 animAttr = enter 492 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation 493 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation; 494 break; 495 case WindowManagerPolicy.TRANSIT_WALLPAPER_OPEN: 496 animAttr = enter 497 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation 498 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation; 499 break; 500 case WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE: 501 animAttr = enter 502 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation 503 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation; 504 break; 505 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN: 506 animAttr = enter 507 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation 508 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation; 509 break; 510 case WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE: 511 animAttr = enter 512 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation 513 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation; 514 break; 515 } 516 a = animAttr != 0 ? loadAnimation(lp, animAttr) : null; 517 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, 518 "applyAnimation:" 519 + " anim=" + a 520 + " animAttr=0x" + Integer.toHexString(animAttr) 521 + " transit=" + transit + " isEntrance=" + enter 522 + " Callers=" + Debug.getCallers(3)); 523 } 524 return a; 525 } 526 527 void postAnimationCallback() { 528 if (mNextAppTransitionCallback != null) { 529 mH.sendMessage(mH.obtainMessage(H.DO_ANIMATION_CALLBACK, mNextAppTransitionCallback)); 530 mNextAppTransitionCallback = null; 531 } 532 } 533 534 void overridePendingAppTransition(String packageName, int enterAnim, int exitAnim, 535 IRemoteCallback startedCallback) { 536 if (isTransitionSet()) { 537 mNextAppTransitionType = ActivityOptions.ANIM_CUSTOM; 538 mNextAppTransitionPackage = packageName; 539 mNextAppTransitionThumbnail = null; 540 mNextAppTransitionEnter = enterAnim; 541 mNextAppTransitionExit = exitAnim; 542 postAnimationCallback(); 543 mNextAppTransitionCallback = startedCallback; 544 } else { 545 postAnimationCallback(); 546 } 547 } 548 549 void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth, 550 int startHeight) { 551 if (isTransitionSet()) { 552 mNextAppTransitionType = ActivityOptions.ANIM_SCALE_UP; 553 mNextAppTransitionPackage = null; 554 mNextAppTransitionThumbnail = null; 555 mNextAppTransitionStartX = startX; 556 mNextAppTransitionStartY = startY; 557 mNextAppTransitionStartWidth = startWidth; 558 mNextAppTransitionStartHeight = startHeight; 559 postAnimationCallback(); 560 mNextAppTransitionCallback = null; 561 } 562 } 563 564 void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX, int startY, 565 IRemoteCallback startedCallback, boolean scaleUp) { 566 if (isTransitionSet()) { 567 mNextAppTransitionType = scaleUp ? ActivityOptions.ANIM_THUMBNAIL_SCALE_UP 568 : ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN; 569 mNextAppTransitionPackage = null; 570 mNextAppTransitionThumbnail = srcThumb; 571 mNextAppTransitionScaleUp = scaleUp; 572 mNextAppTransitionStartX = startX; 573 mNextAppTransitionStartY = startY; 574 postAnimationCallback(); 575 mNextAppTransitionCallback = startedCallback; 576 } else { 577 postAnimationCallback(); 578 } 579 } 580 581 @Override 582 public String toString() { 583 return "mNextAppTransition=0x" + Integer.toHexString(mNextAppTransition); 584 } 585 586 @Override 587 public void dump(PrintWriter pw) { 588 pw.print(" " + this); 589 pw.print(" mAppTransitionReady="); pw.println(mAppTransitionReady); 590 pw.print(" mAppTransitionRunning="); pw.print(mAppTransitionRunning); 591 pw.print(" mAppTransitionTimeout="); pw.println(mAppTransitionTimeout); 592 if (mNextAppTransitionType != ActivityOptions.ANIM_NONE) { 593 pw.print(" mNextAppTransitionType="); pw.println(mNextAppTransitionType); 594 } 595 switch (mNextAppTransitionType) { 596 case ActivityOptions.ANIM_CUSTOM: 597 pw.print(" mNextAppTransitionPackage="); 598 pw.println(mNextAppTransitionPackage); 599 pw.print(" mNextAppTransitionEnter=0x"); 600 pw.print(Integer.toHexString(mNextAppTransitionEnter)); 601 pw.print(" mNextAppTransitionExit=0x"); 602 pw.println(Integer.toHexString(mNextAppTransitionExit)); 603 break; 604 case ActivityOptions.ANIM_SCALE_UP: 605 pw.print(" mNextAppTransitionStartX="); pw.print(mNextAppTransitionStartX); 606 pw.print(" mNextAppTransitionStartY="); 607 pw.println(mNextAppTransitionStartY); 608 pw.print(" mNextAppTransitionStartWidth="); 609 pw.print(mNextAppTransitionStartWidth); 610 pw.print(" mNextAppTransitionStartHeight="); 611 pw.println(mNextAppTransitionStartHeight); 612 break; 613 case ActivityOptions.ANIM_THUMBNAIL_SCALE_UP: 614 case ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN: 615 pw.print(" mNextAppTransitionThumbnail="); 616 pw.print(mNextAppTransitionThumbnail); 617 pw.print(" mNextAppTransitionStartX="); 618 pw.print(mNextAppTransitionStartX); 619 pw.print(" mNextAppTransitionStartY="); 620 pw.println(mNextAppTransitionStartY); 621 pw.print(" mNextAppTransitionScaleUp="); pw.println(mNextAppTransitionScaleUp); 622 break; 623 } 624 if (mNextAppTransitionCallback != null) { 625 pw.print(" mNextAppTransitionCallback="); 626 pw.println(mNextAppTransitionCallback); 627 } 628 } 629} 630