WindowAnimator.java revision ef03a7f441cf0cbef5a5f7fafb58a7d5aea7ef52
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 if (WindowManagerService.DEBUG_WALLPAPER_LIGHT && !token.hidden) Slog.d(TAG, 268 "Hiding wallpaper " + token + " from " + w); 269 token.hidden = true; 270 } 271 } 272 } 273 274 private void updateAppWindowsLocked() { 275 int i; 276 final int NAT = mAppAnimators.size(); 277 for (i=0; i<NAT; i++) { 278 final AppWindowAnimator appAnimator = mAppAnimators.get(i); 279 final boolean wasAnimating = appAnimator.animation != null 280 && appAnimator.animation != AppWindowAnimator.sDummyAnimation; 281 if (appAnimator.stepAnimationLocked(mCurrentTime, mInnerDw, mInnerDh)) { 282 mAnimating = true; 283 } else if (wasAnimating) { 284 // stopped animating, do one more pass through the layout 285 setAppLayoutChanges(appAnimator, WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER, 286 "appToken " + appAnimator.mAppToken + " done"); 287 if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG, 288 "updateWindowsApps...: done animating " + appAnimator.mAppToken); 289 } 290 } 291 292 final int NEAT = mService.mExitingAppTokens.size(); 293 for (i=0; i<NEAT; i++) { 294 final AppWindowAnimator appAnimator = mService.mExitingAppTokens.get(i).mAppAnimator; 295 final boolean wasAnimating = appAnimator.animation != null 296 && appAnimator.animation != AppWindowAnimator.sDummyAnimation; 297 if (appAnimator.stepAnimationLocked(mCurrentTime, mInnerDw, mInnerDh)) { 298 mAnimating = true; 299 } else if (wasAnimating) { 300 // stopped animating, do one more pass through the layout 301 setAppLayoutChanges(appAnimator, WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER, 302 "exiting appToken " + appAnimator.mAppToken + " done"); 303 if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG, 304 "updateWindowsApps...: done animating exiting " + appAnimator.mAppToken); 305 } 306 } 307 } 308 309 private void updateWindowsLocked(final int displayId) { 310 ++mAnimTransactionSequence; 311 312 final WinAnimatorList winAnimatorList = 313 getDisplayContentsAnimatorLocked(displayId).mWinAnimators; 314 ArrayList<WindowStateAnimator> unForceHiding = null; 315 boolean wallpaperInUnForceHiding = false; 316 mForceHiding = KEYGUARD_NOT_SHOWN; 317 318 for (int i = winAnimatorList.size() - 1; i >= 0; i--) { 319 WindowStateAnimator winAnimator = winAnimatorList.get(i); 320 WindowState win = winAnimator.mWin; 321 final int flags = winAnimator.mAttrFlags; 322 323 if (winAnimator.mSurface != null) { 324 final boolean wasAnimating = winAnimator.mWasAnimating; 325 final boolean nowAnimating = winAnimator.stepAnimationLocked(mCurrentTime); 326 327 if (WindowManagerService.DEBUG_WALLPAPER) { 328 Slog.v(TAG, win + ": wasAnimating=" + wasAnimating + 329 ", nowAnimating=" + nowAnimating); 330 } 331 332 if (wasAnimating && !winAnimator.mAnimating && mWallpaperTarget == win) { 333 mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE; 334 setPendingLayoutChanges(Display.DEFAULT_DISPLAY, 335 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); 336 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { 337 mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 2", 338 mPendingLayoutChanges.get(Display.DEFAULT_DISPLAY)); 339 } 340 } 341 342 if (mPolicy.doesForceHide(win, win.mAttrs)) { 343 if (!wasAnimating && nowAnimating) { 344 if (WindowManagerService.DEBUG_ANIM || 345 WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, 346 "Animation started that could impact force hide: " + win); 347 mBulkUpdateParams |= SET_FORCE_HIDING_CHANGED; 348 setPendingLayoutChanges(displayId, 349 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); 350 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { 351 mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 3", 352 mPendingLayoutChanges.get(displayId)); 353 } 354 mService.mFocusMayChange = true; 355 } 356 if (win.isReadyForDisplay()) { 357 if (nowAnimating) { 358 if (winAnimator.mAnimationIsEntrance) { 359 mForceHiding = KEYGUARD_ANIMATING_IN; 360 } else { 361 mForceHiding = KEYGUARD_ANIMATING_OUT; 362 } 363 } else { 364 mForceHiding = KEYGUARD_SHOWN; 365 } 366 } 367 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, 368 "Force hide " + mForceHiding 369 + " hasSurface=" + win.mHasSurface 370 + " policyVis=" + win.mPolicyVisibility 371 + " destroying=" + win.mDestroying 372 + " attHidden=" + win.mAttachedHidden 373 + " vis=" + win.mViewVisibility 374 + " hidden=" + win.mRootToken.hidden 375 + " anim=" + win.mWinAnimator.mAnimation); 376 } else if (mPolicy.canBeForceHidden(win, win.mAttrs)) { 377 final boolean hideWhenLocked = 378 (winAnimator.mAttrFlags & FLAG_SHOW_WHEN_LOCKED) == 0; 379 final boolean changed; 380 if (((mForceHiding == KEYGUARD_ANIMATING_IN) 381 && (!winAnimator.isAnimating() || hideWhenLocked)) 382 || ((mForceHiding == KEYGUARD_SHOWN) && hideWhenLocked)) { 383 changed = win.hideLw(false, false); 384 if (WindowManagerService.DEBUG_VISIBILITY && changed) Slog.v(TAG, 385 "Now policy hidden: " + win); 386 } else { 387 changed = win.showLw(false, false); 388 if (WindowManagerService.DEBUG_VISIBILITY && changed) Slog.v(TAG, 389 "Now policy shown: " + win); 390 if (changed) { 391 if ((mBulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0 392 && win.isVisibleNow() /*w.isReadyForDisplay()*/) { 393 if (unForceHiding == null) { 394 unForceHiding = new ArrayList<WindowStateAnimator>(); 395 } 396 unForceHiding.add(winAnimator); 397 if ((flags & FLAG_SHOW_WALLPAPER) != 0) { 398 wallpaperInUnForceHiding = true; 399 } 400 } 401 if (mCurrentFocus == null || mCurrentFocus.mLayer < win.mLayer) { 402 // We are showing on to of the current 403 // focus, so re-evaluate focus to make 404 // sure it is correct. 405 mService.mFocusMayChange = true; 406 } 407 } 408 } 409 if (changed && (flags & FLAG_SHOW_WALLPAPER) != 0) { 410 mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE; 411 setPendingLayoutChanges(Display.DEFAULT_DISPLAY, 412 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); 413 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { 414 mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 4", 415 mPendingLayoutChanges.get(Display.DEFAULT_DISPLAY)); 416 } 417 } 418 } 419 } 420 421 final AppWindowToken atoken = win.mAppToken; 422 if (winAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW) { 423 if (atoken == null || atoken.allDrawn) { 424 if (winAnimator.performShowLocked()) { 425 mPendingLayoutChanges.put(displayId, 426 WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM); 427 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { 428 mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 5", 429 mPendingLayoutChanges.get(displayId)); 430 } 431 } 432 } 433 } 434 final AppWindowAnimator appAnimator = winAnimator.mAppAnimator; 435 if (appAnimator != null && appAnimator.thumbnail != null) { 436 if (appAnimator.thumbnailTransactionSeq != mAnimTransactionSequence) { 437 appAnimator.thumbnailTransactionSeq = mAnimTransactionSequence; 438 appAnimator.thumbnailLayer = 0; 439 } 440 if (appAnimator.thumbnailLayer < winAnimator.mAnimLayer) { 441 appAnimator.thumbnailLayer = winAnimator.mAnimLayer; 442 } 443 } 444 } // end forall windows 445 446 // If we have windows that are being show due to them no longer 447 // being force-hidden, apply the appropriate animation to them. 448 if (unForceHiding != null) { 449 for (int i=unForceHiding.size()-1; i>=0; i--) { 450 Animation a = mPolicy.createForceHideEnterAnimation(wallpaperInUnForceHiding); 451 if (a != null) { 452 final WindowStateAnimator winAnimator = unForceHiding.get(i); 453 winAnimator.setAnimation(a); 454 winAnimator.mAnimationIsEntrance = true; 455 } 456 } 457 } 458 } 459 460 private void updateWallpaperLocked(int displayId) { 461 final DisplayContentsAnimator displayAnimator = 462 getDisplayContentsAnimatorLocked(displayId); 463 final WinAnimatorList winAnimatorList = displayAnimator.mWinAnimators; 464 WindowStateAnimator windowAnimationBackground = null; 465 int windowAnimationBackgroundColor = 0; 466 WindowState detachedWallpaper = null; 467 final DimSurface windowAnimationBackgroundSurface = 468 displayAnimator.mWindowAnimationBackgroundSurface; 469 470 for (int i = winAnimatorList.size() - 1; i >= 0; i--) { 471 WindowStateAnimator winAnimator = winAnimatorList.get(i); 472 if (winAnimator.mSurface == null) { 473 continue; 474 } 475 476 final int flags = winAnimator.mAttrFlags; 477 final WindowState win = winAnimator.mWin; 478 479 // If this window is animating, make a note that we have 480 // an animating window and take care of a request to run 481 // a detached wallpaper animation. 482 if (winAnimator.mAnimating) { 483 if (winAnimator.mAnimation != null) { 484 if ((flags & FLAG_SHOW_WALLPAPER) != 0 485 && winAnimator.mAnimation.getDetachWallpaper()) { 486 detachedWallpaper = win; 487 } 488 final int backgroundColor = winAnimator.mAnimation.getBackgroundColor(); 489 if (backgroundColor != 0) { 490 if (windowAnimationBackground == null || (winAnimator.mAnimLayer < 491 windowAnimationBackground.mAnimLayer)) { 492 windowAnimationBackground = winAnimator; 493 windowAnimationBackgroundColor = backgroundColor; 494 } 495 } 496 } 497 mAnimating = true; 498 } 499 500 // If this window's app token is running a detached wallpaper 501 // animation, make a note so we can ensure the wallpaper is 502 // displayed behind it. 503 final AppWindowAnimator appAnimator = winAnimator.mAppAnimator; 504 if (appAnimator != null && appAnimator.animation != null 505 && appAnimator.animating) { 506 if ((flags & FLAG_SHOW_WALLPAPER) != 0 507 && appAnimator.animation.getDetachWallpaper()) { 508 detachedWallpaper = win; 509 } 510 511 final int backgroundColor = appAnimator.animation.getBackgroundColor(); 512 if (backgroundColor != 0) { 513 if (windowAnimationBackground == null || (winAnimator.mAnimLayer < 514 windowAnimationBackground.mAnimLayer)) { 515 windowAnimationBackground = winAnimator; 516 windowAnimationBackgroundColor = backgroundColor; 517 } 518 } 519 } 520 } // end forall windows 521 522 if (mWindowDetachedWallpaper != detachedWallpaper) { 523 if (WindowManagerService.DEBUG_WALLPAPER) Slog.v(TAG, 524 "Detached wallpaper changed from " + mWindowDetachedWallpaper 525 + " to " + detachedWallpaper); 526 mWindowDetachedWallpaper = detachedWallpaper; 527 mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE; 528 } 529 530 if (windowAnimationBackgroundColor != 0) { 531 // If the window that wants black is the current wallpaper 532 // target, then the black goes *below* the wallpaper so we 533 // don't cause the wallpaper to suddenly disappear. 534 int animLayer = windowAnimationBackground.mAnimLayer; 535 WindowState win = windowAnimationBackground.mWin; 536 if (mWallpaperTarget == win 537 || mLowerWallpaperTarget == win || mUpperWallpaperTarget == win) { 538 final int N = winAnimatorList.size(); 539 for (int i = 0; i < N; i++) { 540 WindowStateAnimator winAnimator = winAnimatorList.get(i); 541 if (winAnimator.mIsWallpaper) { 542 animLayer = winAnimator.mAnimLayer; 543 break; 544 } 545 } 546 } 547 548 if (windowAnimationBackgroundSurface != null) { 549 windowAnimationBackgroundSurface.show(mDw, mDh, 550 animLayer - WindowManagerService.LAYER_OFFSET_DIM, 551 windowAnimationBackgroundColor); 552 } 553 } else { 554 if (windowAnimationBackgroundSurface != null) { 555 windowAnimationBackgroundSurface.hide(); 556 } 557 } 558 } 559 560 private void testTokenMayBeDrawnLocked() { 561 // See if any windows have been drawn, so they (and others 562 // associated with them) can now be shown. 563 final int NT = mAppAnimators.size(); 564 for (int i=0; i<NT; i++) { 565 AppWindowAnimator appAnimator = mAppAnimators.get(i); 566 AppWindowToken wtoken = appAnimator.mAppToken; 567 final boolean allDrawn = wtoken.allDrawn; 568 if (allDrawn != appAnimator.allDrawn) { 569 appAnimator.allDrawn = allDrawn; 570 if (allDrawn) { 571 // The token has now changed state to having all 572 // windows shown... what to do, what to do? 573 if (appAnimator.freezingScreen) { 574 appAnimator.showAllWindowsLocked(); 575 mService.unsetAppFreezingScreenLocked(wtoken, false, true); 576 if (WindowManagerService.DEBUG_ORIENTATION) Slog.i(TAG, 577 "Setting mOrientationChangeComplete=true because wtoken " 578 + wtoken + " numInteresting=" + wtoken.numInterestingWindows 579 + " numDrawn=" + wtoken.numDrawnWindows); 580 // This will set mOrientationChangeComplete and cause a pass through layout. 581 setAppLayoutChanges(appAnimator, 582 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER, 583 "testTokenMayBeDrawnLocked: freezingScreen"); 584 } else { 585 setAppLayoutChanges(appAnimator, 586 WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM, 587 "testTokenMayBeDrawnLocked"); 588 589 // We can now show all of the drawn windows! 590 if (!mService.mOpeningApps.contains(wtoken)) { 591 mAnimating |= appAnimator.showAllWindowsLocked(); 592 } 593 } 594 } 595 } 596 } 597 } 598 599 private void performAnimationsLocked(final int displayId) { 600 updateWindowsLocked(displayId); 601 updateWallpaperLocked(displayId); 602 } 603 604 // TODO(cmautner): Change the following comment when no longer locked on mWindowMap */ 605 /** Locked on mService.mWindowMap and this. */ 606 private void animateLocked() { 607 if (!mInitialized) { 608 return; 609 } 610 611 mPendingLayoutChanges.clear(); 612 mCurrentTime = SystemClock.uptimeMillis(); 613 mBulkUpdateParams = SET_ORIENTATION_CHANGE_COMPLETE; 614 boolean wasAnimating = mAnimating; 615 mAnimating = false; 616 if (WindowManagerService.DEBUG_WINDOW_TRACE) { 617 Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime); 618 } 619 620 if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i( 621 TAG, ">>> OPEN TRANSACTION animateLocked"); 622 Surface.openTransaction(); 623 Surface.setAnimationTransaction(); 624 try { 625 updateAppWindowsLocked(); 626 627 final int numDisplays = mDisplayContentsAnimators.size(); 628 for (int i = 0; i < numDisplays; i++) { 629 final int displayId = mDisplayContentsAnimators.keyAt(i); 630 DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i); 631 632 final ScreenRotationAnimation screenRotationAnimation = 633 displayAnimator.mScreenRotationAnimation; 634 if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) { 635 if (screenRotationAnimation.stepAnimationLocked(mCurrentTime)) { 636 mAnimating = true; 637 } else { 638 mBulkUpdateParams |= SET_UPDATE_ROTATION; 639 screenRotationAnimation.kill(); 640 displayAnimator.mScreenRotationAnimation = null; 641 } 642 } 643 644 // Update animations of all applications, including those 645 // associated with exiting/removed apps 646 performAnimationsLocked(displayId); 647 648 final WinAnimatorList winAnimatorList = displayAnimator.mWinAnimators; 649 final int N = winAnimatorList.size(); 650 for (int j = 0; j < N; j++) { 651 winAnimatorList.get(j).prepareSurfaceLocked(true); 652 } 653 } 654 655 testTokenMayBeDrawnLocked(); 656 657 for (int i = 0; i < numDisplays; i++) { 658 final int displayId = mDisplayContentsAnimators.keyAt(i); 659 DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i); 660 661 final ScreenRotationAnimation screenRotationAnimation = 662 displayAnimator.mScreenRotationAnimation; 663 if (screenRotationAnimation != null) { 664 screenRotationAnimation.updateSurfacesInTransaction(); 665 } 666 667 final DimAnimator.Parameters dimParams = displayAnimator.mDimParams; 668 final DimAnimator dimAnimator = displayAnimator.mDimAnimator; 669 if (dimAnimator != null && dimParams != null) { 670 dimAnimator.updateParameters(mContext.getResources(), dimParams, mCurrentTime); 671 } 672 if (dimAnimator != null && dimAnimator.mDimShown) { 673 mAnimating |= dimAnimator.updateSurface(isDimmingLocked(displayId), 674 mCurrentTime, !mService.okToDisplay()); 675 } 676 } 677 678 if (mService.mWatermark != null) { 679 mService.mWatermark.drawIfNeeded(); 680 } 681 } catch (RuntimeException e) { 682 Log.wtf(TAG, "Unhandled exception in Window Manager", e); 683 } finally { 684 Surface.closeTransaction(); 685 if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i( 686 TAG, "<<< CLOSE TRANSACTION animateLocked"); 687 } 688 689 for (int i = mPendingLayoutChanges.size() - 1; i >= 0; i--) { 690 if ((mPendingLayoutChanges.valueAt(i) 691 & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) { 692 mPendingActions |= WALLPAPER_ACTION_PENDING; 693 } 694 } 695 696 if (mBulkUpdateParams != 0 || mPendingLayoutChanges.size() > 0) { 697 updateAnimToLayoutLocked(); 698 } 699 700 if (mAnimating) { 701 synchronized (mService.mLayoutToAnim) { 702 mService.scheduleAnimationLocked(); 703 } 704 } else if (wasAnimating) { 705 mService.requestTraversalLocked(); 706 } 707 if (WindowManagerService.DEBUG_WINDOW_TRACE) { 708 Slog.i(TAG, "!!! animate: exit mAnimating=" + mAnimating 709 + " mBulkUpdateParams=" + Integer.toHexString(mBulkUpdateParams) 710 + " mPendingLayoutChanges(DEFAULT_DISPLAY)=" 711 + Integer.toHexString(mPendingLayoutChanges.get(Display.DEFAULT_DISPLAY))); 712 } 713 } 714 715 WindowState mCurrentFocus; 716 void setCurrentFocus(final WindowState currentFocus) { 717 mCurrentFocus = currentFocus; 718 } 719 720 void setDisplayDimensions(final int curWidth, final int curHeight, 721 final int appWidth, final int appHeight) { 722 mDw = curWidth; 723 mDh = curHeight; 724 mInnerDw = appWidth; 725 mInnerDh = appHeight; 726 } 727 728 boolean isDimmingLocked(int displayId) { 729 return getDisplayContentsAnimatorLocked(displayId).mDimParams != null; 730 } 731 732 boolean isDimmingLocked(final WindowStateAnimator winAnimator) { 733 DimAnimator.Parameters dimParams = 734 getDisplayContentsAnimatorLocked(winAnimator.mWin.getDisplayId()).mDimParams; 735 return dimParams != null && dimParams.mDimWinAnimator == winAnimator; 736 } 737 738 public void dumpLocked(PrintWriter pw, String prefix, boolean dumpAll) { 739 if (dumpAll) { 740 if (mWindowDetachedWallpaper != null) { 741 pw.print(prefix); pw.print("mWindowDetachedWallpaper="); 742 pw.println(mWindowDetachedWallpaper); 743 } 744 pw.print(prefix); pw.print("mAnimTransactionSequence="); 745 pw.print(mAnimTransactionSequence); 746 pw.println(" mForceHiding=" + forceHidingToString()); 747 for (int i = 0; i < mDisplayContentsAnimators.size(); i++) { 748 pw.print(prefix); pw.print("DisplayContentsAnimator #"); 749 pw.println(mDisplayContentsAnimators.keyAt(i)); 750 DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i); 751 final String subPrefix = " " + prefix; 752 final String subSubPrefix = " " + subPrefix; 753 if (displayAnimator.mWindowAnimationBackgroundSurface != null) { 754 pw.println(subPrefix + "mWindowAnimationBackgroundSurface:"); 755 displayAnimator.mWindowAnimationBackgroundSurface.printTo(subSubPrefix, pw); 756 } 757 if (displayAnimator.mDimAnimator != null) { 758 pw.println(subPrefix + "mDimAnimator:"); 759 displayAnimator.mDimAnimator.printTo(subSubPrefix, pw); 760 } else { 761 pw.println(subPrefix + "no DimAnimator "); 762 } 763 if (displayAnimator.mDimParams != null) { 764 pw.println(subPrefix + "mDimParams:"); 765 displayAnimator.mDimParams.printTo(subSubPrefix, pw); 766 } else { 767 pw.println(subPrefix + "no DimParams "); 768 } 769 if (displayAnimator.mScreenRotationAnimation != null) { 770 pw.println(subPrefix + "mScreenRotationAnimation:"); 771 displayAnimator.mScreenRotationAnimation.printTo(subSubPrefix, pw); 772 } else { 773 pw.print(subPrefix + "no ScreenRotationAnimation "); 774 } 775 } 776 pw.println(); 777 } 778 } 779 780 void clearPendingActions() { 781 synchronized (this) { 782 mPendingActions = 0; 783 } 784 } 785 786 void setPendingLayoutChanges(final int displayId, final int changes) { 787 mPendingLayoutChanges.put(displayId, mPendingLayoutChanges.get(displayId) | changes); 788 } 789 790 void setAppLayoutChanges(final AppWindowAnimator appAnimator, final int changes, String s) { 791 // Used to track which displays layout changes have been done. 792 SparseIntArray displays = new SparseIntArray(); 793 for (int i = appAnimator.mAllAppWinAnimators.size() - 1; i >= 0; i--) { 794 WindowStateAnimator winAnimator = appAnimator.mAllAppWinAnimators.get(i); 795 final int displayId = winAnimator.mWin.mDisplayContent.getDisplayId(); 796 if (displays.indexOfKey(displayId) < 0) { 797 setPendingLayoutChanges(displayId, changes); 798 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { 799 mService.debugLayoutRepeats(s, mPendingLayoutChanges.get(displayId)); 800 } 801 // Keep from processing this display again. 802 displays.put(displayId, changes); 803 } 804 } 805 } 806 807 private DisplayContentsAnimator getDisplayContentsAnimatorLocked(int displayId) { 808 DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.get(displayId); 809 if (displayAnimator == null) { 810 displayAnimator = new DisplayContentsAnimator(displayId); 811 mDisplayContentsAnimators.put(displayId, displayAnimator); 812 } 813 return displayAnimator; 814 } 815 816 void setScreenRotationAnimationLocked(int displayId, ScreenRotationAnimation animation) { 817 getDisplayContentsAnimatorLocked(displayId).mScreenRotationAnimation = animation; 818 } 819 820 ScreenRotationAnimation getScreenRotationAnimationLocked(int displayId) { 821 return getDisplayContentsAnimatorLocked(displayId).mScreenRotationAnimation; 822 } 823 824 private class DisplayContentsAnimator { 825 WinAnimatorList mWinAnimators = new WinAnimatorList(); 826 DimAnimator mDimAnimator = null; 827 DimAnimator.Parameters mDimParams = null; 828 DimSurface mWindowAnimationBackgroundSurface = null; 829 ScreenRotationAnimation mScreenRotationAnimation = null; 830 831 public DisplayContentsAnimator(int displayId) { 832 mDimAnimator = new DimAnimator(mService.mFxSession, displayId); 833 mWindowAnimationBackgroundSurface = 834 new DimSurface(mService.mFxSession, displayId); 835 } 836 } 837} 838