WindowAnimator.java revision b6ce6e42cc89864354c7ecb9ae80504a6c9dddcf
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; 12 13import static com.android.server.wm.WindowManagerService.H.UPDATE_ANIM_PARAMETERS; 14 15import android.content.Context; 16import android.os.SystemClock; 17import android.util.Log; 18import android.util.Slog; 19import android.util.SparseArray; 20import android.util.SparseIntArray; 21import android.view.Display; 22import android.view.Surface; 23import android.view.WindowManagerPolicy; 24import android.view.animation.Animation; 25 26import com.android.server.wm.WindowManagerService.AppWindowAnimParams; 27import com.android.server.wm.WindowManagerService.LayoutToAnimatorParams; 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 int mAdjResult; 48 49 // Layout changes for individual Displays. Indexed by displayId. 50 SparseIntArray mPendingLayoutChanges = new SparseIntArray(); 51 52 // TODO: Assign these from each iteration through DisplayContent. Only valid between loops. 53 /** Overall window dimensions */ 54 int mDw, mDh; 55 56 /** Interior window dimensions */ 57 int mInnerDw, mInnerDh; 58 59 /** Time of current animation step. Reset on each iteration */ 60 long mCurrentTime; 61 62 /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this 63 * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */ 64 private int mAnimTransactionSequence; 65 66 // Window currently running an animation that has requested it be detached 67 // from the wallpaper. This means we need to ensure the wallpaper is 68 // visible behind it in case it animates in a way that would allow it to be 69 // seen. If multiple windows satisfy this, use the lowest window. 70 WindowState mWindowDetachedWallpaper = null; 71 72 WindowStateAnimator mUniverseBackground = null; 73 int mAboveUniverseLayer = 0; 74 75 int mBulkUpdateParams = 0; 76 77 SparseArray<DisplayContentsAnimator> mDisplayContentsAnimators = 78 new SparseArray<WindowAnimator.DisplayContentsAnimator>(); 79 80 static final int WALLPAPER_ACTION_PENDING = 1; 81 int mPendingActions; 82 83 WindowState mWallpaperTarget = null; 84 AppWindowAnimator mWpAppAnimator = null; 85 WindowState mLowerWallpaperTarget = null; 86 WindowState mUpperWallpaperTarget = null; 87 88 ArrayList<AppWindowAnimator> mAppAnimators = new ArrayList<AppWindowAnimator>(); 89 90 ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>(); 91 92 /** Parameters being passed from this into mService. */ 93 static class AnimatorToLayoutParams { 94 boolean mUpdateQueued; 95 int mBulkUpdateParams; 96 SparseIntArray mPendingLayoutChanges; 97 WindowState mWindowDetachedWallpaper; 98 } 99 /** Do not modify unless holding mService.mWindowMap or this and mAnimToLayout in that order */ 100 final AnimatorToLayoutParams mAnimToLayout = new AnimatorToLayoutParams(); 101 102 boolean mInitialized = false; 103 104 // forceHiding states. 105 static final int KEYGUARD_NOT_SHOWN = 0; 106 static final int KEYGUARD_ANIMATING_IN = 1; 107 static final int KEYGUARD_SHOWN = 2; 108 static final int KEYGUARD_ANIMATING_OUT = 3; 109 int mForceHiding = KEYGUARD_NOT_SHOWN; 110 111 private String forceHidingToString() { 112 switch (mForceHiding) { 113 case KEYGUARD_NOT_SHOWN: return "KEYGUARD_NOT_SHOWN"; 114 case KEYGUARD_ANIMATING_IN: return "KEYGUARD_ANIMATING_IN"; 115 case KEYGUARD_SHOWN: return "KEYGUARD_SHOWN"; 116 case KEYGUARD_ANIMATING_OUT:return "KEYGUARD_ANIMATING_OUT"; 117 default: return "KEYGUARD STATE UNKNOWN " + mForceHiding; 118 } 119 } 120 121 WindowAnimator(final WindowManagerService service) { 122 mService = service; 123 mContext = service.mContext; 124 mPolicy = service.mPolicy; 125 126 mAnimationRunnable = new Runnable() { 127 @Override 128 public void run() { 129 // TODO(cmautner): When full isolation is achieved for animation, the first lock 130 // goes away and only the WindowAnimator.this remains. 131 synchronized(mService.mWindowMap) { 132 synchronized(WindowAnimator.this) { 133 copyLayoutToAnimParamsLocked(); 134 animateLocked(); 135 } 136 } 137 } 138 }; 139 } 140 141 void addDisplayLocked(final int displayId) { 142 // Create the DisplayContentsAnimator object by retrieving it. 143 getDisplayContentsAnimatorLocked(displayId); 144 if (displayId == Display.DEFAULT_DISPLAY) { 145 mInitialized = true; 146 } 147 } 148 149 void removeDisplayLocked(final int displayId) { 150 final DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.get(displayId); 151 if (displayAnimator != null) { 152 if (displayAnimator.mWindowAnimationBackgroundSurface != null) { 153 displayAnimator.mWindowAnimationBackgroundSurface.kill(); 154 displayAnimator.mWindowAnimationBackgroundSurface = null; 155 } 156 if (displayAnimator.mScreenRotationAnimation != null) { 157 displayAnimator.mScreenRotationAnimation.kill(); 158 displayAnimator.mScreenRotationAnimation = null; 159 } 160 if (displayAnimator.mDimAnimator != null) { 161 displayAnimator.mDimAnimator.kill(); 162 displayAnimator.mDimAnimator = null; 163 } 164 } 165 166 mDisplayContentsAnimators.delete(displayId); 167 } 168 169 /** Locked on mAnimToLayout */ 170 void updateAnimToLayoutLocked() { 171 final AnimatorToLayoutParams animToLayout = mAnimToLayout; 172 synchronized (animToLayout) { 173 animToLayout.mBulkUpdateParams = mBulkUpdateParams; 174 animToLayout.mPendingLayoutChanges = mPendingLayoutChanges.clone(); 175 animToLayout.mWindowDetachedWallpaper = mWindowDetachedWallpaper; 176 177 if (!animToLayout.mUpdateQueued) { 178 animToLayout.mUpdateQueued = true; 179 mService.mH.sendMessage(mService.mH.obtainMessage(UPDATE_ANIM_PARAMETERS)); 180 } 181 } 182 } 183 184 /** Copy all WindowManagerService params into local params here. Locked on 'this'. */ 185 private void copyLayoutToAnimParamsLocked() { 186 final LayoutToAnimatorParams layoutToAnim = mService.mLayoutToAnim; 187 synchronized(layoutToAnim) { 188 layoutToAnim.mAnimationScheduled = false; 189 190 if (!layoutToAnim.mParamsModified) { 191 return; 192 } 193 layoutToAnim.mParamsModified = false; 194 195 if ((layoutToAnim.mChanges & LayoutToAnimatorParams.WALLPAPER_TOKENS_CHANGED) != 0) { 196 layoutToAnim.mChanges &= ~LayoutToAnimatorParams.WALLPAPER_TOKENS_CHANGED; 197 mWallpaperTokens = new ArrayList<WindowToken>(layoutToAnim.mWallpaperTokens); 198 } 199 200 mWallpaperTarget = layoutToAnim.mWallpaperTarget; 201 mWpAppAnimator = mWallpaperTarget == null 202 ? null : mWallpaperTarget.mAppToken == null 203 ? null : mWallpaperTarget.mAppToken.mAppAnimator; 204 mLowerWallpaperTarget = layoutToAnim.mLowerWallpaperTarget; 205 mUpperWallpaperTarget = layoutToAnim.mUpperWallpaperTarget; 206 207 // Set the new DimAnimator params. 208 final int numDisplays = mDisplayContentsAnimators.size(); 209 for (int i = 0; i < numDisplays; i++) { 210 final int displayId = mDisplayContentsAnimators.keyAt(i); 211 DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i); 212 213 displayAnimator.mWinAnimators.clear(); 214 final WinAnimatorList winAnimators = layoutToAnim.mWinAnimatorLists.get(displayId); 215 if (winAnimators != null) { 216 displayAnimator.mWinAnimators.addAll(winAnimators); 217 } 218 219 DimAnimator.Parameters dimParams = layoutToAnim.mDimParams.get(displayId); 220 if (dimParams == null) { 221 displayAnimator.mDimParams = null; 222 } else { 223 final WindowStateAnimator newWinAnimator = dimParams.mDimWinAnimator; 224 225 // Only set dim params on the highest dimmed layer. 226 final WindowStateAnimator existingDimWinAnimator = 227 displayAnimator.mDimParams == null ? 228 null : displayAnimator.mDimParams.mDimWinAnimator; 229 // Don't turn on for an unshown surface, or for any layer but the highest 230 // dimmed layer. 231 if (newWinAnimator.mSurfaceShown && (existingDimWinAnimator == null 232 || !existingDimWinAnimator.mSurfaceShown 233 || existingDimWinAnimator.mAnimLayer < newWinAnimator.mAnimLayer)) { 234 displayAnimator.mDimParams = new DimAnimator.Parameters(dimParams); 235 } 236 } 237 } 238 239 mAppAnimators.clear(); 240 final int N = layoutToAnim.mAppWindowAnimParams.size(); 241 for (int i = 0; i < N; i++) { 242 final AppWindowAnimParams params = layoutToAnim.mAppWindowAnimParams.get(i); 243 AppWindowAnimator appAnimator = params.mAppAnimator; 244 appAnimator.mAllAppWinAnimators.clear(); 245 appAnimator.mAllAppWinAnimators.addAll(params.mWinAnimators); 246 mAppAnimators.add(appAnimator); 247 } 248 } 249 } 250 251 void hideWallpapersLocked(final WindowState w) { 252 if ((mWallpaperTarget == w && mLowerWallpaperTarget == null) || mWallpaperTarget == null) { 253 final int numTokens = mWallpaperTokens.size(); 254 for (int i = numTokens - 1; i >= 0; i--) { 255 final WindowToken token = mWallpaperTokens.get(i); 256 final int numWindows = token.windows.size(); 257 for (int j = numWindows - 1; j >= 0; j--) { 258 final WindowState wallpaper = token.windows.get(j); 259 final WindowStateAnimator winAnimator = wallpaper.mWinAnimator; 260 if (!winAnimator.mLastHidden) { 261 winAnimator.hide(); 262 mService.dispatchWallpaperVisibility(wallpaper, false); 263 setPendingLayoutChanges(Display.DEFAULT_DISPLAY, 264 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); 265 } 266 } 267 token.hidden = true; 268 } 269 } 270 } 271 272 private void updateAppWindowsLocked() { 273 int i; 274 final int NAT = mAppAnimators.size(); 275 for (i=0; i<NAT; i++) { 276 final AppWindowAnimator appAnimator = mAppAnimators.get(i); 277 final boolean wasAnimating = appAnimator.animation != null 278 && appAnimator.animation != AppWindowAnimator.sDummyAnimation; 279 if (appAnimator.stepAnimationLocked(mCurrentTime, mInnerDw, mInnerDh)) { 280 mAnimating = true; 281 } else if (wasAnimating) { 282 // stopped animating, do one more pass through the layout 283 setAppLayoutChanges(appAnimator, WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER, 284 "appToken " + appAnimator.mAppToken + " done"); 285 if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG, 286 "updateWindowsApps...: done animating " + appAnimator.mAppToken); 287 } 288 } 289 290 final int NEAT = mService.mExitingAppTokens.size(); 291 for (i=0; i<NEAT; i++) { 292 final AppWindowAnimator appAnimator = mService.mExitingAppTokens.get(i).mAppAnimator; 293 final boolean wasAnimating = appAnimator.animation != null 294 && appAnimator.animation != AppWindowAnimator.sDummyAnimation; 295 if (appAnimator.stepAnimationLocked(mCurrentTime, mInnerDw, mInnerDh)) { 296 mAnimating = true; 297 } else if (wasAnimating) { 298 // stopped animating, do one more pass through the layout 299 setAppLayoutChanges(appAnimator, WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER, 300 "exiting appToken " + appAnimator.mAppToken + " done"); 301 if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG, 302 "updateWindowsApps...: done animating exiting " + appAnimator.mAppToken); 303 } 304 } 305 } 306 307 private void updateWindowsLocked(final int displayId) { 308 ++mAnimTransactionSequence; 309 310 final WinAnimatorList winAnimatorList = 311 getDisplayContentsAnimatorLocked(displayId).mWinAnimators; 312 ArrayList<WindowStateAnimator> unForceHiding = null; 313 boolean wallpaperInUnForceHiding = false; 314 mForceHiding = KEYGUARD_NOT_SHOWN; 315 316 for (int i = winAnimatorList.size() - 1; i >= 0; i--) { 317 WindowStateAnimator winAnimator = winAnimatorList.get(i); 318 WindowState win = winAnimator.mWin; 319 final int flags = winAnimator.mAttrFlags; 320 321 if (winAnimator.mSurface != null) { 322 final boolean wasAnimating = winAnimator.mWasAnimating; 323 final boolean nowAnimating = winAnimator.stepAnimationLocked(mCurrentTime); 324 325 if (WindowManagerService.DEBUG_WALLPAPER) { 326 Slog.v(TAG, win + ": wasAnimating=" + wasAnimating + 327 ", nowAnimating=" + nowAnimating); 328 } 329 330 if (wasAnimating && !winAnimator.mAnimating && mWallpaperTarget == win) { 331 mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE; 332 setPendingLayoutChanges(Display.DEFAULT_DISPLAY, 333 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); 334 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { 335 mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 2", 336 mPendingLayoutChanges.get(Display.DEFAULT_DISPLAY)); 337 } 338 } 339 340 if (mPolicy.doesForceHide(win, win.mAttrs)) { 341 if (!wasAnimating && nowAnimating) { 342 if (WindowManagerService.DEBUG_ANIM || 343 WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, 344 "Animation started that could impact force hide: " + win); 345 mBulkUpdateParams |= SET_FORCE_HIDING_CHANGED; 346 setPendingLayoutChanges(displayId, 347 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); 348 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { 349 mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 3", 350 mPendingLayoutChanges.get(displayId)); 351 } 352 mService.mFocusMayChange = true; 353 } 354 if (win.isReadyForDisplay()) { 355 if (nowAnimating) { 356 if (winAnimator.mAnimationIsEntrance) { 357 mForceHiding = KEYGUARD_ANIMATING_IN; 358 } else { 359 mForceHiding = KEYGUARD_ANIMATING_OUT; 360 } 361 } else { 362 mForceHiding = KEYGUARD_SHOWN; 363 } 364 } 365 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, 366 "Force hide " + mForceHiding 367 + " hasSurface=" + win.mHasSurface 368 + " policyVis=" + win.mPolicyVisibility 369 + " destroying=" + win.mDestroying 370 + " attHidden=" + win.mAttachedHidden 371 + " vis=" + win.mViewVisibility 372 + " hidden=" + win.mRootToken.hidden 373 + " anim=" + win.mWinAnimator.mAnimation); 374 } else if (mPolicy.canBeForceHidden(win, win.mAttrs)) { 375 final boolean hideWhenLocked = 376 (winAnimator.mAttrFlags & FLAG_SHOW_WHEN_LOCKED) == 0; 377 final boolean changed; 378 if (((mForceHiding == KEYGUARD_ANIMATING_IN) 379 && (!winAnimator.isAnimating() || hideWhenLocked)) 380 || ((mForceHiding == KEYGUARD_SHOWN) && hideWhenLocked)) { 381 changed = win.hideLw(false, false); 382 if (WindowManagerService.DEBUG_VISIBILITY && changed) Slog.v(TAG, 383 "Now policy hidden: " + win); 384 } else { 385 changed = win.showLw(false, false); 386 if (WindowManagerService.DEBUG_VISIBILITY && changed) Slog.v(TAG, 387 "Now policy shown: " + win); 388 if (changed) { 389 if ((mBulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0 390 && win.isVisibleNow() /*w.isReadyForDisplay()*/) { 391 if (unForceHiding == null) { 392 unForceHiding = new ArrayList<WindowStateAnimator>(); 393 } 394 unForceHiding.add(winAnimator); 395 if ((flags & FLAG_SHOW_WALLPAPER) != 0) { 396 wallpaperInUnForceHiding = true; 397 } 398 } 399 if (mCurrentFocus == null || mCurrentFocus.mLayer < win.mLayer) { 400 // We are showing on to of the current 401 // focus, so re-evaluate focus to make 402 // sure it is correct. 403 mService.mFocusMayChange = true; 404 } 405 } 406 } 407 if (changed && (flags & FLAG_SHOW_WALLPAPER) != 0) { 408 mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE; 409 setPendingLayoutChanges(Display.DEFAULT_DISPLAY, 410 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); 411 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { 412 mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 4", 413 mPendingLayoutChanges.get(Display.DEFAULT_DISPLAY)); 414 } 415 } 416 } 417 } 418 419 final AppWindowToken atoken = win.mAppToken; 420 if (winAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW) { 421 if (atoken == null || atoken.allDrawn) { 422 if (winAnimator.performShowLocked()) { 423 mPendingLayoutChanges.put(displayId, 424 WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM); 425 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { 426 mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 5", 427 mPendingLayoutChanges.get(displayId)); 428 } 429 } 430 } 431 } 432 final AppWindowAnimator appAnimator = winAnimator.mAppAnimator; 433 if (appAnimator != null && appAnimator.thumbnail != null) { 434 if (appAnimator.thumbnailTransactionSeq != mAnimTransactionSequence) { 435 appAnimator.thumbnailTransactionSeq = mAnimTransactionSequence; 436 appAnimator.thumbnailLayer = 0; 437 } 438 if (appAnimator.thumbnailLayer < winAnimator.mAnimLayer) { 439 appAnimator.thumbnailLayer = winAnimator.mAnimLayer; 440 } 441 } 442 } // end forall windows 443 444 // If we have windows that are being show due to them no longer 445 // being force-hidden, apply the appropriate animation to them. 446 if (unForceHiding != null) { 447 for (int i=unForceHiding.size()-1; i>=0; i--) { 448 Animation a = mPolicy.createForceHideEnterAnimation(wallpaperInUnForceHiding); 449 if (a != null) { 450 final WindowStateAnimator winAnimator = unForceHiding.get(i); 451 winAnimator.setAnimation(a); 452 winAnimator.mAnimationIsEntrance = true; 453 } 454 } 455 } 456 } 457 458 private void updateWallpaperLocked(int displayId) { 459 final DisplayContentsAnimator displayAnimator = 460 getDisplayContentsAnimatorLocked(displayId); 461 final WinAnimatorList winAnimatorList = displayAnimator.mWinAnimators; 462 WindowStateAnimator windowAnimationBackground = null; 463 int windowAnimationBackgroundColor = 0; 464 WindowState detachedWallpaper = null; 465 final DimSurface windowAnimationBackgroundSurface = 466 displayAnimator.mWindowAnimationBackgroundSurface; 467 468 for (int i = winAnimatorList.size() - 1; i >= 0; i--) { 469 WindowStateAnimator winAnimator = winAnimatorList.get(i); 470 if (winAnimator.mSurface == null) { 471 continue; 472 } 473 474 final int flags = winAnimator.mAttrFlags; 475 final WindowState win = winAnimator.mWin; 476 477 // If this window is animating, make a note that we have 478 // an animating window and take care of a request to run 479 // a detached wallpaper animation. 480 if (winAnimator.mAnimating) { 481 if (winAnimator.mAnimation != null) { 482 if ((flags & FLAG_SHOW_WALLPAPER) != 0 483 && winAnimator.mAnimation.getDetachWallpaper()) { 484 detachedWallpaper = win; 485 } 486 final int backgroundColor = winAnimator.mAnimation.getBackgroundColor(); 487 if (backgroundColor != 0) { 488 if (windowAnimationBackground == null || (winAnimator.mAnimLayer < 489 windowAnimationBackground.mAnimLayer)) { 490 windowAnimationBackground = winAnimator; 491 windowAnimationBackgroundColor = backgroundColor; 492 } 493 } 494 } 495 mAnimating = true; 496 } 497 498 // If this window's app token is running a detached wallpaper 499 // animation, make a note so we can ensure the wallpaper is 500 // displayed behind it. 501 final AppWindowAnimator appAnimator = winAnimator.mAppAnimator; 502 if (appAnimator != null && appAnimator.animation != null 503 && appAnimator.animating) { 504 if ((flags & FLAG_SHOW_WALLPAPER) != 0 505 && appAnimator.animation.getDetachWallpaper()) { 506 detachedWallpaper = win; 507 } 508 509 final int backgroundColor = appAnimator.animation.getBackgroundColor(); 510 if (backgroundColor != 0) { 511 if (windowAnimationBackground == null || (winAnimator.mAnimLayer < 512 windowAnimationBackground.mAnimLayer)) { 513 windowAnimationBackground = winAnimator; 514 windowAnimationBackgroundColor = backgroundColor; 515 } 516 } 517 } 518 } // end forall windows 519 520 if (mWindowDetachedWallpaper != detachedWallpaper) { 521 if (WindowManagerService.DEBUG_WALLPAPER) Slog.v(TAG, 522 "Detached wallpaper changed from " + mWindowDetachedWallpaper 523 + " to " + detachedWallpaper); 524 mWindowDetachedWallpaper = detachedWallpaper; 525 mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE; 526 } 527 528 if (windowAnimationBackgroundColor != 0) { 529 // If the window that wants black is the current wallpaper 530 // target, then the black goes *below* the wallpaper so we 531 // don't cause the wallpaper to suddenly disappear. 532 int animLayer = windowAnimationBackground.mAnimLayer; 533 WindowState win = windowAnimationBackground.mWin; 534 if (mWallpaperTarget == win 535 || mLowerWallpaperTarget == win || mUpperWallpaperTarget == win) { 536 final int N = winAnimatorList.size(); 537 for (int i = 0; i < N; i++) { 538 WindowStateAnimator winAnimator = winAnimatorList.get(i); 539 if (winAnimator.mIsWallpaper) { 540 animLayer = winAnimator.mAnimLayer; 541 break; 542 } 543 } 544 } 545 546 if (windowAnimationBackgroundSurface != null) { 547 windowAnimationBackgroundSurface.show(mDw, mDh, 548 animLayer - WindowManagerService.LAYER_OFFSET_DIM, 549 windowAnimationBackgroundColor); 550 } 551 } else { 552 if (windowAnimationBackgroundSurface != null) { 553 windowAnimationBackgroundSurface.hide(); 554 } 555 } 556 } 557 558 private void testTokenMayBeDrawnLocked() { 559 // See if any windows have been drawn, so they (and others 560 // associated with them) can now be shown. 561 final int NT = mAppAnimators.size(); 562 for (int i=0; i<NT; i++) { 563 AppWindowAnimator appAnimator = mAppAnimators.get(i); 564 AppWindowToken wtoken = appAnimator.mAppToken; 565 final boolean allDrawn = wtoken.allDrawn; 566 if (allDrawn != appAnimator.allDrawn) { 567 appAnimator.allDrawn = allDrawn; 568 if (allDrawn) { 569 // The token has now changed state to having all 570 // windows shown... what to do, what to do? 571 if (appAnimator.freezingScreen) { 572 appAnimator.showAllWindowsLocked(); 573 mService.unsetAppFreezingScreenLocked(wtoken, false, true); 574 if (WindowManagerService.DEBUG_ORIENTATION) Slog.i(TAG, 575 "Setting mOrientationChangeComplete=true because wtoken " 576 + wtoken + " numInteresting=" + wtoken.numInterestingWindows 577 + " numDrawn=" + wtoken.numDrawnWindows); 578 // This will set mOrientationChangeComplete and cause a pass through layout. 579 setAppLayoutChanges(appAnimator, 580 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER, 581 "testTokenMayBeDrawnLocked: freezingScreen"); 582 } else { 583 setAppLayoutChanges(appAnimator, 584 WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM, 585 "testTokenMayBeDrawnLocked"); 586 587 // We can now show all of the drawn windows! 588 if (!mService.mOpeningApps.contains(wtoken)) { 589 mAnimating |= appAnimator.showAllWindowsLocked(); 590 } 591 } 592 } 593 } 594 } 595 } 596 597 private void performAnimationsLocked(final int displayId) { 598 updateWindowsLocked(displayId); 599 updateWallpaperLocked(displayId); 600 } 601 602 // TODO(cmautner): Change the following comment when no longer locked on mWindowMap */ 603 /** Locked on mService.mWindowMap and this. */ 604 private void animateLocked() { 605 if (!mInitialized) { 606 return; 607 } 608 609 mPendingLayoutChanges.clear(); 610 mCurrentTime = SystemClock.uptimeMillis(); 611 mBulkUpdateParams = SET_ORIENTATION_CHANGE_COMPLETE; 612 boolean wasAnimating = mAnimating; 613 mAnimating = false; 614 if (WindowManagerService.DEBUG_WINDOW_TRACE) { 615 Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime); 616 } 617 618 if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i( 619 TAG, ">>> OPEN TRANSACTION animateLocked"); 620 Surface.openTransaction(); 621 Surface.setAnimationTransaction(); 622 try { 623 updateAppWindowsLocked(); 624 625 final int numDisplays = mDisplayContentsAnimators.size(); 626 for (int i = 0; i < numDisplays; i++) { 627 final int displayId = mDisplayContentsAnimators.keyAt(i); 628 DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i); 629 630 final ScreenRotationAnimation screenRotationAnimation = 631 displayAnimator.mScreenRotationAnimation; 632 if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) { 633 if (screenRotationAnimation.stepAnimationLocked(mCurrentTime)) { 634 mAnimating = true; 635 } else { 636 mBulkUpdateParams |= SET_UPDATE_ROTATION; 637 screenRotationAnimation.kill(); 638 displayAnimator.mScreenRotationAnimation = null; 639 } 640 } 641 642 // Update animations of all applications, including those 643 // associated with exiting/removed apps 644 performAnimationsLocked(displayId); 645 646 final WinAnimatorList winAnimatorList = displayAnimator.mWinAnimators; 647 final int N = winAnimatorList.size(); 648 for (int j = 0; j < N; j++) { 649 winAnimatorList.get(j).prepareSurfaceLocked(true); 650 } 651 } 652 653 testTokenMayBeDrawnLocked(); 654 655 for (int i = 0; i < numDisplays; i++) { 656 final int displayId = mDisplayContentsAnimators.keyAt(i); 657 DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i); 658 659 final ScreenRotationAnimation screenRotationAnimation = 660 displayAnimator.mScreenRotationAnimation; 661 if (screenRotationAnimation != null) { 662 screenRotationAnimation.updateSurfacesInTransaction(); 663 } 664 665 final DimAnimator.Parameters dimParams = displayAnimator.mDimParams; 666 final DimAnimator dimAnimator = displayAnimator.mDimAnimator; 667 if (dimAnimator != null && dimParams != null) { 668 dimAnimator.updateParameters(mContext.getResources(), dimParams, mCurrentTime); 669 } 670 if (dimAnimator != null && dimAnimator.mDimShown) { 671 mAnimating |= dimAnimator.updateSurface(isDimmingLocked(displayId), 672 mCurrentTime, !mService.okToDisplay()); 673 } 674 } 675 676 if (mService.mWatermark != null) { 677 mService.mWatermark.drawIfNeeded(); 678 } 679 } catch (RuntimeException e) { 680 Log.wtf(TAG, "Unhandled exception in Window Manager", e); 681 } finally { 682 Surface.closeTransaction(); 683 if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i( 684 TAG, "<<< CLOSE TRANSACTION animateLocked"); 685 } 686 687 for (int i = mPendingLayoutChanges.size() - 1; i >= 0; i--) { 688 if ((mPendingLayoutChanges.valueAt(i) 689 & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) { 690 mPendingActions |= WALLPAPER_ACTION_PENDING; 691 } 692 } 693 694 if (mBulkUpdateParams != 0 || mPendingLayoutChanges.size() > 0) { 695 updateAnimToLayoutLocked(); 696 } 697 698 if (mAnimating) { 699 synchronized (mService.mLayoutToAnim) { 700 mService.scheduleAnimationLocked(); 701 } 702 } else if (wasAnimating) { 703 mService.requestTraversalLocked(); 704 } 705 if (WindowManagerService.DEBUG_WINDOW_TRACE) { 706 Slog.i(TAG, "!!! animate: exit mAnimating=" + mAnimating 707 + " mBulkUpdateParams=" + Integer.toHexString(mBulkUpdateParams) 708 + " mPendingLayoutChanges(DEFAULT_DISPLAY)=" 709 + Integer.toHexString(mPendingLayoutChanges.get(Display.DEFAULT_DISPLAY))); 710 } 711 } 712 713 WindowState mCurrentFocus; 714 void setCurrentFocus(final WindowState currentFocus) { 715 mCurrentFocus = currentFocus; 716 } 717 718 void setDisplayDimensions(final int curWidth, final int curHeight, 719 final int appWidth, final int appHeight) { 720 mDw = curWidth; 721 mDh = curHeight; 722 mInnerDw = appWidth; 723 mInnerDh = appHeight; 724 } 725 726 boolean isDimmingLocked(int displayId) { 727 return getDisplayContentsAnimatorLocked(displayId).mDimParams != null; 728 } 729 730 boolean isDimmingLocked(final WindowStateAnimator winAnimator) { 731 DimAnimator.Parameters dimParams = 732 getDisplayContentsAnimatorLocked(winAnimator.mWin.getDisplayId()).mDimParams; 733 return dimParams != null && dimParams.mDimWinAnimator == winAnimator; 734 } 735 736 public void dumpLocked(PrintWriter pw, String prefix, boolean dumpAll) { 737 if (dumpAll) { 738 if (mWindowDetachedWallpaper != null) { 739 pw.print(prefix); pw.print("mWindowDetachedWallpaper="); 740 pw.println(mWindowDetachedWallpaper); 741 } 742 pw.print(prefix); pw.print("mAnimTransactionSequence="); 743 pw.print(mAnimTransactionSequence); 744 pw.println(" mForceHiding=" + forceHidingToString()); 745 for (int i = 0; i < mDisplayContentsAnimators.size(); i++) { 746 pw.print(prefix); pw.print("DisplayContentsAnimator #"); 747 pw.println(mDisplayContentsAnimators.keyAt(i)); 748 DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i); 749 final String subPrefix = " " + prefix; 750 final String subSubPrefix = " " + subPrefix; 751 if (displayAnimator.mWindowAnimationBackgroundSurface != null) { 752 pw.println(subPrefix + "mWindowAnimationBackgroundSurface:"); 753 displayAnimator.mWindowAnimationBackgroundSurface.printTo(subSubPrefix, pw); 754 } 755 if (displayAnimator.mDimAnimator != null) { 756 pw.println(subPrefix + "mDimAnimator:"); 757 displayAnimator.mDimAnimator.printTo(subSubPrefix, pw); 758 } else { 759 pw.println(subPrefix + "no DimAnimator "); 760 } 761 if (displayAnimator.mDimParams != null) { 762 pw.println(subPrefix + "mDimParams:"); 763 displayAnimator.mDimParams.printTo(subSubPrefix, pw); 764 } else { 765 pw.println(subPrefix + "no DimParams "); 766 } 767 if (displayAnimator.mScreenRotationAnimation != null) { 768 pw.println(subPrefix + "mScreenRotationAnimation:"); 769 displayAnimator.mScreenRotationAnimation.printTo(subSubPrefix, pw); 770 } else { 771 pw.print(subPrefix + "no ScreenRotationAnimation "); 772 } 773 } 774 pw.println(); 775 } 776 } 777 778 void clearPendingActions() { 779 synchronized (this) { 780 mPendingActions = 0; 781 } 782 } 783 784 void setPendingLayoutChanges(final int displayId, final int changes) { 785 mPendingLayoutChanges.put(displayId, mPendingLayoutChanges.get(displayId) | changes); 786 } 787 788 void setAppLayoutChanges(final AppWindowAnimator appAnimator, final int changes, String s) { 789 // Used to track which displays layout changes have been done. 790 SparseIntArray displays = new SparseIntArray(); 791 for (int i = appAnimator.mAllAppWinAnimators.size() - 1; i >= 0; i--) { 792 WindowStateAnimator winAnimator = appAnimator.mAllAppWinAnimators.get(i); 793 final int displayId = winAnimator.mWin.mDisplayContent.getDisplayId(); 794 if (displays.indexOfKey(displayId) < 0) { 795 setPendingLayoutChanges(displayId, changes); 796 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { 797 mService.debugLayoutRepeats(s, mPendingLayoutChanges.get(displayId)); 798 } 799 // Keep from processing this display again. 800 displays.put(displayId, changes); 801 } 802 } 803 } 804 805 private DisplayContentsAnimator getDisplayContentsAnimatorLocked(int displayId) { 806 DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.get(displayId); 807 if (displayAnimator == null) { 808 displayAnimator = new DisplayContentsAnimator(displayId); 809 mDisplayContentsAnimators.put(displayId, displayAnimator); 810 } 811 return displayAnimator; 812 } 813 814 void setScreenRotationAnimationLocked(int displayId, ScreenRotationAnimation animation) { 815 getDisplayContentsAnimatorLocked(displayId).mScreenRotationAnimation = animation; 816 } 817 818 ScreenRotationAnimation getScreenRotationAnimationLocked(int displayId) { 819 return getDisplayContentsAnimatorLocked(displayId).mScreenRotationAnimation; 820 } 821 822 private class DisplayContentsAnimator { 823 WinAnimatorList mWinAnimators = new WinAnimatorList(); 824 DimAnimator mDimAnimator = null; 825 DimAnimator.Parameters mDimParams = null; 826 DimSurface mWindowAnimationBackgroundSurface = null; 827 ScreenRotationAnimation mScreenRotationAnimation = null; 828 829 public DisplayContentsAnimator(int displayId) { 830 mDimAnimator = new DimAnimator(mService.mFxSession, displayId); 831 mWindowAnimationBackgroundSurface = 832 new DimSurface(mService.mFxSession, displayId); 833 } 834 } 835} 836