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