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