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 17 package com.android.server.wm; 18 19 import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; 20 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY; 21 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; 22 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; 23 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; 24 import static android.view.WindowManager.TRANSIT_OLD_NONE; 25 26 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ANIM; 27 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_DRAW; 28 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION; 29 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW; 30 import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC; 31 import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_TRANSACTIONS; 32 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM; 33 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; 34 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION; 35 import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; 36 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG; 37 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS; 38 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE; 39 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; 40 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS; 41 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; 42 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; 43 import static com.android.server.wm.WindowManagerService.logWithStack; 44 import static com.android.server.wm.WindowStateAnimatorProto.DRAW_STATE; 45 import static com.android.server.wm.WindowStateAnimatorProto.SURFACE; 46 import static com.android.server.wm.WindowStateAnimatorProto.SYSTEM_DECOR_RECT; 47 48 import android.content.Context; 49 import android.graphics.PixelFormat; 50 import android.graphics.Rect; 51 import android.os.Debug; 52 import android.os.Trace; 53 import android.util.Slog; 54 import android.util.proto.ProtoOutputStream; 55 import android.view.Surface.OutOfResourcesException; 56 import android.view.SurfaceControl; 57 import android.view.WindowManager; 58 import android.view.WindowManager.LayoutParams; 59 import android.view.animation.Animation; 60 import android.view.animation.AnimationUtils; 61 62 import com.android.internal.protolog.ProtoLogImpl; 63 import com.android.internal.protolog.common.ProtoLog; 64 import com.android.server.policy.WindowManagerPolicy; 65 66 import java.io.PrintWriter; 67 68 /** 69 * Keep track of animations and surface operations for a single WindowState. 70 **/ 71 class WindowStateAnimator { 72 static final String TAG = TAG_WITH_CLASS_NAME ? "WindowStateAnimator" : TAG_WM; 73 static final int PRESERVED_SURFACE_LAYER = 1; 74 75 /** 76 * Mode how the window gets clipped by the root task bounds during an animation: The clipping 77 * should be applied after applying the animation transformation, i.e. the root task bounds 78 * don't move during the animation. 79 */ 80 static final int ROOT_TASK_CLIP_AFTER_ANIM = 0; 81 82 /** 83 * Mode how window gets clipped by the root task bounds during an animation: Don't clip the 84 * window by the root task bounds. 85 */ 86 static final int ROOT_TASK_CLIP_NONE = 1; 87 88 // Unchanging local convenience fields. 89 final WindowManagerService mService; 90 final WindowState mWin; 91 final WindowAnimator mAnimator; 92 final Session mSession; 93 final WindowManagerPolicy mPolicy; 94 final Context mContext; 95 final boolean mIsWallpaper; 96 private final WallpaperController mWallpaperControllerLocked; 97 98 boolean mAnimationIsEntrance; 99 100 WindowSurfaceController mSurfaceController; 101 102 float mShownAlpha = 0; 103 float mAlpha = 0; 104 float mLastAlpha = 0; 105 106 /** 107 * This is rectangle of the window's surface that is not covered by 108 * system decorations. 109 */ 110 private final Rect mSystemDecorRect = new Rect(); 111 112 // Set to true if, when the window gets displayed, it should perform 113 // an enter animation. 114 boolean mEnterAnimationPending; 115 116 /** Used to indicate that this window is undergoing an enter animation. Used for system 117 * windows to make the callback to View.dispatchOnWindowShownCallback(). Set when the 118 * window is first added or shown, cleared when the callback has been made. */ 119 boolean mEnteringAnimation; 120 121 /** This is set when there is no Surface */ 122 static final int NO_SURFACE = 0; 123 /** This is set after the Surface has been created but before the window has been drawn. During 124 * this time the surface is hidden. */ 125 static final int DRAW_PENDING = 1; 126 /** This is set after the window has finished drawing for the first time but before its surface 127 * is shown. The surface will be displayed when the next layout is run. */ 128 static final int COMMIT_DRAW_PENDING = 2; 129 /** This is set during the time after the window's drawing has been committed, and before its 130 * surface is actually shown. It is used to delay showing the surface until all windows in a 131 * token are ready to be shown. */ 132 static final int READY_TO_SHOW = 3; 133 /** Set when the window has been shown in the screen the first time. */ 134 static final int HAS_DRAWN = 4; 135 drawStateToString()136 String drawStateToString() { 137 switch (mDrawState) { 138 case NO_SURFACE: return "NO_SURFACE"; 139 case DRAW_PENDING: return "DRAW_PENDING"; 140 case COMMIT_DRAW_PENDING: return "COMMIT_DRAW_PENDING"; 141 case READY_TO_SHOW: return "READY_TO_SHOW"; 142 case HAS_DRAWN: return "HAS_DRAWN"; 143 default: return Integer.toString(mDrawState); 144 } 145 } 146 int mDrawState; 147 148 /** Was this window last hidden? */ 149 boolean mLastHidden; 150 151 int mAttrType; 152 WindowStateAnimator(final WindowState win)153 WindowStateAnimator(final WindowState win) { 154 final WindowManagerService service = win.mWmService; 155 156 mService = service; 157 mAnimator = service.mAnimator; 158 mPolicy = service.mPolicy; 159 mContext = service.mContext; 160 161 mWin = win; 162 mSession = win.mSession; 163 mAttrType = win.mAttrs.type; 164 mIsWallpaper = win.mIsWallpaper; 165 mWallpaperControllerLocked = win.getDisplayContent().mWallpaperController; 166 } 167 onAnimationFinished()168 void onAnimationFinished() { 169 // Done animating, clean up. 170 ProtoLog.v(WM_DEBUG_ANIM, "Animation done in %s: exiting=%b, reportedVisible=%b", 171 this, mWin.mAnimatingExit, 172 (mWin.mActivityRecord != null && mWin.mActivityRecord.reportedVisible)); 173 174 mWin.checkPolicyVisibilityChange(); 175 final DisplayContent displayContent = mWin.getDisplayContent(); 176 if ((mAttrType == LayoutParams.TYPE_STATUS_BAR 177 || mAttrType == LayoutParams.TYPE_NOTIFICATION_SHADE) && mWin.isVisibleByPolicy()) { 178 // Upon completion of a not-visible to visible status bar animation a relayout is 179 // required. 180 displayContent.setLayoutNeeded(); 181 } 182 mWin.onExitAnimationDone(); 183 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM; 184 if (displayContent.mWallpaperController.isWallpaperTarget(mWin)) { 185 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; 186 } 187 if (DEBUG_LAYOUT_REPEATS) { 188 mService.mWindowPlacerLocked.debugLayoutRepeats( 189 "WindowStateAnimator", displayContent.pendingLayoutChanges); 190 } 191 192 if (mWin.mActivityRecord != null) { 193 mWin.mActivityRecord.updateReportedVisibilityLocked(); 194 } 195 } 196 hide(SurfaceControl.Transaction transaction, String reason)197 void hide(SurfaceControl.Transaction transaction, String reason) { 198 if (!mLastHidden) { 199 //dump(); 200 mLastHidden = true; 201 202 if (mSurfaceController != null) { 203 mSurfaceController.hide(transaction, reason); 204 } 205 } 206 } 207 finishDrawingLocked(SurfaceControl.Transaction postDrawTransaction)208 boolean finishDrawingLocked(SurfaceControl.Transaction postDrawTransaction) { 209 final boolean startingWindow = 210 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; 211 if (startingWindow) { 212 ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Finishing drawing window %s: mDrawState=%s", 213 mWin, drawStateToString()); 214 } 215 216 boolean layoutNeeded = false; 217 218 if (mDrawState == DRAW_PENDING) { 219 ProtoLog.v(WM_DEBUG_DRAW, 220 "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING %s in %s", mWin, 221 mSurfaceController); 222 if (startingWindow) { 223 ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Draw state now committed in %s", mWin); 224 } 225 mDrawState = COMMIT_DRAW_PENDING; 226 layoutNeeded = true; 227 } 228 229 if (postDrawTransaction != null) { 230 mWin.getSyncTransaction().merge(postDrawTransaction); 231 layoutNeeded = true; 232 } 233 234 return layoutNeeded; 235 } 236 237 // This must be called while inside a transaction. commitFinishDrawingLocked()238 boolean commitFinishDrawingLocked() { 239 if (DEBUG_STARTING_WINDOW_VERBOSE && 240 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) { 241 Slog.i(TAG, "commitFinishDrawingLocked: " + mWin + " cur mDrawState=" 242 + drawStateToString()); 243 } 244 if (mDrawState != COMMIT_DRAW_PENDING && mDrawState != READY_TO_SHOW) { 245 return false; 246 } 247 ProtoLog.i(WM_DEBUG_ANIM, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW %s", 248 mSurfaceController); 249 mDrawState = READY_TO_SHOW; 250 boolean result = false; 251 final ActivityRecord activity = mWin.mActivityRecord; 252 if (activity == null || activity.canShowWindows() 253 || mWin.mAttrs.type == TYPE_APPLICATION_STARTING) { 254 result = mWin.performShowLocked(); 255 } 256 return result; 257 } 258 resetDrawState()259 void resetDrawState() { 260 mDrawState = DRAW_PENDING; 261 262 if (mWin.mActivityRecord == null) { 263 return; 264 } 265 266 if (!mWin.mActivityRecord.isAnimating(TRANSITION)) { 267 mWin.mActivityRecord.clearAllDrawn(); 268 } 269 } 270 createSurfaceLocked()271 WindowSurfaceController createSurfaceLocked() { 272 final WindowState w = mWin; 273 274 if (mSurfaceController != null) { 275 return mSurfaceController; 276 } 277 278 w.setHasSurface(false); 279 280 ProtoLog.i(WM_DEBUG_ANIM, "createSurface %s: mDrawState=DRAW_PENDING", this); 281 282 resetDrawState(); 283 284 mService.makeWindowFreezingScreenIfNeededLocked(w); 285 286 int flags = SurfaceControl.HIDDEN; 287 final WindowManager.LayoutParams attrs = w.mAttrs; 288 289 if (w.isSecureLocked()) { 290 flags |= SurfaceControl.SECURE; 291 } 292 293 if ((mWin.mAttrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0) { 294 flags |= SurfaceControl.SKIP_SCREENSHOT; 295 } 296 297 if (DEBUG_VISIBILITY) { 298 Slog.v(TAG, "Creating surface in session " 299 + mSession.mSurfaceSession + " window " + this 300 + " format=" + attrs.format + " flags=" + flags); 301 } 302 303 // Set up surface control with initial size. 304 try { 305 306 // This can be removed once we move all Buffer Layers to use BLAST. 307 final boolean isHwAccelerated = (attrs.flags & FLAG_HARDWARE_ACCELERATED) != 0; 308 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format; 309 310 mSurfaceController = new WindowSurfaceController(attrs.getTitle().toString(), format, 311 flags, this, attrs.type); 312 mSurfaceController.setColorSpaceAgnostic(w.getPendingTransaction(), 313 (attrs.privateFlags & LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC) != 0); 314 315 w.setHasSurface(true); 316 // The surface instance is changed. Make sure the input info can be applied to the 317 // new surface, e.g. relaunch activity. 318 w.mInputWindowHandle.forceChange(); 319 320 ProtoLog.i(WM_SHOW_SURFACE_ALLOC, 321 " CREATE SURFACE %s IN SESSION %s: pid=%d format=%d flags=0x%x / %s", 322 mSurfaceController, mSession.mSurfaceSession, mSession.mPid, attrs.format, 323 flags, this); 324 } catch (OutOfResourcesException e) { 325 Slog.w(TAG, "OutOfResourcesException creating surface"); 326 mService.mRoot.reclaimSomeSurfaceMemory(this, "create", true); 327 mDrawState = NO_SURFACE; 328 return null; 329 } catch (Exception e) { 330 Slog.e(TAG, "Exception creating surface (parent dead?)", e); 331 mDrawState = NO_SURFACE; 332 return null; 333 } 334 335 if (DEBUG) { 336 Slog.v(TAG, "Got surface: " + mSurfaceController 337 + ", set left=" + w.getFrame().left + " top=" + w.getFrame().top); 338 } 339 340 if (SHOW_LIGHT_TRANSACTIONS) { 341 Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked"); 342 WindowManagerService.logSurface(w, "CREATE pos=(" 343 + w.getFrame().left + "," + w.getFrame().top + ") HIDE", false); 344 } 345 346 mLastHidden = true; 347 348 if (DEBUG) Slog.v(TAG, "Created surface " + this); 349 return mSurfaceController; 350 } 351 hasSurface()352 boolean hasSurface() { 353 return mSurfaceController != null && mSurfaceController.hasSurface(); 354 } 355 destroySurfaceLocked(SurfaceControl.Transaction t)356 void destroySurfaceLocked(SurfaceControl.Transaction t) { 357 if (mSurfaceController == null) { 358 return; 359 } 360 361 mWin.mHidden = true; 362 363 try { 364 if (DEBUG_VISIBILITY) { 365 logWithStack(TAG, "Window " + this + " destroying surface " 366 + mSurfaceController + ", session " + mSession); 367 } 368 ProtoLog.i(WM_SHOW_SURFACE_ALLOC, "SURFACE DESTROY: %s. %s", 369 mWin, new RuntimeException().fillInStackTrace()); 370 destroySurface(t); 371 // Don't hide wallpaper if we're deferring the surface destroy 372 // because of a surface change. 373 mWallpaperControllerLocked.hideWallpapers(mWin); 374 } catch (RuntimeException e) { 375 Slog.w(TAG, "Exception thrown when destroying Window " + this 376 + " surface " + mSurfaceController + " session " + mSession + ": " 377 + e.toString()); 378 } 379 380 // Whether the surface was preserved (and copied to mPendingDestroySurface) or not, it 381 // needs to be cleared to match the WindowState.mHasSurface state. It is also necessary 382 // so it can be recreated successfully in mPendingDestroySurface case. 383 mWin.setHasSurface(false); 384 if (mSurfaceController != null) { 385 mSurfaceController.setShown(false); 386 } 387 mSurfaceController = null; 388 mDrawState = NO_SURFACE; 389 } 390 computeShownFrameLocked()391 void computeShownFrameLocked() { 392 if (mIsWallpaper && mService.mRoot.mWallpaperActionPending) { 393 return; 394 } else if (mWin.isDragResizeChanged()) { 395 // This window is awaiting a relayout because user just started (or ended) 396 // drag-resizing. The shown frame (which affects surface size and pos) 397 // should not be updated until we get next finished draw with the new surface. 398 // Otherwise one or two frames rendered with old settings would be displayed 399 // with new geometry. 400 return; 401 } 402 403 if (DEBUG) { 404 Slog.v(TAG, "computeShownFrameLocked: " + this 405 + " not attached, mAlpha=" + mAlpha); 406 } 407 408 mShownAlpha = mAlpha; 409 } 410 prepareSurfaceLocked(SurfaceControl.Transaction t)411 void prepareSurfaceLocked(SurfaceControl.Transaction t) { 412 final WindowState w = mWin; 413 if (!hasSurface()) { 414 415 // There is no need to wait for an animation change if our window is gone for layout 416 // already as we'll never be visible. 417 if (w.getOrientationChanging() && w.isGoneForLayout()) { 418 ProtoLog.v(WM_DEBUG_ORIENTATION, "Orientation change skips hidden %s", w); 419 w.setOrientationChanging(false); 420 } 421 return; 422 } 423 424 computeShownFrameLocked(); 425 426 if (!w.isOnScreen()) { 427 hide(t, "prepareSurfaceLocked"); 428 mWallpaperControllerLocked.hideWallpapers(w); 429 430 // If we are waiting for this window to handle an orientation change. If this window is 431 // really hidden (gone for layout), there is no point in still waiting for it. 432 // Note that this does introduce a potential glitch if the window becomes unhidden 433 // before it has drawn for the new orientation. 434 if (w.getOrientationChanging() && w.isGoneForLayout()) { 435 w.setOrientationChanging(false); 436 ProtoLog.v(WM_DEBUG_ORIENTATION, 437 "Orientation change skips hidden %s", w); 438 } 439 } else if (mLastAlpha != mShownAlpha 440 || mLastHidden) { 441 mLastAlpha = mShownAlpha; 442 ProtoLog.i(WM_SHOW_TRANSACTIONS, 443 "SURFACE controller=%s alpha=%f HScale=%f, VScale=%f: %s", 444 mSurfaceController, mShownAlpha, w.mHScale, w.mVScale, w); 445 446 boolean prepared = 447 mSurfaceController.prepareToShowInTransaction(t, mShownAlpha); 448 449 if (prepared && mDrawState == HAS_DRAWN) { 450 if (mLastHidden) { 451 mSurfaceController.showRobustly(t); 452 mLastHidden = false; 453 final DisplayContent displayContent = w.getDisplayContent(); 454 if (!displayContent.getLastHasContent()) { 455 // This draw means the difference between unique content and mirroring. 456 // Run another pass through performLayout to set mHasContent in the 457 // LogicalDisplay. 458 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM; 459 if (DEBUG_LAYOUT_REPEATS) { 460 mService.mWindowPlacerLocked.debugLayoutRepeats( 461 "showSurfaceRobustlyLocked " + w, 462 displayContent.pendingLayoutChanges); 463 } 464 } 465 } 466 } 467 } 468 469 if (w.getOrientationChanging()) { 470 if (!w.isDrawn()) { 471 if (w.mDisplayContent.shouldSyncRotationChange(w)) { 472 w.mWmService.mRoot.mOrientationChangeComplete = false; 473 mAnimator.mLastWindowFreezeSource = w; 474 } 475 ProtoLog.v(WM_DEBUG_ORIENTATION, 476 "Orientation continue waiting for draw in %s", w); 477 } else { 478 w.setOrientationChanging(false); 479 ProtoLog.v(WM_DEBUG_ORIENTATION, "Orientation change complete in %s", w); 480 } 481 } 482 } 483 setOpaqueLocked(boolean isOpaque)484 void setOpaqueLocked(boolean isOpaque) { 485 if (mSurfaceController == null) { 486 return; 487 } 488 mSurfaceController.setOpaque(isOpaque); 489 } 490 setSecureLocked(boolean isSecure)491 void setSecureLocked(boolean isSecure) { 492 if (mSurfaceController == null) { 493 return; 494 } 495 mSurfaceController.setSecure(isSecure); 496 } 497 setColorSpaceAgnosticLocked(boolean agnostic)498 void setColorSpaceAgnosticLocked(boolean agnostic) { 499 if (mSurfaceController == null) { 500 return; 501 } 502 mSurfaceController.setColorSpaceAgnostic(mWin.getPendingTransaction(), agnostic); 503 } 504 applyEnterAnimationLocked()505 void applyEnterAnimationLocked() { 506 final int transit; 507 if (mEnterAnimationPending) { 508 mEnterAnimationPending = false; 509 transit = WindowManagerPolicy.TRANSIT_ENTER; 510 } else { 511 transit = WindowManagerPolicy.TRANSIT_SHOW; 512 } 513 514 // We don't apply animation for application main window here since this window type 515 // should be controlled by ActivityRecord in general. Wallpaper is also excluded because 516 // WallpaperController should handle it. 517 if (mAttrType != TYPE_BASE_APPLICATION && !mIsWallpaper) { 518 applyAnimationLocked(transit, true); 519 } 520 521 if (mService.mAccessibilityController.hasCallbacks()) { 522 mService.mAccessibilityController.onWindowTransition(mWin, transit); 523 } 524 } 525 526 /** 527 * Choose the correct animation and set it to the passed WindowState. 528 * @param transit If AppTransition.TRANSIT_PREVIEW_DONE and the app window has been drawn 529 * then the animation will be app_starting_exit. Any other value loads the animation from 530 * the switch statement below. 531 * @param isEntrance The animation type the last time this was called. Used to keep from 532 * loading the same animation twice. 533 * @return true if an animation has been loaded. 534 */ applyAnimationLocked(int transit, boolean isEntrance)535 boolean applyAnimationLocked(int transit, boolean isEntrance) { 536 if (mWin.isAnimating() && mAnimationIsEntrance == isEntrance) { 537 // If we are trying to apply an animation, but already running 538 // an animation of the same type, then just leave that one alone. 539 return true; 540 } 541 542 if (mWin.mAttrs.type == TYPE_INPUT_METHOD) { 543 mWin.getDisplayContent().adjustForImeIfNeeded(); 544 if (isEntrance) { 545 mWin.setDisplayLayoutNeeded(); 546 mService.mWindowPlacerLocked.requestTraversal(); 547 } 548 } 549 550 if (mWin.mControllableInsetProvider != null) { 551 // All our animations should be driven by the insets control target. 552 return false; 553 } 554 555 // Only apply an animation if the display isn't frozen. If it is 556 // frozen, there is no reason to animate and it can cause strange 557 // artifacts when we unfreeze the display if some different animation 558 // is running. 559 if (mWin.mToken.okToAnimate()) { 560 int anim = mWin.getDisplayContent().getDisplayPolicy().selectAnimation(mWin, transit); 561 int attr = -1; 562 Animation a = null; 563 if (anim != DisplayPolicy.ANIMATION_STYLEABLE) { 564 if (anim != DisplayPolicy.ANIMATION_NONE) { 565 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "WSA#loadAnimation"); 566 a = AnimationUtils.loadAnimation(mContext, anim); 567 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); 568 } 569 } else { 570 switch (transit) { 571 case WindowManagerPolicy.TRANSIT_ENTER: 572 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation; 573 break; 574 case WindowManagerPolicy.TRANSIT_EXIT: 575 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation; 576 break; 577 case WindowManagerPolicy.TRANSIT_SHOW: 578 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation; 579 break; 580 case WindowManagerPolicy.TRANSIT_HIDE: 581 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation; 582 break; 583 } 584 if (attr >= 0) { 585 a = mWin.getDisplayContent().mAppTransition.loadAnimationAttr( 586 mWin.mAttrs, attr, TRANSIT_OLD_NONE); 587 } 588 } 589 if (ProtoLogImpl.isEnabled(WM_DEBUG_ANIM)) { 590 ProtoLog.v(WM_DEBUG_ANIM, "applyAnimation: win=%s" 591 + " anim=%d attr=0x%x a=%s transit=%d type=%d isEntrance=%b Callers %s", 592 this, anim, attr, a, transit, mAttrType, isEntrance, Debug.getCallers(20)); 593 } 594 if (a != null) { 595 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "WSA#startAnimation"); 596 mWin.startAnimation(a); 597 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); 598 mAnimationIsEntrance = isEntrance; 599 } 600 } else { 601 mWin.cancelAnimation(); 602 } 603 604 return mWin.isAnimating(0 /* flags */, ANIMATION_TYPE_WINDOW_ANIMATION); 605 } 606 dumpDebug(ProtoOutputStream proto, long fieldId)607 void dumpDebug(ProtoOutputStream proto, long fieldId) { 608 final long token = proto.start(fieldId); 609 if (mSurfaceController != null) { 610 mSurfaceController.dumpDebug(proto, SURFACE); 611 } 612 proto.write(DRAW_STATE, mDrawState); 613 mSystemDecorRect.dumpDebug(proto, SYSTEM_DECOR_RECT); 614 proto.end(token); 615 } 616 dump(PrintWriter pw, String prefix, boolean dumpAll)617 public void dump(PrintWriter pw, String prefix, boolean dumpAll) { 618 if (mAnimationIsEntrance) { 619 pw.print(prefix); pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance); 620 } 621 if (mSurfaceController != null) { 622 mSurfaceController.dump(pw, prefix, dumpAll); 623 } 624 if (dumpAll) { 625 pw.print(prefix); pw.print("mDrawState="); pw.print(drawStateToString()); 626 pw.print(prefix); pw.print(" mLastHidden="); pw.println(mLastHidden); 627 pw.print(prefix); pw.print("mEnterAnimationPending=" + mEnterAnimationPending); 628 pw.print(prefix); pw.print("mSystemDecorRect="); mSystemDecorRect.printShortString(pw); 629 630 pw.println(); 631 } 632 633 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) { 634 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha); 635 pw.print(" mAlpha="); pw.print(mAlpha); 636 pw.print(" mLastAlpha="); pw.println(mLastAlpha); 637 } 638 if (mWin.mGlobalScale != 1) { 639 pw.print(prefix); pw.print("mGlobalScale="); pw.print(mWin.mGlobalScale); 640 } 641 } 642 643 @Override toString()644 public String toString() { 645 StringBuffer sb = new StringBuffer("WindowStateAnimator{"); 646 sb.append(Integer.toHexString(System.identityHashCode(this))); 647 sb.append(' '); 648 sb.append(mWin.mAttrs.getTitle()); 649 sb.append('}'); 650 return sb.toString(); 651 } 652 getShown()653 boolean getShown() { 654 if (mSurfaceController != null) { 655 return mSurfaceController.getShown(); 656 } 657 return false; 658 } 659 destroySurface(SurfaceControl.Transaction t)660 void destroySurface(SurfaceControl.Transaction t) { 661 try { 662 if (mSurfaceController != null) { 663 mSurfaceController.destroy(t); 664 } 665 } catch (RuntimeException e) { 666 Slog.w(TAG, "Exception thrown when destroying surface " + this 667 + " surface " + mSurfaceController + " session " + mSession + ": " + e); 668 } finally { 669 mWin.setHasSurface(false); 670 mSurfaceController = null; 671 mDrawState = NO_SURFACE; 672 } 673 } 674 getSurfaceControl()675 SurfaceControl getSurfaceControl() { 676 if (!hasSurface()) { 677 return null; 678 } 679 return mSurfaceController.mSurfaceControl; 680 } 681 } 682