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