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