WindowStateAnimator.java revision fa25bf5382467b1018bd9af7f1cb30a23d7d59f7
1// Copyright 2012 Google Inc. All Rights Reserved. 2 3package com.android.server.wm; 4 5import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; 6 7import static com.android.server.wm.WindowManagerService.LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE; 8import static com.android.server.wm.WindowManagerService.LayoutFields.SET_TURN_ON_SCREEN; 9 10import android.content.Context; 11import android.graphics.Matrix; 12import android.graphics.PixelFormat; 13import android.graphics.Point; 14import android.graphics.PointF; 15import android.graphics.Rect; 16import android.graphics.Region; 17import android.os.Debug; 18import android.util.Slog; 19import android.view.Surface; 20import android.view.SurfaceSession; 21import android.view.WindowManager; 22import android.view.WindowManagerPolicy; 23import android.view.WindowManager.LayoutParams; 24import android.view.animation.Animation; 25import android.view.animation.AnimationUtils; 26import android.view.animation.Transformation; 27 28import com.android.server.wm.WindowManagerService.H; 29 30import java.io.PrintWriter; 31import java.util.ArrayList; 32 33/** 34 * Keep track of animations and surface operations for a single WindowState. 35 **/ 36class WindowStateAnimator { 37 static final boolean DEBUG_VISIBILITY = WindowManagerService.DEBUG_VISIBILITY; 38 static final boolean DEBUG_ANIM = WindowManagerService.DEBUG_ANIM; 39 static final boolean DEBUG_LAYERS = WindowManagerService.DEBUG_LAYERS; 40 static final boolean DEBUG_STARTING_WINDOW = WindowManagerService.DEBUG_STARTING_WINDOW; 41 static final boolean SHOW_TRANSACTIONS = WindowManagerService.SHOW_TRANSACTIONS; 42 static final boolean SHOW_LIGHT_TRANSACTIONS = WindowManagerService.SHOW_LIGHT_TRANSACTIONS; 43 static final boolean SHOW_SURFACE_ALLOC = WindowManagerService.SHOW_SURFACE_ALLOC; 44 static final boolean localLOGV = WindowManagerService.localLOGV; 45 static final boolean DEBUG_ORIENTATION = WindowManagerService.DEBUG_ORIENTATION; 46 static final boolean DEBUG_SURFACE_TRACE = WindowManagerService.DEBUG_SURFACE_TRACE; 47 48 static final String TAG = "WindowStateAnimator"; 49 50 // Unchanging local convenience fields. 51 final WindowManagerService mService; 52 final WindowState mWin; 53 final WindowStateAnimator mAttachedWinAnimator; 54 final WindowAnimator mAnimator; 55 final AppWindowAnimator mAppAnimator; 56 final Session mSession; 57 final WindowManagerPolicy mPolicy; 58 final Context mContext; 59 final boolean mIsWallpaper; 60 61 // If this is a universe background window, this is the transformation 62 // it is applying to the rest of the universe. 63 final Transformation mUniverseTransform = new Transformation(); 64 65 // Currently running animation. 66 boolean mAnimating; 67 boolean mLocalAnimating; 68 Animation mAnimation; 69 boolean mAnimationIsEntrance; 70 boolean mHasTransformation; 71 boolean mHasLocalTransformation; 72 final Transformation mTransformation = new Transformation(); 73 boolean mWasAnimating; // Were we animating going into the most recent animation step? 74 int mAnimLayer; 75 int mLastLayer; 76 77 Surface mSurface; 78 Surface mPendingDestroySurface; 79 80 /** 81 * Set when we have changed the size of the surface, to know that 82 * we must tell them application to resize (and thus redraw itself). 83 */ 84 boolean mSurfaceResized; 85 86 /** 87 * Set if the client has asked that the destroy of its surface be delayed 88 * until it explicitly says it is okay. 89 */ 90 boolean mSurfaceDestroyDeferred; 91 92 float mShownAlpha = 0; 93 float mAlpha = 0; 94 float mLastAlpha = 0; 95 96 // Used to save animation distances between the time they are calculated and when they are 97 // used. 98 int mAnimDw; 99 int mAnimDh; 100 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1; 101 float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1; 102 103 boolean mHaveMatrix; 104 105 // For debugging, this is the last information given to the surface flinger. 106 boolean mSurfaceShown; 107 float mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH; 108 int mSurfaceLayer; 109 float mSurfaceAlpha; 110 111 // Set to true if, when the window gets displayed, it should perform 112 // an enter animation. 113 boolean mEnterAnimationPending; 114 115 /** This is set when there is no Surface */ 116 static final int NO_SURFACE = 0; 117 /** This is set after the Surface has been created but before the window has been drawn. During 118 * this time the surface is hidden. */ 119 static final int DRAW_PENDING = 1; 120 /** This is set after the window has finished drawing for the first time but before its surface 121 * is shown. The surface will be displayed when the next layout is run. */ 122 static final int COMMIT_DRAW_PENDING = 2; 123 /** This is set during the time after the window's drawing has been committed, and before its 124 * surface is actually shown. It is used to delay showing the surface until all windows in a 125 * token are ready to be shown. */ 126 static final int READY_TO_SHOW = 3; 127 /** Set when the window has been shown in the screen the first time. */ 128 static final int HAS_DRAWN = 4; 129 static String drawStateToString(int state) { 130 switch (state) { 131 case NO_SURFACE: return "NO_SURFACE"; 132 case DRAW_PENDING: return "DRAW_PENDING"; 133 case COMMIT_DRAW_PENDING: return "COMMIT_DRAW_PENDING"; 134 case READY_TO_SHOW: return "READY_TO_SHOW"; 135 case HAS_DRAWN: return "HAS_DRAWN"; 136 default: return Integer.toString(state); 137 } 138 } 139 int mDrawState; 140 141 /** Was this window last hidden? */ 142 boolean mLastHidden; 143 144 int mAttrFlags; 145 int mAttrType; 146 147 public WindowStateAnimator(final WindowState win) { 148 final WindowManagerService service = win.mService; 149 150 mService = service; 151 mAnimator = service.mAnimator; 152 mPolicy = service.mPolicy; 153 mContext = service.mContext; 154 mAnimDw = service.mDisplayInfo.appWidth; 155 mAnimDh = service.mDisplayInfo.appHeight; 156 157 mWin = win; 158 mAttachedWinAnimator = win.mAttachedWindow == null 159 ? null : win.mAttachedWindow.mWinAnimator; 160 mAppAnimator = win.mAppToken == null ? null : win.mAppToken.mAppAnimator; 161 mSession = win.mSession; 162 mAttrFlags = win.mAttrs.flags; 163 mAttrType = win.mAttrs.type; 164 mIsWallpaper = win.mIsWallpaper; 165 } 166 167 public void setAnimation(Animation anim) { 168 if (localLOGV) Slog.v(TAG, "Setting animation in " + this + ": " + anim); 169 mAnimating = false; 170 mLocalAnimating = false; 171 mAnimation = anim; 172 mAnimation.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION); 173 mAnimation.scaleCurrentDuration(mService.mWindowAnimationScale); 174 // Start out animation gone if window is gone, or visible if window is visible. 175 mTransformation.clear(); 176 mTransformation.setAlpha(mLastHidden ? 0 : 1); 177 mHasLocalTransformation = true; 178 } 179 180 public void clearAnimation() { 181 if (mAnimation != null) { 182 mAnimating = true; 183 mLocalAnimating = false; 184 mAnimation.cancel(); 185 mAnimation = null; 186 } 187 } 188 189 /** Is the window or its container currently animating? */ 190 boolean isAnimating() { 191 return mAnimation != null 192 || (mAttachedWinAnimator != null && mAttachedWinAnimator.mAnimation != null) 193 || (mAppAnimator != null && 194 (mAppAnimator.animation != null 195 || mAppAnimator.mAppToken.inPendingTransaction)); 196 } 197 198 /** Is the window animating the DummyAnimation? */ 199 boolean isDummyAnimation() { 200 return mAppAnimator != null 201 && mAppAnimator.animation == AppWindowAnimator.sDummyAnimation; 202 } 203 204 /** Is this window currently animating? */ 205 boolean isWindowAnimating() { 206 return mAnimation != null; 207 } 208 209 void cancelExitAnimationForNextAnimationLocked() { 210 if (mAnimation != null) { 211 mAnimation.cancel(); 212 mAnimation = null; 213 mLocalAnimating = false; 214 destroySurfaceLocked(); 215 } 216 } 217 218 private boolean stepAnimation(long currentTime) { 219 if ((mAnimation == null) || !mLocalAnimating) { 220 return false; 221 } 222 mTransformation.clear(); 223 final boolean more = mAnimation.getTransformation(currentTime, mTransformation); 224 if (false && DEBUG_ANIM) Slog.v( 225 TAG, "Stepped animation in " + this + 226 ": more=" + more + ", xform=" + mTransformation); 227 return more; 228 } 229 230 // This must be called while inside a transaction. Returns true if 231 // there is more animation to run. 232 boolean stepAnimationLocked(long currentTime) { 233 // Save the animation state as it was before this step so WindowManagerService can tell if 234 // we just started or just stopped animating by comparing mWasAnimating with isAnimating(). 235 mWasAnimating = mAnimating; 236 if (mService.okToDisplay()) { 237 // We will run animations as long as the display isn't frozen. 238 239 if (mWin.isDrawnLw() && mAnimation != null) { 240 mHasTransformation = true; 241 mHasLocalTransformation = true; 242 if (!mLocalAnimating) { 243 if (DEBUG_ANIM) Slog.v( 244 TAG, "Starting animation in " + this + 245 " @ " + currentTime + ": ww=" + mWin.mFrame.width() + 246 " wh=" + mWin.mFrame.height() + 247 " dw=" + mAnimDw + " dh=" + mAnimDh + 248 " scale=" + mService.mWindowAnimationScale); 249 mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(), 250 mAnimDw, mAnimDh); 251 mAnimDw = mService.mDisplayInfo.appWidth; 252 mAnimDh = mService.mDisplayInfo.appHeight; 253 mAnimation.setStartTime(currentTime); 254 mLocalAnimating = true; 255 mAnimating = true; 256 } 257 if ((mAnimation != null) && mLocalAnimating) { 258 if (stepAnimation(currentTime)) { 259 return true; 260 } 261 } 262 if (DEBUG_ANIM) Slog.v( 263 TAG, "Finished animation in " + this + 264 " @ " + currentTime); 265 //WindowManagerService.this.dump(); 266 } 267 mHasLocalTransformation = false; 268 if ((!mLocalAnimating || mAnimationIsEntrance) && mAppAnimator != null 269 && mAppAnimator.animation != null) { 270 // When our app token is animating, we kind-of pretend like 271 // we are as well. Note the mLocalAnimating mAnimationIsEntrance 272 // part of this check means that we will only do this if 273 // our window is not currently exiting, or it is not 274 // locally animating itself. The idea being that one that 275 // is exiting and doing a local animation should be removed 276 // once that animation is done. 277 mAnimating = true; 278 mHasTransformation = true; 279 mTransformation.clear(); 280 return false; 281 } else if (mHasTransformation) { 282 // Little trick to get through the path below to act like 283 // we have finished an animation. 284 mAnimating = true; 285 } else if (isAnimating()) { 286 mAnimating = true; 287 } 288 } else if (mAnimation != null) { 289 // If the display is frozen, and there is a pending animation, 290 // clear it and make sure we run the cleanup code. 291 mAnimating = true; 292 } 293 294 if (!mAnimating && !mLocalAnimating) { 295 return false; 296 } 297 298 // Done animating, clean up. 299 if (DEBUG_ANIM) Slog.v( 300 TAG, "Animation done in " + this + ": exiting=" + mWin.mExiting 301 + ", reportedVisible=" 302 + (mWin.mAppToken != null ? mWin.mAppToken.reportedVisible : false)); 303 304 mAnimating = false; 305 mLocalAnimating = false; 306 if (mAnimation != null) { 307 mAnimation.cancel(); 308 mAnimation = null; 309 } 310 if (mAnimator.mWindowDetachedWallpaper == mWin) { 311 mAnimator.mWindowDetachedWallpaper = null; 312 } 313 mAnimLayer = mWin.mLayer; 314 if (mWin.mIsImWindow) { 315 mAnimLayer += mService.mInputMethodAnimLayerAdjustment; 316 } else if (mIsWallpaper) { 317 mAnimLayer += mService.mWallpaperAnimLayerAdjustment; 318 } 319 if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this 320 + " anim layer: " + mAnimLayer); 321 mHasTransformation = false; 322 mHasLocalTransformation = false; 323 if (mWin.mPolicyVisibility != mWin.mPolicyVisibilityAfterAnim) { 324 if (WindowState.DEBUG_VISIBILITY) { 325 Slog.v(TAG, "Policy visibility changing after anim in " + this + ": " 326 + mWin.mPolicyVisibilityAfterAnim); 327 } 328 mWin.mPolicyVisibility = mWin.mPolicyVisibilityAfterAnim; 329 mService.mLayoutNeeded = true; 330 if (!mWin.mPolicyVisibility) { 331 if (mService.mCurrentFocus == mWin) { 332 mService.mFocusMayChange = true; 333 } 334 // Window is no longer visible -- make sure if we were waiting 335 // for it to be displayed before enabling the display, that 336 // we allow the display to be enabled now. 337 mService.enableScreenIfNeededLocked(); 338 } 339 } 340 mTransformation.clear(); 341 if (mDrawState == HAS_DRAWN 342 && mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING 343 && mWin.mAppToken != null 344 && mWin.mAppToken.firstWindowDrawn 345 && mWin.mAppToken.startingData != null) { 346 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting " 347 + mWin.mToken + ": first real window done animating"); 348 mService.mFinishedStarting.add(mWin.mAppToken); 349 mService.mH.sendEmptyMessage(H.FINISHED_STARTING); 350 } 351 352 finishExit(); 353 mAnimator.mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM; 354 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) mService.debugLayoutRepeats( 355 "WindowStateAnimator", mAnimator.mPendingLayoutChanges); 356 357 if (mWin.mAppToken != null) { 358 mWin.mAppToken.updateReportedVisibilityLocked(); 359 } 360 361 return false; 362 } 363 364 void finishExit() { 365 if (WindowManagerService.DEBUG_ANIM) Slog.v( 366 TAG, "finishExit in " + this 367 + ": exiting=" + mWin.mExiting 368 + " remove=" + mWin.mRemoveOnExit 369 + " windowAnimating=" + isWindowAnimating()); 370 371 final int N = mWin.mChildWindows.size(); 372 for (int i=0; i<N; i++) { 373 mWin.mChildWindows.get(i).mWinAnimator.finishExit(); 374 } 375 376 if (!mWin.mExiting) { 377 return; 378 } 379 380 if (isWindowAnimating()) { 381 return; 382 } 383 384 if (WindowManagerService.localLOGV) Slog.v( 385 TAG, "Exit animation finished in " + this 386 + ": remove=" + mWin.mRemoveOnExit); 387 if (mSurface != null) { 388 mService.mDestroySurface.add(mWin); 389 mWin.mDestroying = true; 390 if (WindowState.SHOW_TRANSACTIONS) WindowManagerService.logSurface( 391 mWin, "HIDE (finishExit)", null); 392 hide(); 393 } 394 mWin.mExiting = false; 395 if (mWin.mRemoveOnExit) { 396 mService.mPendingRemove.add(mWin); 397 mWin.mRemoveOnExit = false; 398 } 399 mAnimator.hideWallpapersLocked(mWin); 400 } 401 402 void hide() { 403 if (!mLastHidden) { 404 //dump(); 405 mLastHidden = true; 406 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, 407 "HIDE (performLayout)", null); 408 if (mSurface != null) { 409 mSurfaceShown = false; 410 try { 411 mSurface.hide(); 412 } catch (RuntimeException e) { 413 Slog.w(TAG, "Exception hiding surface in " + mWin); 414 } 415 } 416 } 417 } 418 419 boolean finishDrawingLocked() { 420 if (DEBUG_STARTING_WINDOW && 421 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) { 422 Slog.v(TAG, "Finishing drawing window " + mWin + ": mDrawState=" 423 + drawStateToString(mDrawState)); 424 } 425 if (mDrawState == DRAW_PENDING) { 426 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION) 427 Slog.v(TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + this + " in " 428 + mSurface); 429 if (DEBUG_STARTING_WINDOW && 430 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) { 431 Slog.v(TAG, "Draw state now committed in " + mWin); 432 } 433 mDrawState = COMMIT_DRAW_PENDING; 434 return true; 435 } 436 return false; 437 } 438 439 // This must be called while inside a transaction. 440 boolean commitFinishDrawingLocked(long currentTime) { 441 if (DEBUG_STARTING_WINDOW && 442 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) { 443 Slog.i(TAG, "commitFinishDrawingLocked: " + mWin + " cur mDrawState=" 444 + drawStateToString(mDrawState)); 445 } 446 if (mDrawState != COMMIT_DRAW_PENDING) { 447 return false; 448 } 449 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM) { 450 Slog.i(TAG, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW " + mSurface); 451 } 452 mDrawState = READY_TO_SHOW; 453 final boolean starting = mWin.mAttrs.type == TYPE_APPLICATION_STARTING; 454 final AppWindowToken atoken = mWin.mAppToken; 455 if (atoken == null || atoken.allDrawn || starting) { 456 performShowLocked(); 457 } 458 return true; 459 } 460 461 static class SurfaceTrace extends Surface { 462 private final static String SURFACE_TAG = "SurfaceTrace"; 463 final static ArrayList<SurfaceTrace> sSurfaces = new ArrayList<SurfaceTrace>(); 464 465 private float mSurfaceTraceAlpha = 0; 466 private int mLayer; 467 private final PointF mPosition = new PointF(); 468 private final Point mSize = new Point(); 469 private final Rect mWindowCrop = new Rect(); 470 private boolean mShown = false; 471 private String mName = "Not named"; 472 473 public SurfaceTrace(SurfaceSession s, 474 int pid, int display, int w, int h, int format, int flags) throws 475 OutOfResourcesException { 476 super(s, pid, display, w, h, format, flags); 477 mSize.set(w, h); 478 Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by " 479 + Debug.getCallers(3)); 480 } 481 482 public SurfaceTrace(SurfaceSession s, 483 int pid, String name, int display, int w, int h, int format, int flags) 484 throws OutOfResourcesException { 485 super(s, pid, name, display, w, h, format, flags); 486 mName = name; 487 mSize.set(w, h); 488 Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by " 489 + Debug.getCallers(3)); 490 } 491 492 @Override 493 public void setAlpha(float alpha) { 494 super.setAlpha(alpha); 495 mSurfaceTraceAlpha = alpha; 496 Slog.v(SURFACE_TAG, "setAlpha: " + this + ". Called by " 497 + Debug.getCallers(3)); 498 } 499 500 @Override 501 public void setLayer(int zorder) { 502 super.setLayer(zorder); 503 mLayer = zorder; 504 Slog.v(SURFACE_TAG, "setLayer: " + this + ". Called by " 505 + Debug.getCallers(3)); 506 507 sSurfaces.remove(this); 508 int i; 509 for (i = sSurfaces.size() - 1; i >= 0; i--) { 510 SurfaceTrace s = sSurfaces.get(i); 511 if (s.mLayer < zorder) { 512 break; 513 } 514 } 515 sSurfaces.add(i + 1, this); 516 } 517 518 @Override 519 public void setPosition(float x, float y) { 520 super.setPosition(x, y); 521 mPosition.set(x, y); 522 Slog.v(SURFACE_TAG, "setPosition: " + this + ". Called by " 523 + Debug.getCallers(3)); 524 } 525 526 @Override 527 public void setSize(int w, int h) { 528 super.setSize(w, h); 529 mSize.set(w, h); 530 Slog.v(SURFACE_TAG, "setSize: " + this + ". Called by " 531 + Debug.getCallers(3)); 532 } 533 534 @Override 535 public void setWindowCrop(Rect crop) { 536 super.setWindowCrop(crop); 537 if (crop != null) { 538 mWindowCrop.set(crop); 539 } 540 Slog.v(SURFACE_TAG, "setWindowCrop: " + this + ". Called by " 541 + Debug.getCallers(3)); 542 } 543 544 @Override 545 public void hide() { 546 super.hide(); 547 mShown = false; 548 Slog.v(SURFACE_TAG, "hide: " + this + ". Called by " 549 + Debug.getCallers(3)); 550 } 551 @Override 552 public void show() { 553 super.show(); 554 mShown = true; 555 Slog.v(SURFACE_TAG, "show: " + this + ". Called by " 556 + Debug.getCallers(3)); 557 } 558 559 @Override 560 public void destroy() { 561 super.destroy(); 562 Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by " 563 + Debug.getCallers(3)); 564 sSurfaces.remove(this); 565 } 566 567 @Override 568 public void release() { 569 super.release(); 570 Slog.v(SURFACE_TAG, "release: " + this + ". Called by " 571 + Debug.getCallers(3)); 572 sSurfaces.remove(this); 573 } 574 575 static void dumpAllSurfaces() { 576 final int N = sSurfaces.size(); 577 for (int i = 0; i < N; i++) { 578 Slog.i(TAG, "SurfaceDump: " + sSurfaces.get(i)); 579 } 580 } 581 582 @Override 583 public String toString() { 584 return "Surface " + Integer.toHexString(System.identityHashCode(this)) + " " 585 + mName + ": shown=" + mShown + " layer=" + mLayer 586 + " alpha=" + mSurfaceTraceAlpha + " " + mPosition.x + "," + mPosition.y 587 + " " + mSize.x + "x" + mSize.y 588 + " crop=" + mWindowCrop.toShortString(); 589 } 590 } 591 592 Surface createSurfaceLocked() { 593 if (mSurface == null) { 594 if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG, 595 "createSurface " + this + ": mDrawState=DRAW_PENDING"); 596 mDrawState = DRAW_PENDING; 597 if (mWin.mAppToken != null) { 598 mWin.mAppToken.allDrawn = false; 599 } 600 601 mService.makeWindowFreezingScreenIfNeededLocked(mWin); 602 603 int flags = 0; 604 final WindowManager.LayoutParams attrs = mWin.mAttrs; 605 606 if ((attrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) { 607 flags |= Surface.SECURE; 608 } 609 if (WindowState.DEBUG_VISIBILITY) Slog.v( 610 TAG, "Creating surface in session " 611 + mSession.mSurfaceSession + " window " + this 612 + " w=" + mWin.mCompatFrame.width() 613 + " h=" + mWin.mCompatFrame.height() + " format=" 614 + attrs.format + " flags=" + flags); 615 616 int w = mWin.mCompatFrame.width(); 617 int h = mWin.mCompatFrame.height(); 618 if ((attrs.flags & LayoutParams.FLAG_SCALED) != 0) { 619 // for a scaled surface, we always want the requested 620 // size. 621 w = mWin.mRequestedWidth; 622 h = mWin.mRequestedHeight; 623 } 624 625 // Something is wrong and SurfaceFlinger will not like this, 626 // try to revert to sane values 627 if (w <= 0) w = 1; 628 if (h <= 0) h = 1; 629 630 mSurfaceShown = false; 631 mSurfaceLayer = 0; 632 mSurfaceAlpha = 0; 633 mSurfaceX = 0; 634 mSurfaceY = 0; 635 mSurfaceW = w; 636 mSurfaceH = h; 637 mWin.mLastSystemDecorRect.set(0, 0, 0, 0); 638 try { 639 final boolean isHwAccelerated = (attrs.flags & 640 WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0; 641 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format; 642 if (!PixelFormat.formatHasAlpha(attrs.format)) { 643 flags |= Surface.OPAQUE; 644 } 645 if (DEBUG_SURFACE_TRACE) { 646 mSurface = new SurfaceTrace( 647 mSession.mSurfaceSession, mSession.mPid, 648 attrs.getTitle().toString(), 649 0, w, h, format, flags); 650 } else { 651 mSurface = new Surface( 652 mSession.mSurfaceSession, mSession.mPid, 653 attrs.getTitle().toString(), 654 0, w, h, format, flags); 655 } 656 mWin.mHasSurface = true; 657 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG, 658 " CREATE SURFACE " 659 + mSurface + " IN SESSION " 660 + mSession.mSurfaceSession 661 + ": pid=" + mSession.mPid + " format=" 662 + attrs.format + " flags=0x" 663 + Integer.toHexString(flags) 664 + " / " + this); 665 } catch (Surface.OutOfResourcesException e) { 666 mWin.mHasSurface = false; 667 Slog.w(TAG, "OutOfResourcesException creating surface"); 668 mService.reclaimSomeSurfaceMemoryLocked(this, "create", true); 669 mDrawState = NO_SURFACE; 670 return null; 671 } catch (Exception e) { 672 mWin.mHasSurface = false; 673 Slog.e(TAG, "Exception creating surface", e); 674 mDrawState = NO_SURFACE; 675 return null; 676 } 677 678 if (WindowManagerService.localLOGV) Slog.v( 679 TAG, "Got surface: " + mSurface 680 + ", set left=" + mWin.mFrame.left + " top=" + mWin.mFrame.top 681 + ", animLayer=" + mAnimLayer); 682 if (SHOW_LIGHT_TRANSACTIONS) { 683 Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked"); 684 WindowManagerService.logSurface(mWin, "CREATE pos=(" 685 + mWin.mFrame.left + "," + mWin.mFrame.top + ") (" 686 + mWin.mCompatFrame.width() + "x" + mWin.mCompatFrame.height() 687 + "), layer=" + mAnimLayer + " HIDE", null); 688 } 689 Surface.openTransaction(); 690 try { 691 try { 692 mSurfaceX = mWin.mFrame.left + mWin.mXOffset; 693 mSurfaceY = mWin.mFrame.top + mWin.mYOffset; 694 mSurface.setPosition(mSurfaceX, mSurfaceY); 695 mSurfaceLayer = mAnimLayer; 696 mSurface.setLayer(mAnimLayer); 697 mSurface.setAlpha(0); 698 mSurfaceShown = false; 699 mSurface.hide(); 700 } catch (RuntimeException e) { 701 Slog.w(TAG, "Error creating surface in " + w, e); 702 mService.reclaimSomeSurfaceMemoryLocked(this, "create-init", true); 703 } 704 mLastHidden = true; 705 } finally { 706 Surface.closeTransaction(); 707 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, 708 "<<< CLOSE TRANSACTION createSurfaceLocked"); 709 } 710 if (WindowManagerService.localLOGV) Slog.v( 711 TAG, "Created surface " + this); 712 } 713 return mSurface; 714 } 715 716 void destroySurfaceLocked() { 717 if (mWin.mAppToken != null && mWin == mWin.mAppToken.startingWindow) { 718 mWin.mAppToken.startingDisplayed = false; 719 } 720 721 if (mSurface != null) { 722 723 int i = mWin.mChildWindows.size(); 724 while (i > 0) { 725 i--; 726 WindowState c = mWin.mChildWindows.get(i); 727 c.mAttachedHidden = true; 728 } 729 730 try { 731 if (DEBUG_VISIBILITY) { 732 RuntimeException e = null; 733 if (!WindowManagerService.HIDE_STACK_CRAWLS) { 734 e = new RuntimeException(); 735 e.fillInStackTrace(); 736 } 737 Slog.w(TAG, "Window " + this + " destroying surface " 738 + mSurface + ", session " + mSession, e); 739 } 740 if (mSurfaceDestroyDeferred) { 741 if (mSurface != null && mPendingDestroySurface != mSurface) { 742 if (mPendingDestroySurface != null) { 743 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) { 744 RuntimeException e = null; 745 if (!WindowManagerService.HIDE_STACK_CRAWLS) { 746 e = new RuntimeException(); 747 e.fillInStackTrace(); 748 } 749 WindowManagerService.logSurface(mWin, "DESTROY PENDING", e); 750 } 751 mPendingDestroySurface.destroy(); 752 } 753 mPendingDestroySurface = mSurface; 754 } 755 } else { 756 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) { 757 RuntimeException e = null; 758 if (!WindowManagerService.HIDE_STACK_CRAWLS) { 759 e = new RuntimeException(); 760 e.fillInStackTrace(); 761 } 762 WindowManagerService.logSurface(mWin, "DESTROY", e); 763 } 764 mSurface.destroy(); 765 } 766 mAnimator.hideWallpapersLocked(mWin); 767 } catch (RuntimeException e) { 768 Slog.w(TAG, "Exception thrown when destroying Window " + this 769 + " surface " + mSurface + " session " + mSession 770 + ": " + e.toString()); 771 } 772 773 mSurfaceShown = false; 774 mSurface = null; 775 mWin.mHasSurface =false; 776 mDrawState = NO_SURFACE; 777 } 778 } 779 780 void destroyDeferredSurfaceLocked() { 781 try { 782 if (mPendingDestroySurface != null) { 783 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) { 784 RuntimeException e = null; 785 if (!WindowManagerService.HIDE_STACK_CRAWLS) { 786 e = new RuntimeException(); 787 e.fillInStackTrace(); 788 } 789 WindowManagerService.logSurface(mWin, "DESTROY PENDING", e); 790 } 791 mPendingDestroySurface.destroy(); 792 mAnimator.hideWallpapersLocked(mWin); 793 } 794 } catch (RuntimeException e) { 795 Slog.w(TAG, "Exception thrown when destroying Window " 796 + this + " surface " + mPendingDestroySurface 797 + " session " + mSession + ": " + e.toString()); 798 } 799 mSurfaceDestroyDeferred = false; 800 mPendingDestroySurface = null; 801 } 802 803 void computeShownFrameLocked() { 804 final boolean selfTransformation = mHasLocalTransformation; 805 Transformation attachedTransformation = 806 (mAttachedWinAnimator != null && mAttachedWinAnimator.mHasLocalTransformation) 807 ? mAttachedWinAnimator.mTransformation : null; 808 Transformation appTransformation = (mAppAnimator != null && mAppAnimator.hasTransformation) 809 ? mAppAnimator.transformation : null; 810 811 // Wallpapers are animated based on the "real" window they 812 // are currently targeting. 813 if (mIsWallpaper && mAnimator.mLowerWallpaperTarget == null 814 && mAnimator.mWallpaperTarget != null) { 815 final WindowStateAnimator wallpaperAnimator = mAnimator.mWallpaperTarget.mWinAnimator; 816 if (wallpaperAnimator.mHasLocalTransformation && 817 wallpaperAnimator.mAnimation != null && 818 !wallpaperAnimator.mAnimation.getDetachWallpaper()) { 819 attachedTransformation = wallpaperAnimator.mTransformation; 820 if (WindowManagerService.DEBUG_WALLPAPER && attachedTransformation != null) { 821 Slog.v(TAG, "WP target attached xform: " + attachedTransformation); 822 } 823 } 824 final AppWindowAnimator wpAppAnimator = mAnimator.mWpAppAnimator; 825 if (wpAppAnimator != null && wpAppAnimator.hasTransformation 826 && wpAppAnimator.animation != null 827 && !wpAppAnimator.animation.getDetachWallpaper()) { 828 appTransformation = wpAppAnimator.transformation; 829 if (WindowManagerService.DEBUG_WALLPAPER && appTransformation != null) { 830 Slog.v(TAG, "WP target app xform: " + appTransformation); 831 } 832 } 833 } 834 835 final boolean screenAnimation = mService.mAnimator.mScreenRotationAnimation != null 836 && mService.mAnimator.mScreenRotationAnimation.isAnimating(); 837 if (selfTransformation || attachedTransformation != null 838 || appTransformation != null || screenAnimation) { 839 // cache often used attributes locally 840 final Rect frame = mWin.mFrame; 841 final float tmpFloats[] = mService.mTmpFloats; 842 final Matrix tmpMatrix = mWin.mTmpMatrix; 843 844 // Compute the desired transformation. 845 if (screenAnimation) { 846 // If we are doing a screen animation, the global rotation 847 // applied to windows can result in windows that are carefully 848 // aligned with each other to slightly separate, allowing you 849 // to see what is behind them. An unsightly mess. This... 850 // thing... magically makes it call good: scale each window 851 // slightly (two pixels larger in each dimension, from the 852 // window's center). 853 final float w = frame.width(); 854 final float h = frame.height(); 855 if (w>=1 && h>=1) { 856 tmpMatrix.setScale(1 + 2/w, 1 + 2/h, w/2, h/2); 857 } else { 858 tmpMatrix.reset(); 859 } 860 } else { 861 tmpMatrix.reset(); 862 } 863 tmpMatrix.postScale(mWin.mGlobalScale, mWin.mGlobalScale); 864 if (selfTransformation) { 865 tmpMatrix.postConcat(mTransformation.getMatrix()); 866 } 867 tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset); 868 if (attachedTransformation != null) { 869 tmpMatrix.postConcat(attachedTransformation.getMatrix()); 870 } 871 if (appTransformation != null) { 872 tmpMatrix.postConcat(appTransformation.getMatrix()); 873 } 874 if (mAnimator.mUniverseBackground != null) { 875 tmpMatrix.postConcat(mAnimator.mUniverseBackground.mUniverseTransform.getMatrix()); 876 } 877 if (screenAnimation) { 878 tmpMatrix.postConcat( 879 mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getMatrix()); 880 } 881 882 // "convert" it into SurfaceFlinger's format 883 // (a 2x2 matrix + an offset) 884 // Here we must not transform the position of the surface 885 // since it is already included in the transformation. 886 //Slog.i(TAG, "Transform: " + matrix); 887 888 mHaveMatrix = true; 889 tmpMatrix.getValues(tmpFloats); 890 mDsDx = tmpFloats[Matrix.MSCALE_X]; 891 mDtDx = tmpFloats[Matrix.MSKEW_Y]; 892 mDsDy = tmpFloats[Matrix.MSKEW_X]; 893 mDtDy = tmpFloats[Matrix.MSCALE_Y]; 894 float x = tmpFloats[Matrix.MTRANS_X]; 895 float y = tmpFloats[Matrix.MTRANS_Y]; 896 int w = frame.width(); 897 int h = frame.height(); 898 mWin.mShownFrame.set(x, y, x+w, y+h); 899 900 // Now set the alpha... but because our current hardware 901 // can't do alpha transformation on a non-opaque surface, 902 // turn it off if we are running an animation that is also 903 // transforming since it is more important to have that 904 // animation be smooth. 905 mShownAlpha = mAlpha; 906 if (!mService.mLimitedAlphaCompositing 907 || (!PixelFormat.formatHasAlpha(mWin.mAttrs.format) 908 || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy) 909 && x == frame.left && y == frame.top))) { 910 //Slog.i(TAG, "Applying alpha transform"); 911 if (selfTransformation) { 912 mShownAlpha *= mTransformation.getAlpha(); 913 } 914 if (attachedTransformation != null) { 915 mShownAlpha *= attachedTransformation.getAlpha(); 916 } 917 if (appTransformation != null) { 918 mShownAlpha *= appTransformation.getAlpha(); 919 } 920 if (mAnimator.mUniverseBackground != null) { 921 mShownAlpha *= mAnimator.mUniverseBackground.mUniverseTransform.getAlpha(); 922 } 923 if (screenAnimation) { 924 mShownAlpha *= 925 mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getAlpha(); 926 } 927 } else { 928 //Slog.i(TAG, "Not applying alpha transform"); 929 } 930 931 if ((DEBUG_SURFACE_TRACE || WindowManagerService.localLOGV) && (mShownAlpha == 1.0 || mShownAlpha == 0.0)) Slog.v( 932 TAG, "computeShownFrameLocked: Animating " + this + 933 " mAlpha=" + mAlpha + 934 " self=" + (selfTransformation ? mTransformation.getAlpha() : "null") + 935 " attached=" + (attachedTransformation == null ? "null" : attachedTransformation.getAlpha()) + 936 " app=" + (appTransformation == null ? "null" : appTransformation.getAlpha()) + 937 " screen=" + (screenAnimation ? mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getAlpha() 938 : "null")); 939 return; 940 } else if (mIsWallpaper && 941 (mAnimator.mPendingActions & WindowAnimator.WALLPAPER_ACTION_PENDING) != 0) { 942 return; 943 } 944 945 if (WindowManagerService.localLOGV) Slog.v( 946 TAG, "computeShownFrameLocked: " + this + 947 " not attached, mAlpha=" + mAlpha); 948 if (mAnimator.mUniverseBackground != null && 949 mWin.mAttrs.type != WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND 950 && mWin.mBaseLayer < mAnimator.mAboveUniverseLayer) { 951 final Rect frame = mWin.mFrame; 952 final float tmpFloats[] = mService.mTmpFloats; 953 final Matrix tmpMatrix = mWin.mTmpMatrix; 954 tmpMatrix.setScale(mWin.mGlobalScale, mWin.mGlobalScale); 955 tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset); 956 tmpMatrix.postConcat(mAnimator.mUniverseBackground.mUniverseTransform.getMatrix()); 957 tmpMatrix.getValues(tmpFloats); 958 mHaveMatrix = true; 959 mDsDx = tmpFloats[Matrix.MSCALE_X]; 960 mDtDx = tmpFloats[Matrix.MSKEW_Y]; 961 mDsDy = tmpFloats[Matrix.MSKEW_X]; 962 mDtDy = tmpFloats[Matrix.MSCALE_Y]; 963 float x = tmpFloats[Matrix.MTRANS_X]; 964 float y = tmpFloats[Matrix.MTRANS_Y]; 965 int w = frame.width(); 966 int h = frame.height(); 967 mWin.mShownFrame.set(x, y, x+w, y+h); 968 mShownAlpha = mAlpha * mAnimator.mUniverseBackground.mUniverseTransform.getAlpha(); 969 } else { 970 mWin.mShownFrame.set(mWin.mFrame); 971 if (mWin.mXOffset != 0 || mWin.mYOffset != 0) { 972 mWin.mShownFrame.offset(mWin.mXOffset, mWin.mYOffset); 973 } 974 mShownAlpha = mAlpha; 975 mHaveMatrix = false; 976 mDsDx = mWin.mGlobalScale; 977 mDtDx = 0; 978 mDsDy = 0; 979 mDtDy = mWin.mGlobalScale; 980 } 981 } 982 983 void applyDecorRect(final Rect decorRect) { 984 final WindowState w = mWin; 985 // Compute the offset of the window in relation to the decor rect. 986 final int offX = w.mXOffset + w.mFrame.left; 987 final int offY = w.mYOffset + w.mFrame.top; 988 // Initialize the decor rect to the entire frame. 989 w.mSystemDecorRect.set(0, 0, w.mFrame.width(), w.mFrame.height()); 990 // Intersect with the decor rect, offsetted by window position. 991 w.mSystemDecorRect.intersect(decorRect.left-offX, decorRect.top-offY, 992 decorRect.right-offX, decorRect.bottom-offY); 993 // If size compatibility is being applied to the window, the 994 // surface is scaled relative to the screen. Also apply this 995 // scaling to the crop rect. We aren't using the standard rect 996 // scale function because we want to round things to make the crop 997 // always round to a larger rect to ensure we don't crop too 998 // much and hide part of the window that should be seen. 999 if (w.mEnforceSizeCompat && w.mInvGlobalScale != 1.0f) { 1000 final float scale = w.mInvGlobalScale; 1001 w.mSystemDecorRect.left = (int) (w.mSystemDecorRect.left * scale - 0.5f); 1002 w.mSystemDecorRect.top = (int) (w.mSystemDecorRect.top * scale - 0.5f); 1003 w.mSystemDecorRect.right = (int) ((w.mSystemDecorRect.right+1) * scale - 0.5f); 1004 w.mSystemDecorRect.bottom = (int) ((w.mSystemDecorRect.bottom+1) * scale - 0.5f); 1005 } 1006 } 1007 1008 void updateSurfaceWindowCrop(final boolean recoveringMemory) { 1009 final WindowState w = mWin; 1010 1011 // Need to recompute a new system decor rect each time. 1012 if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) { 1013 // Currently can't do this cropping for scaled windows. We'll 1014 // just keep the crop rect the same as the source surface. 1015 w.mSystemDecorRect.set(0, 0, w.mRequestedWidth, w.mRequestedHeight); 1016 } else if (w.mLayer >= mService.mSystemDecorLayer) { 1017 // Above the decor layer is easy, just use the entire window. 1018 // Unless we have a universe background... in which case all the 1019 // windows need to be cropped by the screen, so they don't cover 1020 // the universe background. 1021 if (mAnimator.mUniverseBackground == null) { 1022 w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), 1023 w.mCompatFrame.height()); 1024 } else { 1025 applyDecorRect(mService.mScreenRect); 1026 } 1027 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND) { 1028 // The universe background isn't cropped. 1029 w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), 1030 w.mCompatFrame.height()); 1031 } else { 1032 applyDecorRect(mService.mSystemDecorRect); 1033 } 1034 1035 if (!w.mSystemDecorRect.equals(w.mLastSystemDecorRect)) { 1036 w.mLastSystemDecorRect.set(w.mSystemDecorRect); 1037 try { 1038 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w, 1039 "CROP " + w.mSystemDecorRect.toShortString(), null); 1040 mSurface.setWindowCrop(w.mSystemDecorRect); 1041 } catch (RuntimeException e) { 1042 Slog.w(TAG, "Error setting crop surface of " + w 1043 + " crop=" + w.mSystemDecorRect.toShortString(), e); 1044 if (!recoveringMemory) { 1045 mService.reclaimSomeSurfaceMemoryLocked(this, "crop", true); 1046 } 1047 } 1048 } 1049 } 1050 1051 void setSurfaceBoundaries(final boolean recoveringMemory) { 1052 final WindowState w = mWin; 1053 int width, height; 1054 if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) { 1055 // for a scaled surface, we just want to use 1056 // the requested size. 1057 width = w.mRequestedWidth; 1058 height = w.mRequestedHeight; 1059 } else { 1060 width = w.mCompatFrame.width(); 1061 height = w.mCompatFrame.height(); 1062 } 1063 1064 if (width < 1) { 1065 width = 1; 1066 } 1067 if (height < 1) { 1068 height = 1; 1069 } 1070 final boolean surfaceResized = mSurfaceW != width || mSurfaceH != height; 1071 if (surfaceResized) { 1072 mSurfaceW = width; 1073 mSurfaceH = height; 1074 } 1075 1076 final float left = w.mShownFrame.left; 1077 final float top = w.mShownFrame.top; 1078 if (mSurfaceX != left || mSurfaceY != top) { 1079 try { 1080 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w, 1081 "POS " + left + ", " + top, null); 1082 mSurfaceX = left; 1083 mSurfaceY = top; 1084 mSurface.setPosition(left, top); 1085 } catch (RuntimeException e) { 1086 Slog.w(TAG, "Error positioning surface of " + w 1087 + " pos=(" + left 1088 + "," + top + ")", e); 1089 if (!recoveringMemory) { 1090 mService.reclaimSomeSurfaceMemoryLocked(this, "position", true); 1091 } 1092 } 1093 } 1094 1095 if (surfaceResized) { 1096 try { 1097 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w, 1098 "SIZE " + width + "x" + height, null); 1099 mSurfaceResized = true; 1100 mSurface.setSize(width, height); 1101 mAnimator.mPendingLayoutChanges |= 1102 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; 1103 if ((w.mAttrs.flags & LayoutParams.FLAG_DIM_BEHIND) != 0) { 1104 mService.startDimming(this, w.mExiting ? 0 : w.mAttrs.dimAmount, 1105 mService.mDisplayInfo.appWidth, mService.mDisplayInfo.appHeight); 1106 } 1107 } catch (RuntimeException e) { 1108 // If something goes wrong with the surface (such 1109 // as running out of memory), don't take down the 1110 // entire system. 1111 Slog.e(TAG, "Error resizing surface of " + w 1112 + " size=(" + width + "x" + height + ")", e); 1113 if (!recoveringMemory) { 1114 mService.reclaimSomeSurfaceMemoryLocked(this, "size", true); 1115 } 1116 } 1117 } 1118 1119 updateSurfaceWindowCrop(recoveringMemory); 1120 } 1121 1122 public void prepareSurfaceLocked(final boolean recoveringMemory) { 1123 final WindowState w = mWin; 1124 if (mSurface == null) { 1125 if (w.mOrientationChanging) { 1126 if (DEBUG_ORIENTATION) { 1127 Slog.v(TAG, "Orientation change skips hidden " + w); 1128 } 1129 w.mOrientationChanging = false; 1130 } 1131 return; 1132 } 1133 1134 boolean displayed = false; 1135 1136 computeShownFrameLocked(); 1137 1138 setSurfaceBoundaries(recoveringMemory); 1139 1140 if (mIsWallpaper && !mWin.mWallpaperVisible) { 1141 // Wallpaper is no longer visible and there is no wp target => hide it. 1142 hide(); 1143 } else if (w.mAttachedHidden || !w.isReadyForDisplay()) { 1144 hide(); 1145 mAnimator.hideWallpapersLocked(w); 1146 1147 // If we are waiting for this window to handle an 1148 // orientation change, well, it is hidden, so 1149 // doesn't really matter. Note that this does 1150 // introduce a potential glitch if the window 1151 // becomes unhidden before it has drawn for the 1152 // new orientation. 1153 if (w.mOrientationChanging) { 1154 w.mOrientationChanging = false; 1155 if (DEBUG_ORIENTATION) Slog.v(TAG, 1156 "Orientation change skips hidden " + w); 1157 } 1158 } else if (mLastLayer != mAnimLayer 1159 || mLastAlpha != mShownAlpha 1160 || mLastDsDx != mDsDx 1161 || mLastDtDx != mDtDx 1162 || mLastDsDy != mDsDy 1163 || mLastDtDy != mDtDy 1164 || w.mLastHScale != w.mHScale 1165 || w.mLastVScale != w.mVScale 1166 || mLastHidden) { 1167 displayed = true; 1168 mLastAlpha = mShownAlpha; 1169 mLastLayer = mAnimLayer; 1170 mLastDsDx = mDsDx; 1171 mLastDtDx = mDtDx; 1172 mLastDsDy = mDsDy; 1173 mLastDtDy = mDtDy; 1174 w.mLastHScale = w.mHScale; 1175 w.mLastVScale = w.mVScale; 1176 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w, 1177 "alpha=" + mShownAlpha + " layer=" + mAnimLayer 1178 + " matrix=[" + (mDsDx*w.mHScale) 1179 + "," + (mDtDx*w.mVScale) 1180 + "][" + (mDsDy*w.mHScale) 1181 + "," + (mDtDy*w.mVScale) + "]", null); 1182 if (mSurface != null) { 1183 try { 1184 mSurfaceAlpha = mShownAlpha; 1185 mSurface.setAlpha(mShownAlpha); 1186 mSurfaceLayer = mAnimLayer; 1187 mSurface.setLayer(mAnimLayer); 1188 mSurface.setMatrix( 1189 mDsDx*w.mHScale, mDtDx*w.mVScale, 1190 mDsDy*w.mHScale, mDtDy*w.mVScale); 1191 1192 if (mLastHidden && mDrawState == HAS_DRAWN) { 1193 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w, 1194 "SHOW (performLayout)", null); 1195 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w 1196 + " during relayout"); 1197 if (showSurfaceRobustlyLocked()) { 1198 mLastHidden = false; 1199 if (mIsWallpaper) { 1200 mService.dispatchWallpaperVisibility(w, true); 1201 } 1202 } else { 1203 w.mOrientationChanging = false; 1204 } 1205 } 1206 if (mSurface != null) { 1207 w.mToken.hasVisible = true; 1208 } 1209 } catch (RuntimeException e) { 1210 Slog.w(TAG, "Error updating surface in " + w, e); 1211 if (!recoveringMemory) { 1212 mService.reclaimSomeSurfaceMemoryLocked(this, "update", true); 1213 } 1214 } 1215 } 1216 } else { 1217 if (DEBUG_ANIM && isAnimating()) { 1218 Slog.v(TAG, "prepareSurface: No changes in animation for " + this); 1219 } 1220 displayed = true; 1221 } 1222 1223 if (displayed) { 1224 if (w.mOrientationChanging) { 1225 if (!w.isDrawnLw()) { 1226 mAnimator.mBulkUpdateParams &= ~SET_ORIENTATION_CHANGE_COMPLETE; 1227 if (DEBUG_ORIENTATION) Slog.v(TAG, 1228 "Orientation continue waiting for draw in " + w); 1229 } else { 1230 w.mOrientationChanging = false; 1231 if (DEBUG_ORIENTATION) Slog.v(TAG, "Orientation change complete in " + w); 1232 } 1233 } 1234 w.mToken.hasVisible = true; 1235 } 1236 } 1237 1238 void setTransparentRegionHint(final Region region) { 1239 if (mSurface == null) { 1240 Slog.w(TAG, "setTransparentRegionHint: null mSurface after mHasSurface true"); 1241 return; 1242 } 1243 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, 1244 ">>> OPEN TRANSACTION setTransparentRegion"); 1245 Surface.openTransaction(); 1246 try { 1247 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, 1248 "transparentRegionHint=" + region, null); 1249 mSurface.setTransparentRegionHint(region); 1250 } finally { 1251 Surface.closeTransaction(); 1252 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, 1253 "<<< CLOSE TRANSACTION setTransparentRegion"); 1254 } 1255 } 1256 1257 void setWallpaperOffset(int left, int top) { 1258 mSurfaceX = left; 1259 mSurfaceY = top; 1260 if (mAnimating) { 1261 // If this window (or its app token) is animating, then the position 1262 // of the surface will be re-computed on the next animation frame. 1263 // We can't poke it directly here because it depends on whatever 1264 // transformation is being applied by the animation. 1265 return; 1266 } 1267 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, 1268 ">>> OPEN TRANSACTION setWallpaperOffset"); 1269 Surface.openTransaction(); 1270 try { 1271 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, 1272 "POS " + left + ", " + top, null); 1273 mSurface.setPosition(mWin.mFrame.left + left, mWin.mFrame.top + top); 1274 updateSurfaceWindowCrop(false); 1275 } catch (RuntimeException e) { 1276 Slog.w(TAG, "Error positioning surface of " + mWin 1277 + " pos=(" + left + "," + top + ")", e); 1278 } finally { 1279 Surface.closeTransaction(); 1280 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, 1281 "<<< CLOSE TRANSACTION setWallpaperOffset"); 1282 } 1283 } 1284 1285 // This must be called while inside a transaction. 1286 boolean performShowLocked() { 1287 if (DEBUG_VISIBILITY || (DEBUG_STARTING_WINDOW && 1288 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING)) { 1289 RuntimeException e = null; 1290 if (!WindowManagerService.HIDE_STACK_CRAWLS) { 1291 e = new RuntimeException(); 1292 e.fillInStackTrace(); 1293 } 1294 Slog.v(TAG, "performShow on " + this 1295 + ": mDrawState=" + mDrawState + " readyForDisplay=" 1296 + mWin.isReadyForDisplayIgnoringKeyguard() 1297 + " starting=" + (mWin.mAttrs.type == TYPE_APPLICATION_STARTING) 1298 + " during animation: policyVis=" + mWin.mPolicyVisibility 1299 + " attHidden=" + mWin.mAttachedHidden 1300 + " tok.hiddenRequested=" 1301 + (mWin.mAppToken != null ? mWin.mAppToken.hiddenRequested : false) 1302 + " tok.hidden=" 1303 + (mWin.mAppToken != null ? mWin.mAppToken.hidden : false) 1304 + " animating=" + mAnimating 1305 + " tok animating=" 1306 + (mAppAnimator != null ? mAppAnimator.animating : false), e); 1307 } 1308 if (mDrawState == READY_TO_SHOW && mWin.isReadyForDisplayIgnoringKeyguard()) { 1309 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) 1310 WindowManagerService.logSurface(mWin, "SHOW (performShowLocked)", null); 1311 if (DEBUG_VISIBILITY || (DEBUG_STARTING_WINDOW && 1312 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING)) { 1313 Slog.v(TAG, "Showing " + this 1314 + " during animation: policyVis=" + mWin.mPolicyVisibility 1315 + " attHidden=" + mWin.mAttachedHidden 1316 + " tok.hiddenRequested=" 1317 + (mWin.mAppToken != null ? mWin.mAppToken.hiddenRequested : false) 1318 + " tok.hidden=" 1319 + (mWin.mAppToken != null ? mWin.mAppToken.hidden : false) 1320 + " animating=" + mAnimating 1321 + " tok animating=" 1322 + (mAppAnimator != null ? mAppAnimator.animating : false)); 1323 } 1324 1325 mService.enableScreenIfNeededLocked(); 1326 1327 applyEnterAnimationLocked(); 1328 1329 // Force the show in the next prepareSurfaceLocked() call. 1330 mLastAlpha = -1; 1331 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM) 1332 Slog.v(TAG, "performShowLocked: mDrawState=HAS_DRAWN in " + this); 1333 mDrawState = HAS_DRAWN; 1334 mService.updateLayoutToAnimationLocked(); 1335 1336 int i = mWin.mChildWindows.size(); 1337 while (i > 0) { 1338 i--; 1339 WindowState c = mWin.mChildWindows.get(i); 1340 if (c.mAttachedHidden) { 1341 c.mAttachedHidden = false; 1342 if (c.mWinAnimator.mSurface != null) { 1343 c.mWinAnimator.performShowLocked(); 1344 // It hadn't been shown, which means layout not 1345 // performed on it, so now we want to make sure to 1346 // do a layout. If called from within the transaction 1347 // loop, this will cause it to restart with a new 1348 // layout. 1349 mService.mLayoutNeeded = true; 1350 } 1351 } 1352 } 1353 1354 if (mWin.mAttrs.type != TYPE_APPLICATION_STARTING 1355 && mWin.mAppToken != null) { 1356 mWin.mAppToken.firstWindowDrawn = true; 1357 1358 if (mWin.mAppToken.startingData != null) { 1359 if (WindowManagerService.DEBUG_STARTING_WINDOW || 1360 WindowManagerService.DEBUG_ANIM) Slog.v(TAG, 1361 "Finish starting " + mWin.mToken 1362 + ": first real window is shown, no animation"); 1363 // If this initial window is animating, stop it -- we 1364 // will do an animation to reveal it from behind the 1365 // starting window, so there is no need for it to also 1366 // be doing its own stuff. 1367 clearAnimation(); 1368 mService.mFinishedStarting.add(mWin.mAppToken); 1369 mService.mH.sendEmptyMessage(H.FINISHED_STARTING); 1370 } 1371 mWin.mAppToken.updateReportedVisibilityLocked(); 1372 } 1373 1374 return true; 1375 } 1376 1377 return false; 1378 } 1379 1380 /** 1381 * Have the surface flinger show a surface, robustly dealing with 1382 * error conditions. In particular, if there is not enough memory 1383 * to show the surface, then we will try to get rid of other surfaces 1384 * in order to succeed. 1385 * 1386 * @return Returns true if the surface was successfully shown. 1387 */ 1388 boolean showSurfaceRobustlyLocked() { 1389 try { 1390 if (mSurface != null) { 1391 mSurfaceShown = true; 1392 mSurface.show(); 1393 if (mWin.mTurnOnScreen) { 1394 if (DEBUG_VISIBILITY) Slog.v(TAG, 1395 "Show surface turning screen on: " + mWin); 1396 mWin.mTurnOnScreen = false; 1397 mAnimator.mBulkUpdateParams |= SET_TURN_ON_SCREEN; 1398 } 1399 } 1400 return true; 1401 } catch (RuntimeException e) { 1402 Slog.w(TAG, "Failure showing surface " + mSurface + " in " + mWin, e); 1403 } 1404 1405 mService.reclaimSomeSurfaceMemoryLocked(this, "show", true); 1406 1407 return false; 1408 } 1409 1410 void applyEnterAnimationLocked() { 1411 final int transit; 1412 if (mEnterAnimationPending) { 1413 mEnterAnimationPending = false; 1414 transit = WindowManagerPolicy.TRANSIT_ENTER; 1415 } else { 1416 transit = WindowManagerPolicy.TRANSIT_SHOW; 1417 } 1418 1419 applyAnimationLocked(transit, true); 1420 } 1421 1422 // TODO(cmautner): Move back to WindowState? 1423 /** 1424 * Choose the correct animation and set it to the passed WindowState. 1425 * @param transit If WindowManagerPolicy.TRANSIT_PREVIEW_DONE and the app window has been drawn 1426 * then the animation will be app_starting_exit. Any other value loads the animation from 1427 * the switch statement below. 1428 * @param isEntrance The animation type the last time this was called. Used to keep from 1429 * loading the same animation twice. 1430 * @return true if an animation has been loaded. 1431 */ 1432 boolean applyAnimationLocked(int transit, boolean isEntrance) { 1433 if (mLocalAnimating && mAnimationIsEntrance == isEntrance) { 1434 // If we are trying to apply an animation, but already running 1435 // an animation of the same type, then just leave that one alone. 1436 return true; 1437 } 1438 1439 // Only apply an animation if the display isn't frozen. If it is 1440 // frozen, there is no reason to animate and it can cause strange 1441 // artifacts when we unfreeze the display if some different animation 1442 // is running. 1443 if (mService.okToDisplay()) { 1444 int anim = mPolicy.selectAnimationLw(mWin, transit); 1445 int attr = -1; 1446 Animation a = null; 1447 if (anim != 0) { 1448 a = AnimationUtils.loadAnimation(mContext, anim); 1449 } else { 1450 switch (transit) { 1451 case WindowManagerPolicy.TRANSIT_ENTER: 1452 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation; 1453 break; 1454 case WindowManagerPolicy.TRANSIT_EXIT: 1455 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation; 1456 break; 1457 case WindowManagerPolicy.TRANSIT_SHOW: 1458 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation; 1459 break; 1460 case WindowManagerPolicy.TRANSIT_HIDE: 1461 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation; 1462 break; 1463 } 1464 if (attr >= 0) { 1465 a = mService.loadAnimation(mWin.mAttrs, attr); 1466 } 1467 } 1468 if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG, 1469 "applyAnimation: win=" + this 1470 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr) 1471 + " a=" + a 1472 + " mAnimation=" + mAnimation 1473 + " isEntrance=" + isEntrance + " Callers " + Debug.getCallers(3)); 1474 if (a != null) { 1475 if (WindowManagerService.DEBUG_ANIM) { 1476 RuntimeException e = null; 1477 if (!WindowManagerService.HIDE_STACK_CRAWLS) { 1478 e = new RuntimeException(); 1479 e.fillInStackTrace(); 1480 } 1481 Slog.v(TAG, "Loaded animation " + a + " for " + this, e); 1482 } 1483 setAnimation(a); 1484 mAnimationIsEntrance = isEntrance; 1485 } 1486 } else { 1487 clearAnimation(); 1488 } 1489 1490 return mAnimation != null; 1491 } 1492 1493 public void dump(PrintWriter pw, String prefix, boolean dumpAll) { 1494 if (mAnimating || mLocalAnimating || mAnimationIsEntrance 1495 || mAnimation != null) { 1496 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating); 1497 pw.print(" mLocalAnimating="); pw.print(mLocalAnimating); 1498 pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance); 1499 pw.print(" mAnimation="); pw.println(mAnimation); 1500 } 1501 if (mHasTransformation || mHasLocalTransformation) { 1502 pw.print(prefix); pw.print("XForm: has="); 1503 pw.print(mHasTransformation); 1504 pw.print(" hasLocal="); pw.print(mHasLocalTransformation); 1505 pw.print(" "); mTransformation.printShortString(pw); 1506 pw.println(); 1507 } 1508 if (mSurface != null) { 1509 if (dumpAll) { 1510 pw.print(prefix); pw.print("mSurface="); pw.println(mSurface); 1511 pw.print(prefix); pw.print("mDrawState="); 1512 pw.print(drawStateToString(mDrawState)); 1513 pw.print(" mLastHidden="); pw.println(mLastHidden); 1514 } 1515 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown); 1516 pw.print(" layer="); pw.print(mSurfaceLayer); 1517 pw.print(" alpha="); pw.print(mSurfaceAlpha); 1518 pw.print(" rect=("); pw.print(mSurfaceX); 1519 pw.print(","); pw.print(mSurfaceY); 1520 pw.print(") "); pw.print(mSurfaceW); 1521 pw.print(" x "); pw.println(mSurfaceH); 1522 } 1523 if (mPendingDestroySurface != null) { 1524 pw.print(prefix); pw.print("mPendingDestroySurface="); 1525 pw.println(mPendingDestroySurface); 1526 } 1527 if (mSurfaceResized || mSurfaceDestroyDeferred) { 1528 pw.print(prefix); pw.print("mSurfaceResized="); pw.print(mSurfaceResized); 1529 pw.print(" mSurfaceDestroyDeferred="); pw.println(mSurfaceDestroyDeferred); 1530 } 1531 if (mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND) { 1532 pw.print(prefix); pw.print("mUniverseTransform="); 1533 mUniverseTransform.printShortString(pw); 1534 pw.println(); 1535 } 1536 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) { 1537 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha); 1538 pw.print(" mAlpha="); pw.print(mAlpha); 1539 pw.print(" mLastAlpha="); pw.println(mLastAlpha); 1540 } 1541 if (mHaveMatrix || mWin.mGlobalScale != 1) { 1542 pw.print(prefix); pw.print("mGlobalScale="); pw.print(mWin.mGlobalScale); 1543 pw.print(" mDsDx="); pw.print(mDsDx); 1544 pw.print(" mDtDx="); pw.print(mDtDx); 1545 pw.print(" mDsDy="); pw.print(mDsDy); 1546 pw.print(" mDtDy="); pw.println(mDtDy); 1547 } 1548 } 1549 1550 @Override 1551 public String toString() { 1552 StringBuffer sb = new StringBuffer("WindowStateAnimator ("); 1553 sb.append(mWin.mLastTitle + "): "); 1554 sb.append("mSurface " + mSurface); 1555 sb.append(", mAnimation " + mAnimation); 1556 return sb.toString(); 1557 } 1558} 1559