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