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