WindowState.java revision e32c30784191a9244a08450759471c934c85034c
1/*
2 * Copyright (C) 2011 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.FIRST_SUB_WINDOW;
20import static android.view.WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
21import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
22import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
23import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
24import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
25import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
26
27import com.android.server.wm.WindowManagerService.H;
28
29import android.content.res.Configuration;
30import android.graphics.Matrix;
31import android.graphics.PixelFormat;
32import android.graphics.Rect;
33import android.graphics.RectF;
34import android.graphics.Region;
35import android.os.IBinder;
36import android.os.RemoteException;
37import android.util.Slog;
38import android.view.Gravity;
39import android.view.IApplicationToken;
40import android.view.IWindow;
41import android.view.InputChannel;
42import android.view.Surface;
43import android.view.View;
44import android.view.ViewTreeObserver;
45import android.view.WindowManager;
46import android.view.WindowManagerPolicy;
47import android.view.WindowManager.LayoutParams;
48import android.view.animation.Animation;
49import android.view.animation.Transformation;
50
51import java.io.PrintWriter;
52import java.util.ArrayList;
53
54/**
55 * A window in the window manager.
56 */
57final class WindowState implements WindowManagerPolicy.WindowState {
58    static final boolean DEBUG_VISIBILITY = WindowManagerService.DEBUG_VISIBILITY;
59    static final boolean SHOW_TRANSACTIONS = WindowManagerService.SHOW_TRANSACTIONS;
60    static final boolean SHOW_LIGHT_TRANSACTIONS = WindowManagerService.SHOW_LIGHT_TRANSACTIONS;
61    static final boolean SHOW_SURFACE_ALLOC = WindowManagerService.SHOW_SURFACE_ALLOC;
62
63    final WindowManagerService mService;
64    final Session mSession;
65    final IWindow mClient;
66    WindowToken mToken;
67    WindowToken mRootToken;
68    AppWindowToken mAppToken;
69    AppWindowToken mTargetAppToken;
70    final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
71    final DeathRecipient mDeathRecipient;
72    final WindowState mAttachedWindow;
73    final ArrayList<WindowState> mChildWindows = new ArrayList<WindowState>();
74    final int mBaseLayer;
75    final int mSubLayer;
76    final boolean mLayoutAttached;
77    final boolean mIsImWindow;
78    final boolean mIsWallpaper;
79    final boolean mIsFloatingLayer;
80    int mSeq;
81    boolean mEnforceSizeCompat;
82    int mViewVisibility;
83    int mSystemUiVisibility;
84    boolean mPolicyVisibility = true;
85    boolean mPolicyVisibilityAfterAnim = true;
86    boolean mAppFreezing;
87    Surface mSurface;
88    Surface mPendingDestroySurface;
89    boolean mReportDestroySurface;
90    boolean mSurfacePendingDestroy;
91    boolean mAttachedHidden;    // is our parent window hidden?
92    boolean mLastHidden;        // was this window last hidden?
93    boolean mWallpaperVisible;  // for wallpaper, what was last vis report?
94    boolean mWasAnimating;      // Were we animating going into the most recent animation step?
95
96    /**
97     * The window size that was requested by the application.  These are in
98     * the application's coordinate space (without compatibility scale applied).
99     */
100    int mRequestedWidth;
101    int mRequestedHeight;
102    int mLastRequestedWidth;
103    int mLastRequestedHeight;
104
105    int mLayer;
106    int mAnimLayer;
107    int mLastLayer;
108    boolean mHaveFrame;
109    boolean mObscured;
110    boolean mTurnOnScreen;
111
112    int mLayoutSeq = -1;
113
114    Configuration mConfiguration = null;
115
116    /**
117     * Actual frame shown on-screen (may be modified by animation).  These
118     * are in the screen's coordinate space (WITH the compatibility scale
119     * applied).
120     */
121    final RectF mShownFrame = new RectF();
122
123    /**
124     * Set when we have changed the size of the surface, to know that
125     * we must tell them application to resize (and thus redraw itself).
126     */
127    boolean mSurfaceResized;
128
129    /**
130     * Set if the client has asked that the destroy of its surface be delayed
131     * until it explicitly says it is okay.
132     */
133    boolean mSurfaceDestroyDeferred;
134
135    /**
136     * Insets that determine the actually visible area.  These are in the application's
137     * coordinate space (without compatibility scale applied).
138     */
139    final Rect mVisibleInsets = new Rect();
140    final Rect mLastVisibleInsets = new Rect();
141    boolean mVisibleInsetsChanged;
142
143    /**
144     * Insets that are covered by system windows.  These are in the application's
145     * coordinate space (without compatibility scale applied).
146     */
147    final Rect mContentInsets = new Rect();
148    final Rect mLastContentInsets = new Rect();
149    boolean mContentInsetsChanged;
150
151    /**
152     * Set to true if we are waiting for this window to receive its
153     * given internal insets before laying out other windows based on it.
154     */
155    boolean mGivenInsetsPending;
156
157    /**
158     * These are the content insets that were given during layout for
159     * this window, to be applied to windows behind it.
160     */
161    final Rect mGivenContentInsets = new Rect();
162
163    /**
164     * These are the visible insets that were given during layout for
165     * this window, to be applied to windows behind it.
166     */
167    final Rect mGivenVisibleInsets = new Rect();
168
169    /**
170     * This is the given touchable area relative to the window frame, or null if none.
171     */
172    final Region mGivenTouchableRegion = new Region();
173
174    /**
175     * Flag indicating whether the touchable region should be adjusted by
176     * the visible insets; if false the area outside the visible insets is
177     * NOT touchable, so we must use those to adjust the frame during hit
178     * tests.
179     */
180    int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
181
182    // Current transformation being applied.
183    boolean mHaveMatrix;
184    float mGlobalScale=1;
185    float mInvGlobalScale=1;
186    float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
187    float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
188    float mHScale=1, mVScale=1;
189    float mLastHScale=1, mLastVScale=1;
190    final Matrix mTmpMatrix = new Matrix();
191
192    // "Real" frame that the application sees, in display coordinate space.
193    final Rect mFrame = new Rect();
194    final Rect mLastFrame = new Rect();
195    // Frame that is scaled to the application's coordinate space when in
196    // screen size compatibility mode.
197    final Rect mCompatFrame = new Rect();
198
199    final Rect mContainingFrame = new Rect();
200    final Rect mDisplayFrame = new Rect();
201    final Rect mContentFrame = new Rect();
202    final Rect mParentFrame = new Rect();
203    final Rect mVisibleFrame = new Rect();
204
205    boolean mContentChanged;
206
207    float mShownAlpha = 1;
208    float mAlpha = 1;
209    float mLastAlpha = 1;
210
211    // Set to true if, when the window gets displayed, it should perform
212    // an enter animation.
213    boolean mEnterAnimationPending;
214
215    // Currently running animation.
216    boolean mAnimating;
217    boolean mLocalAnimating;
218    Animation mAnimation;
219    boolean mAnimationIsEntrance;
220    boolean mHasTransformation;
221    boolean mHasLocalTransformation;
222    final Transformation mTransformation = new Transformation();
223
224    // If a window showing a wallpaper: the requested offset for the
225    // wallpaper; if a wallpaper window: the currently applied offset.
226    float mWallpaperX = -1;
227    float mWallpaperY = -1;
228
229    // If a window showing a wallpaper: what fraction of the offset
230    // range corresponds to a full virtual screen.
231    float mWallpaperXStep = -1;
232    float mWallpaperYStep = -1;
233
234    // Wallpaper windows: pixels offset based on above variables.
235    int mXOffset;
236    int mYOffset;
237
238    // This is set after IWindowSession.relayout() has been called at
239    // least once for the window.  It allows us to detect the situation
240    // where we don't yet have a surface, but should have one soon, so
241    // we can give the window focus before waiting for the relayout.
242    boolean mRelayoutCalled;
243
244    // If the application has called relayout() with changes that can
245    // impact its window's size, we need to perform a layout pass on it
246    // even if it is not currently visible for layout.  This is set
247    // when in that case until the layout is done.
248    boolean mLayoutNeeded;
249
250    // This is set after the Surface has been created but before the
251    // window has been drawn.  During this time the surface is hidden.
252    boolean mDrawPending;
253
254    // This is set after the window has finished drawing for the first
255    // time but before its surface is shown.  The surface will be
256    // displayed when the next layout is run.
257    boolean mCommitDrawPending;
258
259    // This is set during the time after the window's drawing has been
260    // committed, and before its surface is actually shown.  It is used
261    // to delay showing the surface until all windows in a token are ready
262    // to be shown.
263    boolean mReadyToShow;
264
265    // Set when the window has been shown in the screen the first time.
266    boolean mHasDrawn;
267
268    // Currently running an exit animation?
269    boolean mExiting;
270
271    // Currently on the mDestroySurface list?
272    boolean mDestroying;
273
274    // Completely remove from window manager after exit animation?
275    boolean mRemoveOnExit;
276
277    // Set when the orientation is changing and this window has not yet
278    // been updated for the new orientation.
279    boolean mOrientationChanging;
280
281    // Is this window now (or just being) removed?
282    boolean mRemoved;
283
284    // Temp for keeping track of windows that have been removed when
285    // rebuilding window list.
286    boolean mRebuilding;
287
288    // For debugging, this is the last information given to the surface flinger.
289    boolean mSurfaceShown;
290    float mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
291    int mSurfaceLayer;
292    float mSurfaceAlpha;
293
294    // Input channel and input window handle used by the input dispatcher.
295    final InputWindowHandle mInputWindowHandle;
296    InputChannel mInputChannel;
297
298    // Used to improve performance of toString()
299    String mStringNameCache;
300    CharSequence mLastTitle;
301    boolean mWasPaused;
302
303    // Used to save animation distances between the time they are calculated and when they are
304    // used.
305    int mAnimDw;
306    int mAnimDh;
307
308    static final int ANIM_STATE_IDLE = 0;
309    static final int ANIM_STATE_RUNNING = 1;
310    static final int ANIM_STATE_STOPPING = 2;
311    int mAnimState = ANIM_STATE_IDLE;
312
313    WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
314           WindowState attachedWindow, int seq, WindowManager.LayoutParams a,
315           int viewVisibility) {
316        mService = service;
317        mSession = s;
318        mClient = c;
319        mToken = token;
320        mAttrs.copyFrom(a);
321        mViewVisibility = viewVisibility;
322        DeathRecipient deathRecipient = new DeathRecipient();
323        mAlpha = a.alpha;
324        mSeq = seq;
325        mEnforceSizeCompat = (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0;
326        if (WindowManagerService.localLOGV) Slog.v(
327            WindowManagerService.TAG, "Window " + this + " client=" + c.asBinder()
328            + " token=" + token + " (" + mAttrs.token + ")");
329        try {
330            c.asBinder().linkToDeath(deathRecipient, 0);
331        } catch (RemoteException e) {
332            mDeathRecipient = null;
333            mAttachedWindow = null;
334            mLayoutAttached = false;
335            mIsImWindow = false;
336            mIsWallpaper = false;
337            mIsFloatingLayer = false;
338            mBaseLayer = 0;
339            mSubLayer = 0;
340            mInputWindowHandle = null;
341            return;
342        }
343        mDeathRecipient = deathRecipient;
344
345        if ((mAttrs.type >= FIRST_SUB_WINDOW &&
346                mAttrs.type <= LAST_SUB_WINDOW)) {
347            // The multiplier here is to reserve space for multiple
348            // windows in the same type layer.
349            mBaseLayer = mService.mPolicy.windowTypeToLayerLw(
350                    attachedWindow.mAttrs.type) * WindowManagerService.TYPE_LAYER_MULTIPLIER
351                    + WindowManagerService.TYPE_LAYER_OFFSET;
352            mSubLayer = mService.mPolicy.subWindowTypeToLayerLw(a.type);
353            mAttachedWindow = attachedWindow;
354            if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(WindowManagerService.TAG, "Adding " + this + " to " + mAttachedWindow);
355            mAttachedWindow.mChildWindows.add(this);
356            mLayoutAttached = mAttrs.type !=
357                    WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
358            mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
359                    || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
360            mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER;
361            mIsFloatingLayer = mIsImWindow || mIsWallpaper;
362        } else {
363            // The multiplier here is to reserve space for multiple
364            // windows in the same type layer.
365            mBaseLayer = mService.mPolicy.windowTypeToLayerLw(a.type)
366                    * WindowManagerService.TYPE_LAYER_MULTIPLIER
367                    + WindowManagerService.TYPE_LAYER_OFFSET;
368            mSubLayer = 0;
369            mAttachedWindow = null;
370            mLayoutAttached = false;
371            mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
372                    || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
373            mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
374            mIsFloatingLayer = mIsImWindow || mIsWallpaper;
375        }
376
377        WindowState appWin = this;
378        while (appWin.mAttachedWindow != null) {
379            appWin = mAttachedWindow;
380        }
381        WindowToken appToken = appWin.mToken;
382        while (appToken.appWindowToken == null) {
383            WindowToken parent = mService.mTokenMap.get(appToken.token);
384            if (parent == null || appToken == parent) {
385                break;
386            }
387            appToken = parent;
388        }
389        mRootToken = appToken;
390        mAppToken = appToken.appWindowToken;
391
392        mSurface = null;
393        mRequestedWidth = 0;
394        mRequestedHeight = 0;
395        mLastRequestedWidth = 0;
396        mLastRequestedHeight = 0;
397        mXOffset = 0;
398        mYOffset = 0;
399        mLayer = 0;
400        mAnimLayer = 0;
401        mLastLayer = 0;
402        mInputWindowHandle = new InputWindowHandle(
403                mAppToken != null ? mAppToken.mInputApplicationHandle : null, this);
404    }
405
406    void attach() {
407        if (WindowManagerService.localLOGV) Slog.v(
408            WindowManagerService.TAG, "Attaching " + this + " token=" + mToken
409            + ", list=" + mToken.windows);
410        mSession.windowAddedLocked();
411    }
412
413    public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
414        mHaveFrame = true;
415
416        final Rect container = mContainingFrame;
417        container.set(pf);
418
419        final Rect display = mDisplayFrame;
420        display.set(df);
421
422        final int pw = container.right - container.left;
423        final int ph = container.bottom - container.top;
424
425        int w,h;
426        if ((mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0) {
427            if (mAttrs.width < 0) {
428                w = pw;
429            } else if (mEnforceSizeCompat) {
430                w = (int)(mAttrs.width * mGlobalScale + .5f);
431            } else {
432                w = mAttrs.width;
433            }
434            if (mAttrs.height < 0) {
435                h = ph;
436            } else if (mEnforceSizeCompat) {
437                h = (int)(mAttrs.height * mGlobalScale + .5f);
438            } else {
439                h = mAttrs.height;
440            }
441        } else {
442            if (mAttrs.width == WindowManager.LayoutParams.MATCH_PARENT) {
443                w = pw;
444            } else if (mEnforceSizeCompat) {
445                w = (int)(mRequestedWidth * mGlobalScale + .5f);
446            } else {
447                w = mRequestedWidth;
448            }
449            if (mAttrs.height == WindowManager.LayoutParams.MATCH_PARENT) {
450                h = ph;
451            } else if (mEnforceSizeCompat) {
452                h = (int)(mRequestedHeight * mGlobalScale + .5f);
453            } else {
454                h = mRequestedHeight;
455            }
456        }
457
458        if (!mParentFrame.equals(pf)) {
459            //Slog.i(TAG, "Window " + this + " content frame from " + mParentFrame
460            //        + " to " + pf);
461            mParentFrame.set(pf);
462            mContentChanged = true;
463        }
464        if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) {
465            mLastRequestedWidth = mRequestedWidth;
466            mLastRequestedHeight = mRequestedHeight;
467            mContentChanged = true;
468        }
469
470        final Rect content = mContentFrame;
471        content.set(cf);
472
473        final Rect visible = mVisibleFrame;
474        visible.set(vf);
475
476        final Rect frame = mFrame;
477        final int fw = frame.width();
478        final int fh = frame.height();
479
480        //System.out.println("In: w=" + w + " h=" + h + " container=" +
481        //                   container + " x=" + mAttrs.x + " y=" + mAttrs.y);
482
483        float x, y;
484        if (mEnforceSizeCompat) {
485            x = mAttrs.x * mGlobalScale;
486            y = mAttrs.y * mGlobalScale;
487        } else {
488            x = mAttrs.x;
489            y = mAttrs.y;
490        }
491
492        Gravity.apply(mAttrs.gravity, w, h, container,
493                (int) (x + mAttrs.horizontalMargin * pw),
494                (int) (y + mAttrs.verticalMargin * ph), frame);
495
496        //System.out.println("Out: " + mFrame);
497
498        // Now make sure the window fits in the overall display.
499        Gravity.applyDisplay(mAttrs.gravity, df, frame);
500
501        // Make sure the content and visible frames are inside of the
502        // final window frame.
503        if (content.left < frame.left) content.left = frame.left;
504        if (content.top < frame.top) content.top = frame.top;
505        if (content.right > frame.right) content.right = frame.right;
506        if (content.bottom > frame.bottom) content.bottom = frame.bottom;
507        if (visible.left < frame.left) visible.left = frame.left;
508        if (visible.top < frame.top) visible.top = frame.top;
509        if (visible.right > frame.right) visible.right = frame.right;
510        if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
511
512        final Rect contentInsets = mContentInsets;
513        contentInsets.left = content.left-frame.left;
514        contentInsets.top = content.top-frame.top;
515        contentInsets.right = frame.right-content.right;
516        contentInsets.bottom = frame.bottom-content.bottom;
517
518        final Rect visibleInsets = mVisibleInsets;
519        visibleInsets.left = visible.left-frame.left;
520        visibleInsets.top = visible.top-frame.top;
521        visibleInsets.right = frame.right-visible.right;
522        visibleInsets.bottom = frame.bottom-visible.bottom;
523
524        mCompatFrame.set(frame);
525        if (mEnforceSizeCompat) {
526            // If there is a size compatibility scale being applied to the
527            // window, we need to apply this to its insets so that they are
528            // reported to the app in its coordinate space.
529            contentInsets.scale(mInvGlobalScale);
530            visibleInsets.scale(mInvGlobalScale);
531
532            // Also the scaled frame that we report to the app needs to be
533            // adjusted to be in its coordinate space.
534            mCompatFrame.scale(mInvGlobalScale);
535        }
536
537        if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
538            mService.updateWallpaperOffsetLocked(this,
539                    mService.mAppDisplayWidth, mService.mAppDisplayHeight, false);
540        }
541
542        if (WindowManagerService.localLOGV) {
543            //if ("com.google.android.youtube".equals(mAttrs.packageName)
544            //        && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
545                Slog.v(WindowManagerService.TAG, "Resolving (mRequestedWidth="
546                        + mRequestedWidth + ", mRequestedheight="
547                        + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
548                        + "): frame=" + mFrame.toShortString()
549                        + " ci=" + contentInsets.toShortString()
550                        + " vi=" + visibleInsets.toShortString());
551            //}
552        }
553    }
554
555    public Rect getFrameLw() {
556        return mFrame;
557    }
558
559    public RectF getShownFrameLw() {
560        return mShownFrame;
561    }
562
563    public Rect getDisplayFrameLw() {
564        return mDisplayFrame;
565    }
566
567    public Rect getContentFrameLw() {
568        return mContentFrame;
569    }
570
571    public Rect getVisibleFrameLw() {
572        return mVisibleFrame;
573    }
574
575    public boolean getGivenInsetsPendingLw() {
576        return mGivenInsetsPending;
577    }
578
579    public Rect getGivenContentInsetsLw() {
580        return mGivenContentInsets;
581    }
582
583    public Rect getGivenVisibleInsetsLw() {
584        return mGivenVisibleInsets;
585    }
586
587    public WindowManager.LayoutParams getAttrs() {
588        return mAttrs;
589    }
590
591    public boolean getNeedsMenuLw(WindowManagerPolicy.WindowState bottom) {
592        int index = -1;
593        WindowState ws = this;
594        while (true) {
595            if ((ws.mAttrs.privateFlags
596                    & WindowManager.LayoutParams.PRIVATE_FLAG_SET_NEEDS_MENU_KEY) != 0) {
597                return (ws.mAttrs.flags & WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY) != 0;
598            }
599            // If we reached the bottom of the range of windows we are considering,
600            // assume no menu is needed.
601            if (ws == bottom) {
602                return false;
603            }
604            // The current window hasn't specified whether menu key is needed;
605            // look behind it.
606            // First, we may need to determine the starting position.
607            if (index < 0) {
608                index = mService.mWindows.indexOf(ws);
609            }
610            index--;
611            if (index < 0) {
612                return false;
613            }
614            ws = mService.mWindows.get(index);
615        }
616    }
617
618    public int getSystemUiVisibility() {
619        return mSystemUiVisibility;
620    }
621
622    public int getSurfaceLayer() {
623        return mLayer;
624    }
625
626    public IApplicationToken getAppToken() {
627        return mAppToken != null ? mAppToken.appToken : null;
628    }
629
630    public long getInputDispatchingTimeoutNanos() {
631        return mAppToken != null
632                ? mAppToken.inputDispatchingTimeoutNanos
633                : WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
634    }
635
636    public boolean hasAppShownWindows() {
637        return mAppToken != null ? mAppToken.firstWindowDrawn : false;
638    }
639
640    public void setAnimation(Animation anim) {
641        if (WindowManagerService.localLOGV) Slog.v(
642            WindowManagerService.TAG, "Setting animation in " + this + ": " + anim);
643        mAnimating = false;
644        mLocalAnimating = false;
645        mAnimation = anim;
646        mAnimation.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);
647        mAnimation.scaleCurrentDuration(mService.mWindowAnimationScale);
648    }
649
650    public void clearAnimation() {
651        if (mAnimation != null) {
652            mAnimating = true;
653            mLocalAnimating = false;
654            mAnimation.cancel();
655            mAnimation = null;
656            mAnimState = ANIM_STATE_IDLE;
657        }
658    }
659
660    // TODO: Fix and call finishExit() instead of cancelExitAnimationForNextAnimationLocked()
661    // for avoiding the code duplication.
662    void cancelExitAnimationForNextAnimationLocked() {
663        if (!mExiting) return;
664        if (mAnimation != null) {
665            mAnimation.cancel();
666            mAnimation = null;
667            destroySurfaceLocked();
668            mAnimState = ANIM_STATE_IDLE;
669        }
670        mExiting = false;
671    }
672
673    Surface createSurfaceLocked() {
674        if (mSurface == null) {
675            mReportDestroySurface = false;
676            mSurfacePendingDestroy = false;
677            if (WindowManagerService.DEBUG_ORIENTATION) Slog.i(WindowManagerService.TAG,
678                    "createSurface " + this + ": DRAW NOW PENDING");
679            mDrawPending = true;
680            mCommitDrawPending = false;
681            mReadyToShow = false;
682            if (mAppToken != null) {
683                mAppToken.allDrawn = false;
684            }
685
686            mService.makeWindowFreezingScreenIfNeededLocked(this);
687
688            int flags = 0;
689
690            if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
691                flags |= Surface.SECURE;
692            }
693            if (DEBUG_VISIBILITY) Slog.v(
694                WindowManagerService.TAG, "Creating surface in session "
695                + mSession.mSurfaceSession + " window " + this
696                + " w=" + mCompatFrame.width()
697                + " h=" + mCompatFrame.height() + " format="
698                + mAttrs.format + " flags=" + flags);
699
700            int w = mCompatFrame.width();
701            int h = mCompatFrame.height();
702            if ((mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
703                // for a scaled surface, we always want the requested
704                // size.
705                w = mRequestedWidth;
706                h = mRequestedHeight;
707            }
708
709            // Something is wrong and SurfaceFlinger will not like this,
710            // try to revert to sane values
711            if (w <= 0) w = 1;
712            if (h <= 0) h = 1;
713
714            mSurfaceShown = false;
715            mSurfaceLayer = 0;
716            mSurfaceAlpha = 1;
717            mSurfaceX = 0;
718            mSurfaceY = 0;
719            mSurfaceW = w;
720            mSurfaceH = h;
721            try {
722                final boolean isHwAccelerated = (mAttrs.flags &
723                        WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
724                final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : mAttrs.format;
725                if (!PixelFormat.formatHasAlpha(mAttrs.format)) {
726                    flags |= Surface.OPAQUE;
727                }
728                mSurface = new Surface(
729                        mSession.mSurfaceSession, mSession.mPid,
730                        mAttrs.getTitle().toString(),
731                        0, w, h, format, flags);
732                if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG,
733                        "  CREATE SURFACE "
734                        + mSurface + " IN SESSION "
735                        + mSession.mSurfaceSession
736                        + ": pid=" + mSession.mPid + " format="
737                        + mAttrs.format + " flags=0x"
738                        + Integer.toHexString(flags)
739                        + " / " + this);
740            } catch (Surface.OutOfResourcesException e) {
741                Slog.w(WindowManagerService.TAG, "OutOfResourcesException creating surface");
742                mService.reclaimSomeSurfaceMemoryLocked(this, "create", true);
743                return null;
744            } catch (Exception e) {
745                Slog.e(WindowManagerService.TAG, "Exception creating surface", e);
746                return null;
747            }
748
749            if (WindowManagerService.localLOGV) Slog.v(
750                WindowManagerService.TAG, "Got surface: " + mSurface
751                + ", set left=" + mFrame.left + " top=" + mFrame.top
752                + ", animLayer=" + mAnimLayer);
753            if (SHOW_LIGHT_TRANSACTIONS) {
754                Slog.i(WindowManagerService.TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
755                WindowManagerService.logSurface(this, "CREATE pos=(" + mFrame.left
756                        + "," + mFrame.top + ") (" +
757                        mCompatFrame.width() + "x" + mCompatFrame.height() + "), layer=" +
758                        mAnimLayer + " HIDE", null);
759            }
760            Surface.openTransaction();
761            try {
762                try {
763                    mSurfaceX = mFrame.left + mXOffset;
764                    mSurfaceY = mFrame.top + mYOffset;
765                    mSurface.setPosition(mSurfaceX, mSurfaceY);
766                    mSurfaceLayer = mAnimLayer;
767                    mSurface.setLayer(mAnimLayer);
768                    mSurfaceShown = false;
769                    mSurface.hide();
770                    if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
771                        if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(this, "DITHER", null);
772                        mSurface.setFlags(Surface.SURFACE_DITHER,
773                                Surface.SURFACE_DITHER);
774                    }
775                } catch (RuntimeException e) {
776                    Slog.w(WindowManagerService.TAG, "Error creating surface in " + w, e);
777                    mService.reclaimSomeSurfaceMemoryLocked(this, "create-init", true);
778                }
779                mLastHidden = true;
780            } finally {
781                Surface.closeTransaction();
782                if (SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
783                        "<<< CLOSE TRANSACTION createSurfaceLocked");
784            }
785            if (WindowManagerService.localLOGV) Slog.v(
786                    WindowManagerService.TAG, "Created surface " + this);
787        }
788        return mSurface;
789    }
790
791    void destroySurfaceLocked() {
792        if (mAppToken != null && this == mAppToken.startingWindow) {
793            mAppToken.startingDisplayed = false;
794        }
795
796        if (mSurface != null) {
797            mDrawPending = false;
798            mCommitDrawPending = false;
799            mReadyToShow = false;
800
801            int i = mChildWindows.size();
802            while (i > 0) {
803                i--;
804                WindowState c = mChildWindows.get(i);
805                c.mAttachedHidden = true;
806            }
807
808            if (mReportDestroySurface) {
809                mReportDestroySurface = false;
810                mSurfacePendingDestroy = true;
811                try {
812                    mClient.dispatchGetNewSurface();
813                    // We'll really destroy on the next time around.
814                    return;
815                } catch (RemoteException e) {
816                }
817            }
818
819            try {
820                if (DEBUG_VISIBILITY) {
821                    RuntimeException e = null;
822                    if (!WindowManagerService.HIDE_STACK_CRAWLS) {
823                        e = new RuntimeException();
824                        e.fillInStackTrace();
825                    }
826                    Slog.w(WindowManagerService.TAG, "Window " + this + " destroying surface "
827                            + mSurface + ", session " + mSession, e);
828                }
829                if (mSurfaceDestroyDeferred) {
830                    if (mSurface != null && mPendingDestroySurface != mSurface) {
831                        if (mPendingDestroySurface != null) {
832                            if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
833                                RuntimeException e = null;
834                                if (!WindowManagerService.HIDE_STACK_CRAWLS) {
835                                    e = new RuntimeException();
836                                    e.fillInStackTrace();
837                                }
838                                WindowManagerService.logSurface(this, "DESTROY PENDING", e);
839                            }
840                            mPendingDestroySurface.destroy();
841                        }
842                        mPendingDestroySurface = mSurface;
843                    }
844                } else {
845                    if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
846                        RuntimeException e = null;
847                        if (!WindowManagerService.HIDE_STACK_CRAWLS) {
848                            e = new RuntimeException();
849                            e.fillInStackTrace();
850                        }
851                        WindowManagerService.logSurface(this, "DESTROY", e);
852                    }
853                    mSurface.destroy();
854                }
855            } catch (RuntimeException e) {
856                Slog.w(WindowManagerService.TAG, "Exception thrown when destroying Window " + this
857                    + " surface " + mSurface + " session " + mSession
858                    + ": " + e.toString());
859            }
860
861            mSurfaceShown = false;
862            mSurface = null;
863        }
864    }
865
866    void destroyDeferredSurfaceLocked() {
867        try {
868            if (mPendingDestroySurface != null) {
869                if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
870                    RuntimeException e = null;
871                    if (!WindowManagerService.HIDE_STACK_CRAWLS) {
872                        e = new RuntimeException();
873                        e.fillInStackTrace();
874                    }
875                    mService.logSurface(this, "DESTROY PENDING", e);
876                }
877                mPendingDestroySurface.destroy();
878            }
879        } catch (RuntimeException e) {
880            Slog.w(WindowManagerService.TAG, "Exception thrown when destroying Window "
881                    + this + " surface " + mPendingDestroySurface
882                    + " session " + mSession + ": " + e.toString());
883        }
884        mSurfaceDestroyDeferred = false;
885        mPendingDestroySurface = null;
886    }
887
888    boolean finishDrawingLocked() {
889        if (mDrawPending) {
890            if (SHOW_TRANSACTIONS || WindowManagerService.DEBUG_ORIENTATION) Slog.v(
891                WindowManagerService.TAG, "finishDrawingLocked: " + this + " in " + mSurface);
892            mCommitDrawPending = true;
893            mDrawPending = false;
894            return true;
895        }
896        return false;
897    }
898
899    // This must be called while inside a transaction.
900    boolean commitFinishDrawingLocked(long currentTime) {
901        //Slog.i(TAG, "commitFinishDrawingLocked: " + mSurface);
902        if (!mCommitDrawPending) {
903            return false;
904        }
905        mCommitDrawPending = false;
906        mReadyToShow = true;
907        final boolean starting = mAttrs.type == TYPE_APPLICATION_STARTING;
908        final AppWindowToken atoken = mAppToken;
909        if (atoken == null || atoken.allDrawn || starting) {
910            performShowLocked();
911        }
912        return true;
913    }
914
915    // This must be called while inside a transaction.
916    boolean performShowLocked() {
917        if (DEBUG_VISIBILITY) {
918            RuntimeException e = null;
919            if (!WindowManagerService.HIDE_STACK_CRAWLS) {
920                e = new RuntimeException();
921                e.fillInStackTrace();
922            }
923            Slog.v(WindowManagerService.TAG, "performShow on " + this
924                    + ": readyToShow=" + mReadyToShow + " readyForDisplay=" + isReadyForDisplay()
925                    + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING), e);
926        }
927        if (mReadyToShow && isReadyForDisplay()) {
928            if (SHOW_TRANSACTIONS || WindowManagerService.DEBUG_ORIENTATION) WindowManagerService.logSurface(this,
929                    "SHOW (performShowLocked)", null);
930            if (DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "Showing " + this
931                    + " during animation: policyVis=" + mPolicyVisibility
932                    + " attHidden=" + mAttachedHidden
933                    + " tok.hiddenRequested="
934                    + (mAppToken != null ? mAppToken.hiddenRequested : false)
935                    + " tok.hidden="
936                    + (mAppToken != null ? mAppToken.hidden : false)
937                    + " animating=" + mAnimating
938                    + " tok animating="
939                    + (mAppToken != null ? mAppToken.animating : false));
940            if (!mService.showSurfaceRobustlyLocked(this)) {
941                return false;
942            }
943            mLastAlpha = -1;
944            mHasDrawn = true;
945            mLastHidden = false;
946            mReadyToShow = false;
947            mService.enableScreenIfNeededLocked();
948
949            mService.applyEnterAnimationLocked(this);
950
951            int i = mChildWindows.size();
952            while (i > 0) {
953                i--;
954                WindowState c = mChildWindows.get(i);
955                if (c.mAttachedHidden) {
956                    c.mAttachedHidden = false;
957                    if (c.mSurface != null) {
958                        c.performShowLocked();
959                        // It hadn't been shown, which means layout not
960                        // performed on it, so now we want to make sure to
961                        // do a layout.  If called from within the transaction
962                        // loop, this will cause it to restart with a new
963                        // layout.
964                        mService.mLayoutNeeded = true;
965                    }
966                }
967            }
968
969            if (mAttrs.type != TYPE_APPLICATION_STARTING
970                    && mAppToken != null) {
971                mAppToken.firstWindowDrawn = true;
972
973                if (mAppToken.startingData != null) {
974                    if (WindowManagerService.DEBUG_STARTING_WINDOW || WindowManagerService.DEBUG_ANIM) Slog.v(WindowManagerService.TAG,
975                            "Finish starting " + mToken
976                            + ": first real window is shown, no animation");
977                    // If this initial window is animating, stop it -- we
978                    // will do an animation to reveal it from behind the
979                    // starting window, so there is no need for it to also
980                    // be doing its own stuff.
981                    if (mAnimation != null) {
982                        mAnimation.cancel();
983                        mAnimation = null;
984                        // Make sure we clean up the animation.
985                        mAnimating = true;
986                        mAnimState = ANIM_STATE_IDLE;
987                    }
988                    mService.mFinishedStarting.add(mAppToken);
989                    mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
990                }
991                mAppToken.updateReportedVisibilityLocked();
992            }
993        }
994        return true;
995    }
996
997    private boolean stepAnimation(long currentTime) {
998        if ((mAnimation == null) || !mLocalAnimating || (mAnimState != ANIM_STATE_RUNNING)) {
999            return false;
1000        }
1001        mTransformation.clear();
1002        final boolean more = mAnimation.getTransformation(currentTime, mTransformation);
1003        if (WindowManagerService.DEBUG_ANIM) Slog.v(
1004            WindowManagerService.TAG, "Stepped animation in " + this +
1005            ": more=" + more + ", xform=" + mTransformation);
1006        if (!more) {
1007            mAnimState = ANIM_STATE_STOPPING;
1008        }
1009        return more;
1010    }
1011
1012    // This must be called while inside a transaction.  Returns true if
1013    // there is more animation to run.
1014    boolean stepAnimationLocked(long currentTime) {
1015        // Save the animation state as it was before this step so WindowManagerService can tell if
1016        // we just started or just stopped animating by comparing mWasAnimating with isAnimating().
1017        mWasAnimating = mAnimating;
1018        if (!mService.mDisplayFrozen && mService.mPolicy.isScreenOnFully()) {
1019            // We will run animations as long as the display isn't frozen.
1020
1021            if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
1022                mHasTransformation = true;
1023                mHasLocalTransformation = true;
1024                if (!mLocalAnimating) {
1025                    if (WindowManagerService.DEBUG_ANIM) Slog.v(
1026                        WindowManagerService.TAG, "Starting animation in " + this +
1027                        " @ " + currentTime + ": ww=" + mFrame.width() +
1028                        " wh=" + mFrame.height() +
1029                        " dw=" + mAnimDw + " dh=" + mAnimDh +
1030                        " scale=" + mService.mWindowAnimationScale);
1031                    mAnimation.initialize(mFrame.width(), mFrame.height(), mAnimDw, mAnimDh);
1032                    mAnimation.setStartTime(currentTime);
1033                    mLocalAnimating = true;
1034                    mAnimating = true;
1035                    mAnimState = ANIM_STATE_RUNNING;
1036                }
1037                if ((mAnimation != null) && mLocalAnimating &&
1038                        (mAnimState != ANIM_STATE_STOPPING)) {
1039                    return stepAnimation(currentTime);
1040                }
1041                if (WindowManagerService.DEBUG_ANIM) Slog.v(
1042                    WindowManagerService.TAG, "Finished animation in " + this +
1043                    " @ " + currentTime);
1044                //WindowManagerService.this.dump();
1045            }
1046            mHasLocalTransformation = false;
1047            if ((!mLocalAnimating || mAnimationIsEntrance) && mAppToken != null
1048                    && mAppToken.animation != null) {
1049                // When our app token is animating, we kind-of pretend like
1050                // we are as well.  Note the mLocalAnimating mAnimationIsEntrance
1051                // part of this check means that we will only do this if
1052                // our window is not currently exiting, or it is not
1053                // locally animating itself.  The idea being that one that
1054                // is exiting and doing a local animation should be removed
1055                // once that animation is done.
1056                mAnimating = true;
1057                mHasTransformation = true;
1058                mTransformation.clear();
1059                return false;
1060            } else if (mHasTransformation) {
1061                // Little trick to get through the path below to act like
1062                // we have finished an animation.
1063                mAnimating = true;
1064            } else if (isAnimating()) {
1065                mAnimating = true;
1066            }
1067        } else if (mAnimation != null) {
1068            // If the display is frozen, and there is a pending animation,
1069            // clear it and make sure we run the cleanup code.
1070            mAnimating = true;
1071            mLocalAnimating = true;
1072            mAnimation.cancel();
1073            mAnimation = null;
1074        }
1075
1076        if (!mAnimating && !mLocalAnimating) {
1077            return false;
1078        }
1079
1080        if (WindowManagerService.DEBUG_ANIM) Slog.v(
1081            WindowManagerService.TAG, "Animation done in " + this + ": exiting=" + mExiting
1082            + ", reportedVisible="
1083            + (mAppToken != null ? mAppToken.reportedVisible : false));
1084
1085        mAnimating = false;
1086        mLocalAnimating = false;
1087        if (mAnimation != null) {
1088            mAnimation.cancel();
1089            mAnimation = null;
1090        }
1091        if (mService.mWindowDetachedWallpaper == this) {
1092            mService.mWindowDetachedWallpaper = null;
1093        }
1094        mAnimLayer = mLayer;
1095        if (mIsImWindow) {
1096            mAnimLayer += mService.mInputMethodAnimLayerAdjustment;
1097        } else if (mIsWallpaper) {
1098            mAnimLayer += mService.mWallpaperAnimLayerAdjustment;
1099        }
1100        if (WindowManagerService.DEBUG_LAYERS) Slog.v(WindowManagerService.TAG, "Stepping win " + this
1101                + " anim layer: " + mAnimLayer);
1102        mHasTransformation = false;
1103        mHasLocalTransformation = false;
1104        if (mPolicyVisibility != mPolicyVisibilityAfterAnim) {
1105            if (DEBUG_VISIBILITY) {
1106                Slog.v(WindowManagerService.TAG, "Policy visibility changing after anim in " + this + ": "
1107                        + mPolicyVisibilityAfterAnim);
1108            }
1109            mPolicyVisibility = mPolicyVisibilityAfterAnim;
1110            mService.mLayoutNeeded = true;
1111            if (!mPolicyVisibility) {
1112                if (mService.mCurrentFocus == this) {
1113                    mService.mFocusMayChange = true;
1114                }
1115                // Window is no longer visible -- make sure if we were waiting
1116                // for it to be displayed before enabling the display, that
1117                // we allow the display to be enabled now.
1118                mService.enableScreenIfNeededLocked();
1119            }
1120        }
1121        mTransformation.clear();
1122        if (mHasDrawn
1123                && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
1124                && mAppToken != null
1125                && mAppToken.firstWindowDrawn
1126                && mAppToken.startingData != null) {
1127            if (WindowManagerService.DEBUG_STARTING_WINDOW) Slog.v(WindowManagerService.TAG, "Finish starting "
1128                    + mToken + ": first real window done animating");
1129            mService.mFinishedStarting.add(mAppToken);
1130            mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
1131        }
1132
1133        finishExit();
1134        mService.mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
1135
1136        if (mAppToken != null) {
1137            mAppToken.updateReportedVisibilityLocked();
1138        }
1139
1140        mAnimState = ANIM_STATE_IDLE;
1141        return false;
1142    }
1143
1144    void finishExit() {
1145        if (WindowManagerService.DEBUG_ANIM) Slog.v(
1146                WindowManagerService.TAG, "finishExit in " + this
1147                + ": exiting=" + mExiting
1148                + " remove=" + mRemoveOnExit
1149                + " windowAnimating=" + isWindowAnimating());
1150
1151        final int N = mChildWindows.size();
1152        for (int i=0; i<N; i++) {
1153            mChildWindows.get(i).finishExit();
1154        }
1155
1156        if (!mExiting) {
1157            return;
1158        }
1159
1160        if (isWindowAnimating()) {
1161            return;
1162        }
1163
1164        if (WindowManagerService.localLOGV) Slog.v(
1165                WindowManagerService.TAG, "Exit animation finished in " + this
1166                + ": remove=" + mRemoveOnExit);
1167        if (mSurface != null) {
1168            mService.mDestroySurface.add(this);
1169            mDestroying = true;
1170            if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(this, "HIDE (finishExit)", null);
1171            mSurfaceShown = false;
1172            try {
1173                mSurface.hide();
1174            } catch (RuntimeException e) {
1175                Slog.w(WindowManagerService.TAG, "Error hiding surface in " + this, e);
1176            }
1177            mLastHidden = true;
1178        }
1179        mExiting = false;
1180        if (mRemoveOnExit) {
1181            mService.mPendingRemove.add(this);
1182            mRemoveOnExit = false;
1183        }
1184    }
1185
1186    boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
1187        if (dsdx < .99999f || dsdx > 1.00001f) return false;
1188        if (dtdy < .99999f || dtdy > 1.00001f) return false;
1189        if (dtdx < -.000001f || dtdx > .000001f) return false;
1190        if (dsdy < -.000001f || dsdy > .000001f) return false;
1191        return true;
1192    }
1193
1194    void prelayout() {
1195        if (mEnforceSizeCompat) {
1196            mGlobalScale = mService.mCompatibleScreenScale;
1197            mInvGlobalScale = 1/mGlobalScale;
1198        } else {
1199            mGlobalScale = mInvGlobalScale = 1;
1200        }
1201    }
1202
1203    void computeShownFrameLocked() {
1204        final boolean selfTransformation = mHasLocalTransformation;
1205        Transformation attachedTransformation =
1206                (mAttachedWindow != null && mAttachedWindow.mHasLocalTransformation)
1207                ? mAttachedWindow.mTransformation : null;
1208        Transformation appTransformation =
1209                (mAppToken != null && mAppToken.hasTransformation)
1210                ? mAppToken.transformation : null;
1211
1212        // Wallpapers are animated based on the "real" window they
1213        // are currently targeting.
1214        if (mAttrs.type == TYPE_WALLPAPER && mService.mLowerWallpaperTarget == null
1215                && mService.mWallpaperTarget != null) {
1216            if (mService.mWallpaperTarget.mHasLocalTransformation &&
1217                    mService.mWallpaperTarget.mAnimation != null &&
1218                    !mService.mWallpaperTarget.mAnimation.getDetachWallpaper()) {
1219                attachedTransformation = mService.mWallpaperTarget.mTransformation;
1220                if (WindowManagerService.DEBUG_WALLPAPER && attachedTransformation != null) {
1221                    Slog.v(WindowManagerService.TAG, "WP target attached xform: " + attachedTransformation);
1222                }
1223            }
1224            if (mService.mWallpaperTarget.mAppToken != null &&
1225                    mService.mWallpaperTarget.mAppToken.hasTransformation &&
1226                    mService.mWallpaperTarget.mAppToken.animation != null &&
1227                    !mService.mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) {
1228                appTransformation = mService.mWallpaperTarget.mAppToken.transformation;
1229                if (WindowManagerService.DEBUG_WALLPAPER && appTransformation != null) {
1230                    Slog.v(WindowManagerService.TAG, "WP target app xform: " + appTransformation);
1231                }
1232            }
1233        }
1234
1235        final boolean screenAnimation = mService.mScreenRotationAnimation != null
1236                && mService.mScreenRotationAnimation.isAnimating();
1237        if (selfTransformation || attachedTransformation != null
1238                || appTransformation != null || screenAnimation) {
1239            // cache often used attributes locally
1240            final Rect frame = mFrame;
1241            final float tmpFloats[] = mService.mTmpFloats;
1242            final Matrix tmpMatrix = mTmpMatrix;
1243
1244            // Compute the desired transformation.
1245            if (screenAnimation) {
1246                // If we are doing a screen animation, the global rotation
1247                // applied to windows can result in windows that are carefully
1248                // aligned with each other to slightly separate, allowing you
1249                // to see what is behind them.  An unsightly mess.  This...
1250                // thing...  magically makes it call good: scale each window
1251                // slightly (two pixels larger in each dimension, from the
1252                // window's center).
1253                final float w = frame.width();
1254                final float h = frame.height();
1255                if (w>=1 && h>=1) {
1256                    tmpMatrix.setScale(1 + 2/w, 1 + 2/h, w/2, h/2);
1257                } else {
1258                    tmpMatrix.reset();
1259                }
1260            } else {
1261                tmpMatrix.reset();
1262            }
1263            tmpMatrix.postScale(mGlobalScale, mGlobalScale);
1264            if (selfTransformation) {
1265                tmpMatrix.postConcat(mTransformation.getMatrix());
1266            }
1267            tmpMatrix.postTranslate(frame.left + mXOffset, frame.top + mYOffset);
1268            if (attachedTransformation != null) {
1269                tmpMatrix.postConcat(attachedTransformation.getMatrix());
1270            }
1271            if (appTransformation != null) {
1272                tmpMatrix.postConcat(appTransformation.getMatrix());
1273            }
1274            if (screenAnimation) {
1275                tmpMatrix.postConcat(
1276                        mService.mScreenRotationAnimation.getEnterTransformation().getMatrix());
1277            }
1278
1279            // "convert" it into SurfaceFlinger's format
1280            // (a 2x2 matrix + an offset)
1281            // Here we must not transform the position of the surface
1282            // since it is already included in the transformation.
1283            //Slog.i(TAG, "Transform: " + matrix);
1284
1285            mHaveMatrix = true;
1286            tmpMatrix.getValues(tmpFloats);
1287            mDsDx = tmpFloats[Matrix.MSCALE_X];
1288            mDtDx = tmpFloats[Matrix.MSKEW_Y];
1289            mDsDy = tmpFloats[Matrix.MSKEW_X];
1290            mDtDy = tmpFloats[Matrix.MSCALE_Y];
1291            float x = tmpFloats[Matrix.MTRANS_X];
1292            float y = tmpFloats[Matrix.MTRANS_Y];
1293            int w = frame.width();
1294            int h = frame.height();
1295            mShownFrame.set(x, y, x+w, y+h);
1296
1297            // Now set the alpha...  but because our current hardware
1298            // can't do alpha transformation on a non-opaque surface,
1299            // turn it off if we are running an animation that is also
1300            // transforming since it is more important to have that
1301            // animation be smooth.
1302            mShownAlpha = mAlpha;
1303            if (!mService.mLimitedAlphaCompositing
1304                    || (!PixelFormat.formatHasAlpha(mAttrs.format)
1305                    || (isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
1306                            && x == frame.left && y == frame.top))) {
1307                //Slog.i(TAG, "Applying alpha transform");
1308                if (selfTransformation) {
1309                    mShownAlpha *= mTransformation.getAlpha();
1310                }
1311                if (attachedTransformation != null) {
1312                    mShownAlpha *= attachedTransformation.getAlpha();
1313                }
1314                if (appTransformation != null) {
1315                    mShownAlpha *= appTransformation.getAlpha();
1316                }
1317                if (screenAnimation) {
1318                    mShownAlpha *=
1319                        mService.mScreenRotationAnimation.getEnterTransformation().getAlpha();
1320                }
1321            } else {
1322                //Slog.i(TAG, "Not applying alpha transform");
1323            }
1324
1325            if (WindowManagerService.localLOGV) Slog.v(
1326                WindowManagerService.TAG, "computeShownFrameLocked: Animating " + this +
1327                ": " + mShownFrame +
1328                ", alpha=" + mTransformation.getAlpha() + ", mShownAlpha=" + mShownAlpha);
1329            return;
1330        }
1331
1332        if (WindowManagerService.localLOGV) Slog.v(
1333            WindowManagerService.TAG, "computeShownFrameLocked: " + this +
1334            " not attached, mAlpha=" + mAlpha);
1335        mShownFrame.set(mFrame);
1336        if (mXOffset != 0 || mYOffset != 0) {
1337            mShownFrame.offset(mXOffset, mYOffset);
1338        }
1339        mShownAlpha = mAlpha;
1340        mHaveMatrix = false;
1341        mDsDx = mGlobalScale;
1342        mDtDx = 0;
1343        mDsDy = 0;
1344        mDtDy = mGlobalScale;
1345    }
1346
1347    /**
1348     * Is this window visible?  It is not visible if there is no
1349     * surface, or we are in the process of running an exit animation
1350     * that will remove the surface, or its app token has been hidden.
1351     */
1352    public boolean isVisibleLw() {
1353        final AppWindowToken atoken = mAppToken;
1354        return mSurface != null && mPolicyVisibility && !mAttachedHidden
1355                && (atoken == null || !atoken.hiddenRequested)
1356                && !mExiting && !mDestroying;
1357    }
1358
1359    /**
1360     * Like {@link #isVisibleLw}, but also counts a window that is currently
1361     * "hidden" behind the keyguard as visible.  This allows us to apply
1362     * things like window flags that impact the keyguard.
1363     * XXX I am starting to think we need to have ANOTHER visibility flag
1364     * for this "hidden behind keyguard" state rather than overloading
1365     * mPolicyVisibility.  Ungh.
1366     */
1367    public boolean isVisibleOrBehindKeyguardLw() {
1368        if (mRootToken.waitingToShow &&
1369                mService.mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
1370            return false;
1371        }
1372        final AppWindowToken atoken = mAppToken;
1373        final boolean animating = atoken != null
1374                ? (atoken.animation != null) : false;
1375        return mSurface != null && !mDestroying && !mExiting
1376                && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
1377                && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
1378                                && !mRootToken.hidden)
1379                        || mAnimation != null || animating);
1380    }
1381
1382    /**
1383     * Is this window visible, ignoring its app token?  It is not visible
1384     * if there is no surface, or we are in the process of running an exit animation
1385     * that will remove the surface.
1386     */
1387    public boolean isWinVisibleLw() {
1388        final AppWindowToken atoken = mAppToken;
1389        return mSurface != null && mPolicyVisibility && !mAttachedHidden
1390                && (atoken == null || !atoken.hiddenRequested || atoken.animating)
1391                && !mExiting && !mDestroying;
1392    }
1393
1394    /**
1395     * The same as isVisible(), but follows the current hidden state of
1396     * the associated app token, not the pending requested hidden state.
1397     */
1398    boolean isVisibleNow() {
1399        return mSurface != null && mPolicyVisibility && !mAttachedHidden
1400                && !mRootToken.hidden && !mExiting && !mDestroying;
1401    }
1402
1403    /**
1404     * Can this window possibly be a drag/drop target?  The test here is
1405     * a combination of the above "visible now" with the check that the
1406     * Input Manager uses when discarding windows from input consideration.
1407     */
1408    boolean isPotentialDragTarget() {
1409        return isVisibleNow() && !mRemoved
1410                && mInputChannel != null && mInputWindowHandle != null;
1411    }
1412
1413    /**
1414     * Same as isVisible(), but we also count it as visible between the
1415     * call to IWindowSession.add() and the first relayout().
1416     */
1417    boolean isVisibleOrAdding() {
1418        final AppWindowToken atoken = mAppToken;
1419        return ((mSurface != null && !mReportDestroySurface)
1420                        || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
1421                && mPolicyVisibility && !mAttachedHidden
1422                && (atoken == null || !atoken.hiddenRequested)
1423                && !mExiting && !mDestroying;
1424    }
1425
1426    /**
1427     * Is this window currently on-screen?  It is on-screen either if it
1428     * is visible or it is currently running an animation before no longer
1429     * being visible.
1430     */
1431    boolean isOnScreen() {
1432        final AppWindowToken atoken = mAppToken;
1433        if (atoken != null) {
1434            return mSurface != null && mPolicyVisibility && !mDestroying
1435                    && ((!mAttachedHidden && !atoken.hiddenRequested)
1436                            || mAnimation != null || atoken.animation != null);
1437        } else {
1438            return mSurface != null && mPolicyVisibility && !mDestroying
1439                    && (!mAttachedHidden || mAnimation != null);
1440        }
1441    }
1442
1443    /**
1444     * Like isOnScreen(), but we don't return true if the window is part
1445     * of a transition that has not yet been started.
1446     */
1447    boolean isReadyForDisplay() {
1448        if (mRootToken.waitingToShow &&
1449                mService.mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
1450            return false;
1451        }
1452        return mSurface != null && mPolicyVisibility && !mDestroying
1453                && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
1454                                && !mRootToken.hidden)
1455                        || mAnimation != null
1456                        || ((mAppToken != null) && (mAppToken.animation != null)));
1457    }
1458
1459    /** Is the window or its container currently animating? */
1460    boolean isAnimating() {
1461        final WindowState attached = mAttachedWindow;
1462        final AppWindowToken atoken = mAppToken;
1463        return mAnimation != null
1464                || (attached != null && attached.mAnimation != null)
1465                || (atoken != null &&
1466                        (atoken.animation != null
1467                                || atoken.inPendingTransaction));
1468    }
1469
1470    /** Is this window currently animating? */
1471    boolean isWindowAnimating() {
1472        return mAnimation != null;
1473    }
1474
1475    /**
1476     * Like isOnScreen, but returns false if the surface hasn't yet
1477     * been drawn.
1478     */
1479    public boolean isDisplayedLw() {
1480        final AppWindowToken atoken = mAppToken;
1481        return mSurface != null && mPolicyVisibility && !mDestroying
1482            && !mDrawPending && !mCommitDrawPending
1483            && ((!mAttachedHidden &&
1484                    (atoken == null || !atoken.hiddenRequested))
1485                    || mAnimating);
1486    }
1487
1488    public boolean isGoneForLayoutLw() {
1489        final AppWindowToken atoken = mAppToken;
1490        return mViewVisibility == View.GONE
1491                || !mRelayoutCalled
1492                || (atoken == null && mRootToken.hidden)
1493                || (atoken != null && (atoken.hiddenRequested || atoken.hidden))
1494                || mAttachedHidden
1495                || mExiting || mDestroying;
1496    }
1497
1498    /**
1499     * Returns true if the window has a surface that it has drawn a
1500     * complete UI in to.
1501     */
1502    public boolean isDrawnLw() {
1503        final AppWindowToken atoken = mAppToken;
1504        return mSurface != null && !mDestroying
1505            && !mDrawPending && !mCommitDrawPending;
1506    }
1507
1508    /**
1509     * Return true if the window is opaque and fully drawn.  This indicates
1510     * it may obscure windows behind it.
1511     */
1512    boolean isOpaqueDrawn() {
1513        return (mAttrs.format == PixelFormat.OPAQUE
1514                        || mAttrs.type == TYPE_WALLPAPER)
1515                && mSurface != null && mAnimation == null
1516                && (mAppToken == null || mAppToken.animation == null)
1517                && !mDrawPending && !mCommitDrawPending;
1518    }
1519
1520    /**
1521     * Return whether this window is wanting to have a translation
1522     * animation applied to it for an in-progress move.  (Only makes
1523     * sense to call from performLayoutAndPlaceSurfacesLockedInner().)
1524     */
1525    boolean shouldAnimateMove() {
1526        return mContentChanged && !mExiting && !mLastHidden && !mService.mDisplayFrozen
1527                && (mFrame.top != mLastFrame.top
1528                        || mFrame.left != mLastFrame.left)
1529                && (mAttachedWindow == null || !mAttachedWindow.shouldAnimateMove())
1530                && mService.mPolicy.isScreenOnFully();
1531    }
1532
1533    boolean isFullscreen(int screenWidth, int screenHeight) {
1534        return mFrame.left <= 0 && mFrame.top <= 0 &&
1535                mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
1536    }
1537
1538    void removeLocked() {
1539        disposeInputChannel();
1540
1541        if (mAttachedWindow != null) {
1542            if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(WindowManagerService.TAG, "Removing " + this + " from " + mAttachedWindow);
1543            mAttachedWindow.mChildWindows.remove(this);
1544        }
1545        destroyDeferredSurfaceLocked();
1546        destroySurfaceLocked();
1547        mSession.windowRemovedLocked();
1548        try {
1549            mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
1550        } catch (RuntimeException e) {
1551            // Ignore if it has already been removed (usually because
1552            // we are doing this as part of processing a death note.)
1553        }
1554    }
1555
1556    void setInputChannel(InputChannel inputChannel) {
1557        if (mInputChannel != null) {
1558            throw new IllegalStateException("Window already has an input channel.");
1559        }
1560
1561        mInputChannel = inputChannel;
1562        mInputWindowHandle.inputChannel = inputChannel;
1563    }
1564
1565    void disposeInputChannel() {
1566        if (mInputChannel != null) {
1567            mService.mInputManager.unregisterInputChannel(mInputChannel);
1568
1569            mInputChannel.dispose();
1570            mInputChannel = null;
1571        }
1572
1573        mInputWindowHandle.inputChannel = null;
1574    }
1575
1576    private class DeathRecipient implements IBinder.DeathRecipient {
1577        public void binderDied() {
1578            try {
1579                synchronized(mService.mWindowMap) {
1580                    WindowState win = mService.windowForClientLocked(mSession, mClient, false);
1581                    Slog.i(WindowManagerService.TAG, "WIN DEATH: " + win);
1582                    if (win != null) {
1583                        mService.removeWindowLocked(mSession, win);
1584                    }
1585                }
1586            } catch (IllegalArgumentException ex) {
1587                // This will happen if the window has already been
1588                // removed.
1589            }
1590        }
1591    }
1592
1593    /** Returns true if this window desires key events. */
1594    public final boolean canReceiveKeys() {
1595        return     isVisibleOrAdding()
1596                && (mViewVisibility == View.VISIBLE)
1597                && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0);
1598    }
1599
1600    public boolean hasDrawnLw() {
1601        return mHasDrawn;
1602    }
1603
1604    public boolean showLw(boolean doAnimation) {
1605        return showLw(doAnimation, true);
1606    }
1607
1608    boolean showLw(boolean doAnimation, boolean requestAnim) {
1609        if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
1610            // Already showing.
1611            return false;
1612        }
1613        if (DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "Policy visibility true: " + this);
1614        if (doAnimation) {
1615            if (DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "doAnimation: mPolicyVisibility="
1616                    + mPolicyVisibility + " mAnimation=" + mAnimation);
1617            if (mService.mDisplayFrozen || !mService.mPolicy.isScreenOnFully()) {
1618                doAnimation = false;
1619            } else if (mPolicyVisibility && mAnimation == null) {
1620                // Check for the case where we are currently visible and
1621                // not animating; we do not want to do animation at such a
1622                // point to become visible when we already are.
1623                doAnimation = false;
1624            }
1625        }
1626        mPolicyVisibility = true;
1627        mPolicyVisibilityAfterAnim = true;
1628        if (doAnimation) {
1629            mService.applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
1630        }
1631        if (requestAnim) {
1632            mService.scheduleAnimationLocked();
1633        }
1634        return true;
1635    }
1636
1637    public boolean hideLw(boolean doAnimation) {
1638        return hideLw(doAnimation, true);
1639    }
1640
1641    boolean hideLw(boolean doAnimation, boolean requestAnim) {
1642        if (doAnimation) {
1643            if (mService.mDisplayFrozen || !mService.mPolicy.isScreenOnFully()) {
1644                doAnimation = false;
1645            }
1646        }
1647        boolean current = doAnimation ? mPolicyVisibilityAfterAnim
1648                : mPolicyVisibility;
1649        if (!current) {
1650            // Already hiding.
1651            return false;
1652        }
1653        if (doAnimation) {
1654            mService.applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
1655            if (mAnimation == null) {
1656                doAnimation = false;
1657            }
1658        }
1659        if (doAnimation) {
1660            mPolicyVisibilityAfterAnim = false;
1661        } else {
1662            if (DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "Policy visibility false: " + this);
1663            mPolicyVisibilityAfterAnim = false;
1664            mPolicyVisibility = false;
1665            // Window is no longer visible -- make sure if we were waiting
1666            // for it to be displayed before enabling the display, that
1667            // we allow the display to be enabled now.
1668            mService.enableScreenIfNeededLocked();
1669            if (mService.mCurrentFocus == this) {
1670                mService.mFocusMayChange = true;
1671            }
1672        }
1673        if (requestAnim) {
1674            mService.scheduleAnimationLocked();
1675        }
1676        return true;
1677    }
1678
1679    private static void applyInsets(Region outRegion, Rect frame, Rect inset) {
1680        outRegion.set(
1681                frame.left + inset.left, frame.top + inset.top,
1682                frame.right - inset.right, frame.bottom - inset.bottom);
1683    }
1684
1685    public void getTouchableRegion(Region outRegion) {
1686        final Rect frame = mFrame;
1687        switch (mTouchableInsets) {
1688            default:
1689            case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
1690                outRegion.set(frame);
1691                break;
1692            case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT:
1693                applyInsets(outRegion, frame, mGivenContentInsets);
1694                break;
1695            case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE:
1696                applyInsets(outRegion, frame, mGivenVisibleInsets);
1697                break;
1698            case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION: {
1699                final Region givenTouchableRegion = mGivenTouchableRegion;
1700                outRegion.set(givenTouchableRegion);
1701                outRegion.translate(frame.left, frame.top);
1702                break;
1703            }
1704        }
1705    }
1706
1707    void dump(PrintWriter pw, String prefix, boolean dumpAll) {
1708        pw.print(prefix); pw.print("mSession="); pw.print(mSession);
1709                pw.print(" mClient="); pw.println(mClient.asBinder());
1710        pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
1711        pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
1712                pw.print(" h="); pw.print(mRequestedHeight);
1713                pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
1714        if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) {
1715            pw.print(prefix); pw.print("LastRequested w="); pw.print(mLastRequestedWidth);
1716                    pw.print(" h="); pw.println(mLastRequestedHeight);
1717        }
1718        if (mAttachedWindow != null || mLayoutAttached) {
1719            pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow);
1720                    pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
1721        }
1722        if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
1723            pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
1724                    pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
1725                    pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
1726                    pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
1727        }
1728        if (dumpAll) {
1729            pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
1730                    pw.print(" mSubLayer="); pw.print(mSubLayer);
1731                    pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
1732                    pw.print((mTargetAppToken != null ? mTargetAppToken.animLayerAdjustment
1733                          : (mAppToken != null ? mAppToken.animLayerAdjustment : 0)));
1734                    pw.print("="); pw.print(mAnimLayer);
1735                    pw.print(" mLastLayer="); pw.println(mLastLayer);
1736        }
1737        if (mSurface != null) {
1738            if (dumpAll) {
1739                pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
1740            }
1741            pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
1742                    pw.print(" layer="); pw.print(mSurfaceLayer);
1743                    pw.print(" alpha="); pw.print(mSurfaceAlpha);
1744                    pw.print(" rect=("); pw.print(mSurfaceX);
1745                    pw.print(","); pw.print(mSurfaceY);
1746                    pw.print(") "); pw.print(mSurfaceW);
1747                    pw.print(" x "); pw.println(mSurfaceH);
1748        }
1749        if (mPendingDestroySurface != null) {
1750            pw.print(prefix); pw.print("mPendingDestroySurface=");
1751                    pw.println(mPendingDestroySurface);
1752        }
1753        if (dumpAll) {
1754            pw.print(prefix); pw.print("mToken="); pw.println(mToken);
1755            pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
1756            if (mAppToken != null) {
1757                pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
1758            }
1759            if (mTargetAppToken != null) {
1760                pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken);
1761            }
1762            pw.print(prefix); pw.print("mViewVisibility=0x");
1763            pw.print(Integer.toHexString(mViewVisibility));
1764            pw.print(" mLastHidden="); pw.print(mLastHidden);
1765            pw.print(" mHaveFrame="); pw.print(mHaveFrame);
1766            pw.print(" mObscured="); pw.println(mObscured);
1767            pw.print(prefix); pw.print("mSeq="); pw.print(mSeq);
1768            pw.print(" mSystemUiVisibility=0x");
1769            pw.println(Integer.toHexString(mSystemUiVisibility));
1770        }
1771        if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
1772            pw.print(prefix); pw.print("mPolicyVisibility=");
1773                    pw.print(mPolicyVisibility);
1774                    pw.print(" mPolicyVisibilityAfterAnim=");
1775                    pw.print(mPolicyVisibilityAfterAnim);
1776                    pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
1777        }
1778        if (!mRelayoutCalled || mLayoutNeeded) {
1779            pw.print(prefix); pw.print("mRelayoutCalled="); pw.print(mRelayoutCalled);
1780                    pw.print(" mLayoutNeeded="); pw.println(mLayoutNeeded);
1781        }
1782        if (mSurfaceResized || mSurfaceDestroyDeferred) {
1783            pw.print(prefix); pw.print("mSurfaceResized="); pw.print(mSurfaceResized);
1784                    pw.print(" mSurfaceDestroyDeferred="); pw.println(mSurfaceDestroyDeferred);
1785        }
1786        if (mXOffset != 0 || mYOffset != 0) {
1787            pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
1788                    pw.print(" y="); pw.println(mYOffset);
1789        }
1790        if (dumpAll) {
1791            pw.print(prefix); pw.print("mGivenContentInsets=");
1792                    mGivenContentInsets.printShortString(pw);
1793                    pw.print(" mGivenVisibleInsets=");
1794                    mGivenVisibleInsets.printShortString(pw);
1795                    pw.println();
1796            if (mTouchableInsets != 0 || mGivenInsetsPending) {
1797                pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets);
1798                        pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending);
1799            }
1800            pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
1801        }
1802        pw.print(prefix); pw.print("mShownFrame=");
1803                mShownFrame.printShortString(pw); pw.println();
1804        if (dumpAll) {
1805            pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
1806                    pw.print(" last="); mLastFrame.printShortString(pw);
1807                    pw.println();
1808        }
1809        if (mEnforceSizeCompat) {
1810            pw.print(prefix); pw.print("mCompatFrame="); mCompatFrame.printShortString(pw);
1811                    pw.println();
1812        }
1813        if (dumpAll) {
1814            pw.print(prefix); pw.print("mContainingFrame=");
1815                    mContainingFrame.printShortString(pw);
1816                    pw.print(" mParentFrame=");
1817                    mParentFrame.printShortString(pw);
1818                    pw.print(" mDisplayFrame=");
1819                    mDisplayFrame.printShortString(pw);
1820                    pw.println();
1821            pw.print(prefix); pw.print("mContentFrame="); mContentFrame.printShortString(pw);
1822                    pw.print(" mVisibleFrame="); mVisibleFrame.printShortString(pw);
1823                    pw.println();
1824            pw.print(prefix); pw.print("mContentInsets="); mContentInsets.printShortString(pw);
1825                    pw.print(" last="); mLastContentInsets.printShortString(pw);
1826                    pw.print(" mVisibleInsets="); mVisibleInsets.printShortString(pw);
1827                    pw.print(" last="); mLastVisibleInsets.printShortString(pw);
1828                    pw.println();
1829        }
1830        if (mAnimating || mLocalAnimating || mAnimationIsEntrance
1831                || mAnimation != null) {
1832            pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
1833                    pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
1834                    pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
1835                    pw.print(" mAnimation="); pw.println(mAnimation);
1836        }
1837        if (mHasTransformation || mHasLocalTransformation) {
1838            pw.print(prefix); pw.print("XForm: has=");
1839                    pw.print(mHasTransformation);
1840                    pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
1841                    pw.print(" "); mTransformation.printShortString(pw);
1842                    pw.println();
1843        }
1844        if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
1845            pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
1846                    pw.print(" mAlpha="); pw.print(mAlpha);
1847                    pw.print(" mLastAlpha="); pw.println(mLastAlpha);
1848        }
1849        if (mHaveMatrix || mGlobalScale != 1) {
1850            pw.print(prefix); pw.print("mGlobalScale="); pw.print(mGlobalScale);
1851                    pw.print(" mDsDx="); pw.print(mDsDx);
1852                    pw.print(" mDtDx="); pw.print(mDtDx);
1853                    pw.print(" mDsDy="); pw.print(mDsDy);
1854                    pw.print(" mDtDy="); pw.println(mDtDy);
1855        }
1856        if (dumpAll) {
1857            pw.print(prefix); pw.print("mDrawPending="); pw.print(mDrawPending);
1858                    pw.print(" mCommitDrawPending="); pw.print(mCommitDrawPending);
1859                    pw.print(" mReadyToShow="); pw.print(mReadyToShow);
1860                    pw.print(" mHasDrawn="); pw.println(mHasDrawn);
1861        }
1862        if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
1863            pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
1864                    pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
1865                    pw.print(" mDestroying="); pw.print(mDestroying);
1866                    pw.print(" mRemoved="); pw.println(mRemoved);
1867        }
1868        if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
1869            pw.print(prefix); pw.print("mOrientationChanging=");
1870                    pw.print(mOrientationChanging);
1871                    pw.print(" mAppFreezing="); pw.print(mAppFreezing);
1872                    pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
1873        }
1874        if (mHScale != 1 || mVScale != 1) {
1875            pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
1876                    pw.print(" mVScale="); pw.println(mVScale);
1877        }
1878        if (mWallpaperX != -1 || mWallpaperY != -1) {
1879            pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
1880                    pw.print(" mWallpaperY="); pw.println(mWallpaperY);
1881        }
1882        if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
1883            pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
1884                    pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
1885        }
1886    }
1887
1888    String makeInputChannelName() {
1889        return Integer.toHexString(System.identityHashCode(this))
1890            + " " + mAttrs.getTitle();
1891    }
1892
1893    @Override
1894    public String toString() {
1895        if (mStringNameCache == null || mLastTitle != mAttrs.getTitle()
1896                || mWasPaused != mToken.paused) {
1897            mLastTitle = mAttrs.getTitle();
1898            mWasPaused = mToken.paused;
1899            mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this))
1900                    + " " + mLastTitle + " paused=" + mWasPaused + "}";
1901        }
1902        return mStringNameCache;
1903    }
1904}
1905