2 * Copyright (C) 2014 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.server.wm;
19 import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
20 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
21 import static com.android.server.wm.WindowManagerService.DEBUG_ANIM;
22 import static com.android.server.wm.WindowManagerService.DEBUG_LAYERS;
23 import static com.android.server.wm.WindowManagerService.DEBUG_ORIENTATION;
24 import static com.android.server.wm.WindowManagerService.DEBUG_STARTING_WINDOW;
25 import static com.android.server.wm.WindowManagerService.DEBUG_SURFACE_TRACE;
26 import static com.android.server.wm.WindowManagerService.SHOW_TRANSACTIONS;
27 import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
28 import static com.android.server.wm.WindowManagerService.SHOW_LIGHT_TRANSACTIONS;
29 import static com.android.server.wm.WindowManagerService.SHOW_SURFACE_ALLOC;
30 import static com.android.server.wm.WindowManagerService.localLOGV;
31 import static com.android.server.wm.WindowManagerService.LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE;
32 import static com.android.server.wm.WindowManagerService.LayoutFields.SET_TURN_ON_SCREEN;
34 import android.content.Context;
35 import android.graphics.Matrix;
36 import android.graphics.PixelFormat;
37 import android.graphics.Point;
38 import android.graphics.PointF;
39 import android.graphics.Rect;
40 import android.graphics.RectF;
41 import android.graphics.Region;
42 import android.os.Debug;
43 import android.os.RemoteException;
44 import android.os.UserHandle;
45 import android.util.Slog;
46 import android.view.Display;
47 import android.view.DisplayInfo;
48 import android.view.MagnificationSpec;
49 import android.view.Surface.OutOfResourcesException;
50 import android.view.SurfaceControl;
51 import android.view.SurfaceSession;
52 import android.view.View;
53 import android.view.WindowManager;
54 import android.view.WindowManagerPolicy;
55 import android.view.WindowManager.LayoutParams;
56 import android.view.animation.AlphaAnimation;
57 import android.view.animation.Animation;
58 import android.view.animation.AnimationSet;
59 import android.view.animation.AnimationUtils;
60 import android.view.animation.Transformation;
62 import com.android.internal.R;
63 import com.android.server.wm.WindowManagerService.H;
65 import java.io.PrintWriter;
66 import java.util.ArrayList;
68 class WinAnimatorList extends ArrayList<WindowStateAnimator> {
72 * Keep track of animations and surface operations for a single WindowState.
74 class WindowStateAnimator {
75 static final String TAG = "WindowStateAnimator";
77 // Unchanging local convenience fields.
78 final WindowManagerService mService;
79 final WindowState mWin;
80 final WindowStateAnimator mAttachedWinAnimator;
81 final WindowAnimator mAnimator;
82 AppWindowAnimator mAppAnimator;
83 final Session mSession;
84 final WindowManagerPolicy mPolicy;
85 final Context mContext;
86 final boolean mIsWallpaper;
88 // If this is a universe background window, this is the transformation
89 // it is applying to the rest of the universe.
90 final Transformation mUniverseTransform = new Transformation();
92 // Currently running animation.
94 boolean mLocalAnimating;
96 boolean mAnimationIsEntrance;
97 boolean mHasTransformation;
98 boolean mHasLocalTransformation;
99 final Transformation mTransformation = new Transformation();
100 boolean mWasAnimating; // Were we animating going into the most recent animation step?
103 long mAnimationStartTime;
104 long mLastAnimationTime;
106 SurfaceControl mSurfaceControl;
107 SurfaceControl mPendingDestroySurface;
110 * Set when we have changed the size of the surface, to know that
111 * we must tell them application to resize (and thus redraw itself).
113 boolean mSurfaceResized;
116 * Set if the client has asked that the destroy of its surface be delayed
117 * until it explicitly says it is okay.
119 boolean mSurfaceDestroyDeferred;
121 float mShownAlpha = 0;
123 float mLastAlpha = 0;
125 boolean mHasClipRect;
126 Rect mClipRect = new Rect();
127 Rect mTmpClipRect = new Rect();
128 Rect mLastClipRect = new Rect();
130 // Used to save animation distances between the time they are calculated and when they are
134 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
135 float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
139 // For debugging, this is the last information given to the surface flinger.
140 boolean mSurfaceShown;
141 float mSurfaceX, mSurfaceY;
142 float mSurfaceW, mSurfaceH;
146 // Set to true if, when the window gets displayed, it should perform
147 // an enter animation.
148 boolean mEnterAnimationPending;
150 /** Used to indicate that this window is undergoing an enter animation. Used for system
151 * windows to make the callback to View.dispatchOnWindowShownCallback(). Set when the
152 * window is first added or shown, cleared when the callback has been made. */
153 boolean mEnteringAnimation;
155 boolean mKeyguardGoingAwayAnimation;
157 /** This is set when there is no Surface */
158 static final int NO_SURFACE = 0;
159 /** This is set after the Surface has been created but before the window has been drawn. During
160 * this time the surface is hidden. */
161 static final int DRAW_PENDING = 1;
162 /** This is set after the window has finished drawing for the first time but before its surface
163 * is shown. The surface will be displayed when the next layout is run. */
164 static final int COMMIT_DRAW_PENDING = 2;
165 /** This is set during the time after the window's drawing has been committed, and before its
166 * surface is actually shown. It is used to delay showing the surface until all windows in a
167 * token are ready to be shown. */
168 static final int READY_TO_SHOW = 3;
169 /** Set when the window has been shown in the screen the first time. */
170 static final int HAS_DRAWN = 4;
172 private static final int SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN =
173 View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
175 String drawStateToString() {
176 switch (mDrawState) {
177 case NO_SURFACE: return "NO_SURFACE";
178 case DRAW_PENDING: return "DRAW_PENDING";
179 case COMMIT_DRAW_PENDING: return "COMMIT_DRAW_PENDING";
180 case READY_TO_SHOW: return "READY_TO_SHOW";
181 case HAS_DRAWN: return "HAS_DRAWN";
182 default: return Integer.toString(mDrawState);
187 /** Was this window last hidden? */
192 public WindowStateAnimator(final WindowState win) {
193 final WindowManagerService service = win.mService;
196 mAnimator = service.mAnimator;
197 mPolicy = service.mPolicy;
198 mContext = service.mContext;
199 final DisplayContent displayContent = win.getDisplayContent();
200 if (displayContent != null) {
201 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
202 mAnimDw = displayInfo.appWidth;
203 mAnimDh = displayInfo.appHeight;
205 Slog.w(TAG, "WindowStateAnimator ctor: Display has been removed");
206 // This is checked on return and dealt with.
210 mAttachedWinAnimator = win.mAttachedWindow == null
211 ? null : win.mAttachedWindow.mWinAnimator;
212 mAppAnimator = win.mAppToken == null ? null : win.mAppToken.mAppAnimator;
213 mSession = win.mSession;
214 mAttrType = win.mAttrs.type;
215 mIsWallpaper = win.mIsWallpaper;
218 public void setAnimation(Animation anim, long startTime) {
219 if (localLOGV) Slog.v(TAG, "Setting animation in " + this + ": " + anim);
221 mLocalAnimating = false;
223 mAnimation.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);
224 mAnimation.scaleCurrentDuration(mService.getWindowAnimationScaleLocked());
225 // Start out animation gone if window is gone, or visible if window is visible.
226 mTransformation.clear();
227 mTransformation.setAlpha(mLastHidden ? 0 : 1);
228 mHasLocalTransformation = true;
229 mAnimationStartTime = startTime;
232 public void setAnimation(Animation anim) {
233 setAnimation(anim, -1);
236 public void clearAnimation() {
237 if (mAnimation != null) {
239 mLocalAnimating = false;
242 mKeyguardGoingAwayAnimation = false;
246 /** Is the window or its container currently animating? */
247 boolean isAnimating() {
248 return mAnimation != null
249 || (mAttachedWinAnimator != null && mAttachedWinAnimator.mAnimation != null)
250 || (mAppAnimator != null &&
251 (mAppAnimator.animation != null
252 || mAppAnimator.mAppToken.inPendingTransaction));
255 /** Is the window animating the DummyAnimation? */
256 boolean isDummyAnimation() {
257 return mAppAnimator != null
258 && mAppAnimator.animation == AppWindowAnimator.sDummyAnimation;
261 /** Is this window currently animating? */
262 boolean isWindowAnimating() {
263 return mAnimation != null;
266 void cancelExitAnimationForNextAnimationLocked() {
267 if (mAnimation != null) {
270 mLocalAnimating = false;
271 destroySurfaceLocked();
275 private boolean stepAnimation(long currentTime) {
276 if ((mAnimation == null) || !mLocalAnimating) {
279 mTransformation.clear();
280 final boolean more = mAnimation.getTransformation(currentTime, mTransformation);
281 if (false && DEBUG_ANIM) Slog.v(
282 TAG, "Stepped animation in " + this +
283 ": more=" + more + ", xform=" + mTransformation);
287 // This must be called while inside a transaction. Returns true if
288 // there is more animation to run.
289 boolean stepAnimationLocked(long currentTime) {
290 // Save the animation state as it was before this step so WindowManagerService can tell if
291 // we just started or just stopped animating by comparing mWasAnimating with isAnimating().
292 mWasAnimating = mAnimating;
293 final DisplayContent displayContent = mWin.getDisplayContent();
294 if (displayContent != null && mService.okToDisplay()) {
295 // We will run animations as long as the display isn't frozen.
297 if (mWin.isDrawnLw() && mAnimation != null) {
298 mHasTransformation = true;
299 mHasLocalTransformation = true;
300 if (!mLocalAnimating) {
301 if (DEBUG_ANIM) Slog.v(
302 TAG, "Starting animation in " + this +
303 " @ " + currentTime + ": ww=" + mWin.mFrame.width() +
304 " wh=" + mWin.mFrame.height() +
305 " dw=" + mAnimDw + " dh=" + mAnimDh +
306 " scale=" + mService.getWindowAnimationScaleLocked());
307 mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(),
309 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
310 mAnimDw = displayInfo.appWidth;
311 mAnimDh = displayInfo.appHeight;
312 mAnimation.setStartTime(mAnimationStartTime != -1
313 ? mAnimationStartTime
315 mLocalAnimating = true;
318 if ((mAnimation != null) && mLocalAnimating) {
319 mLastAnimationTime = currentTime;
320 if (stepAnimation(currentTime)) {
324 if (DEBUG_ANIM) Slog.v(
325 TAG, "Finished animation in " + this +
326 " @ " + currentTime);
327 //WindowManagerService.this.dump();
329 mHasLocalTransformation = false;
330 if ((!mLocalAnimating || mAnimationIsEntrance) && mAppAnimator != null
331 && mAppAnimator.animation != null) {
332 // When our app token is animating, we kind-of pretend like
333 // we are as well. Note the mLocalAnimating mAnimationIsEntrance
334 // part of this check means that we will only do this if
335 // our window is not currently exiting, or it is not
336 // locally animating itself. The idea being that one that
337 // is exiting and doing a local animation should be removed
338 // once that animation is done.
340 mHasTransformation = true;
341 mTransformation.clear();
343 } else if (mHasTransformation) {
344 // Little trick to get through the path below to act like
345 // we have finished an animation.
347 } else if (isAnimating()) {
350 } else if (mAnimation != null) {
351 // If the display is frozen, and there is a pending animation,
352 // clear it and make sure we run the cleanup code.
356 if (!mAnimating && !mLocalAnimating) {
360 // Done animating, clean up.
361 if (DEBUG_ANIM) Slog.v(
362 TAG, "Animation done in " + this + ": exiting=" + mWin.mExiting
363 + ", reportedVisible="
364 + (mWin.mAppToken != null ? mWin.mAppToken.reportedVisible : false));
367 mKeyguardGoingAwayAnimation = false;
368 mLocalAnimating = false;
369 if (mAnimation != null) {
373 if (mAnimator.mWindowDetachedWallpaper == mWin) {
374 mAnimator.mWindowDetachedWallpaper = null;
376 mAnimLayer = mWin.mLayer;
377 if (mWin.mIsImWindow) {
378 mAnimLayer += mService.mInputMethodAnimLayerAdjustment;
379 } else if (mIsWallpaper) {
380 mAnimLayer += mService.mWallpaperAnimLayerAdjustment;
382 if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
383 + " anim layer: " + mAnimLayer);
384 mHasTransformation = false;
385 mHasLocalTransformation = false;
386 if (mWin.mPolicyVisibility != mWin.mPolicyVisibilityAfterAnim) {
387 if (DEBUG_VISIBILITY) {
388 Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
389 + mWin.mPolicyVisibilityAfterAnim);
391 mWin.mPolicyVisibility = mWin.mPolicyVisibilityAfterAnim;
392 if (displayContent != null) {
393 displayContent.layoutNeeded = true;
395 if (!mWin.mPolicyVisibility) {
396 if (mService.mCurrentFocus == mWin) {
397 if (WindowManagerService.DEBUG_FOCUS_LIGHT) Slog.i(TAG,
398 "setAnimationLocked: setting mFocusMayChange true");
399 mService.mFocusMayChange = true;
401 // Window is no longer visible -- make sure if we were waiting
402 // for it to be displayed before enabling the display, that
403 // we allow the display to be enabled now.
404 mService.enableScreenIfNeededLocked();
407 mTransformation.clear();
408 if (mDrawState == HAS_DRAWN
409 && mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
410 && mWin.mAppToken != null
411 && mWin.mAppToken.firstWindowDrawn
412 && mWin.mAppToken.startingData != null) {
413 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting "
414 + mWin.mToken + ": first real window done animating");
415 mService.mFinishedStarting.add(mWin.mAppToken);
416 mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
417 } else if (mAttrType == LayoutParams.TYPE_STATUS_BAR && mWin.mPolicyVisibility) {
418 // Upon completion of a not-visible to visible status bar animation a relayout is
420 if (displayContent != null) {
421 displayContent.layoutNeeded = true;
426 final int displayId = mWin.getDisplayId();
427 mAnimator.setPendingLayoutChanges(displayId, WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
428 if (WindowManagerService.DEBUG_LAYOUT_REPEATS) mService.debugLayoutRepeats(
429 "WindowStateAnimator", mAnimator.getPendingLayoutChanges(displayId));
431 if (mWin.mAppToken != null) {
432 mWin.mAppToken.updateReportedVisibilityLocked();
439 if (WindowManagerService.DEBUG_ANIM) Slog.v(
440 TAG, "finishExit in " + this
441 + ": exiting=" + mWin.mExiting
442 + " remove=" + mWin.mRemoveOnExit
443 + " windowAnimating=" + isWindowAnimating());
445 final int N = mWin.mChildWindows.size();
446 for (int i=0; i<N; i++) {
447 mWin.mChildWindows.get(i).mWinAnimator.finishExit();
450 if (mEnteringAnimation && mWin.mAppToken == null) {
452 mEnteringAnimation = false;
453 mWin.mClient.dispatchWindowShown();
454 } catch (RemoteException e) {
458 if (!isWindowAnimating()) {
459 //TODO (multidisplay): Accessibility is supported only for the default display.
460 if (mService.mAccessibilityController != null
461 && mWin.getDisplayId() == Display.DEFAULT_DISPLAY) {
462 mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
466 if (!mWin.mExiting) {
470 if (isWindowAnimating()) {
474 if (WindowManagerService.localLOGV) Slog.v(
475 TAG, "Exit animation finished in " + this
476 + ": remove=" + mWin.mRemoveOnExit);
477 if (mSurfaceControl != null) {
478 mService.mDestroySurface.add(mWin);
479 mWin.mDestroying = true;
480 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(
481 mWin, "HIDE (finishExit)", null);
484 mWin.mExiting = false;
485 if (mWin.mRemoveOnExit) {
486 mService.mPendingRemove.add(mWin);
487 mWin.mRemoveOnExit = false;
489 mAnimator.hideWallpapersLocked(mWin);
496 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
497 "HIDE (performLayout)", null);
498 if (mSurfaceControl != null) {
499 mSurfaceShown = false;
501 mSurfaceControl.hide();
502 } catch (RuntimeException e) {
503 Slog.w(TAG, "Exception hiding surface in " + mWin);
509 boolean finishDrawingLocked() {
510 final boolean startingWindow =
511 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
512 if (DEBUG_STARTING_WINDOW && startingWindow) {
513 Slog.v(TAG, "Finishing drawing window " + mWin + ": mDrawState="
514 + drawStateToString());
516 if (mDrawState == DRAW_PENDING) {
517 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
518 Slog.v(TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + this + " in "
520 if (DEBUG_STARTING_WINDOW && startingWindow) {
521 Slog.v(TAG, "Draw state now committed in " + mWin);
523 mDrawState = COMMIT_DRAW_PENDING;
529 // This must be called while inside a transaction.
530 boolean commitFinishDrawingLocked(long currentTime) {
531 if (DEBUG_STARTING_WINDOW &&
532 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
533 Slog.i(TAG, "commitFinishDrawingLocked: " + mWin + " cur mDrawState="
534 + drawStateToString());
536 if (mDrawState != COMMIT_DRAW_PENDING && mDrawState != READY_TO_SHOW) {
539 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM) {
540 Slog.i(TAG, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW " + mSurfaceControl);
542 mDrawState = READY_TO_SHOW;
543 final AppWindowToken atoken = mWin.mAppToken;
544 if (atoken == null || atoken.allDrawn || mWin.mAttrs.type == TYPE_APPLICATION_STARTING) {
545 return performShowLocked();
550 static class SurfaceTrace extends SurfaceControl {
551 private final static String SURFACE_TAG = "SurfaceTrace";
552 private final static boolean logSurfaceTrace = DEBUG_SURFACE_TRACE;
553 final static ArrayList<SurfaceTrace> sSurfaces = new ArrayList<SurfaceTrace>();
555 private float mSurfaceTraceAlpha = 0;
557 private final PointF mPosition = new PointF();
558 private final Point mSize = new Point();
559 private final Rect mWindowCrop = new Rect();
560 private boolean mShown = false;
561 private int mLayerStack;
562 private boolean mIsOpaque;
563 private float mDsdx, mDtdx, mDsdy, mDtdy;
564 private final String mName;
566 public SurfaceTrace(SurfaceSession s,
567 String name, int w, int h, int format, int flags)
568 throws OutOfResourcesException {
569 super(s, name, w, h, format, flags);
570 mName = name != null ? name : "Not named";
572 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
573 + Debug.getCallers(3));
574 synchronized (sSurfaces) {
575 sSurfaces.add(0, this);
580 public void setAlpha(float alpha) {
581 if (mSurfaceTraceAlpha != alpha) {
582 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setAlpha(" + alpha + "): OLD:" + this +
583 ". Called by " + Debug.getCallers(3));
584 mSurfaceTraceAlpha = alpha;
586 super.setAlpha(alpha);
590 public void setLayer(int zorder) {
591 if (zorder != mLayer) {
592 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setLayer(" + zorder + "): OLD:" + this
593 + ". Called by " + Debug.getCallers(3));
596 super.setLayer(zorder);
598 synchronized (sSurfaces) {
599 sSurfaces.remove(this);
601 for (i = sSurfaces.size() - 1; i >= 0; i--) {
602 SurfaceTrace s = sSurfaces.get(i);
603 if (s.mLayer < zorder) {
607 sSurfaces.add(i + 1, this);
612 public void setPosition(float x, float y) {
613 if (x != mPosition.x || y != mPosition.y) {
614 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setPosition(" + x + "," + y + "): OLD:"
615 + this + ". Called by " + Debug.getCallers(3));
618 super.setPosition(x, y);
622 public void setSize(int w, int h) {
623 if (w != mSize.x || h != mSize.y) {
624 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setSize(" + w + "," + h + "): OLD:"
625 + this + ". Called by " + Debug.getCallers(3));
632 public void setWindowCrop(Rect crop) {
634 if (!crop.equals(mWindowCrop)) {
635 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setWindowCrop("
636 + crop.toShortString() + "): OLD:" + this + ". Called by "
637 + Debug.getCallers(3));
638 mWindowCrop.set(crop);
641 super.setWindowCrop(crop);
645 public void setLayerStack(int layerStack) {
646 if (layerStack != mLayerStack) {
647 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setLayerStack(" + layerStack + "): OLD:"
648 + this + ". Called by " + Debug.getCallers(3));
649 mLayerStack = layerStack;
651 super.setLayerStack(layerStack);
655 public void setOpaque(boolean isOpaque) {
656 if (isOpaque != mIsOpaque) {
657 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setOpaque(" + isOpaque + "): OLD:"
658 + this + ". Called by " + Debug.getCallers(3));
659 mIsOpaque = isOpaque;
661 super.setOpaque(isOpaque);
665 public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
666 if (dsdx != mDsdx || dtdx != mDtdx || dsdy != mDsdy || dtdy != mDtdy) {
667 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setMatrix(" + dsdx + "," + dtdx + ","
668 + dsdy + "," + dtdy + "): OLD:" + this + ". Called by "
669 + Debug.getCallers(3));
675 super.setMatrix(dsdx, dtdx, dsdy, dtdy);
681 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "hide: OLD:" + this + ". Called by "
682 + Debug.getCallers(3));
691 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "show: OLD:" + this + ". Called by "
692 + Debug.getCallers(3));
699 public void destroy() {
701 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by "
702 + Debug.getCallers(3));
703 synchronized (sSurfaces) {
704 sSurfaces.remove(this);
709 public void release() {
711 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "release: " + this + ". Called by "
712 + Debug.getCallers(3));
713 synchronized (sSurfaces) {
714 sSurfaces.remove(this);
718 static void dumpAllSurfaces(PrintWriter pw, String header) {
719 synchronized (sSurfaces) {
720 final int N = sSurfaces.size();
724 if (header != null) {
727 pw.println("WINDOW MANAGER SURFACES (dumpsys window surfaces)");
728 for (int i = 0; i < N; i++) {
729 SurfaceTrace s = sSurfaces.get(i);
730 pw.print(" Surface #"); pw.print(i); pw.print(": #");
731 pw.print(Integer.toHexString(System.identityHashCode(s)));
732 pw.print(" "); pw.println(s.mName);
733 pw.print(" mLayerStack="); pw.print(s.mLayerStack);
734 pw.print(" mLayer="); pw.println(s.mLayer);
735 pw.print(" mShown="); pw.print(s.mShown); pw.print(" mAlpha=");
736 pw.print(s.mSurfaceTraceAlpha); pw.print(" mIsOpaque=");
737 pw.println(s.mIsOpaque);
738 pw.print(" mPosition="); pw.print(s.mPosition.x); pw.print(",");
739 pw.print(s.mPosition.y);
740 pw.print(" mSize="); pw.print(s.mSize.x); pw.print("x");
741 pw.println(s.mSize.y);
742 pw.print(" mCrop="); s.mWindowCrop.printShortString(pw); pw.println();
743 pw.print(" Transform: ("); pw.print(s.mDsdx); pw.print(", ");
744 pw.print(s.mDtdx); pw.print(", "); pw.print(s.mDsdy);
745 pw.print(", "); pw.print(s.mDtdy); pw.println(")");
751 public String toString() {
752 return "Surface " + Integer.toHexString(System.identityHashCode(this)) + " "
753 + mName + " (" + mLayerStack + "): shown=" + mShown + " layer=" + mLayer
754 + " alpha=" + mSurfaceTraceAlpha + " " + mPosition.x + "," + mPosition.y
755 + " " + mSize.x + "x" + mSize.y
756 + " crop=" + mWindowCrop.toShortString()
757 + " opaque=" + mIsOpaque
758 + " (" + mDsdx + "," + mDtdx + "," + mDsdy + "," + mDtdy + ")";
762 SurfaceControl createSurfaceLocked() {
763 final WindowState w = mWin;
764 if (mSurfaceControl == null) {
765 if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG,
766 "createSurface " + this + ": mDrawState=DRAW_PENDING");
767 mDrawState = DRAW_PENDING;
768 if (w.mAppToken != null) {
769 if (w.mAppToken.mAppAnimator.animation == null) {
770 w.mAppToken.allDrawn = false;
771 w.mAppToken.deferClearAllDrawn = false;
773 // Currently animating, persist current state of allDrawn until animation
775 w.mAppToken.deferClearAllDrawn = true;
779 mService.makeWindowFreezingScreenIfNeededLocked(w);
781 int flags = SurfaceControl.HIDDEN;
782 final WindowManager.LayoutParams attrs = w.mAttrs;
784 if ((attrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
785 flags |= SurfaceControl.SECURE;
788 if (mService.isScreenCaptureDisabledLocked(UserHandle.getUserId(mWin.mOwnerUid))) {
789 flags |= SurfaceControl.SECURE;
794 if ((attrs.flags & LayoutParams.FLAG_SCALED) != 0) {
795 // for a scaled surface, we always want the requested
797 width = w.mRequestedWidth;
798 height = w.mRequestedHeight;
800 width = w.mCompatFrame.width();
801 height = w.mCompatFrame.height();
804 // Something is wrong and SurfaceFlinger will not like this,
805 // try to revert to sane values
813 float left = w.mFrame.left + w.mXOffset;
814 float top = w.mFrame.top + w.mYOffset;
816 // Adjust for surface insets.
817 width += attrs.surfaceInsets.left + attrs.surfaceInsets.right;
818 height += attrs.surfaceInsets.top + attrs.surfaceInsets.bottom;
819 left -= attrs.surfaceInsets.left;
820 top -= attrs.surfaceInsets.top;
822 if (DEBUG_VISIBILITY) {
823 Slog.v(TAG, "Creating surface in session "
824 + mSession.mSurfaceSession + " window " + this
825 + " w=" + width + " h=" + height
826 + " x=" + left + " y=" + top
827 + " format=" + attrs.format + " flags=" + flags);
830 // We may abort, so initialize to defaults.
831 mSurfaceShown = false;
836 w.mLastSystemDecorRect.set(0, 0, 0, 0);
837 mLastClipRect.set(0, 0, 0, 0);
839 // Set up surface control with initial size.
844 final boolean isHwAccelerated = (attrs.flags &
845 WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
846 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
847 if (!PixelFormat.formatHasAlpha(attrs.format)
848 && attrs.surfaceInsets.left == 0
849 && attrs.surfaceInsets.top == 0
850 && attrs.surfaceInsets.right == 0
851 && attrs.surfaceInsets.bottom == 0) {
852 flags |= SurfaceControl.OPAQUE;
855 if (DEBUG_SURFACE_TRACE) {
856 mSurfaceControl = new SurfaceTrace(
857 mSession.mSurfaceSession,
858 attrs.getTitle().toString(),
859 width, height, format, flags);
861 mSurfaceControl = new SurfaceControl(
862 mSession.mSurfaceSession,
863 attrs.getTitle().toString(),
864 width, height, format, flags);
867 w.mHasSurface = true;
869 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
870 Slog.i(TAG, " CREATE SURFACE "
871 + mSurfaceControl + " IN SESSION "
872 + mSession.mSurfaceSession
873 + ": pid=" + mSession.mPid + " format="
874 + attrs.format + " flags=0x"
875 + Integer.toHexString(flags)
878 } catch (OutOfResourcesException e) {
879 w.mHasSurface = false;
880 Slog.w(TAG, "OutOfResourcesException creating surface");
881 mService.reclaimSomeSurfaceMemoryLocked(this, "create", true);
882 mDrawState = NO_SURFACE;
884 } catch (Exception e) {
885 w.mHasSurface = false;
886 Slog.e(TAG, "Exception creating surface", e);
887 mDrawState = NO_SURFACE;
891 if (WindowManagerService.localLOGV) {
892 Slog.v(TAG, "Got surface: " + mSurfaceControl
893 + ", set left=" + w.mFrame.left + " top=" + w.mFrame.top
894 + ", animLayer=" + mAnimLayer);
897 if (SHOW_LIGHT_TRANSACTIONS) {
898 Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
899 WindowManagerService.logSurface(w, "CREATE pos=("
900 + w.mFrame.left + "," + w.mFrame.top + ") ("
901 + w.mCompatFrame.width() + "x" + w.mCompatFrame.height()
902 + "), layer=" + mAnimLayer + " HIDE", null);
905 // Start a new transaction and apply position & offset.
906 SurfaceControl.openTransaction();
912 mSurfaceControl.setPosition(left, top);
913 mSurfaceLayer = mAnimLayer;
914 final DisplayContent displayContent = w.getDisplayContent();
915 if (displayContent != null) {
916 mSurfaceControl.setLayerStack(displayContent.getDisplay().getLayerStack());
918 mSurfaceControl.setLayer(mAnimLayer);
919 mSurfaceControl.setAlpha(0);
920 mSurfaceShown = false;
921 } catch (RuntimeException e) {
922 Slog.w(TAG, "Error creating surface in " + w, e);
923 mService.reclaimSomeSurfaceMemoryLocked(this, "create-init", true);
927 SurfaceControl.closeTransaction();
928 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
929 "<<< CLOSE TRANSACTION createSurfaceLocked");
931 if (WindowManagerService.localLOGV) Slog.v(
932 TAG, "Created surface " + this);
934 return mSurfaceControl;
937 void destroySurfaceLocked() {
938 if (mWin.mAppToken != null && mWin == mWin.mAppToken.startingWindow) {
939 mWin.mAppToken.startingDisplayed = false;
942 if (mSurfaceControl != null) {
944 int i = mWin.mChildWindows.size();
947 WindowState c = mWin.mChildWindows.get(i);
948 c.mAttachedHidden = true;
952 if (DEBUG_VISIBILITY) {
953 RuntimeException e = null;
954 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
955 e = new RuntimeException();
956 e.fillInStackTrace();
958 Slog.w(TAG, "Window " + this + " destroying surface "
959 + mSurfaceControl + ", session " + mSession, e);
961 if (mSurfaceDestroyDeferred) {
962 if (mSurfaceControl != null && mPendingDestroySurface != mSurfaceControl) {
963 if (mPendingDestroySurface != null) {
964 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
965 RuntimeException e = null;
966 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
967 e = new RuntimeException();
968 e.fillInStackTrace();
970 WindowManagerService.logSurface(mWin, "DESTROY PENDING", e);
972 mPendingDestroySurface.destroy();
974 mPendingDestroySurface = mSurfaceControl;
977 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
978 RuntimeException e = null;
979 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
980 e = new RuntimeException();
981 e.fillInStackTrace();
983 WindowManagerService.logSurface(mWin, "DESTROY", e);
985 mSurfaceControl.destroy();
987 mAnimator.hideWallpapersLocked(mWin);
988 } catch (RuntimeException e) {
989 Slog.w(TAG, "Exception thrown when destroying Window " + this
990 + " surface " + mSurfaceControl + " session " + mSession
991 + ": " + e.toString());
994 mSurfaceShown = false;
995 mSurfaceControl = null;
996 mWin.mHasSurface = false;
997 mDrawState = NO_SURFACE;
1001 void destroyDeferredSurfaceLocked() {
1003 if (mPendingDestroySurface != null) {
1004 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
1005 RuntimeException e = null;
1006 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
1007 e = new RuntimeException();
1008 e.fillInStackTrace();
1010 WindowManagerService.logSurface(mWin, "DESTROY PENDING", e);
1012 mPendingDestroySurface.destroy();
1013 mAnimator.hideWallpapersLocked(mWin);
1015 } catch (RuntimeException e) {
1016 Slog.w(TAG, "Exception thrown when destroying Window "
1017 + this + " surface " + mPendingDestroySurface
1018 + " session " + mSession + ": " + e.toString());
1020 mSurfaceDestroyDeferred = false;
1021 mPendingDestroySurface = null;
1024 void computeShownFrameLocked() {
1025 final boolean selfTransformation = mHasLocalTransformation;
1026 Transformation attachedTransformation =
1027 (mAttachedWinAnimator != null && mAttachedWinAnimator.mHasLocalTransformation)
1028 ? mAttachedWinAnimator.mTransformation : null;
1029 Transformation appTransformation = (mAppAnimator != null && mAppAnimator.hasTransformation)
1030 ? mAppAnimator.transformation : null;
1032 // Wallpapers are animated based on the "real" window they
1033 // are currently targeting.
1034 final WindowState wallpaperTarget = mService.mWallpaperTarget;
1035 if (mIsWallpaper && wallpaperTarget != null && mService.mAnimateWallpaperWithTarget) {
1036 final WindowStateAnimator wallpaperAnimator = wallpaperTarget.mWinAnimator;
1037 if (wallpaperAnimator.mHasLocalTransformation &&
1038 wallpaperAnimator.mAnimation != null &&
1039 !wallpaperAnimator.mAnimation.getDetachWallpaper()) {
1040 attachedTransformation = wallpaperAnimator.mTransformation;
1041 if (WindowManagerService.DEBUG_WALLPAPER && attachedTransformation != null) {
1042 Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
1045 final AppWindowAnimator wpAppAnimator = wallpaperTarget.mAppToken == null ?
1046 null : wallpaperTarget.mAppToken.mAppAnimator;
1047 if (wpAppAnimator != null && wpAppAnimator.hasTransformation
1048 && wpAppAnimator.animation != null
1049 && !wpAppAnimator.animation.getDetachWallpaper()) {
1050 appTransformation = wpAppAnimator.transformation;
1051 if (WindowManagerService.DEBUG_WALLPAPER && appTransformation != null) {
1052 Slog.v(TAG, "WP target app xform: " + appTransformation);
1057 final int displayId = mWin.getDisplayId();
1058 final ScreenRotationAnimation screenRotationAnimation =
1059 mAnimator.getScreenRotationAnimationLocked(displayId);
1060 final boolean screenAnimation =
1061 screenRotationAnimation != null && screenRotationAnimation.isAnimating();
1062 if (selfTransformation || attachedTransformation != null
1063 || appTransformation != null || screenAnimation) {
1064 // cache often used attributes locally
1065 final Rect frame = mWin.mFrame;
1066 final float tmpFloats[] = mService.mTmpFloats;
1067 final Matrix tmpMatrix = mWin.mTmpMatrix;
1069 // Compute the desired transformation.
1070 if (screenAnimation && screenRotationAnimation.isRotating()) {
1071 // If we are doing a screen animation, the global rotation
1072 // applied to windows can result in windows that are carefully
1073 // aligned with each other to slightly separate, allowing you
1074 // to see what is behind them. An unsightly mess. This...
1075 // thing... magically makes it call good: scale each window
1076 // slightly (two pixels larger in each dimension, from the
1077 // window's center).
1078 final float w = frame.width();
1079 final float h = frame.height();
1081 tmpMatrix.setScale(1 + 2/w, 1 + 2/h, w/2, h/2);
1088 tmpMatrix.postScale(mWin.mGlobalScale, mWin.mGlobalScale);
1089 if (selfTransformation) {
1090 tmpMatrix.postConcat(mTransformation.getMatrix());
1092 tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
1093 if (attachedTransformation != null) {
1094 tmpMatrix.postConcat(attachedTransformation.getMatrix());
1096 if (appTransformation != null) {
1097 tmpMatrix.postConcat(appTransformation.getMatrix());
1099 if (mAnimator.mUniverseBackground != null) {
1100 tmpMatrix.postConcat(mAnimator.mUniverseBackground.mUniverseTransform.getMatrix());
1102 if (screenAnimation) {
1103 tmpMatrix.postConcat(screenRotationAnimation.getEnterTransformation().getMatrix());
1106 //TODO (multidisplay): Magnification is supported only for the default display.
1107 if (mService.mAccessibilityController != null && displayId == Display.DEFAULT_DISPLAY) {
1108 MagnificationSpec spec = mService.mAccessibilityController
1109 .getMagnificationSpecForWindowLocked(mWin);
1110 if (spec != null && !spec.isNop()) {
1111 tmpMatrix.postScale(spec.scale, spec.scale);
1112 tmpMatrix.postTranslate(spec.offsetX, spec.offsetY);
1116 // "convert" it into SurfaceFlinger's format
1117 // (a 2x2 matrix + an offset)
1118 // Here we must not transform the position of the surface
1119 // since it is already included in the transformation.
1120 //Slog.i(TAG, "Transform: " + matrix);
1123 tmpMatrix.getValues(tmpFloats);
1124 mDsDx = tmpFloats[Matrix.MSCALE_X];
1125 mDtDx = tmpFloats[Matrix.MSKEW_Y];
1126 mDsDy = tmpFloats[Matrix.MSKEW_X];
1127 mDtDy = tmpFloats[Matrix.MSCALE_Y];
1128 float x = tmpFloats[Matrix.MTRANS_X];
1129 float y = tmpFloats[Matrix.MTRANS_Y];
1130 int w = frame.width();
1131 int h = frame.height();
1132 mWin.mShownFrame.set(x, y, x+w, y+h);
1134 // Now set the alpha... but because our current hardware
1135 // can't do alpha transformation on a non-opaque surface,
1136 // turn it off if we are running an animation that is also
1137 // transforming since it is more important to have that
1138 // animation be smooth.
1139 mShownAlpha = mAlpha;
1140 mHasClipRect = false;
1141 if (!mService.mLimitedAlphaCompositing
1142 || (!PixelFormat.formatHasAlpha(mWin.mAttrs.format)
1143 || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
1144 && x == frame.left && y == frame.top))) {
1145 //Slog.i(TAG, "Applying alpha transform");
1146 if (selfTransformation) {
1147 mShownAlpha *= mTransformation.getAlpha();
1149 if (attachedTransformation != null) {
1150 mShownAlpha *= attachedTransformation.getAlpha();
1152 if (appTransformation != null) {
1153 mShownAlpha *= appTransformation.getAlpha();
1154 if (appTransformation.hasClipRect()) {
1155 mClipRect.set(appTransformation.getClipRect());
1156 if (mWin.mHScale > 0) {
1157 mClipRect.left /= mWin.mHScale;
1158 mClipRect.right /= mWin.mHScale;
1160 if (mWin.mVScale > 0) {
1161 mClipRect.top /= mWin.mVScale;
1162 mClipRect.bottom /= mWin.mVScale;
1164 mHasClipRect = true;
1167 if (mAnimator.mUniverseBackground != null) {
1168 mShownAlpha *= mAnimator.mUniverseBackground.mUniverseTransform.getAlpha();
1170 if (screenAnimation) {
1171 mShownAlpha *= screenRotationAnimation.getEnterTransformation().getAlpha();
1174 //Slog.i(TAG, "Not applying alpha transform");
1177 if ((DEBUG_SURFACE_TRACE || WindowManagerService.localLOGV)
1178 && (mShownAlpha == 1.0 || mShownAlpha == 0.0)) Slog.v(
1179 TAG, "computeShownFrameLocked: Animating " + this + " mAlpha=" + mAlpha
1180 + " self=" + (selfTransformation ? mTransformation.getAlpha() : "null")
1181 + " attached=" + (attachedTransformation == null ?
1182 "null" : attachedTransformation.getAlpha())
1183 + " app=" + (appTransformation == null ? "null" : appTransformation.getAlpha())
1184 + " screen=" + (screenAnimation ?
1185 screenRotationAnimation.getEnterTransformation().getAlpha() : "null"));
1187 } else if (mIsWallpaper && mService.mInnerFields.mWallpaperActionPending) {
1191 if (WindowManagerService.localLOGV) Slog.v(
1192 TAG, "computeShownFrameLocked: " + this +
1193 " not attached, mAlpha=" + mAlpha);
1195 final boolean applyUniverseTransformation = (mAnimator.mUniverseBackground != null
1196 && mWin.mAttrs.type != WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND
1197 && mWin.mBaseLayer < mAnimator.mAboveUniverseLayer);
1198 MagnificationSpec spec = null;
1199 //TODO (multidisplay): Magnification is supported only for the default display.
1200 if (mService.mAccessibilityController != null && displayId == Display.DEFAULT_DISPLAY) {
1201 spec = mService.mAccessibilityController.getMagnificationSpecForWindowLocked(mWin);
1203 if (applyUniverseTransformation || spec != null) {
1204 final Rect frame = mWin.mFrame;
1205 final float tmpFloats[] = mService.mTmpFloats;
1206 final Matrix tmpMatrix = mWin.mTmpMatrix;
1208 tmpMatrix.setScale(mWin.mGlobalScale, mWin.mGlobalScale);
1209 tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
1211 if (applyUniverseTransformation) {
1212 tmpMatrix.postConcat(mAnimator.mUniverseBackground.mUniverseTransform.getMatrix());
1215 if (spec != null && !spec.isNop()) {
1216 tmpMatrix.postScale(spec.scale, spec.scale);
1217 tmpMatrix.postTranslate(spec.offsetX, spec.offsetY);
1220 tmpMatrix.getValues(tmpFloats);
1223 mDsDx = tmpFloats[Matrix.MSCALE_X];
1224 mDtDx = tmpFloats[Matrix.MSKEW_Y];
1225 mDsDy = tmpFloats[Matrix.MSKEW_X];
1226 mDtDy = tmpFloats[Matrix.MSCALE_Y];
1227 float x = tmpFloats[Matrix.MTRANS_X];
1228 float y = tmpFloats[Matrix.MTRANS_Y];
1229 int w = frame.width();
1230 int h = frame.height();
1231 mWin.mShownFrame.set(x, y, x + w, y + h);
1233 mShownAlpha = mAlpha;
1234 if (applyUniverseTransformation) {
1235 mShownAlpha *= mAnimator.mUniverseBackground.mUniverseTransform.getAlpha();
1238 mWin.mShownFrame.set(mWin.mFrame);
1239 if (mWin.mXOffset != 0 || mWin.mYOffset != 0) {
1240 mWin.mShownFrame.offset(mWin.mXOffset, mWin.mYOffset);
1242 mShownAlpha = mAlpha;
1243 mHaveMatrix = false;
1244 mDsDx = mWin.mGlobalScale;
1247 mDtDy = mWin.mGlobalScale;
1251 void applyDecorRect(final Rect decorRect) {
1252 final WindowState w = mWin;
1253 final int width = w.mFrame.width();
1254 final int height = w.mFrame.height();
1256 // Compute the offset of the window in relation to the decor rect.
1257 final int left = w.mXOffset + w.mFrame.left;
1258 final int top = w.mYOffset + w.mFrame.top;
1260 // Initialize the decor rect to the entire frame.
1261 w.mSystemDecorRect.set(0, 0, width, height);
1263 // Intersect with the decor rect, offsetted by window position.
1264 w.mSystemDecorRect.intersect(decorRect.left - left, decorRect.top - top,
1265 decorRect.right - left, decorRect.bottom - top);
1267 // If size compatibility is being applied to the window, the
1268 // surface is scaled relative to the screen. Also apply this
1269 // scaling to the crop rect. We aren't using the standard rect
1270 // scale function because we want to round things to make the crop
1271 // always round to a larger rect to ensure we don't crop too
1272 // much and hide part of the window that should be seen.
1273 if (w.mEnforceSizeCompat && w.mInvGlobalScale != 1.0f) {
1274 final float scale = w.mInvGlobalScale;
1275 w.mSystemDecorRect.left = (int) (w.mSystemDecorRect.left * scale - 0.5f);
1276 w.mSystemDecorRect.top = (int) (w.mSystemDecorRect.top * scale - 0.5f);
1277 w.mSystemDecorRect.right = (int) ((w.mSystemDecorRect.right+1) * scale - 0.5f);
1278 w.mSystemDecorRect.bottom = (int) ((w.mSystemDecorRect.bottom+1) * scale - 0.5f);
1282 void updateSurfaceWindowCrop(final boolean recoveringMemory) {
1283 final WindowState w = mWin;
1284 final DisplayContent displayContent = w.getDisplayContent();
1285 if (displayContent == null) {
1289 // Need to recompute a new system decor rect each time.
1290 if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
1291 // Currently can't do this cropping for scaled windows. We'll
1292 // just keep the crop rect the same as the source surface.
1293 w.mSystemDecorRect.set(0, 0, w.mRequestedWidth, w.mRequestedHeight);
1294 } else if (!w.isDefaultDisplay()) {
1295 // On a different display there is no system decor. Crop the window
1296 // by the screen boundaries.
1297 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
1298 w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
1299 w.mSystemDecorRect.intersect(-w.mCompatFrame.left, -w.mCompatFrame.top,
1300 displayInfo.logicalWidth - w.mCompatFrame.left,
1301 displayInfo.logicalHeight - w.mCompatFrame.top);
1302 } else if (w.mLayer >= mService.mSystemDecorLayer) {
1303 // Above the decor layer is easy, just use the entire window.
1304 // Unless we have a universe background... in which case all the
1305 // windows need to be cropped by the screen, so they don't cover
1306 // the universe background.
1307 if (mAnimator.mUniverseBackground == null) {
1308 w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
1310 applyDecorRect(mService.mScreenRect);
1312 } else if (w.mAttrs.type == WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND
1313 || w.mDecorFrame.isEmpty()) {
1314 // The universe background isn't cropped, nor windows without policy decor.
1315 w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
1316 } else if (w.mAttrs.type == LayoutParams.TYPE_WALLPAPER && mAnimator.mAnimating) {
1317 // If we're animating, the wallpaper crop should only be updated at the end of the
1319 mTmpClipRect.set(w.mSystemDecorRect);
1320 applyDecorRect(w.mDecorFrame);
1321 w.mSystemDecorRect.union(mTmpClipRect);
1323 // Crop to the system decor specified by policy.
1324 applyDecorRect(w.mDecorFrame);
1327 // By default, the clip rect is the system decor.
1328 final Rect clipRect = mTmpClipRect;
1329 clipRect.set(w.mSystemDecorRect);
1331 // Expand the clip rect for surface insets.
1332 final WindowManager.LayoutParams attrs = w.mAttrs;
1333 clipRect.left -= attrs.surfaceInsets.left;
1334 clipRect.top -= attrs.surfaceInsets.top;
1335 clipRect.right += attrs.surfaceInsets.right;
1336 clipRect.bottom += attrs.surfaceInsets.bottom;
1338 // If we have an animated clip rect, intersect it with the clip rect.
1340 // NOTE: We are adding a temporary workaround due to the status bar
1341 // not always reporting the correct system decor rect. In such
1342 // cases, we take into account the specified content insets as well.
1343 if ((w.mSystemUiVisibility & SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN)
1344 == SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN
1345 || (w.mAttrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0) {
1346 // Don't apply the workaround to apps explicitly requesting
1347 // fullscreen layout or when the bars are transparent.
1348 clipRect.intersect(mClipRect);
1350 final int offsetTop = Math.max(clipRect.top, w.mContentInsets.top);
1351 clipRect.offset(0, -offsetTop);
1352 clipRect.intersect(mClipRect);
1353 clipRect.offset(0, offsetTop);
1357 // The clip rect was generated assuming (0,0) as the window origin,
1358 // so we need to translate to match the actual surface coordinates.
1359 clipRect.offset(attrs.surfaceInsets.left, attrs.surfaceInsets.top);
1361 if (!clipRect.equals(mLastClipRect)) {
1362 mLastClipRect.set(clipRect);
1364 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
1365 "CROP " + clipRect.toShortString(), null);
1366 mSurfaceControl.setWindowCrop(clipRect);
1367 } catch (RuntimeException e) {
1368 Slog.w(TAG, "Error setting crop surface of " + w
1369 + " crop=" + clipRect.toShortString(), e);
1370 if (!recoveringMemory) {
1371 mService.reclaimSomeSurfaceMemoryLocked(this, "crop", true);
1377 void setSurfaceBoundariesLocked(final boolean recoveringMemory) {
1378 final WindowState w = mWin;
1382 if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
1383 // for a scaled surface, we always want the requested
1385 width = w.mRequestedWidth;
1386 height = w.mRequestedHeight;
1388 width = w.mCompatFrame.width();
1389 height = w.mCompatFrame.height();
1392 // Something is wrong and SurfaceFlinger will not like this,
1393 // try to revert to sane values
1401 float left = w.mShownFrame.left;
1402 float top = w.mShownFrame.top;
1404 // Adjust for surface insets.
1405 final LayoutParams attrs = w.getAttrs();
1406 width += attrs.surfaceInsets.left + attrs.surfaceInsets.right;
1407 height += attrs.surfaceInsets.top + attrs.surfaceInsets.bottom;
1408 left -= attrs.surfaceInsets.left;
1409 top -= attrs.surfaceInsets.top;
1411 final boolean surfaceMoved = mSurfaceX != left || mSurfaceY != top;
1417 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
1418 "POS " + left + ", " + top, null);
1419 mSurfaceControl.setPosition(left, top);
1420 } catch (RuntimeException e) {
1421 Slog.w(TAG, "Error positioning surface of " + w
1422 + " pos=(" + left + "," + top + ")", e);
1423 if (!recoveringMemory) {
1424 mService.reclaimSomeSurfaceMemoryLocked(this, "position", true);
1429 final boolean surfaceResized = mSurfaceW != width || mSurfaceH != height;
1430 if (surfaceResized) {
1433 mSurfaceResized = true;
1436 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
1437 "SIZE " + width + "x" + height, null);
1438 mSurfaceControl.setSize(width, height);
1439 mAnimator.setPendingLayoutChanges(w.getDisplayId(),
1440 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
1441 if ((w.mAttrs.flags & LayoutParams.FLAG_DIM_BEHIND) != 0) {
1442 final TaskStack stack = w.getStack();
1443 if (stack != null) {
1444 stack.startDimmingIfNeeded(this);
1447 } catch (RuntimeException e) {
1448 // If something goes wrong with the surface (such
1449 // as running out of memory), don't take down the
1451 Slog.e(TAG, "Error resizing surface of " + w
1452 + " size=(" + width + "x" + height + ")", e);
1453 if (!recoveringMemory) {
1454 mService.reclaimSomeSurfaceMemoryLocked(this, "size", true);
1459 updateSurfaceWindowCrop(recoveringMemory);
1462 public void prepareSurfaceLocked(final boolean recoveringMemory) {
1463 final WindowState w = mWin;
1464 if (mSurfaceControl == null) {
1465 if (w.mOrientationChanging) {
1466 if (DEBUG_ORIENTATION) {
1467 Slog.v(TAG, "Orientation change skips hidden " + w);
1469 w.mOrientationChanging = false;
1474 boolean displayed = false;
1476 computeShownFrameLocked();
1478 setSurfaceBoundariesLocked(recoveringMemory);
1480 if (mIsWallpaper && !mWin.mWallpaperVisible) {
1481 // Wallpaper is no longer visible and there is no wp target => hide it.
1483 } else if (w.mAttachedHidden || !w.isOnScreen()) {
1485 mAnimator.hideWallpapersLocked(w);
1487 // If we are waiting for this window to handle an
1488 // orientation change, well, it is hidden, so
1489 // doesn't really matter. Note that this does
1490 // introduce a potential glitch if the window
1491 // becomes unhidden before it has drawn for the
1493 if (w.mOrientationChanging) {
1494 w.mOrientationChanging = false;
1495 if (DEBUG_ORIENTATION) Slog.v(TAG,
1496 "Orientation change skips hidden " + w);
1498 } else if (mLastLayer != mAnimLayer
1499 || mLastAlpha != mShownAlpha
1500 || mLastDsDx != mDsDx
1501 || mLastDtDx != mDtDx
1502 || mLastDsDy != mDsDy
1503 || mLastDtDy != mDtDy
1504 || w.mLastHScale != w.mHScale
1505 || w.mLastVScale != w.mVScale
1508 mLastAlpha = mShownAlpha;
1509 mLastLayer = mAnimLayer;
1514 w.mLastHScale = w.mHScale;
1515 w.mLastVScale = w.mVScale;
1516 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
1517 "alpha=" + mShownAlpha + " layer=" + mAnimLayer
1518 + " matrix=[" + mDsDx + "*" + w.mHScale
1519 + "," + mDtDx + "*" + w.mVScale
1520 + "][" + mDsDy + "*" + w.mHScale
1521 + "," + mDtDy + "*" + w.mVScale + "]", null);
1522 if (mSurfaceControl != null) {
1524 mSurfaceAlpha = mShownAlpha;
1525 mSurfaceControl.setAlpha(mShownAlpha);
1526 mSurfaceLayer = mAnimLayer;
1527 mSurfaceControl.setLayer(mAnimLayer);
1528 mSurfaceControl.setMatrix(
1529 mDsDx * w.mHScale, mDtDx * w.mVScale,
1530 mDsDy * w.mHScale, mDtDy * w.mVScale);
1532 if (mLastHidden && mDrawState == HAS_DRAWN) {
1533 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
1534 "SHOW (performLayout)", null);
1535 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
1536 + " during relayout");
1537 if (showSurfaceRobustlyLocked()) {
1538 mLastHidden = false;
1540 mService.dispatchWallpaperVisibility(w, true);
1542 // This draw means the difference between unique content and mirroring.
1543 // Run another pass through performLayout to set mHasContent in the
1545 mAnimator.setPendingLayoutChanges(w.getDisplayId(),
1546 WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
1548 w.mOrientationChanging = false;
1551 if (mSurfaceControl != null) {
1552 w.mToken.hasVisible = true;
1554 } catch (RuntimeException e) {
1555 Slog.w(TAG, "Error updating surface in " + w, e);
1556 if (!recoveringMemory) {
1557 mService.reclaimSomeSurfaceMemoryLocked(this, "update", true);
1562 if (DEBUG_ANIM && isAnimating()) {
1563 Slog.v(TAG, "prepareSurface: No changes in animation for " + this);
1569 if (w.mOrientationChanging) {
1570 if (!w.isDrawnLw()) {
1571 mAnimator.mBulkUpdateParams &= ~SET_ORIENTATION_CHANGE_COMPLETE;
1572 mAnimator.mLastWindowFreezeSource = w;
1573 if (DEBUG_ORIENTATION) Slog.v(TAG,
1574 "Orientation continue waiting for draw in " + w);
1576 w.mOrientationChanging = false;
1577 if (DEBUG_ORIENTATION) Slog.v(TAG, "Orientation change complete in " + w);
1580 w.mToken.hasVisible = true;
1584 void setTransparentRegionHintLocked(final Region region) {
1585 if (mSurfaceControl == null) {
1586 Slog.w(TAG, "setTransparentRegionHint: null mSurface after mHasSurface true");
1589 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setTransparentRegion");
1590 SurfaceControl.openTransaction();
1592 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
1593 "transparentRegionHint=" + region, null);
1594 mSurfaceControl.setTransparentRegionHint(region);
1596 SurfaceControl.closeTransaction();
1597 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1598 "<<< CLOSE TRANSACTION setTransparentRegion");
1602 void setWallpaperOffset(RectF shownFrame) {
1603 final LayoutParams attrs = mWin.getAttrs();
1604 final int left = ((int) shownFrame.left) - attrs.surfaceInsets.left;
1605 final int top = ((int) shownFrame.top) - attrs.surfaceInsets.top;
1606 if (mSurfaceX != left || mSurfaceY != top) {
1610 // If this window (or its app token) is animating, then the position
1611 // of the surface will be re-computed on the next animation frame.
1612 // We can't poke it directly here because it depends on whatever
1613 // transformation is being applied by the animation.
1616 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setWallpaperOffset");
1617 SurfaceControl.openTransaction();
1619 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
1620 "POS " + left + ", " + top, null);
1621 mSurfaceControl.setPosition(mWin.mFrame.left + left, mWin.mFrame.top + top);
1622 updateSurfaceWindowCrop(false);
1623 } catch (RuntimeException e) {
1624 Slog.w(TAG, "Error positioning surface of " + mWin
1625 + " pos=(" + left + "," + top + ")", e);
1627 SurfaceControl.closeTransaction();
1628 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1629 "<<< CLOSE TRANSACTION setWallpaperOffset");
1634 void setOpaqueLocked(boolean isOpaque) {
1635 if (mSurfaceControl == null) {
1638 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setOpaqueLocked");
1639 SurfaceControl.openTransaction();
1641 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, "isOpaque=" + isOpaque,
1643 mSurfaceControl.setOpaque(isOpaque);
1645 SurfaceControl.closeTransaction();
1646 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setOpaqueLocked");
1650 // This must be called while inside a transaction.
1651 boolean performShowLocked() {
1652 if (mWin.isHiddenFromUserLocked()) {
1655 if (DEBUG_VISIBILITY || (DEBUG_STARTING_WINDOW &&
1656 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING)) {
1657 RuntimeException e = null;
1658 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
1659 e = new RuntimeException();
1660 e.fillInStackTrace();
1662 Slog.v(TAG, "performShow on " + this
1663 + ": mDrawState=" + mDrawState + " readyForDisplay="
1664 + mWin.isReadyForDisplayIgnoringKeyguard()
1665 + " starting=" + (mWin.mAttrs.type == TYPE_APPLICATION_STARTING)
1666 + " during animation: policyVis=" + mWin.mPolicyVisibility
1667 + " attHidden=" + mWin.mAttachedHidden
1668 + " tok.hiddenRequested="
1669 + (mWin.mAppToken != null ? mWin.mAppToken.hiddenRequested : false)
1671 + (mWin.mAppToken != null ? mWin.mAppToken.hidden : false)
1672 + " animating=" + mAnimating
1674 + (mAppAnimator != null ? mAppAnimator.animating : false), e);
1676 if (mDrawState == READY_TO_SHOW && mWin.isReadyForDisplayIgnoringKeyguard()) {
1677 if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
1678 WindowManagerService.logSurface(mWin, "SHOW (performShowLocked)", null);
1679 if (DEBUG_VISIBILITY || (DEBUG_STARTING_WINDOW &&
1680 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING)) {
1681 Slog.v(TAG, "Showing " + this
1682 + " during animation: policyVis=" + mWin.mPolicyVisibility
1683 + " attHidden=" + mWin.mAttachedHidden
1684 + " tok.hiddenRequested="
1685 + (mWin.mAppToken != null ? mWin.mAppToken.hiddenRequested : false)
1687 + (mWin.mAppToken != null ? mWin.mAppToken.hidden : false)
1688 + " animating=" + mAnimating
1690 + (mAppAnimator != null ? mAppAnimator.animating : false));
1693 mService.enableScreenIfNeededLocked();
1695 applyEnterAnimationLocked();
1697 // Force the show in the next prepareSurfaceLocked() call.
1699 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM)
1700 Slog.v(TAG, "performShowLocked: mDrawState=HAS_DRAWN in " + this);
1701 mDrawState = HAS_DRAWN;
1702 mService.scheduleAnimationLocked();
1704 int i = mWin.mChildWindows.size();
1707 WindowState c = mWin.mChildWindows.get(i);
1708 if (c.mAttachedHidden) {
1709 c.mAttachedHidden = false;
1710 if (c.mWinAnimator.mSurfaceControl != null) {
1711 c.mWinAnimator.performShowLocked();
1712 // It hadn't been shown, which means layout not
1713 // performed on it, so now we want to make sure to
1714 // do a layout. If called from within the transaction
1715 // loop, this will cause it to restart with a new
1717 final DisplayContent displayContent = c.getDisplayContent();
1718 if (displayContent != null) {
1719 displayContent.layoutNeeded = true;
1725 if (mWin.mAttrs.type != TYPE_APPLICATION_STARTING
1726 && mWin.mAppToken != null) {
1727 mWin.mAppToken.firstWindowDrawn = true;
1729 if (mWin.mAppToken.startingData != null) {
1730 if (WindowManagerService.DEBUG_STARTING_WINDOW ||
1731 WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
1732 "Finish starting " + mWin.mToken
1733 + ": first real window is shown, no animation");
1734 // If this initial window is animating, stop it -- we
1735 // will do an animation to reveal it from behind the
1736 // starting window, so there is no need for it to also
1737 // be doing its own stuff.
1739 mService.mFinishedStarting.add(mWin.mAppToken);
1740 mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
1742 mWin.mAppToken.updateReportedVisibilityLocked();
1752 * Have the surface flinger show a surface, robustly dealing with
1753 * error conditions. In particular, if there is not enough memory
1754 * to show the surface, then we will try to get rid of other surfaces
1755 * in order to succeed.
1757 * @return Returns true if the surface was successfully shown.
1759 boolean showSurfaceRobustlyLocked() {
1761 if (mSurfaceControl != null) {
1762 mSurfaceShown = true;
1763 mSurfaceControl.show();
1764 if (mWin.mTurnOnScreen) {
1765 if (DEBUG_VISIBILITY) Slog.v(TAG,
1766 "Show surface turning screen on: " + mWin);
1767 mWin.mTurnOnScreen = false;
1768 mAnimator.mBulkUpdateParams |= SET_TURN_ON_SCREEN;
1772 } catch (RuntimeException e) {
1773 Slog.w(TAG, "Failure showing surface " + mSurfaceControl + " in " + mWin, e);
1776 mService.reclaimSomeSurfaceMemoryLocked(this, "show", true);
1781 void applyEnterAnimationLocked() {
1783 if (mEnterAnimationPending) {
1784 mEnterAnimationPending = false;
1785 transit = WindowManagerPolicy.TRANSIT_ENTER;
1787 transit = WindowManagerPolicy.TRANSIT_SHOW;
1789 applyAnimationLocked(transit, true);
1790 //TODO (multidisplay): Magnification is supported only for the default display.
1791 if (mService.mAccessibilityController != null
1792 && mWin.getDisplayId() == Display.DEFAULT_DISPLAY) {
1793 mService.mAccessibilityController.onWindowTransitionLocked(mWin, transit);
1798 * Choose the correct animation and set it to the passed WindowState.
1799 * @param transit If AppTransition.TRANSIT_PREVIEW_DONE and the app window has been drawn
1800 * then the animation will be app_starting_exit. Any other value loads the animation from
1801 * the switch statement below.
1802 * @param isEntrance The animation type the last time this was called. Used to keep from
1803 * loading the same animation twice.
1804 * @return true if an animation has been loaded.
1806 boolean applyAnimationLocked(int transit, boolean isEntrance) {
1807 if ((mLocalAnimating && mAnimationIsEntrance == isEntrance)
1808 || mKeyguardGoingAwayAnimation) {
1809 // If we are trying to apply an animation, but already running
1810 // an animation of the same type, then just leave that one alone.
1812 // If we are in a keyguard exit animation, and the window should animate away, modify
1813 // keyguard exit animation such that it also fades out.
1814 if (mAnimation != null && mKeyguardGoingAwayAnimation
1815 && transit == WindowManagerPolicy.TRANSIT_PREVIEW_DONE) {
1816 applyFadeoutDuringKeyguardExitAnimation();
1821 // Only apply an animation if the display isn't frozen. If it is
1822 // frozen, there is no reason to animate and it can cause strange
1823 // artifacts when we unfreeze the display if some different animation
1825 if (mService.okToDisplay()) {
1826 int anim = mPolicy.selectAnimationLw(mWin, transit);
1830 a = anim != -1 ? AnimationUtils.loadAnimation(mContext, anim) : null;
1833 case WindowManagerPolicy.TRANSIT_ENTER:
1834 attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
1836 case WindowManagerPolicy.TRANSIT_EXIT:
1837 attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
1839 case WindowManagerPolicy.TRANSIT_SHOW:
1840 attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
1842 case WindowManagerPolicy.TRANSIT_HIDE:
1843 attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
1847 a = mService.mAppTransition.loadAnimationAttr(mWin.mAttrs, attr);
1850 if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
1851 "applyAnimation: win=" + this
1852 + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
1854 + " transit=" + transit
1855 + " isEntrance=" + isEntrance + " Callers " + Debug.getCallers(3));
1857 if (WindowManagerService.DEBUG_ANIM) {
1858 RuntimeException e = null;
1859 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
1860 e = new RuntimeException();
1861 e.fillInStackTrace();
1863 Slog.v(TAG, "Loaded animation " + a + " for " + this, e);
1866 mAnimationIsEntrance = isEntrance;
1872 return mAnimation != null;
1875 private void applyFadeoutDuringKeyguardExitAnimation() {
1876 long startTime = mAnimation.getStartTime();
1877 long duration = mAnimation.getDuration();
1878 long elapsed = mLastAnimationTime - startTime;
1879 long fadeDuration = duration - elapsed;
1880 if (fadeDuration <= 0) {
1881 // Never mind, this would be no visible animation, so abort the animation change.
1884 AnimationSet newAnimation = new AnimationSet(false /* shareInterpolator */);
1885 newAnimation.setDuration(duration);
1886 newAnimation.setStartTime(startTime);
1887 newAnimation.addAnimation(mAnimation);
1888 Animation fadeOut = AnimationUtils.loadAnimation(
1889 mContext, com.android.internal.R.anim.app_starting_exit);
1890 fadeOut.setDuration(fadeDuration);
1891 fadeOut.setStartOffset(elapsed);
1892 newAnimation.addAnimation(fadeOut);
1893 newAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(), mAnimDw, mAnimDh);
1894 mAnimation = newAnimation;
1897 public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
1898 if (mAnimating || mLocalAnimating || mAnimationIsEntrance
1899 || mAnimation != null) {
1900 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
1901 pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
1902 pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
1903 pw.print(" mAnimation="); pw.println(mAnimation);
1905 if (mHasTransformation || mHasLocalTransformation) {
1906 pw.print(prefix); pw.print("XForm: has=");
1907 pw.print(mHasTransformation);
1908 pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
1909 pw.print(" "); mTransformation.printShortString(pw);
1912 if (mSurfaceControl != null) {
1914 pw.print(prefix); pw.print("mSurface="); pw.println(mSurfaceControl);
1915 pw.print(prefix); pw.print("mDrawState=");
1916 pw.print(drawStateToString());
1917 pw.print(" mLastHidden="); pw.println(mLastHidden);
1919 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
1920 pw.print(" layer="); pw.print(mSurfaceLayer);
1921 pw.print(" alpha="); pw.print(mSurfaceAlpha);
1922 pw.print(" rect=("); pw.print(mSurfaceX);
1923 pw.print(","); pw.print(mSurfaceY);
1924 pw.print(") "); pw.print(mSurfaceW);
1925 pw.print(" x "); pw.println(mSurfaceH);
1927 if (mPendingDestroySurface != null) {
1928 pw.print(prefix); pw.print("mPendingDestroySurface=");
1929 pw.println(mPendingDestroySurface);
1931 if (mSurfaceResized || mSurfaceDestroyDeferred) {
1932 pw.print(prefix); pw.print("mSurfaceResized="); pw.print(mSurfaceResized);
1933 pw.print(" mSurfaceDestroyDeferred="); pw.println(mSurfaceDestroyDeferred);
1935 if (mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND) {
1936 pw.print(prefix); pw.print("mUniverseTransform=");
1937 mUniverseTransform.printShortString(pw);
1940 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
1941 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
1942 pw.print(" mAlpha="); pw.print(mAlpha);
1943 pw.print(" mLastAlpha="); pw.println(mLastAlpha);
1945 if (mHaveMatrix || mWin.mGlobalScale != 1) {
1946 pw.print(prefix); pw.print("mGlobalScale="); pw.print(mWin.mGlobalScale);
1947 pw.print(" mDsDx="); pw.print(mDsDx);
1948 pw.print(" mDtDx="); pw.print(mDtDx);
1949 pw.print(" mDsDy="); pw.print(mDsDy);
1950 pw.print(" mDtDy="); pw.println(mDtDy);
1955 public String toString() {
1956 StringBuffer sb = new StringBuffer("WindowStateAnimator{");
1957 sb.append(Integer.toHexString(System.identityHashCode(this)));
1959 sb.append(mWin.mAttrs.getTitle());
1961 return sb.toString();