WindowAnimator.java revision 4bf18a7c97c0f312ccf12bcd952b420af0c95e5f
1// Copyright 2012 Google Inc. All Rights Reserved. 2 3package com.android.server.wm; 4 5import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; 6import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; 7 8import static com.android.server.wm.WindowManagerService.LayoutFields.SET_UPDATE_ROTATION; 9import static com.android.server.wm.WindowManagerService.LayoutFields.SET_WALLPAPER_MAY_CHANGE; 10import static com.android.server.wm.WindowManagerService.LayoutFields.SET_FORCE_HIDING_CHANGED; 11import static com.android.server.wm.WindowManagerService.LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE; 12 13import static com.android.server.wm.WindowManagerService.H.UPDATE_ANIM_PARAMETERS; 14 15import android.content.Context; 16import android.os.SystemClock; 17import android.util.Log; 18import android.util.Slog; 19import android.view.Surface; 20import android.view.WindowManagerPolicy; 21import android.view.animation.Animation; 22 23import com.android.internal.policy.impl.PhoneWindowManager; 24import com.android.server.wm.WindowManagerService.LayoutToAnimatorParams; 25 26import java.io.PrintWriter; 27import java.util.ArrayList; 28 29/** 30 * Singleton class that carries out the animations and Surface operations in a separate task 31 * on behalf of WindowManagerService. 32 */ 33public class WindowAnimator { 34 private static final String TAG = "WindowAnimator"; 35 36 final WindowManagerService mService; 37 final Context mContext; 38 final WindowManagerPolicy mPolicy; 39 40 ArrayList<WindowStateAnimator> mWinAnimators = new ArrayList<WindowStateAnimator>(); 41 42 boolean mAnimating; 43 44 final Runnable mAnimationRunnable; 45 46 int mAdjResult; 47 48 int mPendingLayoutChanges; 49 50 /** Overall window dimensions */ 51 int mDw, mDh; 52 53 /** Interior window dimensions */ 54 int mInnerDw, mInnerDh; 55 56 /** Time of current animation step. Reset on each iteration */ 57 long mCurrentTime; 58 59 /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this 60 * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */ 61 private int mAnimTransactionSequence; 62 63 /** The one and only screen rotation if one is happening */ 64 ScreenRotationAnimation mScreenRotationAnimation = null; 65 66 // Window currently running an animation that has requested it be detached 67 // from the wallpaper. This means we need to ensure the wallpaper is 68 // visible behind it in case it animates in a way that would allow it to be 69 // seen. If multiple windows satisfy this, use the lowest window. 70 WindowState mWindowDetachedWallpaper = null; 71 72 DimSurface mWindowAnimationBackgroundSurface = null; 73 74 WindowStateAnimator mUniverseBackground = null; 75 int mAboveUniverseLayer = 0; 76 77 int mBulkUpdateParams = 0; 78 79 DimAnimator mDimAnimator = null; 80 DimAnimator.Parameters mDimParams = null; 81 82 static final int WALLPAPER_ACTION_PENDING = 1; 83 int mPendingActions; 84 85 WindowState mWallpaperTarget = null; 86 AppWindowAnimator mWpAppAnimator = null; 87 WindowState mLowerWallpaperTarget = null; 88 WindowState mUpperWallpaperTarget = null; 89 90 ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>(); 91 92 /** Parameters being passed from this into mService. */ 93 static class AnimatorToLayoutParams { 94 boolean mUpdateQueued; 95 int mBulkUpdateParams; 96 int mPendingLayoutChanges; 97 WindowState mWindowDetachedWallpaper; 98 } 99 /** Do not modify unless holding mService.mWindowMap or this and mAnimToLayout in that order */ 100 final AnimatorToLayoutParams mAnimToLayout = new AnimatorToLayoutParams(); 101 102 WindowAnimator(final WindowManagerService service) { 103 mService = service; 104 mContext = service.mContext; 105 mPolicy = service.mPolicy; 106 107 mAnimationRunnable = new Runnable() { 108 @Override 109 public void run() { 110 // TODO(cmautner): When full isolation is achieved for animation, the first lock 111 // goes away and only the WindowAnimator.this remains. 112 synchronized(mService.mWindowMap) { 113 synchronized(WindowAnimator.this) { 114 copyLayoutToAnimParamsLocked(); 115 animateLocked(); 116 } 117 } 118 } 119 }; 120 121 mWindowAnimationBackgroundSurface = new DimSurface(mService.mFxSession); 122 mDimAnimator = new DimAnimator(mService.mFxSession); 123 } 124 125 /** Locked on mAnimToLayout */ 126 void updateAnimToLayoutLocked() { 127 final AnimatorToLayoutParams animToLayout = mAnimToLayout; 128 synchronized (animToLayout) { 129 animToLayout.mBulkUpdateParams = mBulkUpdateParams; 130 animToLayout.mPendingLayoutChanges = mPendingLayoutChanges; 131 animToLayout.mWindowDetachedWallpaper = mWindowDetachedWallpaper; 132 133 if (!animToLayout.mUpdateQueued) { 134 animToLayout.mUpdateQueued = true; 135 mService.mH.sendMessage(mService.mH.obtainMessage(UPDATE_ANIM_PARAMETERS)); 136 } 137 } 138 } 139 140 /** Copy all WindowManagerService params into local params here. Locked on 'this'. */ 141 private void copyLayoutToAnimParamsLocked() { 142 final LayoutToAnimatorParams layoutToAnim = mService.mLayoutToAnim; 143 synchronized(layoutToAnim) { 144 layoutToAnim.mAnimationScheduled = false; 145 146 if ((layoutToAnim.mChanges & LayoutToAnimatorParams.WALLPAPER_TOKENS_CHANGED) != 0) { 147 layoutToAnim.mChanges &= ~LayoutToAnimatorParams.WALLPAPER_TOKENS_CHANGED; 148 mWallpaperTokens = new ArrayList<WindowToken>(layoutToAnim.mWallpaperTokens); 149 } 150 151 mWinAnimators = new ArrayList<WindowStateAnimator>(layoutToAnim.mWinAnimators); 152 mWallpaperTarget = layoutToAnim.mWallpaperTarget; 153 mWpAppAnimator = mWallpaperTarget == null 154 ? null : mWallpaperTarget.mAppToken == null 155 ? null : mWallpaperTarget.mAppToken.mAppAnimator; 156 mLowerWallpaperTarget = layoutToAnim.mLowerWallpaperTarget; 157 mUpperWallpaperTarget = layoutToAnim.mUpperWallpaperTarget; 158 159 // Set the new DimAnimator params. 160 DimAnimator.Parameters dimParams = layoutToAnim.mDimParams; 161 if (dimParams == null) { 162 mDimParams = dimParams; 163 } else { 164 final WindowStateAnimator newWinAnimator = dimParams.mDimWinAnimator; 165 166 // Only set dim params on the highest dimmed layer. 167 final WindowStateAnimator existingDimWinAnimator = mDimParams == null 168 ? null : mDimParams.mDimWinAnimator; 169 // Don't turn on for an unshown surface, or for any layer but the highest dimmed one. 170 if (newWinAnimator.mSurfaceShown && 171 (existingDimWinAnimator == null || !existingDimWinAnimator.mSurfaceShown 172 || existingDimWinAnimator.mAnimLayer < newWinAnimator.mAnimLayer)) { 173 mDimParams = dimParams; 174 } 175 } 176 } 177 } 178 179 void hideWallpapersLocked(final WindowState w) { 180 if ((mWallpaperTarget == w && mLowerWallpaperTarget == null) || mWallpaperTarget == null) { 181 final int numTokens = mWallpaperTokens.size(); 182 for (int i = numTokens - 1; i >= 0; i--) { 183 final WindowToken token = mWallpaperTokens.get(i); 184 final int numWindows = token.windows.size(); 185 for (int j = numWindows - 1; j >= 0; j--) { 186 final WindowState wallpaper = token.windows.get(j); 187 final WindowStateAnimator winAnimator = wallpaper.mWinAnimator; 188 if (!winAnimator.mLastHidden) { 189 winAnimator.hide(); 190 mService.dispatchWallpaperVisibility(wallpaper, false); 191 mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; 192 } 193 } 194 token.hidden = true; 195 } 196 } 197 } 198 199 private void updateWindowsAppsAndRotationAnimationsLocked() { 200 final ArrayList<AppWindowToken> appTokens = mService.mAnimatingAppTokens; 201 int i; 202 final int NAT = appTokens.size(); 203 for (i=0; i<NAT; i++) { 204 final AppWindowAnimator appAnimator = appTokens.get(i).mAppAnimator; 205 final boolean wasAnimating = appAnimator.animation != null 206 && appAnimator.animation != AppWindowAnimator.sDummyAnimation; 207 if (appAnimator.stepAnimationLocked(mCurrentTime, mInnerDw, mInnerDh)) { 208 mAnimating = true; 209 } else if (wasAnimating) { 210 // stopped animating, do one more pass through the layout 211 mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; 212 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { 213 mService.debugLayoutRepeats("appToken " + appAnimator.mAppToken + " done", 214 mPendingLayoutChanges); 215 } 216 if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG, 217 "updateWindowsApps...: done animating " + appAnimator.mAppToken); 218 } 219 } 220 221 final int NEAT = mService.mExitingAppTokens.size(); 222 for (i=0; i<NEAT; i++) { 223 final AppWindowAnimator appAnimator = mService.mExitingAppTokens.get(i).mAppAnimator; 224 final boolean wasAnimating = appAnimator.animation != null 225 && appAnimator.animation != AppWindowAnimator.sDummyAnimation; 226 if (appAnimator.stepAnimationLocked(mCurrentTime, mInnerDw, mInnerDh)) { 227 mAnimating = true; 228 } else if (wasAnimating) { 229 // stopped animating, do one more pass through the layout 230 mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; 231 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { 232 mService.debugLayoutRepeats("exiting appToken " + appAnimator.mAppToken 233 + " done", mPendingLayoutChanges); 234 } 235 if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG, 236 "updateWindowsApps...: done animating exiting " + appAnimator.mAppToken); 237 } 238 } 239 240 if (mScreenRotationAnimation != null && mScreenRotationAnimation.isAnimating()) { 241 if (mScreenRotationAnimation.stepAnimationLocked(mCurrentTime)) { 242 mAnimating = true; 243 } else { 244 mBulkUpdateParams |= SET_UPDATE_ROTATION; 245 mScreenRotationAnimation.kill(); 246 mScreenRotationAnimation = null; 247 } 248 } 249 } 250 251 private void updateWindowsLocked() { 252 ++mAnimTransactionSequence; 253 254 ArrayList<WindowStateAnimator> unForceHiding = null; 255 boolean wallpaperInUnForceHiding = false; 256 257 // forceHiding states. 258 final int KEYGUARD_NOT_SHOWN = 0; 259 final int KEYGUARD_ANIMATING_IN = 1; 260 final int KEYGUARD_SHOWN = 2; 261 final int KEYGUARD_ANIMATING_OUT = 3; 262 int forceHiding = KEYGUARD_NOT_SHOWN; 263 264 for (int i = mWinAnimators.size() - 1; i >= 0; i--) { 265 WindowStateAnimator winAnimator = mWinAnimators.get(i); 266 WindowState win = winAnimator.mWin; 267 final int flags = winAnimator.mAttrFlags; 268 269 if (winAnimator.mSurface != null) { 270 final boolean wasAnimating = winAnimator.mWasAnimating; 271 final boolean nowAnimating = winAnimator.stepAnimationLocked(mCurrentTime); 272 273 if (WindowManagerService.DEBUG_WALLPAPER) { 274 Slog.v(TAG, win + ": wasAnimating=" + wasAnimating + 275 ", nowAnimating=" + nowAnimating); 276 } 277 278 if (wasAnimating && !winAnimator.mAnimating && mWallpaperTarget == win) { 279 mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE; 280 mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; 281 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { 282 mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 2", 283 mPendingLayoutChanges); 284 } 285 } 286 287 if (mPolicy.doesForceHide(win, win.mAttrs)) { 288 if (!wasAnimating && nowAnimating) { 289 if (WindowManagerService.DEBUG_ANIM || 290 WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, 291 "Animation started that could impact force hide: " + win); 292 mBulkUpdateParams |= SET_FORCE_HIDING_CHANGED; 293 mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; 294 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { 295 mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 3", 296 mPendingLayoutChanges); 297 } 298 mService.mFocusMayChange = true; 299 } 300 if (win.isReadyForDisplay()) { 301 if (nowAnimating) { 302 if (winAnimator.mAnimationIsEntrance) { 303 forceHiding = KEYGUARD_ANIMATING_IN; 304 } else { 305 forceHiding = KEYGUARD_ANIMATING_OUT; 306 } 307 } else { 308 forceHiding = KEYGUARD_SHOWN; 309 } 310 } 311 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, 312 "Force hide " + forceHiding 313 + " hasSurface=" + win.mHasSurface 314 + " policyVis=" + win.mPolicyVisibility 315 + " destroying=" + win.mDestroying 316 + " attHidden=" + win.mAttachedHidden 317 + " vis=" + win.mViewVisibility 318 + " hidden=" + win.mRootToken.hidden 319 + " anim=" + win.mWinAnimator.mAnimation); 320 } else if (mPolicy.canBeForceHidden(win, win.mAttrs)) { 321 final boolean hideWhenLocked = 322 (winAnimator.mAttrFlags & FLAG_SHOW_WHEN_LOCKED) == 0; 323 final boolean changed; 324 if (((forceHiding == KEYGUARD_ANIMATING_IN) 325 && (!winAnimator.isAnimating() || hideWhenLocked)) 326 || ((forceHiding == KEYGUARD_SHOWN) && hideWhenLocked)) { 327 changed = win.hideLw(false, false); 328 if (WindowManagerService.DEBUG_VISIBILITY && changed) Slog.v(TAG, 329 "Now policy hidden: " + win); 330 } else { 331 changed = win.showLw(false, false); 332 if (WindowManagerService.DEBUG_VISIBILITY && changed) Slog.v(TAG, 333 "Now policy shown: " + win); 334 if (changed) { 335 if ((mBulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0 336 && win.isVisibleNow() /*w.isReadyForDisplay()*/) { 337 if (unForceHiding == null) { 338 unForceHiding = new ArrayList<WindowStateAnimator>(); 339 } 340 unForceHiding.add(winAnimator); 341 if ((flags & FLAG_SHOW_WALLPAPER) != 0) { 342 wallpaperInUnForceHiding = true; 343 } 344 } 345 if (mCurrentFocus == null || mCurrentFocus.mLayer < win.mLayer) { 346 // We are showing on to of the current 347 // focus, so re-evaluate focus to make 348 // sure it is correct. 349 mService.mFocusMayChange = true; 350 } 351 } 352 } 353 if (changed && (flags & FLAG_SHOW_WALLPAPER) != 0) { 354 mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE; 355 mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; 356 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { 357 mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 4", 358 mPendingLayoutChanges); 359 } 360 } 361 } 362 } 363 364 final AppWindowToken atoken = win.mAppToken; 365 if (winAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW) { 366 if (atoken == null || atoken.allDrawn) { 367 if (winAnimator.performShowLocked()) { 368 mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM; 369 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { 370 mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 5", 371 mPendingLayoutChanges); 372 } 373 } 374 } 375 } 376 final AppWindowAnimator appAnimator = 377 atoken == null ? null : atoken.mAppAnimator; 378 if (appAnimator != null && appAnimator.thumbnail != null) { 379 if (appAnimator.thumbnailTransactionSeq != mAnimTransactionSequence) { 380 appAnimator.thumbnailTransactionSeq = mAnimTransactionSequence; 381 appAnimator.thumbnailLayer = 0; 382 } 383 if (appAnimator.thumbnailLayer < winAnimator.mAnimLayer) { 384 appAnimator.thumbnailLayer = winAnimator.mAnimLayer; 385 } 386 } 387 } // end forall windows 388 389 // If we have windows that are being show due to them no longer 390 // being force-hidden, apply the appropriate animation to them. 391 if (unForceHiding != null) { 392 for (int i=unForceHiding.size()-1; i>=0; i--) { 393 Animation a = mPolicy.createForceHideEnterAnimation(wallpaperInUnForceHiding); 394 if (a != null) { 395 final WindowStateAnimator winAnimator = unForceHiding.get(i); 396 winAnimator.setAnimation(a); 397 winAnimator.mAnimationIsEntrance = true; 398 } 399 } 400 } 401 } 402 403 private void updateWallpaperLocked() { 404 WindowStateAnimator windowAnimationBackground = null; 405 int windowAnimationBackgroundColor = 0; 406 WindowState detachedWallpaper = null; 407 408 for (int i = mWinAnimators.size() - 1; i >= 0; i--) { 409 WindowStateAnimator winAnimator = mWinAnimators.get(i); 410 if (winAnimator.mSurface == null) { 411 continue; 412 } 413 414 final int flags = winAnimator.mAttrFlags; 415 final WindowState win = winAnimator.mWin; 416 417 // If this window is animating, make a note that we have 418 // an animating window and take care of a request to run 419 // a detached wallpaper animation. 420 if (winAnimator.mAnimating) { 421 if (winAnimator.mAnimation != null) { 422 if ((flags & FLAG_SHOW_WALLPAPER) != 0 423 && winAnimator.mAnimation.getDetachWallpaper()) { 424 detachedWallpaper = win; 425 } 426 final int backgroundColor = winAnimator.mAnimation.getBackgroundColor(); 427 if (backgroundColor != 0) { 428 if (windowAnimationBackground == null || (winAnimator.mAnimLayer < 429 windowAnimationBackground.mAnimLayer)) { 430 windowAnimationBackground = winAnimator; 431 windowAnimationBackgroundColor = backgroundColor; 432 } 433 } 434 } 435 mAnimating = true; 436 } 437 438 // If this window's app token is running a detached wallpaper 439 // animation, make a note so we can ensure the wallpaper is 440 // displayed behind it. 441 final AppWindowAnimator appAnimator = 442 win.mAppToken == null ? null : win.mAppToken.mAppAnimator; 443 if (appAnimator != null && appAnimator.animation != null 444 && appAnimator.animating) { 445 if ((flags & FLAG_SHOW_WALLPAPER) != 0 446 && appAnimator.animation.getDetachWallpaper()) { 447 detachedWallpaper = win; 448 } 449 450 final int backgroundColor = appAnimator.animation.getBackgroundColor(); 451 if (backgroundColor != 0) { 452 if (windowAnimationBackground == null || (winAnimator.mAnimLayer < 453 windowAnimationBackground.mAnimLayer)) { 454 windowAnimationBackground = winAnimator; 455 windowAnimationBackgroundColor = backgroundColor; 456 } 457 } 458 } 459 } // end forall windows 460 461 if (mWindowDetachedWallpaper != detachedWallpaper) { 462 if (WindowManagerService.DEBUG_WALLPAPER) Slog.v(TAG, 463 "Detached wallpaper changed from " + mWindowDetachedWallpaper 464 + " to " + detachedWallpaper); 465 mWindowDetachedWallpaper = detachedWallpaper; 466 mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE; 467 } 468 469 if (windowAnimationBackgroundColor != 0) { 470 // If the window that wants black is the current wallpaper 471 // target, then the black goes *below* the wallpaper so we 472 // don't cause the wallpaper to suddenly disappear. 473 int animLayer = windowAnimationBackground.mAnimLayer; 474 WindowState win = windowAnimationBackground.mWin; 475 if (windowAnimationBackground != null && mWallpaperTarget == win 476 || mLowerWallpaperTarget == win || mUpperWallpaperTarget == win) { 477 final int N = mWinAnimators.size(); 478 for (int i = 0; i < N; i++) { 479 WindowStateAnimator winAnimator = mWinAnimators.get(i); 480 if (winAnimator.mIsWallpaper) { 481 animLayer = winAnimator.mAnimLayer; 482 break; 483 } 484 } 485 } 486 487 mWindowAnimationBackgroundSurface.show(mDw, mDh, 488 animLayer - WindowManagerService.LAYER_OFFSET_DIM, 489 windowAnimationBackgroundColor); 490 } else { 491 mWindowAnimationBackgroundSurface.hide(); 492 } 493 } 494 495 private void testTokenMayBeDrawnLocked() { 496 // See if any windows have been drawn, so they (and others 497 // associated with them) can now be shown. 498 final ArrayList<AppWindowToken> appTokens = mService.mAnimatingAppTokens; 499 final int NT = appTokens.size(); 500 for (int i=0; i<NT; i++) { 501 AppWindowToken wtoken = appTokens.get(i); 502 final boolean allDrawn = wtoken.allDrawn; 503 if (allDrawn != wtoken.mAppAnimator.allDrawn) { 504 wtoken.mAppAnimator.allDrawn = allDrawn; 505 if (allDrawn) { 506 // The token has now changed state to having all 507 // windows shown... what to do, what to do? 508 if (wtoken.mAppAnimator.freezingScreen) { 509 wtoken.mAppAnimator.showAllWindowsLocked(); 510 mService.unsetAppFreezingScreenLocked(wtoken, false, true); 511 if (WindowManagerService.DEBUG_ORIENTATION) Slog.i(TAG, 512 "Setting mOrientationChangeComplete=true because wtoken " 513 + wtoken + " numInteresting=" + wtoken.numInterestingWindows 514 + " numDrawn=" + wtoken.numDrawnWindows); 515 // This will set mOrientationChangeComplete and cause a pass through layout. 516 mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; 517 } else { 518 mPendingLayoutChanges |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM; 519 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { 520 mService.debugLayoutRepeats("testTokenMayBeDrawnLocked", 521 mPendingLayoutChanges); 522 } 523 524 // We can now show all of the drawn windows! 525 if (!mService.mOpeningApps.contains(wtoken)) { 526 mAnimating |= wtoken.mAppAnimator.showAllWindowsLocked(); 527 } 528 } 529 } 530 } 531 } 532 } 533 534 private void performAnimationsLocked() { 535 updateWindowsLocked(); 536 updateWallpaperLocked(); 537 538 if ((mPendingLayoutChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) { 539 mPendingActions |= WALLPAPER_ACTION_PENDING; 540 } 541 542 testTokenMayBeDrawnLocked(); 543 } 544 545 // TODO(cmautner): Change the following comment when no longer locked on mWindowMap */ 546 /** Locked on mService.mWindowMap and this. */ 547 private void animateLocked() { 548 mPendingLayoutChanges = 0; 549 mCurrentTime = SystemClock.uptimeMillis(); 550 mBulkUpdateParams = SET_ORIENTATION_CHANGE_COMPLETE; 551 boolean wasAnimating = mAnimating; 552 mAnimating = false; 553 if (WindowManagerService.DEBUG_WINDOW_TRACE) { 554 Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime); 555 } 556 557 // Update animations of all applications, including those 558 // associated with exiting/removed apps 559 Surface.openTransaction(); 560 561 try { 562 updateWindowsAppsAndRotationAnimationsLocked(); 563 performAnimationsLocked(); 564 565 // THIRD LOOP: Update the surfaces of all windows. 566 567 if (mScreenRotationAnimation != null) { 568 mScreenRotationAnimation.updateSurfaces(); 569 } 570 571 final int N = mWinAnimators.size(); 572 for (int i = 0; i < N; i++) { 573 mWinAnimators.get(i).prepareSurfaceLocked(true); 574 } 575 576 if (mDimParams != null) { 577 mDimAnimator.updateParameters(mContext.getResources(), mDimParams, mCurrentTime); 578 } 579 if (mDimAnimator != null && mDimAnimator.mDimShown) { 580 mAnimating |= mDimAnimator.updateSurface(isDimming(), mCurrentTime, 581 !mService.okToDisplay()); 582 } 583 584 if (mService.mBlackFrame != null) { 585 if (mScreenRotationAnimation != null) { 586 mService.mBlackFrame.setMatrix( 587 mScreenRotationAnimation.getEnterTransformation().getMatrix()); 588 } else { 589 mService.mBlackFrame.clearMatrix(); 590 } 591 } 592 593 if (mService.mWatermark != null) { 594 mService.mWatermark.drawIfNeeded(); 595 } 596 } catch (RuntimeException e) { 597 Log.wtf(TAG, "Unhandled exception in Window Manager", e); 598 } finally { 599 Surface.closeTransaction(); 600 } 601 602 if (mBulkUpdateParams != 0 || mPendingLayoutChanges != 0) { 603 updateAnimToLayoutLocked(); 604 } 605 606 if (mAnimating) { 607 synchronized (mService.mLayoutToAnim) { 608 mService.scheduleAnimationLocked(); 609 } 610 } else if (wasAnimating) { 611 mService.requestTraversalLocked(); 612 } 613 if (WindowManagerService.DEBUG_WINDOW_TRACE) { 614 Slog.i(TAG, "!!! animate: exit mAnimating=" + mAnimating 615 + " mBulkUpdateParams=" + Integer.toHexString(mBulkUpdateParams) 616 + " mPendingLayoutChanges=" + Integer.toHexString(mPendingLayoutChanges)); 617 } 618 } 619 620 WindowState mCurrentFocus; 621 void setCurrentFocus(final WindowState currentFocus) { 622 mCurrentFocus = currentFocus; 623 } 624 625 void setDisplayDimensions(final int curWidth, final int curHeight, 626 final int appWidth, final int appHeight) { 627 mDw = curWidth; 628 mDh = curHeight; 629 mInnerDw = appWidth; 630 mInnerDh = appHeight; 631 } 632 633 boolean isDimming() { 634 return mDimParams != null; 635 } 636 637 boolean isDimming(final WindowStateAnimator winAnimator) { 638 return mDimParams != null && mDimParams.mDimWinAnimator == winAnimator; 639 } 640 641 public void dump(PrintWriter pw, String prefix, boolean dumpAll) { 642 if (dumpAll) { 643 if (mWindowDetachedWallpaper != null) { 644 pw.print(prefix); pw.print("mWindowDetachedWallpaper="); 645 pw.println(mWindowDetachedWallpaper); 646 } 647 pw.print(prefix); pw.print("mAnimTransactionSequence="); 648 pw.println(mAnimTransactionSequence); 649 if (mWindowAnimationBackgroundSurface != null) { 650 pw.print(prefix); pw.print("mWindowAnimationBackgroundSurface:"); 651 mWindowAnimationBackgroundSurface.printTo(prefix + " ", pw); 652 } 653 if (mDimAnimator != null) { 654 pw.print(prefix); pw.print("mDimAnimator:"); 655 mDimAnimator.printTo(prefix + " ", pw); 656 } else { 657 pw.print(prefix); pw.print("no DimAnimator "); 658 } 659 } 660 } 661 662 static class SetAnimationParams { 663 final WindowStateAnimator mWinAnimator; 664 final Animation mAnimation; 665 final int mAnimDw; 666 final int mAnimDh; 667 public SetAnimationParams(final WindowStateAnimator winAnimator, 668 final Animation animation, final int animDw, final int animDh) { 669 mWinAnimator = winAnimator; 670 mAnimation = animation; 671 mAnimDw = animDw; 672 mAnimDh = animDh; 673 } 674 } 675 676 synchronized void clearPendingActions() { 677 mPendingActions = 0; 678 } 679} 680