WindowAnimator.java revision 1bf2b873470d2ba8a4ac218da73516cc2b20aa76
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.SurfaceControl; 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 /** 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<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 ArrayList<TaskStack> stacks = mService.getDisplayContentLocked(displayId).getStacks(); 155 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 156 final TaskStack stack = stacks.get(stackNdx); 157 final ArrayList<Task> tasks = stack.getTasks(); 158 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 159 final AppTokenList tokens = tasks.get(taskNdx).mAppTokens; 160 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --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, 169 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER, 170 "appToken " + appAnimator.mAppToken + " done"); 171 if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG, 172 "updateWindowsApps...: done animating " + appAnimator.mAppToken); 173 } 174 } 175 } 176 177 final AppTokenList exitingAppTokens = stack.mExitingAppTokens; 178 final int NEAT = exitingAppTokens.size(); 179 for (int i = 0; i < NEAT; i++) { 180 final AppWindowAnimator appAnimator = exitingAppTokens.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 "exiting appToken " + appAnimator.mAppToken + " done"); 189 if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG, 190 "updateWindowsApps...: done animating exiting " + appAnimator.mAppToken); 191 } 192 } 193 } 194 } 195 196 private void updateWindowsLocked(final int displayId) { 197 ++mAnimTransactionSequence; 198 199 final WindowList windows = mService.getWindowListLocked(displayId); 200 ArrayList<WindowStateAnimator> unForceHiding = null; 201 boolean wallpaperInUnForceHiding = false; 202 mForceHiding = KEYGUARD_NOT_SHOWN; 203 204 for (int i = windows.size() - 1; i >= 0; i--) { 205 WindowState win = windows.get(i); 206 WindowStateAnimator winAnimator = win.mWinAnimator; 207 final int flags = winAnimator.mAttrFlags; 208 209 if (winAnimator.mSurfaceControl != null) { 210 final boolean wasAnimating = winAnimator.mWasAnimating; 211 final boolean nowAnimating = winAnimator.stepAnimationLocked(mCurrentTime); 212 213 if (WindowManagerService.DEBUG_WALLPAPER) { 214 Slog.v(TAG, win + ": wasAnimating=" + wasAnimating + 215 ", nowAnimating=" + nowAnimating); 216 } 217 218 if (wasAnimating && !winAnimator.mAnimating && mService.mWallpaperTarget == win) { 219 mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE; 220 setPendingLayoutChanges(Display.DEFAULT_DISPLAY, 221 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); 222 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { 223 mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 2", 224 getPendingLayoutChanges(Display.DEFAULT_DISPLAY)); 225 } 226 } 227 228 if (mPolicy.doesForceHide(win, win.mAttrs)) { 229 if (!wasAnimating && nowAnimating) { 230 if (WindowManagerService.DEBUG_ANIM || 231 WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, 232 "Animation started that could impact force hide: " + win); 233 mBulkUpdateParams |= SET_FORCE_HIDING_CHANGED; 234 setPendingLayoutChanges(displayId, 235 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); 236 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { 237 mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 3", 238 getPendingLayoutChanges(displayId)); 239 } 240 mService.mFocusMayChange = true; 241 } 242 if (win.isReadyForDisplay()) { 243 if (nowAnimating) { 244 if (winAnimator.mAnimationIsEntrance) { 245 mForceHiding = KEYGUARD_ANIMATING_IN; 246 } else { 247 mForceHiding = KEYGUARD_ANIMATING_OUT; 248 } 249 } else { 250 mForceHiding = win.isDrawnLw() ? KEYGUARD_SHOWN : KEYGUARD_NOT_SHOWN; 251 } 252 } 253 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, 254 "Force hide " + mForceHiding 255 + " hasSurface=" + win.mHasSurface 256 + " policyVis=" + win.mPolicyVisibility 257 + " destroying=" + win.mDestroying 258 + " attHidden=" + win.mAttachedHidden 259 + " vis=" + win.mViewVisibility 260 + " hidden=" + win.mRootToken.hidden 261 + " anim=" + win.mWinAnimator.mAnimation); 262 } else if (mPolicy.canBeForceHidden(win, win.mAttrs)) { 263 final boolean hideWhenLocked = 264 (winAnimator.mAttrFlags & FLAG_SHOW_WHEN_LOCKED) == 0; 265 final boolean changed; 266 if (((mForceHiding == KEYGUARD_ANIMATING_IN) 267 && (!winAnimator.isAnimating() || hideWhenLocked)) 268 || ((mForceHiding == KEYGUARD_SHOWN) && hideWhenLocked)) { 269 changed = win.hideLw(false, false); 270 if (WindowManagerService.DEBUG_VISIBILITY && changed) Slog.v(TAG, 271 "Now policy hidden: " + win); 272 } else { 273 changed = win.showLw(false, false); 274 if (WindowManagerService.DEBUG_VISIBILITY && changed) Slog.v(TAG, 275 "Now policy shown: " + win); 276 if (changed) { 277 if ((mBulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0 278 && win.isVisibleNow() /*w.isReadyForDisplay()*/) { 279 if (unForceHiding == null) { 280 unForceHiding = new ArrayList<WindowStateAnimator>(); 281 } 282 unForceHiding.add(winAnimator); 283 if ((flags & FLAG_SHOW_WALLPAPER) != 0) { 284 wallpaperInUnForceHiding = true; 285 } 286 } 287 final WindowState currentFocus = mService.mCurrentFocus; 288 if (currentFocus == null || currentFocus.mLayer < win.mLayer) { 289 // We are showing on to of the current 290 // focus, so re-evaluate focus to make 291 // sure it is correct. 292 if (WindowManagerService.DEBUG_FOCUS_LIGHT) Slog.v(TAG, 293 "updateWindowsLocked: setting mFocusMayChange true"); 294 mService.mFocusMayChange = true; 295 } 296 } 297 } 298 if (changed && (flags & FLAG_SHOW_WALLPAPER) != 0) { 299 mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE; 300 setPendingLayoutChanges(Display.DEFAULT_DISPLAY, 301 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); 302 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { 303 mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 4", 304 getPendingLayoutChanges(Display.DEFAULT_DISPLAY)); 305 } 306 } 307 } 308 } 309 310 final AppWindowToken atoken = win.mAppToken; 311 if (winAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW) { 312 if (atoken == null || atoken.allDrawn) { 313 if (winAnimator.performShowLocked()) { 314 setPendingLayoutChanges(displayId, 315 WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM); 316 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { 317 mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 5", 318 getPendingLayoutChanges(displayId)); 319 } 320 } 321 } 322 } 323 final AppWindowAnimator appAnimator = winAnimator.mAppAnimator; 324 if (appAnimator != null && appAnimator.thumbnail != null) { 325 if (appAnimator.thumbnailTransactionSeq != mAnimTransactionSequence) { 326 appAnimator.thumbnailTransactionSeq = mAnimTransactionSequence; 327 appAnimator.thumbnailLayer = 0; 328 } 329 if (appAnimator.thumbnailLayer < winAnimator.mAnimLayer) { 330 appAnimator.thumbnailLayer = winAnimator.mAnimLayer; 331 } 332 } 333 } // end forall windows 334 335 // If we have windows that are being show due to them no longer 336 // being force-hidden, apply the appropriate animation to them. 337 if (unForceHiding != null) { 338 for (int i=unForceHiding.size()-1; i>=0; i--) { 339 Animation a = mPolicy.createForceHideEnterAnimation(wallpaperInUnForceHiding); 340 if (a != null) { 341 final WindowStateAnimator winAnimator = unForceHiding.get(i); 342 winAnimator.setAnimation(a); 343 winAnimator.mAnimationIsEntrance = true; 344 } 345 } 346 } 347 } 348 349 private void updateWallpaperLocked(int displayId) { 350 mService.getDisplayContentLocked(displayId).resetAnimationBackgroundAnimator(); 351 352 final WindowList windows = mService.getWindowListLocked(displayId); 353 WindowState detachedWallpaper = null; 354 355 for (int i = windows.size() - 1; i >= 0; i--) { 356 final WindowState win = windows.get(i); 357 WindowStateAnimator winAnimator = win.mWinAnimator; 358 if (winAnimator.mSurfaceControl == null) { 359 continue; 360 } 361 362 final int flags = winAnimator.mAttrFlags; 363 364 // If this window is animating, make a note that we have 365 // an animating window and take care of a request to run 366 // a detached wallpaper animation. 367 if (winAnimator.mAnimating) { 368 if (winAnimator.mAnimation != null) { 369 if ((flags & FLAG_SHOW_WALLPAPER) != 0 370 && winAnimator.mAnimation.getDetachWallpaper()) { 371 detachedWallpaper = win; 372 } 373 final int color = winAnimator.mAnimation.getBackgroundColor(); 374 if (color != 0) { 375 win.getStack().setAnimationBackground(winAnimator, color); 376 } 377 } 378 mAnimating = true; 379 } 380 381 // If this window's app token is running a detached wallpaper 382 // animation, make a note so we can ensure the wallpaper is 383 // displayed behind it. 384 final AppWindowAnimator appAnimator = winAnimator.mAppAnimator; 385 if (appAnimator != null && appAnimator.animation != null 386 && appAnimator.animating) { 387 if ((flags & FLAG_SHOW_WALLPAPER) != 0 388 && appAnimator.animation.getDetachWallpaper()) { 389 detachedWallpaper = win; 390 } 391 392 final int color = appAnimator.animation.getBackgroundColor(); 393 if (color != 0) { 394 win.getStack().setAnimationBackground(winAnimator, color); 395 } 396 } 397 } // end forall windows 398 399 if (mWindowDetachedWallpaper != detachedWallpaper) { 400 if (WindowManagerService.DEBUG_WALLPAPER) Slog.v(TAG, 401 "Detached wallpaper changed from " + mWindowDetachedWallpaper 402 + " to " + detachedWallpaper); 403 mWindowDetachedWallpaper = detachedWallpaper; 404 mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE; 405 } 406 } 407 408 /** See if any windows have been drawn, so they (and others associated with them) can now be 409 * shown. */ 410 private void testTokenMayBeDrawnLocked(int displayId) { 411 // See if any windows have been drawn, so they (and others 412 // associated with them) can now be shown. 413 final ArrayList<Task> tasks = mService.getDisplayContentLocked(displayId).getTasks(); 414 final int numTasks = tasks.size(); 415 for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) { 416 final AppTokenList tokens = tasks.get(taskNdx).mAppTokens; 417 final int numTokens = tokens.size(); 418 for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) { 419 final AppWindowToken wtoken = tokens.get(tokenNdx); 420 AppWindowAnimator appAnimator = wtoken.mAppAnimator; 421 final boolean allDrawn = wtoken.allDrawn; 422 if (allDrawn != appAnimator.allDrawn) { 423 appAnimator.allDrawn = allDrawn; 424 if (allDrawn) { 425 // The token has now changed state to having all 426 // windows shown... what to do, what to do? 427 if (appAnimator.freezingScreen) { 428 appAnimator.showAllWindowsLocked(); 429 mService.unsetAppFreezingScreenLocked(wtoken, false, true); 430 if (WindowManagerService.DEBUG_ORIENTATION) Slog.i(TAG, 431 "Setting mOrientationChangeComplete=true because wtoken " 432 + wtoken + " numInteresting=" + wtoken.numInterestingWindows 433 + " numDrawn=" + wtoken.numDrawnWindows); 434 // This will set mOrientationChangeComplete and cause a pass through layout. 435 setAppLayoutChanges(appAnimator, 436 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER, 437 "testTokenMayBeDrawnLocked: freezingScreen"); 438 } else { 439 setAppLayoutChanges(appAnimator, 440 WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM, 441 "testTokenMayBeDrawnLocked"); 442 443 // We can now show all of the drawn windows! 444 if (!mService.mOpeningApps.contains(wtoken)) { 445 mAnimating |= appAnimator.showAllWindowsLocked(); 446 } 447 } 448 } 449 } 450 } 451 } 452 } 453 454 455 /** Locked on mService.mWindowMap. */ 456 private void animateLocked() { 457 if (!mInitialized) { 458 return; 459 } 460 461 mCurrentTime = SystemClock.uptimeMillis(); 462 mBulkUpdateParams = SET_ORIENTATION_CHANGE_COMPLETE; 463 boolean wasAnimating = mAnimating; 464 mAnimating = false; 465 if (WindowManagerService.DEBUG_WINDOW_TRACE) { 466 Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime); 467 } 468 469 if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i( 470 TAG, ">>> OPEN TRANSACTION animateLocked"); 471 SurfaceControl.openTransaction(); 472 SurfaceControl.setAnimationTransaction(); 473 try { 474 final int numDisplays = mDisplayContentsAnimators.size(); 475 for (int i = 0; i < numDisplays; i++) { 476 final int displayId = mDisplayContentsAnimators.keyAt(i); 477 updateAppWindowsLocked(displayId); 478 DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i); 479 480 final ScreenRotationAnimation screenRotationAnimation = 481 displayAnimator.mScreenRotationAnimation; 482 if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) { 483 if (screenRotationAnimation.stepAnimationLocked(mCurrentTime)) { 484 mAnimating = true; 485 } else { 486 mBulkUpdateParams |= SET_UPDATE_ROTATION; 487 screenRotationAnimation.kill(); 488 displayAnimator.mScreenRotationAnimation = null; 489 } 490 } 491 492 // Update animations of all applications, including those 493 // associated with exiting/removed apps 494 updateWindowsLocked(displayId); 495 updateWallpaperLocked(displayId); 496 497 final WindowList windows = mService.getWindowListLocked(displayId); 498 final int N = windows.size(); 499 for (int j = 0; j < N; j++) { 500 windows.get(j).mWinAnimator.prepareSurfaceLocked(true); 501 } 502 } 503 504 for (int i = 0; i < numDisplays; i++) { 505 final int displayId = mDisplayContentsAnimators.keyAt(i); 506 507 testTokenMayBeDrawnLocked(displayId); 508 509 final ScreenRotationAnimation screenRotationAnimation = 510 mDisplayContentsAnimators.valueAt(i).mScreenRotationAnimation; 511 if (screenRotationAnimation != null) { 512 screenRotationAnimation.updateSurfacesInTransaction(); 513 } 514 515 mAnimating |= mService.getDisplayContentLocked(displayId).animateDimLayers(); 516 517 //TODO (multidisplay): Magnification is supported only for the default display. 518 if (mService.mDisplayMagnifier != null && displayId == Display.DEFAULT_DISPLAY) { 519 mService.mDisplayMagnifier.drawMagnifiedRegionBorderIfNeededLocked(); 520 } 521 } 522 523 if (mAnimating) { 524 mService.scheduleAnimationLocked(); 525 } 526 527 mService.setFocusedStackLayer(); 528 529 if (mService.mWatermark != null) { 530 mService.mWatermark.drawIfNeeded(); 531 } 532 } catch (RuntimeException e) { 533 Log.wtf(TAG, "Unhandled exception in Window Manager", e); 534 } finally { 535 SurfaceControl.closeTransaction(); 536 if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i( 537 TAG, "<<< CLOSE TRANSACTION animateLocked"); 538 } 539 540 boolean hasPendingLayoutChanges = false; 541 final int numDisplays = mService.mDisplayContents.size(); 542 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 543 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx); 544 final int pendingChanges = getPendingLayoutChanges(displayContent.getDisplayId()); 545 if ((pendingChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) { 546 mBulkUpdateParams |= SET_WALLPAPER_ACTION_PENDING; 547 } 548 if (pendingChanges != 0) { 549 hasPendingLayoutChanges = true; 550 } 551 } 552 553 boolean doRequest = false; 554 if (mBulkUpdateParams != 0) { 555 doRequest = mService.copyAnimToLayoutParamsLocked(); 556 } 557 558 if (hasPendingLayoutChanges || doRequest) { 559 mService.requestTraversalLocked(); 560 } 561 562 if (!mAnimating && wasAnimating) { 563 mService.requestTraversalLocked(); 564 } 565 if (WindowManagerService.DEBUG_WINDOW_TRACE) { 566 Slog.i(TAG, "!!! animate: exit mAnimating=" + mAnimating 567 + " mBulkUpdateParams=" + Integer.toHexString(mBulkUpdateParams) 568 + " mPendingLayoutChanges(DEFAULT_DISPLAY)=" 569 + Integer.toHexString(getPendingLayoutChanges(Display.DEFAULT_DISPLAY))); 570 } 571 } 572 573 static String bulkUpdateParamsToString(int bulkUpdateParams) { 574 StringBuilder builder = new StringBuilder(128); 575 if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) { 576 builder.append(" UPDATE_ROTATION"); 577 } 578 if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) { 579 builder.append(" WALLPAPER_MAY_CHANGE"); 580 } 581 if ((bulkUpdateParams & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) { 582 builder.append(" FORCE_HIDING_CHANGED"); 583 } 584 if ((bulkUpdateParams & LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE) != 0) { 585 builder.append(" ORIENTATION_CHANGE_COMPLETE"); 586 } 587 if ((bulkUpdateParams & LayoutFields.SET_TURN_ON_SCREEN) != 0) { 588 builder.append(" TURN_ON_SCREEN"); 589 } 590 return builder.toString(); 591 } 592 593 public void dumpLocked(PrintWriter pw, String prefix, boolean dumpAll) { 594 final String subPrefix = " " + prefix; 595 final String subSubPrefix = " " + subPrefix; 596 597 for (int i = 0; i < mDisplayContentsAnimators.size(); i++) { 598 pw.print(prefix); pw.print("DisplayContentsAnimator #"); 599 pw.print(mDisplayContentsAnimators.keyAt(i)); 600 pw.println(":"); 601 DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i); 602 final WindowList windows = 603 mService.getWindowListLocked(mDisplayContentsAnimators.keyAt(i)); 604 final int N = windows.size(); 605 for (int j = 0; j < N; j++) { 606 WindowStateAnimator wanim = windows.get(j).mWinAnimator; 607 pw.print(subPrefix); pw.print("Window #"); pw.print(j); 608 pw.print(": "); pw.println(wanim); 609 } 610 if (displayAnimator.mScreenRotationAnimation != null) { 611 pw.print(subPrefix); pw.println("mScreenRotationAnimation:"); 612 displayAnimator.mScreenRotationAnimation.printTo(subSubPrefix, pw); 613 } else if (dumpAll) { 614 pw.print(subPrefix); pw.println("no ScreenRotationAnimation "); 615 } 616 } 617 618 pw.println(); 619 620 if (dumpAll) { 621 pw.print(prefix); pw.print("mAnimTransactionSequence="); 622 pw.print(mAnimTransactionSequence); 623 pw.print(" mForceHiding="); pw.println(forceHidingToString()); 624 pw.print(prefix); pw.print("mCurrentTime="); 625 pw.println(TimeUtils.formatUptime(mCurrentTime)); 626 } 627 if (mBulkUpdateParams != 0) { 628 pw.print(prefix); pw.print("mBulkUpdateParams=0x"); 629 pw.print(Integer.toHexString(mBulkUpdateParams)); 630 pw.println(bulkUpdateParamsToString(mBulkUpdateParams)); 631 } 632 if (mWindowDetachedWallpaper != null) { 633 pw.print(prefix); pw.print("mWindowDetachedWallpaper="); 634 pw.println(mWindowDetachedWallpaper); 635 } 636 if (mUniverseBackground != null) { 637 pw.print(prefix); pw.print("mUniverseBackground="); pw.print(mUniverseBackground); 638 pw.print(" mAboveUniverseLayer="); pw.println(mAboveUniverseLayer); 639 } 640 } 641 642 int getPendingLayoutChanges(final int displayId) { 643 if (displayId < 0) { 644 return 0; 645 } 646 return mService.getDisplayContentLocked(displayId).pendingLayoutChanges; 647 } 648 649 void setPendingLayoutChanges(final int displayId, final int changes) { 650 if (displayId >= 0) { 651 mService.getDisplayContentLocked(displayId).pendingLayoutChanges |= changes; 652 } 653 } 654 655 void setAppLayoutChanges(final AppWindowAnimator appAnimator, final int changes, String s) { 656 // Used to track which displays layout changes have been done. 657 SparseIntArray displays = new SparseIntArray(2); 658 WindowList windows = appAnimator.mAppToken.allAppWindows; 659 for (int i = windows.size() - 1; i >= 0; i--) { 660 final int displayId = windows.get(i).getDisplayId(); 661 if (displayId >= 0 && displays.indexOfKey(displayId) < 0) { 662 setPendingLayoutChanges(displayId, changes); 663 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { 664 mService.debugLayoutRepeats(s, getPendingLayoutChanges(displayId)); 665 } 666 // Keep from processing this display again. 667 displays.put(displayId, changes); 668 } 669 } 670 } 671 672 private DisplayContentsAnimator getDisplayContentsAnimatorLocked(int displayId) { 673 DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.get(displayId); 674 if (displayAnimator == null) { 675 displayAnimator = new DisplayContentsAnimator(); 676 mDisplayContentsAnimators.put(displayId, displayAnimator); 677 } 678 return displayAnimator; 679 } 680 681 void setScreenRotationAnimationLocked(int displayId, ScreenRotationAnimation animation) { 682 if (displayId >= 0) { 683 getDisplayContentsAnimatorLocked(displayId).mScreenRotationAnimation = animation; 684 } 685 } 686 687 ScreenRotationAnimation getScreenRotationAnimationLocked(int displayId) { 688 if (displayId < 0) { 689 return null; 690 } 691 return getDisplayContentsAnimatorLocked(displayId).mScreenRotationAnimation; 692 } 693 694 private class DisplayContentsAnimator { 695 ScreenRotationAnimation mScreenRotationAnimation = null; 696 } 697} 698