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