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