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