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