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