WindowStateAnimator.java revision 3cc321ecf505d87850740ad3c63849e6793a8ef6
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 WindowState mAttachedWindow; 54 final WindowAnimator mAnimator; 55 final Session mSession; 56 final WindowManagerPolicy mPolicy; 57 final Context mContext; 58 final boolean mIsWallpaper; 59 60 // If this is a universe background window, this is the transformation 61 // it is applying to the rest of the universe. 62 final Transformation mUniverseTransform = new Transformation(); 63 64 // Currently running animation. 65 boolean mAnimating; 66 boolean mLocalAnimating; 67 Animation mAnimation; 68 boolean mAnimationIsEntrance; 69 boolean mHasTransformation; 70 boolean mHasLocalTransformation; 71 final Transformation mTransformation = new Transformation(); 72 boolean mWasAnimating; // Were we animating going into the most recent animation step? 73 int mAnimLayer; 74 int mLastLayer; 75 76 Surface mSurface; 77 Surface mPendingDestroySurface; 78 79 /** 80 * Set when we have changed the size of the surface, to know that 81 * we must tell them application to resize (and thus redraw itself). 82 */ 83 boolean mSurfaceResized; 84 85 /** 86 * Set if the client has asked that the destroy of its surface be delayed 87 * until it explicitly says it is okay. 88 */ 89 boolean mSurfaceDestroyDeferred; 90 91 float mShownAlpha = 0; 92 float mAlpha = 0; 93 float mLastAlpha = 0; 94 95 // Used to save animation distances between the time they are calculated and when they are 96 // used. 97 int mAnimDw; 98 int mAnimDh; 99 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1; 100 float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1; 101 102 boolean mHaveMatrix; 103 104 // For debugging, this is the last information given to the surface flinger. 105 boolean mSurfaceShown; 106 float mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH; 107 int mSurfaceLayer; 108 float mSurfaceAlpha; 109 110 // Set to true if, when the window gets displayed, it should perform 111 // an enter animation. 112 boolean mEnterAnimationPending; 113 114 /** This is set when there is no Surface */ 115 static final int NO_SURFACE = 0; 116 /** This is set after the Surface has been created but before the window has been drawn. During 117 * this time the surface is hidden. */ 118 static final int DRAW_PENDING = 1; 119 /** This is set after the window has finished drawing for the first time but before its surface 120 * is shown. The surface will be displayed when the next layout is run. */ 121 static final int COMMIT_DRAW_PENDING = 2; 122 /** This is set during the time after the window's drawing has been committed, and before its 123 * surface is actually shown. It is used to delay showing the surface until all windows in a 124 * token are ready to be shown. */ 125 static final int READY_TO_SHOW = 3; 126 /** Set when the window has been shown in the screen the first time. */ 127 static final int HAS_DRAWN = 4; 128 static String drawStateToString(int state) { 129 switch (state) { 130 case NO_SURFACE: return "NO_SURFACE"; 131 case DRAW_PENDING: return "DRAW_PENDING"; 132 case COMMIT_DRAW_PENDING: return "COMMIT_DRAW_PENDING"; 133 case READY_TO_SHOW: return "READY_TO_SHOW"; 134 case HAS_DRAWN: return "HAS_DRAWN"; 135 default: return Integer.toString(state); 136 } 137 } 138 int mDrawState; 139 140 /** Was this window last hidden? */ 141 boolean mLastHidden; 142 143 int mAttrFlags; 144 int mAttrType; 145 146 public WindowStateAnimator(final WindowState win) { 147 final WindowManagerService service = win.mService; 148 149 mService = service; 150 mAnimator = service.mAnimator; 151 mPolicy = service.mPolicy; 152 mContext = service.mContext; 153 mAnimDw = service.mAppDisplayWidth; 154 mAnimDh = service.mAppDisplayHeight; 155 156 mWin = win; 157 mAttachedWindow = win.mAttachedWindow; 158 mSession = win.mSession; 159 mAttrFlags = win.mAttrs.flags; 160 mAttrType = win.mAttrs.type; 161 mIsWallpaper = win.mIsWallpaper; 162 } 163 164 public void setAnimation(Animation anim) { 165 if (localLOGV) Slog.v(TAG, "Setting animation in " + this + ": " + anim); 166 mAnimating = false; 167 mLocalAnimating = false; 168 mAnimation = anim; 169 mAnimation.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION); 170 mAnimation.scaleCurrentDuration(mService.mWindowAnimationScale); 171 // Start out animation gone if window is gone, or visible if window is visible. 172 mTransformation.clear(); 173 mTransformation.setAlpha(mLastHidden ? 0 : 1); 174 mHasLocalTransformation = true; 175 } 176 177 public void clearAnimation() { 178 if (mAnimation != null) { 179 mAnimating = true; 180 mLocalAnimating = false; 181 mAnimation.cancel(); 182 mAnimation = null; 183 } 184 } 185 186 /** Is the window or its container currently animating? */ 187 boolean isAnimating() { 188 final WindowState attached = mAttachedWindow; 189 final AppWindowToken atoken = mWin.mAppToken; 190 return mAnimation != null 191 || (attached != null && attached.mWinAnimator.mAnimation != null) 192 || (atoken != null && 193 (atoken.mAppAnimator.animation != null 194 || atoken.inPendingTransaction)); 195 } 196 197 /** Is the window animating the DummyAnimation? */ 198 boolean isDummyAnimation() { 199 final AppWindowToken atoken = mWin.mAppToken; 200 return atoken != null 201 && atoken.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.mAppDisplayWidth; 252 mAnimDh = mService.mAppDisplayHeight; 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) && mWin.mAppToken != null 269 && mWin.mAppToken.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 (mAttachedWindow != null && mAttachedWindow.mWinAnimator.mHasLocalTransformation) 807 ? mAttachedWindow.mWinAnimator.mTransformation : null; 808 final AppWindowAnimator appAnimator = 809 mWin.mAppToken == null ? null : mWin.mAppToken.mAppAnimator; 810 Transformation appTransformation = (appAnimator != null && appAnimator.hasTransformation) 811 ? appAnimator.transformation : null; 812 813 // Wallpapers are animated based on the "real" window they 814 // are currently targeting. 815 if (mIsWallpaper && mAnimator.mLowerWallpaperTarget == null 816 && mAnimator.mWallpaperTarget != null) { 817 final WindowStateAnimator wallpaperAnimator = mAnimator.mWallpaperTarget.mWinAnimator; 818 if (wallpaperAnimator.mHasLocalTransformation && 819 wallpaperAnimator.mAnimation != null && 820 !wallpaperAnimator.mAnimation.getDetachWallpaper()) { 821 attachedTransformation = wallpaperAnimator.mTransformation; 822 if (WindowManagerService.DEBUG_WALLPAPER && attachedTransformation != null) { 823 Slog.v(TAG, "WP target attached xform: " + attachedTransformation); 824 } 825 } 826 final AppWindowAnimator wpAppAnimator = mAnimator.mWpAppAnimator; 827 if (wpAppAnimator != null && wpAppAnimator.hasTransformation 828 && wpAppAnimator.animation != null 829 && !wpAppAnimator.animation.getDetachWallpaper()) { 830 appTransformation = wpAppAnimator.transformation; 831 if (WindowManagerService.DEBUG_WALLPAPER && appTransformation != null) { 832 Slog.v(TAG, "WP target app xform: " + appTransformation); 833 } 834 } 835 } 836 837 final boolean screenAnimation = mService.mAnimator.mScreenRotationAnimation != null 838 && mService.mAnimator.mScreenRotationAnimation.isAnimating(); 839 if (selfTransformation || attachedTransformation != null 840 || appTransformation != null || screenAnimation) { 841 // cache often used attributes locally 842 final Rect frame = mWin.mFrame; 843 final float tmpFloats[] = mService.mTmpFloats; 844 final Matrix tmpMatrix = mWin.mTmpMatrix; 845 846 // Compute the desired transformation. 847 if (screenAnimation) { 848 // If we are doing a screen animation, the global rotation 849 // applied to windows can result in windows that are carefully 850 // aligned with each other to slightly separate, allowing you 851 // to see what is behind them. An unsightly mess. This... 852 // thing... magically makes it call good: scale each window 853 // slightly (two pixels larger in each dimension, from the 854 // window's center). 855 final float w = frame.width(); 856 final float h = frame.height(); 857 if (w>=1 && h>=1) { 858 tmpMatrix.setScale(1 + 2/w, 1 + 2/h, w/2, h/2); 859 } else { 860 tmpMatrix.reset(); 861 } 862 } else { 863 tmpMatrix.reset(); 864 } 865 tmpMatrix.postScale(mWin.mGlobalScale, mWin.mGlobalScale); 866 if (selfTransformation) { 867 tmpMatrix.postConcat(mTransformation.getMatrix()); 868 } 869 tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset); 870 if (attachedTransformation != null) { 871 tmpMatrix.postConcat(attachedTransformation.getMatrix()); 872 } 873 if (appTransformation != null) { 874 tmpMatrix.postConcat(appTransformation.getMatrix()); 875 } 876 if (mAnimator.mUniverseBackground != null) { 877 tmpMatrix.postConcat(mAnimator.mUniverseBackground.mUniverseTransform.getMatrix()); 878 } 879 if (screenAnimation) { 880 tmpMatrix.postConcat( 881 mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getMatrix()); 882 } 883 884 // "convert" it into SurfaceFlinger's format 885 // (a 2x2 matrix + an offset) 886 // Here we must not transform the position of the surface 887 // since it is already included in the transformation. 888 //Slog.i(TAG, "Transform: " + matrix); 889 890 mHaveMatrix = true; 891 tmpMatrix.getValues(tmpFloats); 892 mDsDx = tmpFloats[Matrix.MSCALE_X]; 893 mDtDx = tmpFloats[Matrix.MSKEW_Y]; 894 mDsDy = tmpFloats[Matrix.MSKEW_X]; 895 mDtDy = tmpFloats[Matrix.MSCALE_Y]; 896 float x = tmpFloats[Matrix.MTRANS_X]; 897 float y = tmpFloats[Matrix.MTRANS_Y]; 898 int w = frame.width(); 899 int h = frame.height(); 900 mWin.mShownFrame.set(x, y, x+w, y+h); 901 902 // Now set the alpha... but because our current hardware 903 // can't do alpha transformation on a non-opaque surface, 904 // turn it off if we are running an animation that is also 905 // transforming since it is more important to have that 906 // animation be smooth. 907 mShownAlpha = mAlpha; 908 if (!mService.mLimitedAlphaCompositing 909 || (!PixelFormat.formatHasAlpha(mWin.mAttrs.format) 910 || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy) 911 && x == frame.left && y == frame.top))) { 912 //Slog.i(TAG, "Applying alpha transform"); 913 if (selfTransformation) { 914 mShownAlpha *= mTransformation.getAlpha(); 915 } 916 if (attachedTransformation != null) { 917 mShownAlpha *= attachedTransformation.getAlpha(); 918 } 919 if (appTransformation != null) { 920 mShownAlpha *= appTransformation.getAlpha(); 921 } 922 if (mAnimator.mUniverseBackground != null) { 923 mShownAlpha *= mAnimator.mUniverseBackground.mUniverseTransform.getAlpha(); 924 } 925 if (screenAnimation) { 926 mShownAlpha *= 927 mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getAlpha(); 928 } 929 } else { 930 //Slog.i(TAG, "Not applying alpha transform"); 931 } 932 933 if ((DEBUG_SURFACE_TRACE || WindowManagerService.localLOGV) && (mShownAlpha == 1.0 || mShownAlpha == 0.0)) Slog.v( 934 TAG, "computeShownFrameLocked: Animating " + this + 935 " mAlpha=" + mAlpha + 936 " self=" + (selfTransformation ? mTransformation.getAlpha() : "null") + 937 " attached=" + (attachedTransformation == null ? "null" : attachedTransformation.getAlpha()) + 938 " app=" + (appTransformation == null ? "null" : appTransformation.getAlpha()) + 939 " screen=" + (screenAnimation ? mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getAlpha() 940 : "null")); 941 return; 942 } else if (mIsWallpaper && 943 (mAnimator.mPendingActions & WindowAnimator.WALLPAPER_ACTION_PENDING) != 0) { 944 return; 945 } 946 947 if (WindowManagerService.localLOGV) Slog.v( 948 TAG, "computeShownFrameLocked: " + this + 949 " not attached, mAlpha=" + mAlpha); 950 if (mAnimator.mUniverseBackground != null && 951 mWin.mAttrs.type != WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND 952 && mWin.mBaseLayer < mAnimator.mAboveUniverseLayer) { 953 final Rect frame = mWin.mFrame; 954 final float tmpFloats[] = mService.mTmpFloats; 955 final Matrix tmpMatrix = mWin.mTmpMatrix; 956 tmpMatrix.setScale(mWin.mGlobalScale, mWin.mGlobalScale); 957 tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset); 958 tmpMatrix.postConcat(mAnimator.mUniverseBackground.mUniverseTransform.getMatrix()); 959 tmpMatrix.getValues(tmpFloats); 960 mHaveMatrix = true; 961 mDsDx = tmpFloats[Matrix.MSCALE_X]; 962 mDtDx = tmpFloats[Matrix.MSKEW_Y]; 963 mDsDy = tmpFloats[Matrix.MSKEW_X]; 964 mDtDy = tmpFloats[Matrix.MSCALE_Y]; 965 float x = tmpFloats[Matrix.MTRANS_X]; 966 float y = tmpFloats[Matrix.MTRANS_Y]; 967 int w = frame.width(); 968 int h = frame.height(); 969 mWin.mShownFrame.set(x, y, x+w, y+h); 970 mShownAlpha = mAlpha * mAnimator.mUniverseBackground.mUniverseTransform.getAlpha(); 971 } else { 972 mWin.mShownFrame.set(mWin.mFrame); 973 if (mWin.mXOffset != 0 || mWin.mYOffset != 0) { 974 mWin.mShownFrame.offset(mWin.mXOffset, mWin.mYOffset); 975 } 976 mShownAlpha = mAlpha; 977 mHaveMatrix = false; 978 mDsDx = mWin.mGlobalScale; 979 mDtDx = 0; 980 mDsDy = 0; 981 mDtDy = mWin.mGlobalScale; 982 } 983 } 984 985 void applyDecorRect(final Rect decorRect) { 986 final WindowState w = mWin; 987 // Compute the offset of the window in relation to the decor rect. 988 final int offX = w.mXOffset + w.mFrame.left; 989 final int offY = w.mYOffset + w.mFrame.top; 990 // Initialize the decor rect to the entire frame. 991 w.mSystemDecorRect.set(0, 0, w.mFrame.width(), w.mFrame.height()); 992 // Intersect with the decor rect, offsetted by window position. 993 w.mSystemDecorRect.intersect(decorRect.left-offX, decorRect.top-offY, 994 decorRect.right-offX, decorRect.bottom-offY); 995 // If size compatibility is being applied to the window, the 996 // surface is scaled relative to the screen. Also apply this 997 // scaling to the crop rect. We aren't using the standard rect 998 // scale function because we want to round things to make the crop 999 // always round to a larger rect to ensure we don't crop too 1000 // much and hide part of the window that should be seen. 1001 if (w.mEnforceSizeCompat && w.mInvGlobalScale != 1.0f) { 1002 final float scale = w.mInvGlobalScale; 1003 w.mSystemDecorRect.left = (int) (w.mSystemDecorRect.left * scale - 0.5f); 1004 w.mSystemDecorRect.top = (int) (w.mSystemDecorRect.top * scale - 0.5f); 1005 w.mSystemDecorRect.right = (int) ((w.mSystemDecorRect.right+1) * scale - 0.5f); 1006 w.mSystemDecorRect.bottom = (int) ((w.mSystemDecorRect.bottom+1) * scale - 0.5f); 1007 } 1008 } 1009 1010 void updateSurfaceWindowCrop(final boolean recoveringMemory) { 1011 final WindowState w = mWin; 1012 1013 // Need to recompute a new system decor rect each time. 1014 if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) { 1015 // Currently can't do this cropping for scaled windows. We'll 1016 // just keep the crop rect the same as the source surface. 1017 w.mSystemDecorRect.set(0, 0, w.mRequestedWidth, w.mRequestedHeight); 1018 } else if (w.mLayer >= mService.mSystemDecorLayer) { 1019 // Above the decor layer is easy, just use the entire window. 1020 // Unless we have a universe background... in which case all the 1021 // windows need to be cropped by the screen, so they don't cover 1022 // the universe background. 1023 if (mAnimator.mUniverseBackground == null) { 1024 w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), 1025 w.mCompatFrame.height()); 1026 } else { 1027 applyDecorRect(mService.mScreenRect); 1028 } 1029 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND) { 1030 // The universe background isn't cropped. 1031 w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), 1032 w.mCompatFrame.height()); 1033 } else { 1034 applyDecorRect(mService.mSystemDecorRect); 1035 } 1036 1037 if (!w.mSystemDecorRect.equals(w.mLastSystemDecorRect)) { 1038 w.mLastSystemDecorRect.set(w.mSystemDecorRect); 1039 try { 1040 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w, 1041 "CROP " + w.mSystemDecorRect.toShortString(), null); 1042 mSurface.setWindowCrop(w.mSystemDecorRect); 1043 } catch (RuntimeException e) { 1044 Slog.w(TAG, "Error setting crop surface of " + w 1045 + " crop=" + w.mSystemDecorRect.toShortString(), e); 1046 if (!recoveringMemory) { 1047 mService.reclaimSomeSurfaceMemoryLocked(this, "crop", true); 1048 } 1049 } 1050 } 1051 } 1052 1053 void setSurfaceBoundaries(final boolean recoveringMemory) { 1054 final WindowState w = mWin; 1055 int width, height; 1056 if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) { 1057 // for a scaled surface, we just want to use 1058 // the requested size. 1059 width = w.mRequestedWidth; 1060 height = w.mRequestedHeight; 1061 } else { 1062 width = w.mCompatFrame.width(); 1063 height = w.mCompatFrame.height(); 1064 } 1065 1066 if (width < 1) { 1067 width = 1; 1068 } 1069 if (height < 1) { 1070 height = 1; 1071 } 1072 final boolean surfaceResized = mSurfaceW != width || mSurfaceH != height; 1073 if (surfaceResized) { 1074 mSurfaceW = width; 1075 mSurfaceH = height; 1076 } 1077 1078 final float left = w.mShownFrame.left; 1079 final float top = w.mShownFrame.top; 1080 if (mSurfaceX != left || mSurfaceY != top) { 1081 try { 1082 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w, 1083 "POS " + left + ", " + top, null); 1084 mSurfaceX = left; 1085 mSurfaceY = top; 1086 mSurface.setPosition(left, top); 1087 } catch (RuntimeException e) { 1088 Slog.w(TAG, "Error positioning surface of " + w 1089 + " pos=(" + left 1090 + "," + top + ")", e); 1091 if (!recoveringMemory) { 1092 mService.reclaimSomeSurfaceMemoryLocked(this, "position", true); 1093 } 1094 } 1095 } 1096 1097 if (surfaceResized) { 1098 try { 1099 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w, 1100 "SIZE " + width + "x" + height, null); 1101 mSurfaceResized = true; 1102 mSurface.setSize(width, height); 1103 mAnimator.mPendingLayoutChanges |= 1104 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; 1105 if ((w.mAttrs.flags & LayoutParams.FLAG_DIM_BEHIND) != 0) { 1106 mService.startDimming(this, w.mExiting ? 0 : w.mAttrs.dimAmount, 1107 mService.mAppDisplayWidth, mService.mAppDisplayHeight); 1108 } 1109 } catch (RuntimeException e) { 1110 // If something goes wrong with the surface (such 1111 // as running out of memory), don't take down the 1112 // entire system. 1113 Slog.e(TAG, "Error resizing surface of " + w 1114 + " size=(" + width + "x" + height + ")", e); 1115 if (!recoveringMemory) { 1116 mService.reclaimSomeSurfaceMemoryLocked(this, "size", true); 1117 } 1118 } 1119 } 1120 1121 updateSurfaceWindowCrop(recoveringMemory); 1122 } 1123 1124 public void prepareSurfaceLocked(final boolean recoveringMemory) { 1125 final WindowState w = mWin; 1126 if (mSurface == null) { 1127 if (w.mOrientationChanging) { 1128 if (DEBUG_ORIENTATION) { 1129 Slog.v(TAG, "Orientation change skips hidden " + w); 1130 } 1131 w.mOrientationChanging = false; 1132 } 1133 return; 1134 } 1135 1136 boolean displayed = false; 1137 1138 computeShownFrameLocked(); 1139 1140 setSurfaceBoundaries(recoveringMemory); 1141 1142 if (mIsWallpaper && !mWin.mWallpaperVisible) { 1143 // Wallpaper is no longer visible and there is no wp target => hide it. 1144 hide(); 1145 } else if (w.mAttachedHidden || !w.isReadyForDisplay()) { 1146 hide(); 1147 mAnimator.hideWallpapersLocked(w); 1148 1149 // If we are waiting for this window to handle an 1150 // orientation change, well, it is hidden, so 1151 // doesn't really matter. Note that this does 1152 // introduce a potential glitch if the window 1153 // becomes unhidden before it has drawn for the 1154 // new orientation. 1155 if (w.mOrientationChanging) { 1156 w.mOrientationChanging = false; 1157 if (DEBUG_ORIENTATION) Slog.v(TAG, 1158 "Orientation change skips hidden " + w); 1159 } 1160 } else if (mLastLayer != mAnimLayer 1161 || mLastAlpha != mShownAlpha 1162 || mLastDsDx != mDsDx 1163 || mLastDtDx != mDtDx 1164 || mLastDsDy != mDsDy 1165 || mLastDtDy != mDtDy 1166 || w.mLastHScale != w.mHScale 1167 || w.mLastVScale != w.mVScale 1168 || mLastHidden) { 1169 displayed = true; 1170 mLastAlpha = mShownAlpha; 1171 mLastLayer = mAnimLayer; 1172 mLastDsDx = mDsDx; 1173 mLastDtDx = mDtDx; 1174 mLastDsDy = mDsDy; 1175 mLastDtDy = mDtDy; 1176 w.mLastHScale = w.mHScale; 1177 w.mLastVScale = w.mVScale; 1178 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w, 1179 "alpha=" + mShownAlpha + " layer=" + mAnimLayer 1180 + " matrix=[" + (mDsDx*w.mHScale) 1181 + "," + (mDtDx*w.mVScale) 1182 + "][" + (mDsDy*w.mHScale) 1183 + "," + (mDtDy*w.mVScale) + "]", null); 1184 if (mSurface != null) { 1185 try { 1186 mSurfaceAlpha = mShownAlpha; 1187 mSurface.setAlpha(mShownAlpha); 1188 mSurfaceLayer = mAnimLayer; 1189 mSurface.setLayer(mAnimLayer); 1190 mSurface.setMatrix( 1191 mDsDx*w.mHScale, mDtDx*w.mVScale, 1192 mDsDy*w.mHScale, mDtDy*w.mVScale); 1193 1194 if (mLastHidden && mDrawState == HAS_DRAWN) { 1195 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w, 1196 "SHOW (performLayout)", null); 1197 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w 1198 + " during relayout"); 1199 if (showSurfaceRobustlyLocked()) { 1200 mLastHidden = false; 1201 if (mIsWallpaper) { 1202 mService.dispatchWallpaperVisibility(w, true); 1203 } 1204 } else { 1205 w.mOrientationChanging = false; 1206 } 1207 } 1208 if (mSurface != null) { 1209 w.mToken.hasVisible = true; 1210 } 1211 } catch (RuntimeException e) { 1212 Slog.w(TAG, "Error updating surface in " + w, e); 1213 if (!recoveringMemory) { 1214 mService.reclaimSomeSurfaceMemoryLocked(this, "update", true); 1215 } 1216 } 1217 } 1218 } else { 1219 if (DEBUG_ANIM && isAnimating()) { 1220 Slog.v(TAG, "prepareSurface: No changes in animation for " + this); 1221 } 1222 displayed = true; 1223 } 1224 1225 if (displayed) { 1226 if (w.mOrientationChanging) { 1227 if (!w.isDrawnLw()) { 1228 mAnimator.mBulkUpdateParams &= ~SET_ORIENTATION_CHANGE_COMPLETE; 1229 if (DEBUG_ORIENTATION) Slog.v(TAG, 1230 "Orientation continue waiting for draw in " + w); 1231 } else { 1232 w.mOrientationChanging = false; 1233 if (DEBUG_ORIENTATION) Slog.v(TAG, "Orientation change complete in " + w); 1234 } 1235 } 1236 w.mToken.hasVisible = true; 1237 } 1238 } 1239 1240 void setTransparentRegionHint(final Region region) { 1241 if (mSurface == null) { 1242 Slog.w(TAG, "setTransparentRegionHint: null mSurface after mHasSurface true"); 1243 return; 1244 } 1245 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, 1246 ">>> OPEN TRANSACTION setTransparentRegion"); 1247 Surface.openTransaction(); 1248 try { 1249 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, 1250 "transparentRegionHint=" + region, null); 1251 mSurface.setTransparentRegionHint(region); 1252 } finally { 1253 Surface.closeTransaction(); 1254 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, 1255 "<<< CLOSE TRANSACTION setTransparentRegion"); 1256 } 1257 } 1258 1259 void setWallpaperOffset(int left, int top) { 1260 mSurfaceX = left; 1261 mSurfaceY = top; 1262 if (mAnimating) { 1263 // If this window (or its app token) is animating, then the position 1264 // of the surface will be re-computed on the next animation frame. 1265 // We can't poke it directly here because it depends on whatever 1266 // transformation is being applied by the animation. 1267 return; 1268 } 1269 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, 1270 ">>> OPEN TRANSACTION setWallpaperOffset"); 1271 Surface.openTransaction(); 1272 try { 1273 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, 1274 "POS " + left + ", " + top, null); 1275 mSurface.setPosition(mWin.mFrame.left + left, mWin.mFrame.top + top); 1276 updateSurfaceWindowCrop(false); 1277 } catch (RuntimeException e) { 1278 Slog.w(TAG, "Error positioning surface of " + mWin 1279 + " pos=(" + left + "," + top + ")", e); 1280 } finally { 1281 Surface.closeTransaction(); 1282 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, 1283 "<<< CLOSE TRANSACTION setWallpaperOffset"); 1284 } 1285 } 1286 1287 // This must be called while inside a transaction. 1288 boolean performShowLocked() { 1289 if (DEBUG_VISIBILITY || (DEBUG_STARTING_WINDOW && 1290 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING)) { 1291 RuntimeException e = null; 1292 if (!WindowManagerService.HIDE_STACK_CRAWLS) { 1293 e = new RuntimeException(); 1294 e.fillInStackTrace(); 1295 } 1296 Slog.v(TAG, "performShow on " + this 1297 + ": mDrawState=" + mDrawState + " readyForDisplay=" 1298 + mWin.isReadyForDisplayIgnoringKeyguard() 1299 + " starting=" + (mWin.mAttrs.type == TYPE_APPLICATION_STARTING) 1300 + " during animation: policyVis=" + mWin.mPolicyVisibility 1301 + " attHidden=" + mWin.mAttachedHidden 1302 + " tok.hiddenRequested=" 1303 + (mWin.mAppToken != null ? mWin.mAppToken.hiddenRequested : false) 1304 + " tok.hidden=" 1305 + (mWin.mAppToken != null ? mWin.mAppToken.hidden : false) 1306 + " animating=" + mAnimating 1307 + " tok animating=" 1308 + (mWin.mAppToken != null ? mWin.mAppToken.mAppAnimator.animating : false), e); 1309 } 1310 if (mDrawState == READY_TO_SHOW && mWin.isReadyForDisplayIgnoringKeyguard()) { 1311 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) 1312 WindowManagerService.logSurface(mWin, "SHOW (performShowLocked)", null); 1313 if (DEBUG_VISIBILITY || (DEBUG_STARTING_WINDOW && 1314 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING)) { 1315 Slog.v(TAG, "Showing " + this 1316 + " during animation: policyVis=" + mWin.mPolicyVisibility 1317 + " attHidden=" + mWin.mAttachedHidden 1318 + " tok.hiddenRequested=" 1319 + (mWin.mAppToken != null ? mWin.mAppToken.hiddenRequested : false) 1320 + " tok.hidden=" 1321 + (mWin.mAppToken != null ? mWin.mAppToken.hidden : false) 1322 + " animating=" + mAnimating 1323 + " tok animating=" 1324 + (mWin.mAppToken != null ? mWin.mAppToken.mAppAnimator.animating : false)); 1325 } 1326 1327 mService.enableScreenIfNeededLocked(); 1328 1329 applyEnterAnimationLocked(); 1330 1331 // Force the show in the next prepareSurfaceLocked() call. 1332 mLastAlpha = -1; 1333 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM) 1334 Slog.v(TAG, "performShowLocked: mDrawState=HAS_DRAWN in " + this); 1335 mDrawState = HAS_DRAWN; 1336 mService.updateLayoutToAnimationLocked(); 1337 1338 int i = mWin.mChildWindows.size(); 1339 while (i > 0) { 1340 i--; 1341 WindowState c = mWin.mChildWindows.get(i); 1342 if (c.mAttachedHidden) { 1343 c.mAttachedHidden = false; 1344 if (c.mWinAnimator.mSurface != null) { 1345 c.mWinAnimator.performShowLocked(); 1346 // It hadn't been shown, which means layout not 1347 // performed on it, so now we want to make sure to 1348 // do a layout. If called from within the transaction 1349 // loop, this will cause it to restart with a new 1350 // layout. 1351 mService.mLayoutNeeded = true; 1352 } 1353 } 1354 } 1355 1356 if (mWin.mAttrs.type != TYPE_APPLICATION_STARTING 1357 && mWin.mAppToken != null) { 1358 mWin.mAppToken.firstWindowDrawn = true; 1359 1360 if (mWin.mAppToken.startingData != null) { 1361 if (WindowManagerService.DEBUG_STARTING_WINDOW || 1362 WindowManagerService.DEBUG_ANIM) Slog.v(TAG, 1363 "Finish starting " + mWin.mToken 1364 + ": first real window is shown, no animation"); 1365 // If this initial window is animating, stop it -- we 1366 // will do an animation to reveal it from behind the 1367 // starting window, so there is no need for it to also 1368 // be doing its own stuff. 1369 clearAnimation(); 1370 mService.mFinishedStarting.add(mWin.mAppToken); 1371 mService.mH.sendEmptyMessage(H.FINISHED_STARTING); 1372 } 1373 mWin.mAppToken.updateReportedVisibilityLocked(); 1374 } 1375 1376 return true; 1377 } 1378 1379 return false; 1380 } 1381 1382 /** 1383 * Have the surface flinger show a surface, robustly dealing with 1384 * error conditions. In particular, if there is not enough memory 1385 * to show the surface, then we will try to get rid of other surfaces 1386 * in order to succeed. 1387 * 1388 * @return Returns true if the surface was successfully shown. 1389 */ 1390 boolean showSurfaceRobustlyLocked() { 1391 try { 1392 if (mSurface != null) { 1393 mSurfaceShown = true; 1394 mSurface.show(); 1395 if (mWin.mTurnOnScreen) { 1396 if (DEBUG_VISIBILITY) Slog.v(TAG, 1397 "Show surface turning screen on: " + mWin); 1398 mWin.mTurnOnScreen = false; 1399 mAnimator.mBulkUpdateParams |= SET_TURN_ON_SCREEN; 1400 } 1401 } 1402 return true; 1403 } catch (RuntimeException e) { 1404 Slog.w(TAG, "Failure showing surface " + mSurface + " in " + mWin, e); 1405 } 1406 1407 mService.reclaimSomeSurfaceMemoryLocked(this, "show", true); 1408 1409 return false; 1410 } 1411 1412 void applyEnterAnimationLocked() { 1413 final int transit; 1414 if (mEnterAnimationPending) { 1415 mEnterAnimationPending = false; 1416 transit = WindowManagerPolicy.TRANSIT_ENTER; 1417 } else { 1418 transit = WindowManagerPolicy.TRANSIT_SHOW; 1419 } 1420 1421 applyAnimationLocked(transit, true); 1422 } 1423 1424 // TODO(cmautner): Move back to WindowState? 1425 /** 1426 * Choose the correct animation and set it to the passed WindowState. 1427 * @param transit If WindowManagerPolicy.TRANSIT_PREVIEW_DONE and the app window has been drawn 1428 * then the animation will be app_starting_exit. Any other value loads the animation from 1429 * the switch statement below. 1430 * @param isEntrance The animation type the last time this was called. Used to keep from 1431 * loading the same animation twice. 1432 * @return true if an animation has been loaded. 1433 */ 1434 boolean applyAnimationLocked(int transit, boolean isEntrance) { 1435 if (mLocalAnimating && mAnimationIsEntrance == isEntrance) { 1436 // If we are trying to apply an animation, but already running 1437 // an animation of the same type, then just leave that one alone. 1438 return true; 1439 } 1440 1441 // Only apply an animation if the display isn't frozen. If it is 1442 // frozen, there is no reason to animate and it can cause strange 1443 // artifacts when we unfreeze the display if some different animation 1444 // is running. 1445 if (mService.okToDisplay()) { 1446 int anim = mPolicy.selectAnimationLw(mWin, transit); 1447 int attr = -1; 1448 Animation a = null; 1449 if (anim != 0) { 1450 a = AnimationUtils.loadAnimation(mContext, anim); 1451 } else { 1452 switch (transit) { 1453 case WindowManagerPolicy.TRANSIT_ENTER: 1454 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation; 1455 break; 1456 case WindowManagerPolicy.TRANSIT_EXIT: 1457 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation; 1458 break; 1459 case WindowManagerPolicy.TRANSIT_SHOW: 1460 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation; 1461 break; 1462 case WindowManagerPolicy.TRANSIT_HIDE: 1463 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation; 1464 break; 1465 } 1466 if (attr >= 0) { 1467 a = mService.loadAnimation(mWin.mAttrs, attr); 1468 } 1469 } 1470 if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG, 1471 "applyAnimation: win=" + this 1472 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr) 1473 + " a=" + a 1474 + " mAnimation=" + mAnimation 1475 + " isEntrance=" + isEntrance + " Callers " + Debug.getCallers(3)); 1476 if (a != null) { 1477 if (WindowManagerService.DEBUG_ANIM) { 1478 RuntimeException e = null; 1479 if (!WindowManagerService.HIDE_STACK_CRAWLS) { 1480 e = new RuntimeException(); 1481 e.fillInStackTrace(); 1482 } 1483 Slog.v(TAG, "Loaded animation " + a + " for " + this, e); 1484 } 1485 setAnimation(a); 1486 mAnimationIsEntrance = isEntrance; 1487 } 1488 } else { 1489 clearAnimation(); 1490 } 1491 1492 return mAnimation != null; 1493 } 1494 1495 public void dump(PrintWriter pw, String prefix, boolean dumpAll) { 1496 if (mAnimating || mLocalAnimating || mAnimationIsEntrance 1497 || mAnimation != null) { 1498 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating); 1499 pw.print(" mLocalAnimating="); pw.print(mLocalAnimating); 1500 pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance); 1501 pw.print(" mAnimation="); pw.println(mAnimation); 1502 } 1503 if (mHasTransformation || mHasLocalTransformation) { 1504 pw.print(prefix); pw.print("XForm: has="); 1505 pw.print(mHasTransformation); 1506 pw.print(" hasLocal="); pw.print(mHasLocalTransformation); 1507 pw.print(" "); mTransformation.printShortString(pw); 1508 pw.println(); 1509 } 1510 if (mSurface != null) { 1511 if (dumpAll) { 1512 pw.print(prefix); pw.print("mSurface="); pw.println(mSurface); 1513 pw.print(prefix); pw.print("mDrawState="); 1514 pw.print(drawStateToString(mDrawState)); 1515 pw.print(" mLastHidden="); pw.println(mLastHidden); 1516 } 1517 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown); 1518 pw.print(" layer="); pw.print(mSurfaceLayer); 1519 pw.print(" alpha="); pw.print(mSurfaceAlpha); 1520 pw.print(" rect=("); pw.print(mSurfaceX); 1521 pw.print(","); pw.print(mSurfaceY); 1522 pw.print(") "); pw.print(mSurfaceW); 1523 pw.print(" x "); pw.println(mSurfaceH); 1524 } 1525 if (mPendingDestroySurface != null) { 1526 pw.print(prefix); pw.print("mPendingDestroySurface="); 1527 pw.println(mPendingDestroySurface); 1528 } 1529 if (mSurfaceResized || mSurfaceDestroyDeferred) { 1530 pw.print(prefix); pw.print("mSurfaceResized="); pw.print(mSurfaceResized); 1531 pw.print(" mSurfaceDestroyDeferred="); pw.println(mSurfaceDestroyDeferred); 1532 } 1533 if (mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND) { 1534 pw.print(prefix); pw.print("mUniverseTransform="); 1535 mUniverseTransform.printShortString(pw); 1536 pw.println(); 1537 } 1538 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) { 1539 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha); 1540 pw.print(" mAlpha="); pw.print(mAlpha); 1541 pw.print(" mLastAlpha="); pw.println(mLastAlpha); 1542 } 1543 if (mHaveMatrix || mWin.mGlobalScale != 1) { 1544 pw.print(prefix); pw.print("mGlobalScale="); pw.print(mWin.mGlobalScale); 1545 pw.print(" mDsDx="); pw.print(mDsDx); 1546 pw.print(" mDtDx="); pw.print(mDtDx); 1547 pw.print(" mDsDy="); pw.print(mDsDy); 1548 pw.print(" mDtDy="); pw.println(mDtDy); 1549 } 1550 } 1551 1552 @Override 1553 public String toString() { 1554 StringBuffer sb = new StringBuffer("WindowStateAnimator ("); 1555 sb.append(mWin.mLastTitle + "): "); 1556 sb.append("mSurface " + mSurface); 1557 sb.append(", mAnimation " + mAnimation); 1558 return sb.toString(); 1559 } 1560} 1561