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