AppTransition.java revision a4ccb86ddc8f9f486aee25fb836f4aff97bf7679
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.content.Context; 20import android.content.res.Configuration; 21import android.graphics.Bitmap; 22import android.graphics.Rect; 23import android.os.Debug; 24import android.os.Handler; 25import android.os.IRemoteCallback; 26import android.util.Slog; 27import android.view.WindowManager; 28import android.view.animation.AlphaAnimation; 29import android.view.animation.Animation; 30import android.view.animation.AnimationSet; 31import android.view.animation.AnimationUtils; 32import android.view.animation.ClipRectAnimation; 33import android.view.animation.Interpolator; 34import android.view.animation.ScaleAnimation; 35import android.view.animation.TranslateAnimation; 36import com.android.internal.util.DumpUtils.Dump; 37import com.android.server.AttributeCache; 38import com.android.server.wm.WindowManagerService.H; 39 40import java.io.PrintWriter; 41 42import static com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation; 43import static com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation; 44import static com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation; 45import static com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation; 46import static com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation; 47import static com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation; 48import static com.android.internal.R.styleable.WindowAnimation_launchTaskBehindBackgroundAnimation; 49import static com.android.internal.R.styleable.WindowAnimation_launchTaskBehindSourceAnimation; 50import static com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation; 51import static com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation; 52import static com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation; 53import static com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation; 54import static com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation; 55import static com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation; 56import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation; 57import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation; 58import static com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation; 59import static com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation; 60import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation; 61import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation; 62import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation; 63import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation; 64 65// State management of app transitions. When we are preparing for a 66// transition, mNextAppTransition will be the kind of transition to 67// perform or TRANSIT_NONE if we are not waiting. If we are waiting, 68// mOpeningApps and mClosingApps are the lists of tokens that will be 69// made visible or hidden at the next transition. 70public class AppTransition implements Dump { 71 private static final String TAG = "AppTransition"; 72 private static final boolean DEBUG_APP_TRANSITIONS = 73 WindowManagerService.DEBUG_APP_TRANSITIONS; 74 private static final boolean DEBUG_ANIM = WindowManagerService.DEBUG_ANIM; 75 76 77 /** Not set up for a transition. */ 78 public static final int TRANSIT_UNSET = -1; 79 /** No animation for transition. */ 80 public static final int TRANSIT_NONE = 0; 81 /** A window in a new activity is being opened on top of an existing one in the same task. */ 82 public static final int TRANSIT_ACTIVITY_OPEN = 6; 83 /** The window in the top-most activity is being closed to reveal the 84 * previous activity in the same task. */ 85 public static final int TRANSIT_ACTIVITY_CLOSE = 7; 86 /** A window in a new task is being opened on top of an existing one 87 * in another activity's task. */ 88 public static final int TRANSIT_TASK_OPEN = 8; 89 /** A window in the top-most activity is being closed to reveal the 90 * previous activity in a different task. */ 91 public static final int TRANSIT_TASK_CLOSE = 9; 92 /** A window in an existing task is being displayed on top of an existing one 93 * in another activity's task. */ 94 public static final int TRANSIT_TASK_TO_FRONT = 10; 95 /** A window in an existing task is being put below all other tasks. */ 96 public static final int TRANSIT_TASK_TO_BACK = 11; 97 /** A window in a new activity that doesn't have a wallpaper is being opened on top of one that 98 * does, effectively closing the wallpaper. */ 99 public static final int TRANSIT_WALLPAPER_CLOSE = 12; 100 /** A window in a new activity that does have a wallpaper is being opened on one that didn't, 101 * effectively opening the wallpaper. */ 102 public static final int TRANSIT_WALLPAPER_OPEN = 13; 103 /** A window in a new activity is being opened on top of an existing one, and both are on top 104 * of the wallpaper. */ 105 public static final int TRANSIT_WALLPAPER_INTRA_OPEN = 14; 106 /** The window in the top-most activity is being closed to reveal the previous activity, and 107 * both are on top of the wallpaper. */ 108 public static final int TRANSIT_WALLPAPER_INTRA_CLOSE = 15; 109 /** A window in a new task is being opened behind an existing one in another activity's task. 110 * The new window will show briefly and then be gone. */ 111 public static final int TRANSIT_TASK_OPEN_BEHIND = 16; 112 113 /** Fraction of animation at which the recents thumbnail stays completely transparent */ 114 private static final float RECENTS_THUMBNAIL_FADEIN_FRACTION = 0.7f; 115 /** Fraction of animation at which the recents thumbnail becomes completely transparent */ 116 private static final float RECENTS_THUMBNAIL_FADEOUT_FRACTION = 0.3f; 117 118 private static final int DEFAULT_APP_TRANSITION_DURATION = 250; 119 private static final int THUMBNAIL_APP_TRANSITION_DURATION = 300; 120 private static final int THUMBNAIL_APP_TRANSITION_ALPHA_DURATION = 325; 121 122 private final Context mContext; 123 private final Handler mH; 124 125 private int mNextAppTransition = TRANSIT_UNSET; 126 127 private static final int NEXT_TRANSIT_TYPE_NONE = 0; 128 private static final int NEXT_TRANSIT_TYPE_CUSTOM = 1; 129 private static final int NEXT_TRANSIT_TYPE_SCALE_UP = 2; 130 private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP = 3; 131 private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN = 4; 132 private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP = 5; 133 private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN = 6; 134 private int mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE; 135 136 // These are the possible states for the enter/exit activities during a thumbnail transition 137 private static final int THUMBNAIL_TRANSITION_ENTER_SCALE_UP = 0; 138 private static final int THUMBNAIL_TRANSITION_EXIT_SCALE_UP = 1; 139 private static final int THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN = 2; 140 private static final int THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN = 3; 141 142 private String mNextAppTransitionPackage; 143 private Bitmap mNextAppTransitionThumbnail; 144 // Used for thumbnail transitions. True if we're scaling up, false if scaling down 145 private boolean mNextAppTransitionScaleUp; 146 private IRemoteCallback mNextAppTransitionCallback; 147 private int mNextAppTransitionEnter; 148 private int mNextAppTransitionExit; 149 private int mNextAppTransitionStartX; 150 private int mNextAppTransitionStartY; 151 private int mNextAppTransitionStartWidth; 152 private int mNextAppTransitionStartHeight; 153 private Rect mNextAppTransitionInsets = new Rect(); 154 155 private Rect mTmpFromClipRect = new Rect(); 156 private Rect mTmpToClipRect = new Rect(); 157 158 private final static int APP_STATE_IDLE = 0; 159 private final static int APP_STATE_READY = 1; 160 private final static int APP_STATE_RUNNING = 2; 161 private final static int APP_STATE_TIMEOUT = 3; 162 private int mAppTransitionState = APP_STATE_IDLE; 163 164 private final int mConfigShortAnimTime; 165 private final Interpolator mDecelerateInterpolator; 166 private final Interpolator mThumbnailFadeInInterpolator; 167 private final Interpolator mThumbnailFadeOutInterpolator; 168 private final Interpolator mThumbnailFastOutSlowInInterpolator; 169 170 private int mCurrentUserId = 0; 171 172 AppTransition(Context context, Handler h) { 173 mContext = context; 174 mH = h; 175 mConfigShortAnimTime = context.getResources().getInteger( 176 com.android.internal.R.integer.config_shortAnimTime); 177 mDecelerateInterpolator = AnimationUtils.loadInterpolator(context, 178 com.android.internal.R.interpolator.decelerate_cubic); 179 mThumbnailFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context, 180 com.android.internal.R.interpolator.fast_out_slow_in); 181 mThumbnailFadeInInterpolator = new Interpolator() { 182 @Override 183 public float getInterpolation(float input) { 184 // Linear response for first fraction, then complete after that. 185 if (input < RECENTS_THUMBNAIL_FADEIN_FRACTION) { 186 return 0f; 187 } 188 return (input - RECENTS_THUMBNAIL_FADEIN_FRACTION) / 189 (1f - RECENTS_THUMBNAIL_FADEIN_FRACTION); 190 } 191 }; 192 mThumbnailFadeOutInterpolator = new Interpolator() { 193 @Override 194 public float getInterpolation(float input) { 195 // Linear response for first fraction, then complete after that. 196 if (input < RECENTS_THUMBNAIL_FADEOUT_FRACTION) { 197 return input / RECENTS_THUMBNAIL_FADEOUT_FRACTION; 198 } 199 return 1f; 200 } 201 }; 202 } 203 204 boolean isTransitionSet() { 205 return mNextAppTransition != TRANSIT_UNSET; 206 } 207 208 boolean isTransitionNone() { 209 return mNextAppTransition == TRANSIT_NONE; 210 } 211 212 boolean isTransitionEqual(int transit) { 213 return mNextAppTransition == transit; 214 } 215 216 int getAppTransition() { 217 return mNextAppTransition; 218 } 219 220 void setAppTransition(int transit) { 221 mNextAppTransition = transit; 222 } 223 224 boolean isReady() { 225 return mAppTransitionState == APP_STATE_READY 226 || mAppTransitionState == APP_STATE_TIMEOUT; 227 } 228 229 void setReady() { 230 mAppTransitionState = APP_STATE_READY; 231 } 232 233 boolean isRunning() { 234 return mAppTransitionState == APP_STATE_RUNNING; 235 } 236 237 void setIdle() { 238 mAppTransitionState = APP_STATE_IDLE; 239 } 240 241 boolean isTimeout() { 242 return mAppTransitionState == APP_STATE_TIMEOUT; 243 } 244 245 void setTimeout() { 246 mAppTransitionState = APP_STATE_TIMEOUT; 247 } 248 249 Bitmap getNextAppTransitionThumbnail() { 250 return mNextAppTransitionThumbnail; 251 } 252 253 /** Returns whether the next thumbnail transition is aspect scaled up. */ 254 boolean isNextThumbnailTransitionAspectScaled() { 255 return mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP || 256 mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN; 257 } 258 259 /** Returns whether the next thumbnail transition is scaling up. */ 260 boolean isNextThumbnailTransitionScaleUp() { 261 return mNextAppTransitionScaleUp; 262 } 263 264 int getStartingX() { 265 return mNextAppTransitionStartX; 266 } 267 268 int getStartingY() { 269 return mNextAppTransitionStartY; 270 } 271 272 void prepare() { 273 if (!isRunning()) { 274 mAppTransitionState = APP_STATE_IDLE; 275 } 276 } 277 278 void goodToGo() { 279 mNextAppTransition = TRANSIT_UNSET; 280 mAppTransitionState = APP_STATE_RUNNING; 281 } 282 283 void clear() { 284 mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE; 285 mNextAppTransitionPackage = null; 286 mNextAppTransitionThumbnail = null; 287 } 288 289 void freeze() { 290 setAppTransition(AppTransition.TRANSIT_UNSET); 291 clear(); 292 setReady(); 293 } 294 295 private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) { 296 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: layout params pkg=" 297 + (lp != null ? lp.packageName : null) 298 + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null)); 299 if (lp != null && lp.windowAnimations != 0) { 300 // If this is a system resource, don't try to load it from the 301 // application resources. It is nice to avoid loading application 302 // resources if we can. 303 String packageName = lp.packageName != null ? lp.packageName : "android"; 304 int resId = lp.windowAnimations; 305 if ((resId&0xFF000000) == 0x01000000) { 306 packageName = "android"; 307 } 308 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package=" 309 + packageName); 310 return AttributeCache.instance().get(packageName, resId, 311 com.android.internal.R.styleable.WindowAnimation, mCurrentUserId); 312 } 313 return null; 314 } 315 316 private AttributeCache.Entry getCachedAnimations(String packageName, int resId) { 317 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: package=" 318 + packageName + " resId=0x" + Integer.toHexString(resId)); 319 if (packageName != null) { 320 if ((resId&0xFF000000) == 0x01000000) { 321 packageName = "android"; 322 } 323 if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package=" 324 + packageName); 325 return AttributeCache.instance().get(packageName, resId, 326 com.android.internal.R.styleable.WindowAnimation, mCurrentUserId); 327 } 328 return null; 329 } 330 331 Animation loadAnimationAttr(WindowManager.LayoutParams lp, int animAttr) { 332 int anim = 0; 333 Context context = mContext; 334 if (animAttr >= 0) { 335 AttributeCache.Entry ent = getCachedAnimations(lp); 336 if (ent != null) { 337 context = ent.context; 338 anim = ent.array.getResourceId(animAttr, 0); 339 } 340 } 341 if (anim != 0) { 342 return AnimationUtils.loadAnimation(context, anim); 343 } 344 return null; 345 } 346 347 Animation loadAnimationRes(WindowManager.LayoutParams lp, int resId) { 348 Context context = mContext; 349 if (resId >= 0) { 350 AttributeCache.Entry ent = getCachedAnimations(lp); 351 if (ent != null) { 352 context = ent.context; 353 } 354 return AnimationUtils.loadAnimation(context, resId); 355 } 356 return null; 357 } 358 359 private Animation loadAnimationRes(String packageName, int resId) { 360 int anim = 0; 361 Context context = mContext; 362 if (resId >= 0) { 363 AttributeCache.Entry ent = getCachedAnimations(packageName, resId); 364 if (ent != null) { 365 context = ent.context; 366 anim = resId; 367 } 368 } 369 if (anim != 0) { 370 return AnimationUtils.loadAnimation(context, anim); 371 } 372 return null; 373 } 374 375 /** 376 * Compute the pivot point for an animation that is scaling from a small 377 * rect on screen to a larger rect. The pivot point varies depending on 378 * the distance between the inner and outer edges on both sides. This 379 * function computes the pivot point for one dimension. 380 * @param startPos Offset from left/top edge of outer rectangle to 381 * left/top edge of inner rectangle. 382 * @param finalScale The scaling factor between the size of the outer 383 * and inner rectangles. 384 */ 385 private static float computePivot(int startPos, float finalScale) { 386 final float denom = finalScale-1; 387 if (Math.abs(denom) < .0001f) { 388 return startPos; 389 } 390 return -startPos / denom; 391 } 392 393 private Animation createScaleUpAnimationLocked(int transit, boolean enter, 394 int appWidth, int appHeight) { 395 Animation a = null; 396 if (enter) { 397 // Entering app zooms out from the center of the initial rect. 398 float scaleW = mNextAppTransitionStartWidth / (float) appWidth; 399 float scaleH = mNextAppTransitionStartHeight / (float) appHeight; 400 Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1, 401 computePivot(mNextAppTransitionStartX, scaleW), 402 computePivot(mNextAppTransitionStartY, scaleH)); 403 scale.setInterpolator(mDecelerateInterpolator); 404 405 Animation alpha = new AlphaAnimation(0, 1); 406 alpha.setInterpolator(mThumbnailFadeOutInterpolator); 407 408 AnimationSet set = new AnimationSet(false); 409 set.addAnimation(scale); 410 set.addAnimation(alpha); 411 set.setDetachWallpaper(true); 412 a = set; 413 } else if (transit == TRANSIT_WALLPAPER_INTRA_OPEN || 414 transit == TRANSIT_WALLPAPER_INTRA_CLOSE) { 415 // If we are on top of the wallpaper, we need an animation that 416 // correctly handles the wallpaper staying static behind all of 417 // the animated elements. To do this, will just have the existing 418 // element fade out. 419 a = new AlphaAnimation(1, 0); 420 a.setDetachWallpaper(true); 421 } else { 422 // For normal animations, the exiting element just holds in place. 423 a = new AlphaAnimation(1, 1); 424 } 425 426 // Pick the desired duration. If this is an inter-activity transition, 427 // it is the standard duration for that. Otherwise we use the longer 428 // task transition duration. 429 final long duration; 430 switch (transit) { 431 case TRANSIT_ACTIVITY_OPEN: 432 case TRANSIT_ACTIVITY_CLOSE: 433 duration = mConfigShortAnimTime; 434 break; 435 default: 436 duration = DEFAULT_APP_TRANSITION_DURATION; 437 break; 438 } 439 a.setDuration(duration); 440 a.setFillAfter(true); 441 a.setInterpolator(mDecelerateInterpolator); 442 a.initialize(appWidth, appHeight, appWidth, appHeight); 443 return a; 444 } 445 446 /** 447 * Prepares the specified animation with a standard duration, interpolator, etc. 448 */ 449 Animation prepareThumbnailAnimationWithDuration(Animation a, int appWidth, int appHeight, 450 int duration, Interpolator interpolator) { 451 if (duration > 0) { 452 a.setDuration(duration); 453 } 454 a.setFillAfter(true); 455 a.setInterpolator(interpolator); 456 a.initialize(appWidth, appHeight, appWidth, appHeight); 457 return a; 458 } 459 460 /** 461 * Prepares the specified animation with a standard duration, interpolator, etc. 462 */ 463 Animation prepareThumbnailAnimation(Animation a, int appWidth, int appHeight, int transit) { 464 // Pick the desired duration. If this is an inter-activity transition, 465 // it is the standard duration for that. Otherwise we use the longer 466 // task transition duration. 467 final int duration; 468 switch (transit) { 469 case TRANSIT_ACTIVITY_OPEN: 470 case TRANSIT_ACTIVITY_CLOSE: 471 duration = mConfigShortAnimTime; 472 break; 473 default: 474 duration = DEFAULT_APP_TRANSITION_DURATION; 475 break; 476 } 477 return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, duration, 478 mDecelerateInterpolator); 479 } 480 481 /** 482 * Return the current thumbnail transition state. 483 */ 484 int getThumbnailTransitionState(boolean enter) { 485 if (enter) { 486 if (mNextAppTransitionScaleUp) { 487 return THUMBNAIL_TRANSITION_ENTER_SCALE_UP; 488 } else { 489 return THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN; 490 } 491 } else { 492 if (mNextAppTransitionScaleUp) { 493 return THUMBNAIL_TRANSITION_EXIT_SCALE_UP; 494 } else { 495 return THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN; 496 } 497 } 498 } 499 500 /** 501 * This animation runs for the thumbnail that gets cross faded with the enter/exit activity 502 * when a thumbnail is specified with the activity options. 503 */ 504 Animation createThumbnailAspectScaleAnimationLocked(int appWidth, int appHeight, 505 int deviceWidth, int transit) { 506 Animation a; 507 final int thumbWidthI = mNextAppTransitionThumbnail.getWidth(); 508 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1; 509 final int thumbHeightI = mNextAppTransitionThumbnail.getHeight(); 510 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1; 511 512 float scaleW = deviceWidth / thumbWidth; 513 float unscaledWidth = deviceWidth; 514 float unscaledHeight = thumbHeight * scaleW; 515 float unscaledStartY = mNextAppTransitionStartY - (unscaledHeight - thumbHeight) / 2f; 516 if (mNextAppTransitionScaleUp) { 517 // Animation up from the thumbnail to the full screen 518 Animation scale = new ScaleAnimation(1f, scaleW, 1f, scaleW, 519 mNextAppTransitionStartX + (thumbWidth / 2f), 520 mNextAppTransitionStartY + (thumbHeight / 2f)); 521 scale.setInterpolator(mThumbnailFastOutSlowInInterpolator); 522 scale.setDuration(THUMBNAIL_APP_TRANSITION_DURATION); 523 Animation alpha = new AlphaAnimation(1, 0); 524 alpha.setInterpolator(mThumbnailFadeOutInterpolator); 525 alpha.setDuration(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION); 526 Animation translate = new TranslateAnimation(0, 0, 0, -unscaledStartY + 527 mNextAppTransitionInsets.top); 528 translate.setInterpolator(mThumbnailFastOutSlowInInterpolator); 529 translate.setDuration(THUMBNAIL_APP_TRANSITION_DURATION); 530 531 // This AnimationSet uses the Interpolators assigned above. 532 AnimationSet set = new AnimationSet(false); 533 set.addAnimation(scale); 534 set.addAnimation(alpha); 535 set.addAnimation(translate); 536 a = set; 537 } else { 538 // Animation down from the full screen to the thumbnail 539 Animation scale = new ScaleAnimation(scaleW, 1f, scaleW, 1f, 540 mNextAppTransitionStartX + (thumbWidth / 2f), 541 mNextAppTransitionStartY + (thumbHeight / 2f)); 542 scale.setInterpolator(mThumbnailFastOutSlowInInterpolator); 543 scale.setDuration(THUMBNAIL_APP_TRANSITION_DURATION); 544 Animation alpha = new AlphaAnimation(0f, 1f); 545 alpha.setInterpolator(mThumbnailFadeInInterpolator); 546 alpha.setDuration(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION); 547 Animation translate = new TranslateAnimation(0, 0, -unscaledStartY + 548 mNextAppTransitionInsets.top, 0); 549 translate.setInterpolator(mThumbnailFastOutSlowInInterpolator); 550 translate.setDuration(THUMBNAIL_APP_TRANSITION_DURATION); 551 552 // This AnimationSet uses the Interpolators assigned above. 553 AnimationSet set = new AnimationSet(false); 554 set.addAnimation(scale); 555 set.addAnimation(alpha); 556 set.addAnimation(translate); 557 a = set; 558 559 } 560 return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, 0, 561 mThumbnailFastOutSlowInInterpolator); 562 } 563 564 /** 565 * This alternate animation is created when we are doing a thumbnail transition, for the 566 * activity that is leaving, and the activity that is entering. 567 */ 568 Animation createAspectScaledThumbnailEnterExitAnimationLocked(int thumbTransitState, 569 int appWidth, int appHeight, int orientation, int transit, Rect containingFrame, 570 Rect contentInsets, boolean isFullScreen) { 571 Animation a; 572 final int thumbWidthI = mNextAppTransitionThumbnail.getWidth(); 573 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1; 574 final int thumbHeightI = mNextAppTransitionThumbnail.getHeight(); 575 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1; 576 577 // Used for the ENTER_SCALE_UP and EXIT_SCALE_DOWN transitions 578 float scale = 1f; 579 int scaledTopDecor = 0; 580 581 switch (thumbTransitState) { 582 case THUMBNAIL_TRANSITION_ENTER_SCALE_UP: { 583 // App window scaling up to become full screen 584 if (orientation == Configuration.ORIENTATION_PORTRAIT) { 585 // In portrait, we scale the width and clip to the top/left square 586 scale = thumbWidth / appWidth; 587 scaledTopDecor = (int) (scale * contentInsets.top); 588 int unscaledThumbHeight = (int) (thumbHeight / scale); 589 mTmpFromClipRect.set(containingFrame); 590 if (isFullScreen) { 591 mTmpFromClipRect.top = contentInsets.top; 592 } 593 mTmpFromClipRect.bottom = (mTmpFromClipRect.top + unscaledThumbHeight); 594 mTmpToClipRect.set(containingFrame); 595 } else { 596 // In landscape, we scale the height and clip to the top/left square 597 scale = thumbHeight / (appHeight - contentInsets.top); 598 scaledTopDecor = (int) (scale * contentInsets.top); 599 int unscaledThumbWidth = (int) (thumbWidth / scale); 600 int unscaledThumbHeight = (int) (thumbHeight / scale); 601 mTmpFromClipRect.set(containingFrame); 602 if (isFullScreen) { 603 mTmpFromClipRect.top = contentInsets.top; 604 mTmpFromClipRect.bottom = (mTmpFromClipRect.top + unscaledThumbHeight); 605 } 606 mTmpFromClipRect.right = (mTmpFromClipRect.left + unscaledThumbWidth); 607 mTmpToClipRect.set(containingFrame); 608 } 609 mNextAppTransitionInsets.set(contentInsets); 610 611 Animation scaleAnim = new ScaleAnimation(scale, 1, scale, 1, 612 computePivot(mNextAppTransitionStartX, scale), 613 computePivot(mNextAppTransitionStartY, scale)); 614 Animation clipAnim = new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect); 615 Animation translateAnim = new TranslateAnimation(0, 0, -scaledTopDecor, 0); 616 617 AnimationSet set = new AnimationSet(true); 618 set.addAnimation(clipAnim); 619 set.addAnimation(scaleAnim); 620 set.addAnimation(translateAnim); 621 a = set; 622 break; 623 } 624 case THUMBNAIL_TRANSITION_EXIT_SCALE_UP: { 625 // Previous app window during the scale up 626 if (transit == TRANSIT_WALLPAPER_INTRA_OPEN) { 627 // Fade out the source activity if we are animating to a wallpaper 628 // activity. 629 a = new AlphaAnimation(1, 0); 630 } else { 631 a = new AlphaAnimation(1, 1); 632 } 633 break; 634 } 635 case THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN: { 636 // Target app window during the scale down 637 if (transit == TRANSIT_WALLPAPER_INTRA_OPEN) { 638 // Fade in the destination activity if we are animating from a wallpaper 639 // activity. 640 a = new AlphaAnimation(0, 1); 641 } else { 642 a = new AlphaAnimation(1, 1); 643 } 644 break; 645 } 646 case THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN: { 647 // App window scaling down from full screen 648 if (orientation == Configuration.ORIENTATION_PORTRAIT) { 649 // In portrait, we scale the width and clip to the top/left square 650 scale = thumbWidth / appWidth; 651 scaledTopDecor = (int) (scale * contentInsets.top); 652 int unscaledThumbHeight = (int) (thumbHeight / scale); 653 mTmpFromClipRect.set(containingFrame); 654 mTmpToClipRect.set(containingFrame); 655 if (isFullScreen) { 656 mTmpToClipRect.top = contentInsets.top; 657 } 658 mTmpToClipRect.bottom = (mTmpToClipRect.top + unscaledThumbHeight); 659 } else { 660 // In landscape, we scale the height and clip to the top/left square 661 scale = thumbHeight / (appHeight - contentInsets.top); 662 scaledTopDecor = (int) (scale * contentInsets.top); 663 int unscaledThumbWidth = (int) (thumbWidth / scale); 664 int unscaledThumbHeight = (int) (thumbHeight / scale); 665 mTmpFromClipRect.set(containingFrame); 666 mTmpToClipRect.set(containingFrame); 667 if (isFullScreen) { 668 mTmpToClipRect.top = contentInsets.top; 669 mTmpToClipRect.bottom = (mTmpToClipRect.top + unscaledThumbHeight); 670 } 671 mTmpToClipRect.right = (mTmpToClipRect.left + unscaledThumbWidth); 672 } 673 mNextAppTransitionInsets.set(contentInsets); 674 675 Animation scaleAnim = new ScaleAnimation(1, scale, 1, scale, 676 computePivot(mNextAppTransitionStartX, scale), 677 computePivot(mNextAppTransitionStartY, scale)); 678 Animation clipAnim = new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect); 679 Animation translateAnim = new TranslateAnimation(0, 0, 0, -scaledTopDecor); 680 681 AnimationSet set = new AnimationSet(true); 682 set.addAnimation(clipAnim); 683 set.addAnimation(scaleAnim); 684 set.addAnimation(translateAnim); 685 686 a = set; 687 a.setZAdjustment(Animation.ZORDER_TOP); 688 break; 689 } 690 default: 691 throw new RuntimeException("Invalid thumbnail transition state"); 692 } 693 694 return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, 695 THUMBNAIL_APP_TRANSITION_DURATION, mThumbnailFastOutSlowInInterpolator); 696 } 697 698 /** 699 * This animation runs for the thumbnail that gets cross faded with the enter/exit activity 700 * when a thumbnail is specified with the activity options. 701 */ 702 Animation createThumbnailScaleAnimationLocked(int appWidth, int appHeight, int transit) { 703 Animation a; 704 final int thumbWidthI = mNextAppTransitionThumbnail.getWidth(); 705 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1; 706 final int thumbHeightI = mNextAppTransitionThumbnail.getHeight(); 707 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1; 708 709 if (mNextAppTransitionScaleUp) { 710 // Animation for the thumbnail zooming from its initial size to the full screen 711 float scaleW = appWidth / thumbWidth; 712 float scaleH = appHeight / thumbHeight; 713 Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH, 714 computePivot(mNextAppTransitionStartX, 1 / scaleW), 715 computePivot(mNextAppTransitionStartY, 1 / scaleH)); 716 scale.setInterpolator(mDecelerateInterpolator); 717 718 Animation alpha = new AlphaAnimation(1, 0); 719 alpha.setInterpolator(mThumbnailFadeOutInterpolator); 720 721 // This AnimationSet uses the Interpolators assigned above. 722 AnimationSet set = new AnimationSet(false); 723 set.addAnimation(scale); 724 set.addAnimation(alpha); 725 a = set; 726 } else { 727 // Animation for the thumbnail zooming down from the full screen to its final size 728 float scaleW = appWidth / thumbWidth; 729 float scaleH = appHeight / thumbHeight; 730 a = new ScaleAnimation(scaleW, 1, scaleH, 1, 731 computePivot(mNextAppTransitionStartX, 1 / scaleW), 732 computePivot(mNextAppTransitionStartY, 1 / scaleH)); 733 } 734 735 return prepareThumbnailAnimation(a, appWidth, appHeight, transit); 736 } 737 738 /** 739 * This animation is created when we are doing a thumbnail transition, for the activity that is 740 * leaving, and the activity that is entering. 741 */ 742 Animation createThumbnailEnterExitAnimationLocked(int thumbTransitState, int appWidth, 743 int appHeight, int transit) { 744 Animation a; 745 final int thumbWidthI = mNextAppTransitionThumbnail.getWidth(); 746 final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1; 747 final int thumbHeightI = mNextAppTransitionThumbnail.getHeight(); 748 final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1; 749 750 switch (thumbTransitState) { 751 case THUMBNAIL_TRANSITION_ENTER_SCALE_UP: { 752 // Entering app scales up with the thumbnail 753 float scaleW = thumbWidth / appWidth; 754 float scaleH = thumbHeight / appHeight; 755 a = new ScaleAnimation(scaleW, 1, scaleH, 1, 756 computePivot(mNextAppTransitionStartX, scaleW), 757 computePivot(mNextAppTransitionStartY, scaleH)); 758 break; 759 } 760 case THUMBNAIL_TRANSITION_EXIT_SCALE_UP: { 761 // Exiting app while the thumbnail is scaling up should fade or stay in place 762 if (transit == TRANSIT_WALLPAPER_INTRA_OPEN) { 763 // Fade out while bringing up selected activity. This keeps the 764 // current activity from showing through a launching wallpaper 765 // activity. 766 a = new AlphaAnimation(1, 0); 767 } else { 768 // noop animation 769 a = new AlphaAnimation(1, 1); 770 } 771 break; 772 } 773 case THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN: { 774 // Entering the other app, it should just be visible while we scale the thumbnail 775 // down above it 776 a = new AlphaAnimation(1, 1); 777 break; 778 } 779 case THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN: { 780 // Exiting the current app, the app should scale down with the thumbnail 781 float scaleW = thumbWidth / appWidth; 782 float scaleH = thumbHeight / appHeight; 783 Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH, 784 computePivot(mNextAppTransitionStartX, scaleW), 785 computePivot(mNextAppTransitionStartY, scaleH)); 786 787 Animation alpha = new AlphaAnimation(1, 0); 788 789 AnimationSet set = new AnimationSet(true); 790 set.addAnimation(scale); 791 set.addAnimation(alpha); 792 set.setZAdjustment(Animation.ZORDER_TOP); 793 a = set; 794 break; 795 } 796 default: 797 throw new RuntimeException("Invalid thumbnail transition state"); 798 } 799 800 return prepareThumbnailAnimation(a, appWidth, appHeight, transit); 801 } 802 803 804 Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter, 805 int appWidth, int appHeight, int orientation, Rect containingFrame, Rect contentInsets, 806 boolean isFullScreen, boolean isVoiceInteraction) { 807 Animation a; 808 if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_OPEN 809 || transit == TRANSIT_TASK_OPEN 810 || transit == TRANSIT_TASK_TO_FRONT)) { 811 a = loadAnimationRes(lp, enter 812 ? com.android.internal.R.anim.voice_activity_open_enter 813 : com.android.internal.R.anim.voice_activity_open_exit); 814 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, 815 "applyAnimation voice:" 816 + " anim=" + a + " transit=" + transit + " isEntrance=" + enter 817 + " Callers=" + Debug.getCallers(3)); 818 } else if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_CLOSE 819 || transit == TRANSIT_TASK_CLOSE 820 || transit == TRANSIT_TASK_TO_BACK)) { 821 a = loadAnimationRes(lp, enter 822 ? com.android.internal.R.anim.voice_activity_close_enter 823 : com.android.internal.R.anim.voice_activity_close_exit); 824 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, 825 "applyAnimation voice:" 826 + " anim=" + a + " transit=" + transit + " isEntrance=" + enter 827 + " Callers=" + Debug.getCallers(3)); 828 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) { 829 a = loadAnimationRes(mNextAppTransitionPackage, enter ? 830 mNextAppTransitionEnter : mNextAppTransitionExit); 831 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, 832 "applyAnimation:" 833 + " anim=" + a + " nextAppTransition=ANIM_CUSTOM" 834 + " transit=" + transit + " isEntrance=" + enter 835 + " Callers=" + Debug.getCallers(3)); 836 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_SCALE_UP) { 837 a = createScaleUpAnimationLocked(transit, enter, appWidth, appHeight); 838 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, 839 "applyAnimation:" 840 + " anim=" + a + " nextAppTransition=ANIM_SCALE_UP" 841 + " transit=" + transit + " isEntrance=" + enter 842 + " Callers=" + Debug.getCallers(3)); 843 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP || 844 mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN) { 845 mNextAppTransitionScaleUp = 846 (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP); 847 a = createThumbnailEnterExitAnimationLocked(getThumbnailTransitionState(enter), 848 appWidth, appHeight, transit); 849 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) { 850 String animName = mNextAppTransitionScaleUp ? 851 "ANIM_THUMBNAIL_SCALE_UP" : "ANIM_THUMBNAIL_SCALE_DOWN"; 852 Slog.v(TAG, "applyAnimation:" 853 + " anim=" + a + " nextAppTransition=" + animName 854 + " transit=" + transit + " isEntrance=" + enter 855 + " Callers=" + Debug.getCallers(3)); 856 } 857 } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP || 858 mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN) { 859 mNextAppTransitionScaleUp = 860 (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP); 861 a = createAspectScaledThumbnailEnterExitAnimationLocked( 862 getThumbnailTransitionState(enter), appWidth, appHeight, orientation, 863 transit, containingFrame, contentInsets, isFullScreen); 864 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) { 865 String animName = mNextAppTransitionScaleUp ? 866 "ANIM_THUMBNAIL_ASPECT_SCALE_UP" : "ANIM_THUMBNAIL_ASPECT_SCALE_DOWN"; 867 Slog.v(TAG, "applyAnimation:" 868 + " anim=" + a + " nextAppTransition=" + animName 869 + " transit=" + transit + " isEntrance=" + enter 870 + " Callers=" + Debug.getCallers(3)); 871 } 872 } else { 873 int animAttr = 0; 874 switch (transit) { 875 case TRANSIT_ACTIVITY_OPEN: 876 animAttr = enter 877 ? WindowAnimation_activityOpenEnterAnimation 878 : WindowAnimation_activityOpenExitAnimation; 879 break; 880 case TRANSIT_ACTIVITY_CLOSE: 881 animAttr = enter 882 ? WindowAnimation_activityCloseEnterAnimation 883 : WindowAnimation_activityCloseExitAnimation; 884 break; 885 case TRANSIT_TASK_OPEN: 886 animAttr = enter 887 ? WindowAnimation_taskOpenEnterAnimation 888 : WindowAnimation_taskOpenExitAnimation; 889 break; 890 case TRANSIT_TASK_CLOSE: 891 animAttr = enter 892 ? WindowAnimation_taskCloseEnterAnimation 893 : WindowAnimation_taskCloseExitAnimation; 894 break; 895 case TRANSIT_TASK_TO_FRONT: 896 animAttr = enter 897 ? WindowAnimation_taskToFrontEnterAnimation 898 : WindowAnimation_taskToFrontExitAnimation; 899 break; 900 case TRANSIT_TASK_TO_BACK: 901 animAttr = enter 902 ? WindowAnimation_taskToBackEnterAnimation 903 : WindowAnimation_taskToBackExitAnimation; 904 break; 905 case TRANSIT_WALLPAPER_OPEN: 906 animAttr = enter 907 ? WindowAnimation_wallpaperOpenEnterAnimation 908 : WindowAnimation_wallpaperOpenExitAnimation; 909 break; 910 case TRANSIT_WALLPAPER_CLOSE: 911 animAttr = enter 912 ? WindowAnimation_wallpaperCloseEnterAnimation 913 : WindowAnimation_wallpaperCloseExitAnimation; 914 break; 915 case TRANSIT_WALLPAPER_INTRA_OPEN: 916 animAttr = enter 917 ? WindowAnimation_wallpaperIntraOpenEnterAnimation 918 : WindowAnimation_wallpaperIntraOpenExitAnimation; 919 break; 920 case TRANSIT_WALLPAPER_INTRA_CLOSE: 921 animAttr = enter 922 ? WindowAnimation_wallpaperIntraCloseEnterAnimation 923 : WindowAnimation_wallpaperIntraCloseExitAnimation; 924 break; 925 case TRANSIT_TASK_OPEN_BEHIND: 926 animAttr = enter 927 ? WindowAnimation_launchTaskBehindSourceAnimation 928 : WindowAnimation_launchTaskBehindBackgroundAnimation; 929 } 930 a = animAttr != 0 ? loadAnimationAttr(lp, animAttr) : null; 931 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, 932 "applyAnimation:" 933 + " anim=" + a 934 + " animAttr=0x" + Integer.toHexString(animAttr) 935 + " transit=" + transit + " isEntrance=" + enter 936 + " Callers=" + Debug.getCallers(3)); 937 } 938 return a; 939 } 940 941 void postAnimationCallback() { 942 if (mNextAppTransitionCallback != null) { 943 mH.sendMessage(mH.obtainMessage(H.DO_ANIMATION_CALLBACK, mNextAppTransitionCallback)); 944 mNextAppTransitionCallback = null; 945 } 946 } 947 948 void overridePendingAppTransition(String packageName, int enterAnim, int exitAnim, 949 IRemoteCallback startedCallback) { 950 if (isTransitionSet()) { 951 mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM; 952 mNextAppTransitionPackage = packageName; 953 mNextAppTransitionThumbnail = null; 954 mNextAppTransitionEnter = enterAnim; 955 mNextAppTransitionExit = exitAnim; 956 postAnimationCallback(); 957 mNextAppTransitionCallback = startedCallback; 958 } else { 959 postAnimationCallback(); 960 } 961 } 962 963 void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth, 964 int startHeight) { 965 if (isTransitionSet()) { 966 mNextAppTransitionType = NEXT_TRANSIT_TYPE_SCALE_UP; 967 mNextAppTransitionPackage = null; 968 mNextAppTransitionThumbnail = null; 969 mNextAppTransitionStartX = startX; 970 mNextAppTransitionStartY = startY; 971 mNextAppTransitionStartWidth = startWidth; 972 mNextAppTransitionStartHeight = startHeight; 973 postAnimationCallback(); 974 mNextAppTransitionCallback = null; 975 } 976 } 977 978 void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX, int startY, 979 IRemoteCallback startedCallback, boolean scaleUp) { 980 if (isTransitionSet()) { 981 mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP 982 : NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN; 983 mNextAppTransitionPackage = null; 984 mNextAppTransitionThumbnail = srcThumb; 985 mNextAppTransitionScaleUp = scaleUp; 986 mNextAppTransitionStartX = startX; 987 mNextAppTransitionStartY = startY; 988 postAnimationCallback(); 989 mNextAppTransitionCallback = startedCallback; 990 } else { 991 postAnimationCallback(); 992 } 993 } 994 995 void overridePendingAppTransitionAspectScaledThumb(Bitmap srcThumb, int startX, int startY, 996 IRemoteCallback startedCallback, boolean scaleUp) { 997 if (isTransitionSet()) { 998 mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP 999 : NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN; 1000 mNextAppTransitionPackage = null; 1001 mNextAppTransitionThumbnail = srcThumb; 1002 mNextAppTransitionScaleUp = scaleUp; 1003 mNextAppTransitionStartX = startX; 1004 mNextAppTransitionStartY = startY; 1005 postAnimationCallback(); 1006 mNextAppTransitionCallback = startedCallback; 1007 } else { 1008 postAnimationCallback(); 1009 } 1010 } 1011 1012 @Override 1013 public String toString() { 1014 return "mNextAppTransition=0x" + Integer.toHexString(mNextAppTransition); 1015 } 1016 1017 /** 1018 * Returns the human readable name of a window transition. 1019 * 1020 * @param transition The window transition. 1021 * @return The transition symbolic name. 1022 */ 1023 public static String appTransitionToString(int transition) { 1024 switch (transition) { 1025 case TRANSIT_UNSET: { 1026 return "TRANSIT_UNSET"; 1027 } 1028 case TRANSIT_NONE: { 1029 return "TRANSIT_NONE"; 1030 } 1031 case TRANSIT_ACTIVITY_OPEN: { 1032 return "TRANSIT_ACTIVITY_OPEN"; 1033 } 1034 case TRANSIT_ACTIVITY_CLOSE: { 1035 return "TRANSIT_ACTIVITY_CLOSE"; 1036 } 1037 case TRANSIT_TASK_OPEN: { 1038 return "TRANSIT_TASK_OPEN"; 1039 } 1040 case TRANSIT_TASK_CLOSE: { 1041 return "TRANSIT_TASK_CLOSE"; 1042 } 1043 case TRANSIT_TASK_TO_FRONT: { 1044 return "TRANSIT_TASK_TO_FRONT"; 1045 } 1046 case TRANSIT_TASK_TO_BACK: { 1047 return "TRANSIT_TASK_TO_BACK"; 1048 } 1049 case TRANSIT_WALLPAPER_CLOSE: { 1050 return "TRANSIT_WALLPAPER_CLOSE"; 1051 } 1052 case TRANSIT_WALLPAPER_OPEN: { 1053 return "TRANSIT_WALLPAPER_OPEN"; 1054 } 1055 case TRANSIT_WALLPAPER_INTRA_OPEN: { 1056 return "TRANSIT_WALLPAPER_INTRA_OPEN"; 1057 } 1058 case TRANSIT_WALLPAPER_INTRA_CLOSE: { 1059 return "TRANSIT_WALLPAPER_INTRA_CLOSE"; 1060 } 1061 case TRANSIT_TASK_OPEN_BEHIND: { 1062 return "TRANSIT_TASK_OPEN_BEHIND"; 1063 } 1064 default: { 1065 return "<UNKNOWN>"; 1066 } 1067 } 1068 } 1069 1070 private String appStateToString() { 1071 switch (mAppTransitionState) { 1072 case APP_STATE_IDLE: 1073 return "APP_STATE_IDLE"; 1074 case APP_STATE_READY: 1075 return "APP_STATE_READY"; 1076 case APP_STATE_RUNNING: 1077 return "APP_STATE_RUNNING"; 1078 case APP_STATE_TIMEOUT: 1079 return "APP_STATE_TIMEOUT"; 1080 default: 1081 return "unknown state=" + mAppTransitionState; 1082 } 1083 } 1084 1085 private String transitTypeToString() { 1086 switch (mNextAppTransitionType) { 1087 case NEXT_TRANSIT_TYPE_NONE: 1088 return "NEXT_TRANSIT_TYPE_NONE"; 1089 case NEXT_TRANSIT_TYPE_CUSTOM: 1090 return "NEXT_TRANSIT_TYPE_CUSTOM"; 1091 case NEXT_TRANSIT_TYPE_SCALE_UP: 1092 return "NEXT_TRANSIT_TYPE_SCALE_UP"; 1093 case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP: 1094 return "NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP"; 1095 case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN: 1096 return "NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN"; 1097 case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP: 1098 return "NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP"; 1099 case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN: 1100 return "NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN"; 1101 default: 1102 return "unknown type=" + mNextAppTransitionType; 1103 } 1104 } 1105 1106 @Override 1107 public void dump(PrintWriter pw) { 1108 pw.print(" " + this); 1109 pw.print(" mAppTransitionState="); pw.println(appStateToString()); 1110 if (mNextAppTransitionType != NEXT_TRANSIT_TYPE_NONE) { 1111 pw.print(" mNextAppTransitionType="); pw.println(transitTypeToString()); 1112 } 1113 switch (mNextAppTransitionType) { 1114 case NEXT_TRANSIT_TYPE_CUSTOM: 1115 pw.print(" mNextAppTransitionPackage="); 1116 pw.println(mNextAppTransitionPackage); 1117 pw.print(" mNextAppTransitionEnter=0x"); 1118 pw.print(Integer.toHexString(mNextAppTransitionEnter)); 1119 pw.print(" mNextAppTransitionExit=0x"); 1120 pw.println(Integer.toHexString(mNextAppTransitionExit)); 1121 break; 1122 case NEXT_TRANSIT_TYPE_SCALE_UP: 1123 pw.print(" mNextAppTransitionStartX="); pw.print(mNextAppTransitionStartX); 1124 pw.print(" mNextAppTransitionStartY="); 1125 pw.println(mNextAppTransitionStartY); 1126 pw.print(" mNextAppTransitionStartWidth="); 1127 pw.print(mNextAppTransitionStartWidth); 1128 pw.print(" mNextAppTransitionStartHeight="); 1129 pw.println(mNextAppTransitionStartHeight); 1130 break; 1131 case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP: 1132 case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN: 1133 case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP: 1134 case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN: 1135 pw.print(" mNextAppTransitionThumbnail="); 1136 pw.print(mNextAppTransitionThumbnail); 1137 pw.print(" mNextAppTransitionStartX="); 1138 pw.print(mNextAppTransitionStartX); 1139 pw.print(" mNextAppTransitionStartY="); 1140 pw.println(mNextAppTransitionStartY); 1141 pw.print(" mNextAppTransitionScaleUp="); pw.println(mNextAppTransitionScaleUp); 1142 break; 1143 } 1144 if (mNextAppTransitionCallback != null) { 1145 pw.print(" mNextAppTransitionCallback="); 1146 pw.println(mNextAppTransitionCallback); 1147 } 1148 } 1149 1150 public void setCurrentUser(int newUserId) { 1151 mCurrentUserId = newUserId; 1152 } 1153} 1154