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