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