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