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