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