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