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