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