WindowAnimator.java revision dc548483ae90ba26ad9e2e2cb79f4673140edb49
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<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 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 private void performAnimationsLocked(final int displayId) { 455 updateWindowsLocked(displayId); 456 updateWallpaperLocked(displayId); 457 } 458 459 460 /** Locked on mService.mWindowMap. */ 461 private void animateLocked() { 462 if (!mInitialized) { 463 return; 464 } 465 466 mCurrentTime = SystemClock.uptimeMillis(); 467 mBulkUpdateParams = SET_ORIENTATION_CHANGE_COMPLETE; 468 boolean wasAnimating = mAnimating; 469 mAnimating = false; 470 if (WindowManagerService.DEBUG_WINDOW_TRACE) { 471 Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime); 472 } 473 474 if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i( 475 TAG, ">>> OPEN TRANSACTION animateLocked"); 476 SurfaceControl.openTransaction(); 477 SurfaceControl.setAnimationTransaction(); 478 try { 479 final int numDisplays = mDisplayContentsAnimators.size(); 480 for (int i = 0; i < numDisplays; i++) { 481 final int displayId = mDisplayContentsAnimators.keyAt(i); 482 updateAppWindowsLocked(displayId); 483 DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i); 484 485 final ScreenRotationAnimation screenRotationAnimation = 486 displayAnimator.mScreenRotationAnimation; 487 if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) { 488 if (screenRotationAnimation.stepAnimationLocked(mCurrentTime)) { 489 mAnimating = true; 490 } else { 491 mBulkUpdateParams |= SET_UPDATE_ROTATION; 492 screenRotationAnimation.kill(); 493 displayAnimator.mScreenRotationAnimation = null; 494 } 495 } 496 497 // Update animations of all applications, including those 498 // associated with exiting/removed apps 499 performAnimationsLocked(displayId); 500 501 final WindowList windows = mService.getWindowListLocked(displayId); 502 final int N = windows.size(); 503 for (int j = 0; j < N; j++) { 504 windows.get(j).mWinAnimator.prepareSurfaceLocked(true); 505 } 506 } 507 508 for (int i = 0; i < numDisplays; i++) { 509 final int displayId = mDisplayContentsAnimators.keyAt(i); 510 511 testTokenMayBeDrawnLocked(displayId); 512 513 final ScreenRotationAnimation screenRotationAnimation = 514 mDisplayContentsAnimators.valueAt(i).mScreenRotationAnimation; 515 if (screenRotationAnimation != null) { 516 screenRotationAnimation.updateSurfacesInTransaction(); 517 } 518 519 mAnimating |= mService.getDisplayContentLocked(displayId).animateDimLayers(); 520 521 //TODO (multidisplay): Magnification is supported only for the default display. 522 if (mService.mDisplayMagnifier != null && displayId == Display.DEFAULT_DISPLAY) { 523 mService.mDisplayMagnifier.drawMagnifiedRegionBorderIfNeededLocked(); 524 } 525 } 526 527 if (mAnimating) { 528 mService.scheduleAnimationLocked(); 529 } 530 531 mService.setFocusedStackLayer(); 532 533 if (mService.mWatermark != null) { 534 mService.mWatermark.drawIfNeeded(); 535 } 536 } catch (RuntimeException e) { 537 Log.wtf(TAG, "Unhandled exception in Window Manager", e); 538 } finally { 539 SurfaceControl.closeTransaction(); 540 if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i( 541 TAG, "<<< CLOSE TRANSACTION animateLocked"); 542 } 543 544 boolean hasPendingLayoutChanges = false; 545 final int numDisplays = mService.mDisplayContents.size(); 546 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 547 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx); 548 final int pendingChanges = getPendingLayoutChanges(displayContent.getDisplayId()); 549 if ((pendingChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) { 550 mBulkUpdateParams |= SET_WALLPAPER_ACTION_PENDING; 551 } 552 if (pendingChanges != 0) { 553 hasPendingLayoutChanges = true; 554 } 555 } 556 557 boolean doRequest = false; 558 if (mBulkUpdateParams != 0) { 559 doRequest = mService.copyAnimToLayoutParamsLocked(); 560 } 561 562 if (hasPendingLayoutChanges || doRequest) { 563 mService.requestTraversalLocked(); 564 } 565 566 if (!mAnimating && wasAnimating) { 567 mService.requestTraversalLocked(); 568 } 569 if (WindowManagerService.DEBUG_WINDOW_TRACE) { 570 Slog.i(TAG, "!!! animate: exit mAnimating=" + mAnimating 571 + " mBulkUpdateParams=" + Integer.toHexString(mBulkUpdateParams) 572 + " mPendingLayoutChanges(DEFAULT_DISPLAY)=" 573 + Integer.toHexString(getPendingLayoutChanges(Display.DEFAULT_DISPLAY))); 574 } 575 } 576 577 static String bulkUpdateParamsToString(int bulkUpdateParams) { 578 StringBuilder builder = new StringBuilder(128); 579 if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) { 580 builder.append(" UPDATE_ROTATION"); 581 } 582 if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) { 583 builder.append(" WALLPAPER_MAY_CHANGE"); 584 } 585 if ((bulkUpdateParams & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) { 586 builder.append(" FORCE_HIDING_CHANGED"); 587 } 588 if ((bulkUpdateParams & LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE) != 0) { 589 builder.append(" ORIENTATION_CHANGE_COMPLETE"); 590 } 591 if ((bulkUpdateParams & LayoutFields.SET_TURN_ON_SCREEN) != 0) { 592 builder.append(" TURN_ON_SCREEN"); 593 } 594 return builder.toString(); 595 } 596 597 public void dumpLocked(PrintWriter pw, String prefix, boolean dumpAll) { 598 final String subPrefix = " " + prefix; 599 final String subSubPrefix = " " + subPrefix; 600 601 for (int i = 0; i < mDisplayContentsAnimators.size(); i++) { 602 pw.print(prefix); pw.print("DisplayContentsAnimator #"); 603 pw.print(mDisplayContentsAnimators.keyAt(i)); 604 pw.println(":"); 605 DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i); 606 final WindowList windows = 607 mService.getWindowListLocked(mDisplayContentsAnimators.keyAt(i)); 608 final int N = windows.size(); 609 for (int j = 0; j < N; j++) { 610 WindowStateAnimator wanim = windows.get(j).mWinAnimator; 611 pw.print(subPrefix); pw.print("Window #"); pw.print(j); 612 pw.print(": "); pw.println(wanim); 613 } 614 if (displayAnimator.mScreenRotationAnimation != null) { 615 pw.print(subPrefix); pw.println("mScreenRotationAnimation:"); 616 displayAnimator.mScreenRotationAnimation.printTo(subSubPrefix, pw); 617 } else if (dumpAll) { 618 pw.print(subPrefix); pw.println("no ScreenRotationAnimation "); 619 } 620 } 621 622 pw.println(); 623 624 if (dumpAll) { 625 pw.print(prefix); pw.print("mAnimTransactionSequence="); 626 pw.print(mAnimTransactionSequence); 627 pw.print(" mForceHiding="); pw.println(forceHidingToString()); 628 pw.print(prefix); pw.print("mCurrentTime="); 629 pw.println(TimeUtils.formatUptime(mCurrentTime)); 630 } 631 if (mBulkUpdateParams != 0) { 632 pw.print(prefix); pw.print("mBulkUpdateParams=0x"); 633 pw.print(Integer.toHexString(mBulkUpdateParams)); 634 pw.println(bulkUpdateParamsToString(mBulkUpdateParams)); 635 } 636 if (mWindowDetachedWallpaper != null) { 637 pw.print(prefix); pw.print("mWindowDetachedWallpaper="); 638 pw.println(mWindowDetachedWallpaper); 639 } 640 if (mUniverseBackground != null) { 641 pw.print(prefix); pw.print("mUniverseBackground="); pw.print(mUniverseBackground); 642 pw.print(" mAboveUniverseLayer="); pw.println(mAboveUniverseLayer); 643 } 644 } 645 646 int getPendingLayoutChanges(final int displayId) { 647 if (displayId < 0) { 648 return 0; 649 } 650 return mService.getDisplayContentLocked(displayId).pendingLayoutChanges; 651 } 652 653 void setPendingLayoutChanges(final int displayId, final int changes) { 654 if (displayId >= 0) { 655 mService.getDisplayContentLocked(displayId).pendingLayoutChanges |= changes; 656 } 657 } 658 659 void setAppLayoutChanges(final AppWindowAnimator appAnimator, final int changes, String s) { 660 // Used to track which displays layout changes have been done. 661 SparseIntArray displays = new SparseIntArray(2); 662 WindowList windows = appAnimator.mAppToken.allAppWindows; 663 for (int i = windows.size() - 1; i >= 0; i--) { 664 final int displayId = windows.get(i).getDisplayId(); 665 if (displayId >= 0 && displays.indexOfKey(displayId) < 0) { 666 setPendingLayoutChanges(displayId, changes); 667 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { 668 mService.debugLayoutRepeats(s, getPendingLayoutChanges(displayId)); 669 } 670 // Keep from processing this display again. 671 displays.put(displayId, changes); 672 } 673 } 674 } 675 676 private DisplayContentsAnimator getDisplayContentsAnimatorLocked(int displayId) { 677 DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.get(displayId); 678 if (displayAnimator == null) { 679 displayAnimator = new DisplayContentsAnimator(); 680 mDisplayContentsAnimators.put(displayId, displayAnimator); 681 } 682 return displayAnimator; 683 } 684 685 void setScreenRotationAnimationLocked(int displayId, ScreenRotationAnimation animation) { 686 if (displayId >= 0) { 687 getDisplayContentsAnimatorLocked(displayId).mScreenRotationAnimation = animation; 688 } 689 } 690 691 ScreenRotationAnimation getScreenRotationAnimationLocked(int displayId) { 692 if (displayId < 0) { 693 return null; 694 } 695 return getDisplayContentsAnimatorLocked(displayId).mScreenRotationAnimation; 696 } 697 698 private class DisplayContentsAnimator { 699 ScreenRotationAnimation mScreenRotationAnimation = null; 700 } 701} 702