WindowState.java revision fa25bf5382467b1018bd9af7f1cb30a23d7d59f7
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_INPUT_METHOD;
23import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
24import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
25
26import com.android.server.input.InputWindowHandle;
27
28import android.content.Context;
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.View;
43import android.view.ViewTreeObserver;
44import android.view.WindowManager;
45import android.view.WindowManagerPolicy;
46
47import java.io.PrintWriter;
48import java.util.ArrayList;
49
50/**
51 * A window in the window manager.
52 */
53final class WindowState implements WindowManagerPolicy.WindowState {
54    static final String TAG = "WindowState";
55
56    static final boolean DEBUG_VISIBILITY = WindowManagerService.DEBUG_VISIBILITY;
57    static final boolean SHOW_TRANSACTIONS = WindowManagerService.SHOW_TRANSACTIONS;
58    static final boolean SHOW_LIGHT_TRANSACTIONS = WindowManagerService.SHOW_LIGHT_TRANSACTIONS;
59    static final boolean SHOW_SURFACE_ALLOC = WindowManagerService.SHOW_SURFACE_ALLOC;
60
61    final WindowManagerService mService;
62    final WindowManagerPolicy mPolicy;
63    final Context mContext;
64    final Session mSession;
65    final IWindow mClient;
66    WindowToken mToken;
67    WindowToken mRootToken;
68    AppWindowToken mAppToken;
69    AppWindowToken mTargetAppToken;
70
71    // mAttrs.flags is tested in animation without being locked. If the bits tested are ever
72    // modified they will need to be locked.
73    final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
74    final DeathRecipient mDeathRecipient;
75    final WindowState mAttachedWindow;
76    final ArrayList<WindowState> mChildWindows = new ArrayList<WindowState>();
77    final int mBaseLayer;
78    final int mSubLayer;
79    final boolean mLayoutAttached;
80    final boolean mIsImWindow;
81    final boolean mIsWallpaper;
82    final boolean mIsFloatingLayer;
83    int mSeq;
84    boolean mEnforceSizeCompat;
85    int mViewVisibility;
86    int mSystemUiVisibility;
87    boolean mPolicyVisibility = true;
88    boolean mPolicyVisibilityAfterAnim = true;
89    boolean mAppFreezing;
90    boolean mAttachedHidden;    // is our parent window hidden?
91    boolean mWallpaperVisible;  // for wallpaper, what was last vis report?
92
93    /**
94     * The window size that was requested by the application.  These are in
95     * the application's coordinate space (without compatibility scale applied).
96     */
97    int mRequestedWidth;
98    int mRequestedHeight;
99    int mLastRequestedWidth;
100    int mLastRequestedHeight;
101
102    int mLayer;
103    boolean mHaveFrame;
104    boolean mObscured;
105    boolean mTurnOnScreen;
106
107    int mLayoutSeq = -1;
108
109    Configuration mConfiguration = null;
110
111    /**
112     * Actual frame shown on-screen (may be modified by animation).  These
113     * are in the screen's coordinate space (WITH the compatibility scale
114     * applied).
115     */
116    final RectF mShownFrame = new RectF();
117
118    /**
119     * Insets that determine the actually visible area.  These are in the application's
120     * coordinate space (without compatibility scale applied).
121     */
122    final Rect mVisibleInsets = new Rect();
123    final Rect mLastVisibleInsets = new Rect();
124    boolean mVisibleInsetsChanged;
125
126    /**
127     * Insets that are covered by system windows (such as the status bar) and
128     * transient docking windows (such as the IME).  These are in the application's
129     * coordinate space (without compatibility scale applied).
130     */
131    final Rect mContentInsets = new Rect();
132    final Rect mLastContentInsets = new Rect();
133    boolean mContentInsetsChanged;
134
135    /**
136     * Set to true if we are waiting for this window to receive its
137     * given internal insets before laying out other windows based on it.
138     */
139    boolean mGivenInsetsPending;
140
141    /**
142     * These are the content insets that were given during layout for
143     * this window, to be applied to windows behind it.
144     */
145    final Rect mGivenContentInsets = new Rect();
146
147    /**
148     * These are the visible insets that were given during layout for
149     * this window, to be applied to windows behind it.
150     */
151    final Rect mGivenVisibleInsets = new Rect();
152
153    /**
154     * This is the given touchable area relative to the window frame, or null if none.
155     */
156    final Region mGivenTouchableRegion = new Region();
157
158    /**
159     * Flag indicating whether the touchable region should be adjusted by
160     * the visible insets; if false the area outside the visible insets is
161     * NOT touchable, so we must use those to adjust the frame during hit
162     * tests.
163     */
164    int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
165
166    /**
167     * This is rectangle of the window's surface that is not covered by
168     * system decorations.
169     */
170    final Rect mSystemDecorRect = new Rect();
171    final Rect mLastSystemDecorRect = new Rect();
172
173    // Current transformation being applied.
174    float mGlobalScale=1;
175    float mInvGlobalScale=1;
176    float mHScale=1, mVScale=1;
177    float mLastHScale=1, mLastVScale=1;
178    final Matrix mTmpMatrix = new Matrix();
179
180    // "Real" frame that the application sees, in display coordinate space.
181    final Rect mFrame = new Rect();
182    final Rect mLastFrame = new Rect();
183    // Frame that is scaled to the application's coordinate space when in
184    // screen size compatibility mode.
185    final Rect mCompatFrame = new Rect();
186
187    final Rect mContainingFrame = new Rect();
188    final Rect mDisplayFrame = new Rect();
189    final Rect mContentFrame = new Rect();
190    final Rect mParentFrame = new Rect();
191    final Rect mVisibleFrame = new Rect();
192
193    boolean mContentChanged;
194
195    // If a window showing a wallpaper: the requested offset for the
196    // wallpaper; if a wallpaper window: the currently applied offset.
197    float mWallpaperX = -1;
198    float mWallpaperY = -1;
199
200    // If a window showing a wallpaper: what fraction of the offset
201    // range corresponds to a full virtual screen.
202    float mWallpaperXStep = -1;
203    float mWallpaperYStep = -1;
204
205    // Wallpaper windows: pixels offset based on above variables.
206    int mXOffset;
207    int mYOffset;
208
209    // This is set after IWindowSession.relayout() has been called at
210    // least once for the window.  It allows us to detect the situation
211    // where we don't yet have a surface, but should have one soon, so
212    // we can give the window focus before waiting for the relayout.
213    boolean mRelayoutCalled;
214
215    // If the application has called relayout() with changes that can
216    // impact its window's size, we need to perform a layout pass on it
217    // even if it is not currently visible for layout.  This is set
218    // when in that case until the layout is done.
219    boolean mLayoutNeeded;
220
221    // Currently running an exit animation?
222    boolean mExiting;
223
224    // Currently on the mDestroySurface list?
225    boolean mDestroying;
226
227    // Completely remove from window manager after exit animation?
228    boolean mRemoveOnExit;
229
230    // Set when the orientation is changing and this window has not yet
231    // been updated for the new orientation.
232    boolean mOrientationChanging;
233
234    // Is this window now (or just being) removed?
235    boolean mRemoved;
236
237    // Temp for keeping track of windows that have been removed when
238    // rebuilding window list.
239    boolean mRebuilding;
240
241    // Input channel and input window handle used by the input dispatcher.
242    final InputWindowHandle mInputWindowHandle;
243    InputChannel mInputChannel;
244
245    // Used to improve performance of toString()
246    String mStringNameCache;
247    CharSequence mLastTitle;
248    boolean mWasPaused;
249
250    final WindowStateAnimator mWinAnimator;
251
252    boolean mHasSurface = false;
253
254    WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
255           WindowState attachedWindow, int seq, WindowManager.LayoutParams a,
256           int viewVisibility) {
257        mService = service;
258        mSession = s;
259        mClient = c;
260        mToken = token;
261        mAttrs.copyFrom(a);
262        mViewVisibility = viewVisibility;
263        mPolicy = mService.mPolicy;
264        mContext = mService.mContext;
265        DeathRecipient deathRecipient = new DeathRecipient();
266        mSeq = seq;
267        mEnforceSizeCompat = (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0;
268        if (WindowManagerService.localLOGV) Slog.v(
269            TAG, "Window " + this + " client=" + c.asBinder()
270            + " token=" + token + " (" + mAttrs.token + ")");
271        try {
272            c.asBinder().linkToDeath(deathRecipient, 0);
273        } catch (RemoteException e) {
274            mDeathRecipient = null;
275            mAttachedWindow = null;
276            mLayoutAttached = false;
277            mIsImWindow = false;
278            mIsWallpaper = false;
279            mIsFloatingLayer = false;
280            mBaseLayer = 0;
281            mSubLayer = 0;
282            mInputWindowHandle = null;
283            mWinAnimator = null;
284            return;
285        }
286        mDeathRecipient = deathRecipient;
287
288        if ((mAttrs.type >= FIRST_SUB_WINDOW &&
289                mAttrs.type <= LAST_SUB_WINDOW)) {
290            // The multiplier here is to reserve space for multiple
291            // windows in the same type layer.
292            mBaseLayer = mPolicy.windowTypeToLayerLw(
293                    attachedWindow.mAttrs.type) * WindowManagerService.TYPE_LAYER_MULTIPLIER
294                    + WindowManagerService.TYPE_LAYER_OFFSET;
295            mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
296            mAttachedWindow = attachedWindow;
297            if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + mAttachedWindow);
298            mAttachedWindow.mChildWindows.add(this);
299            mLayoutAttached = mAttrs.type !=
300                    WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
301            mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
302                    || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
303            mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER;
304            mIsFloatingLayer = mIsImWindow || mIsWallpaper;
305        } else {
306            // The multiplier here is to reserve space for multiple
307            // windows in the same type layer.
308            mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
309                    * WindowManagerService.TYPE_LAYER_MULTIPLIER
310                    + WindowManagerService.TYPE_LAYER_OFFSET;
311            mSubLayer = 0;
312            mAttachedWindow = null;
313            mLayoutAttached = false;
314            mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
315                    || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
316            mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
317            mIsFloatingLayer = mIsImWindow || mIsWallpaper;
318        }
319
320        WindowState appWin = this;
321        while (appWin.mAttachedWindow != null) {
322            appWin = appWin.mAttachedWindow;
323        }
324        WindowToken appToken = appWin.mToken;
325        while (appToken.appWindowToken == null) {
326            WindowToken parent = mService.mTokenMap.get(appToken.token);
327            if (parent == null || appToken == parent) {
328                break;
329            }
330            appToken = parent;
331        }
332        mRootToken = appToken;
333        mAppToken = appToken.appWindowToken;
334
335        mWinAnimator = new WindowStateAnimator(this);
336        mWinAnimator.mAlpha = a.alpha;
337
338        mRequestedWidth = 0;
339        mRequestedHeight = 0;
340        mLastRequestedWidth = 0;
341        mLastRequestedHeight = 0;
342        mXOffset = 0;
343        mYOffset = 0;
344        mLayer = 0;
345        mInputWindowHandle = new InputWindowHandle(
346                mAppToken != null ? mAppToken.mInputApplicationHandle : null, this);
347    }
348
349    void attach() {
350        if (WindowManagerService.localLOGV) Slog.v(
351            TAG, "Attaching " + this + " token=" + mToken
352            + ", list=" + mToken.windows);
353        mSession.windowAddedLocked();
354    }
355
356    @Override
357    public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
358        mHaveFrame = true;
359
360        final Rect container = mContainingFrame;
361        container.set(pf);
362
363        final Rect display = mDisplayFrame;
364        display.set(df);
365
366        final int pw = container.right - container.left;
367        final int ph = container.bottom - container.top;
368
369        int w,h;
370        if ((mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0) {
371            if (mAttrs.width < 0) {
372                w = pw;
373            } else if (mEnforceSizeCompat) {
374                w = (int)(mAttrs.width * mGlobalScale + .5f);
375            } else {
376                w = mAttrs.width;
377            }
378            if (mAttrs.height < 0) {
379                h = ph;
380            } else if (mEnforceSizeCompat) {
381                h = (int)(mAttrs.height * mGlobalScale + .5f);
382            } else {
383                h = mAttrs.height;
384            }
385        } else {
386            if (mAttrs.width == WindowManager.LayoutParams.MATCH_PARENT) {
387                w = pw;
388            } else if (mEnforceSizeCompat) {
389                w = (int)(mRequestedWidth * mGlobalScale + .5f);
390            } else {
391                w = mRequestedWidth;
392            }
393            if (mAttrs.height == WindowManager.LayoutParams.MATCH_PARENT) {
394                h = ph;
395            } else if (mEnforceSizeCompat) {
396                h = (int)(mRequestedHeight * mGlobalScale + .5f);
397            } else {
398                h = mRequestedHeight;
399            }
400        }
401
402        if (!mParentFrame.equals(pf)) {
403            //Slog.i(TAG, "Window " + this + " content frame from " + mParentFrame
404            //        + " to " + pf);
405            mParentFrame.set(pf);
406            mContentChanged = true;
407        }
408        if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) {
409            mLastRequestedWidth = mRequestedWidth;
410            mLastRequestedHeight = mRequestedHeight;
411            mContentChanged = true;
412        }
413
414        final Rect content = mContentFrame;
415        content.set(cf);
416
417        final Rect visible = mVisibleFrame;
418        visible.set(vf);
419
420        final Rect frame = mFrame;
421        final int fw = frame.width();
422        final int fh = frame.height();
423
424        //System.out.println("In: w=" + w + " h=" + h + " container=" +
425        //                   container + " x=" + mAttrs.x + " y=" + mAttrs.y);
426
427        float x, y;
428        if (mEnforceSizeCompat) {
429            x = mAttrs.x * mGlobalScale;
430            y = mAttrs.y * mGlobalScale;
431        } else {
432            x = mAttrs.x;
433            y = mAttrs.y;
434        }
435
436        Gravity.apply(mAttrs.gravity, w, h, container,
437                (int) (x + mAttrs.horizontalMargin * pw),
438                (int) (y + mAttrs.verticalMargin * ph), frame);
439
440        //System.out.println("Out: " + mFrame);
441
442        // Now make sure the window fits in the overall display.
443        Gravity.applyDisplay(mAttrs.gravity, df, frame);
444
445        // Make sure the system, content and visible frames are inside of the
446        // final window frame.
447        if (content.left < frame.left) content.left = frame.left;
448        if (content.top < frame.top) content.top = frame.top;
449        if (content.right > frame.right) content.right = frame.right;
450        if (content.bottom > frame.bottom) content.bottom = frame.bottom;
451        if (visible.left < frame.left) visible.left = frame.left;
452        if (visible.top < frame.top) visible.top = frame.top;
453        if (visible.right > frame.right) visible.right = frame.right;
454        if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
455
456        final Rect contentInsets = mContentInsets;
457        contentInsets.left = content.left-frame.left;
458        contentInsets.top = content.top-frame.top;
459        contentInsets.right = frame.right-content.right;
460        contentInsets.bottom = frame.bottom-content.bottom;
461
462        final Rect visibleInsets = mVisibleInsets;
463        visibleInsets.left = visible.left-frame.left;
464        visibleInsets.top = visible.top-frame.top;
465        visibleInsets.right = frame.right-visible.right;
466        visibleInsets.bottom = frame.bottom-visible.bottom;
467
468        mCompatFrame.set(frame);
469        if (mEnforceSizeCompat) {
470            // If there is a size compatibility scale being applied to the
471            // window, we need to apply this to its insets so that they are
472            // reported to the app in its coordinate space.
473            contentInsets.scale(mInvGlobalScale);
474            visibleInsets.scale(mInvGlobalScale);
475
476            // Also the scaled frame that we report to the app needs to be
477            // adjusted to be in its coordinate space.
478            mCompatFrame.scale(mInvGlobalScale);
479        }
480
481        if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
482            mService.updateWallpaperOffsetLocked(this,
483                    mService.mDisplayInfo.appWidth, mService.mDisplayInfo.appHeight, false);
484        }
485
486        if (WindowManagerService.localLOGV) {
487            //if ("com.google.android.youtube".equals(mAttrs.packageName)
488            //        && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
489                Slog.v(TAG, "Resolving (mRequestedWidth="
490                        + mRequestedWidth + ", mRequestedheight="
491                        + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
492                        + "): frame=" + mFrame.toShortString()
493                        + " ci=" + contentInsets.toShortString()
494                        + " vi=" + visibleInsets.toShortString());
495            //}
496        }
497    }
498
499    @Override
500    public Rect getFrameLw() {
501        return mFrame;
502    }
503
504    @Override
505    public RectF getShownFrameLw() {
506        return mShownFrame;
507    }
508
509    @Override
510    public Rect getDisplayFrameLw() {
511        return mDisplayFrame;
512    }
513
514    @Override
515    public Rect getContentFrameLw() {
516        return mContentFrame;
517    }
518
519    @Override
520    public Rect getVisibleFrameLw() {
521        return mVisibleFrame;
522    }
523
524    @Override
525    public boolean getGivenInsetsPendingLw() {
526        return mGivenInsetsPending;
527    }
528
529    @Override
530    public Rect getGivenContentInsetsLw() {
531        return mGivenContentInsets;
532    }
533
534    @Override
535    public Rect getGivenVisibleInsetsLw() {
536        return mGivenVisibleInsets;
537    }
538
539    @Override
540    public WindowManager.LayoutParams getAttrs() {
541        return mAttrs;
542    }
543
544    public boolean getNeedsMenuLw(WindowManagerPolicy.WindowState bottom) {
545        int index = -1;
546        WindowState ws = this;
547        while (true) {
548            if ((ws.mAttrs.privateFlags
549                    & WindowManager.LayoutParams.PRIVATE_FLAG_SET_NEEDS_MENU_KEY) != 0) {
550                return (ws.mAttrs.flags & WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY) != 0;
551            }
552            // If we reached the bottom of the range of windows we are considering,
553            // assume no menu is needed.
554            if (ws == bottom) {
555                return false;
556            }
557            // The current window hasn't specified whether menu key is needed;
558            // look behind it.
559            // First, we may need to determine the starting position.
560            if (index < 0) {
561                index = mService.mWindows.indexOf(ws);
562            }
563            index--;
564            if (index < 0) {
565                return false;
566            }
567            ws = mService.mWindows.get(index);
568        }
569    }
570
571    public int getSystemUiVisibility() {
572        return mSystemUiVisibility;
573    }
574
575    public int getSurfaceLayer() {
576        return mLayer;
577    }
578
579    public IApplicationToken getAppToken() {
580        return mAppToken != null ? mAppToken.appToken : null;
581    }
582
583    public long getInputDispatchingTimeoutNanos() {
584        return mAppToken != null
585                ? mAppToken.inputDispatchingTimeoutNanos
586                : WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
587    }
588
589    public boolean hasAppShownWindows() {
590        return mAppToken != null && (mAppToken.firstWindowDrawn || mAppToken.startingDisplayed);
591    }
592
593    boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
594        if (dsdx < .99999f || dsdx > 1.00001f) return false;
595        if (dtdy < .99999f || dtdy > 1.00001f) return false;
596        if (dtdx < -.000001f || dtdx > .000001f) return false;
597        if (dsdy < -.000001f || dsdy > .000001f) return false;
598        return true;
599    }
600
601    void prelayout() {
602        if (mEnforceSizeCompat) {
603            mGlobalScale = mService.mCompatibleScreenScale;
604            mInvGlobalScale = 1/mGlobalScale;
605        } else {
606            mGlobalScale = mInvGlobalScale = 1;
607        }
608    }
609
610    /**
611     * Is this window visible?  It is not visible if there is no
612     * surface, or we are in the process of running an exit animation
613     * that will remove the surface, or its app token has been hidden.
614     */
615    public boolean isVisibleLw() {
616        final AppWindowToken atoken = mAppToken;
617        return mHasSurface && mPolicyVisibility && !mAttachedHidden
618                && (atoken == null || !atoken.hiddenRequested)
619                && !mExiting && !mDestroying;
620    }
621
622    /**
623     * Like {@link #isVisibleLw}, but also counts a window that is currently
624     * "hidden" behind the keyguard as visible.  This allows us to apply
625     * things like window flags that impact the keyguard.
626     * XXX I am starting to think we need to have ANOTHER visibility flag
627     * for this "hidden behind keyguard" state rather than overloading
628     * mPolicyVisibility.  Ungh.
629     */
630    public boolean isVisibleOrBehindKeyguardLw() {
631        if (mRootToken.waitingToShow &&
632                mService.mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
633            return false;
634        }
635        final AppWindowToken atoken = mAppToken;
636        final boolean animating = atoken != null
637                ? (atoken.mAppAnimator.animation != null) : false;
638        return mHasSurface && !mDestroying && !mExiting
639                && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
640                && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
641                                && !mRootToken.hidden)
642                        || mWinAnimator.mAnimation != null || animating);
643    }
644
645    /**
646     * Is this window visible, ignoring its app token?  It is not visible
647     * if there is no surface, or we are in the process of running an exit animation
648     * that will remove the surface.
649     */
650    public boolean isWinVisibleLw() {
651        final AppWindowToken atoken = mAppToken;
652        return mHasSurface && mPolicyVisibility && !mAttachedHidden
653                && (atoken == null || !atoken.hiddenRequested || atoken.mAppAnimator.animating)
654                && !mExiting && !mDestroying;
655    }
656
657    /**
658     * The same as isVisible(), but follows the current hidden state of
659     * the associated app token, not the pending requested hidden state.
660     */
661    boolean isVisibleNow() {
662        return mHasSurface && mPolicyVisibility && !mAttachedHidden
663                && !mRootToken.hidden && !mExiting && !mDestroying;
664    }
665
666    /**
667     * Can this window possibly be a drag/drop target?  The test here is
668     * a combination of the above "visible now" with the check that the
669     * Input Manager uses when discarding windows from input consideration.
670     */
671    boolean isPotentialDragTarget() {
672        return isVisibleNow() && !mRemoved
673                && mInputChannel != null && mInputWindowHandle != null;
674    }
675
676    /**
677     * Same as isVisible(), but we also count it as visible between the
678     * call to IWindowSession.add() and the first relayout().
679     */
680    boolean isVisibleOrAdding() {
681        final AppWindowToken atoken = mAppToken;
682        return (mHasSurface || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
683                && mPolicyVisibility && !mAttachedHidden
684                && (atoken == null || !atoken.hiddenRequested)
685                && !mExiting && !mDestroying;
686    }
687
688    /**
689     * Is this window currently on-screen?  It is on-screen either if it
690     * is visible or it is currently running an animation before no longer
691     * being visible.
692     */
693    boolean isOnScreen() {
694        if (!mHasSurface || !mPolicyVisibility || mDestroying) {
695            return false;
696        }
697        final AppWindowToken atoken = mAppToken;
698        if (atoken != null) {
699            return ((!mAttachedHidden && !atoken.hiddenRequested)
700                            || mWinAnimator.mAnimation != null || atoken.mAppAnimator.animation != null);
701        }
702        return !mAttachedHidden || mWinAnimator.mAnimation != null;
703    }
704
705    /**
706     * Like isOnScreen(), but we don't return true if the window is part
707     * of a transition that has not yet been started.
708     */
709    boolean isReadyForDisplay() {
710        if (mRootToken.waitingToShow &&
711                mService.mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
712            return false;
713        }
714        return mHasSurface && mPolicyVisibility && !mDestroying
715                && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
716                                && !mRootToken.hidden)
717                        || mWinAnimator.mAnimation != null
718                        || ((mAppToken != null) && (mAppToken.mAppAnimator.animation != null)));
719    }
720
721    /**
722     * Like isReadyForDisplay(), but ignores any force hiding of the window due
723     * to the keyguard.
724     */
725    boolean isReadyForDisplayIgnoringKeyguard() {
726        if (mRootToken.waitingToShow &&
727                mService.mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
728            return false;
729        }
730        final AppWindowToken atoken = mAppToken;
731        if (atoken == null && !mPolicyVisibility) {
732            // If this is not an app window, and the policy has asked to force
733            // hide, then we really do want to hide.
734            return false;
735        }
736        return mHasSurface && !mDestroying
737                && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
738                                && !mRootToken.hidden)
739                        || mWinAnimator.mAnimation != null
740                        || ((atoken != null) && (atoken.mAppAnimator.animation != null)
741                                && !mWinAnimator.isDummyAnimation()));
742    }
743
744    /**
745     * Like isOnScreen, but returns false if the surface hasn't yet
746     * been drawn.
747     */
748    public boolean isDisplayedLw() {
749        final AppWindowToken atoken = mAppToken;
750        return isDrawnLw() && mPolicyVisibility
751            && ((!mAttachedHidden &&
752                    (atoken == null || !atoken.hiddenRequested))
753                    || mWinAnimator.mAnimating);
754    }
755
756    /**
757     * Return true if this window (or a window it is attached to, but not
758     * considering its app token) is currently animating.
759     */
760    public boolean isAnimatingLw() {
761        return mWinAnimator.mAnimation != null;
762    }
763
764    public boolean isGoneForLayoutLw() {
765        final AppWindowToken atoken = mAppToken;
766        return mViewVisibility == View.GONE
767                || !mRelayoutCalled
768                || (atoken == null && mRootToken.hidden)
769                || (atoken != null && (atoken.hiddenRequested || atoken.hidden))
770                || mAttachedHidden
771                || mExiting || mDestroying;
772    }
773
774    /**
775     * Returns true if the window has a surface that it has drawn a
776     * complete UI in to.
777     */
778    public boolean isDrawnLw() {
779        return mHasSurface && !mDestroying &&
780                (mWinAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW
781                || mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN);
782    }
783
784    /**
785     * Return true if the window is opaque and fully drawn.  This indicates
786     * it may obscure windows behind it.
787     */
788    boolean isOpaqueDrawn() {
789        return (mAttrs.format == PixelFormat.OPAQUE
790                        || mAttrs.type == TYPE_WALLPAPER)
791                && isDrawnLw() && mWinAnimator.mAnimation == null
792                && (mAppToken == null || mAppToken.mAppAnimator.animation == null);
793    }
794
795    /**
796     * Return whether this window is wanting to have a translation
797     * animation applied to it for an in-progress move.  (Only makes
798     * sense to call from performLayoutAndPlaceSurfacesLockedInner().)
799     */
800    boolean shouldAnimateMove() {
801        return mContentChanged && !mExiting && !mWinAnimator.mLastHidden && mService.okToDisplay()
802                && (mFrame.top != mLastFrame.top
803                        || mFrame.left != mLastFrame.left)
804                && (mAttachedWindow == null || !mAttachedWindow.shouldAnimateMove());
805    }
806
807    boolean isFullscreen(int screenWidth, int screenHeight) {
808        return mFrame.left <= 0 && mFrame.top <= 0 &&
809                mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
810    }
811
812    void removeLocked() {
813        disposeInputChannel();
814
815        if (mAttachedWindow != null) {
816            if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + this + " from " + mAttachedWindow);
817            mAttachedWindow.mChildWindows.remove(this);
818        }
819        mWinAnimator.destroyDeferredSurfaceLocked();
820        mWinAnimator.destroySurfaceLocked();
821        mSession.windowRemovedLocked();
822        try {
823            mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
824        } catch (RuntimeException e) {
825            // Ignore if it has already been removed (usually because
826            // we are doing this as part of processing a death note.)
827        }
828    }
829
830    void setInputChannel(InputChannel inputChannel) {
831        if (mInputChannel != null) {
832            throw new IllegalStateException("Window already has an input channel.");
833        }
834
835        mInputChannel = inputChannel;
836        mInputWindowHandle.inputChannel = inputChannel;
837    }
838
839    void disposeInputChannel() {
840        if (mInputChannel != null) {
841            mService.mInputManager.unregisterInputChannel(mInputChannel);
842
843            mInputChannel.dispose();
844            mInputChannel = null;
845        }
846
847        mInputWindowHandle.inputChannel = null;
848    }
849
850    private class DeathRecipient implements IBinder.DeathRecipient {
851        public void binderDied() {
852            try {
853                synchronized(mService.mWindowMap) {
854                    WindowState win = mService.windowForClientLocked(mSession, mClient, false);
855                    Slog.i(TAG, "WIN DEATH: " + win);
856                    if (win != null) {
857                        mService.removeWindowLocked(mSession, win);
858                    }
859                }
860            } catch (IllegalArgumentException ex) {
861                // This will happen if the window has already been
862                // removed.
863            }
864        }
865    }
866
867    /** Returns true if this window desires key events.
868     * TODO(cmautner): Is this the same as {@link WindowManagerService#canBeImeTarget}
869     */
870    public final boolean canReceiveKeys() {
871        return     isVisibleOrAdding()
872                && (mViewVisibility == View.VISIBLE)
873                && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0);
874    }
875
876    @Override
877    public boolean hasDrawnLw() {
878        return mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN;
879    }
880
881    @Override
882    public boolean showLw(boolean doAnimation) {
883        return showLw(doAnimation, true);
884    }
885
886    boolean showLw(boolean doAnimation, boolean requestAnim) {
887        if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
888            // Already showing.
889            return false;
890        }
891        if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
892        if (doAnimation) {
893            if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
894                    + mPolicyVisibility + " mAnimation=" + mWinAnimator.mAnimation);
895            if (!mService.okToDisplay()) {
896                doAnimation = false;
897            } else if (mPolicyVisibility && mWinAnimator.mAnimation == null) {
898                // Check for the case where we are currently visible and
899                // not animating; we do not want to do animation at such a
900                // point to become visible when we already are.
901                doAnimation = false;
902            }
903        }
904        mPolicyVisibility = true;
905        mPolicyVisibilityAfterAnim = true;
906        if (doAnimation) {
907            mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_ENTER, true);
908        }
909        if (requestAnim) {
910            mService.updateLayoutToAnimationLocked();
911        }
912        return true;
913    }
914
915    @Override
916    public boolean hideLw(boolean doAnimation) {
917        return hideLw(doAnimation, true);
918    }
919
920    boolean hideLw(boolean doAnimation, boolean requestAnim) {
921        if (doAnimation) {
922            if (!mService.okToDisplay()) {
923                doAnimation = false;
924            }
925        }
926        boolean current = doAnimation ? mPolicyVisibilityAfterAnim
927                : mPolicyVisibility;
928        if (!current) {
929            // Already hiding.
930            return false;
931        }
932        if (doAnimation) {
933            mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT, false);
934            if (mWinAnimator.mAnimation == null) {
935                doAnimation = false;
936            }
937        }
938        if (doAnimation) {
939            mPolicyVisibilityAfterAnim = false;
940        } else {
941            if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this);
942            mPolicyVisibilityAfterAnim = false;
943            mPolicyVisibility = false;
944            // Window is no longer visible -- make sure if we were waiting
945            // for it to be displayed before enabling the display, that
946            // we allow the display to be enabled now.
947            mService.enableScreenIfNeededLocked();
948            if (mService.mCurrentFocus == this) {
949                mService.mFocusMayChange = true;
950            }
951        }
952        if (requestAnim) {
953            mService.updateLayoutToAnimationLocked();
954        }
955        return true;
956    }
957
958    @Override
959    public boolean isAlive() {
960        return mClient.asBinder().isBinderAlive();
961    }
962
963    private static void applyInsets(Region outRegion, Rect frame, Rect inset) {
964        outRegion.set(
965                frame.left + inset.left, frame.top + inset.top,
966                frame.right - inset.right, frame.bottom - inset.bottom);
967    }
968
969    public void getTouchableRegion(Region outRegion) {
970        final Rect frame = mFrame;
971        switch (mTouchableInsets) {
972            default:
973            case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
974                outRegion.set(frame);
975                break;
976            case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT:
977                applyInsets(outRegion, frame, mGivenContentInsets);
978                break;
979            case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE:
980                applyInsets(outRegion, frame, mGivenVisibleInsets);
981                break;
982            case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION: {
983                final Region givenTouchableRegion = mGivenTouchableRegion;
984                outRegion.set(givenTouchableRegion);
985                outRegion.translate(frame.left, frame.top);
986                break;
987            }
988        }
989    }
990
991    void dump(PrintWriter pw, String prefix, boolean dumpAll) {
992        pw.print(prefix); pw.print("mSession="); pw.print(mSession);
993                pw.print(" mClient="); pw.println(mClient.asBinder());
994        pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
995        pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
996                pw.print(" h="); pw.print(mRequestedHeight);
997                pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
998        if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) {
999            pw.print(prefix); pw.print("LastRequested w="); pw.print(mLastRequestedWidth);
1000                    pw.print(" h="); pw.println(mLastRequestedHeight);
1001        }
1002        if (mAttachedWindow != null || mLayoutAttached) {
1003            pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow);
1004                    pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
1005        }
1006        if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
1007            pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
1008                    pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
1009                    pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
1010                    pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
1011        }
1012        if (dumpAll) {
1013            pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
1014                    pw.print(" mSubLayer="); pw.print(mSubLayer);
1015                    pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
1016                    pw.print((mTargetAppToken != null ?
1017                            mTargetAppToken.mAppAnimator.animLayerAdjustment
1018                          : (mAppToken != null ? mAppToken.mAppAnimator.animLayerAdjustment : 0)));
1019                    pw.print("="); pw.print(mWinAnimator.mAnimLayer);
1020                    pw.print(" mLastLayer="); pw.println(mWinAnimator.mLastLayer);
1021        }
1022        if (dumpAll) {
1023            pw.print(prefix); pw.print("mToken="); pw.println(mToken);
1024            pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
1025            if (mAppToken != null) {
1026                pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
1027            }
1028            if (mTargetAppToken != null) {
1029                pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken);
1030            }
1031            pw.print(prefix); pw.print("mViewVisibility=0x");
1032            pw.print(Integer.toHexString(mViewVisibility));
1033            pw.print(" mHaveFrame="); pw.print(mHaveFrame);
1034            pw.print(" mObscured="); pw.println(mObscured);
1035            pw.print(prefix); pw.print("mSeq="); pw.print(mSeq);
1036            pw.print(" mSystemUiVisibility=0x");
1037            pw.println(Integer.toHexString(mSystemUiVisibility));
1038        }
1039        if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
1040            pw.print(prefix); pw.print("mPolicyVisibility=");
1041                    pw.print(mPolicyVisibility);
1042                    pw.print(" mPolicyVisibilityAfterAnim=");
1043                    pw.print(mPolicyVisibilityAfterAnim);
1044                    pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
1045        }
1046        if (!mRelayoutCalled || mLayoutNeeded) {
1047            pw.print(prefix); pw.print("mRelayoutCalled="); pw.print(mRelayoutCalled);
1048                    pw.print(" mLayoutNeeded="); pw.println(mLayoutNeeded);
1049        }
1050        if (mXOffset != 0 || mYOffset != 0) {
1051            pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
1052                    pw.print(" y="); pw.println(mYOffset);
1053        }
1054        if (dumpAll) {
1055            pw.print(prefix); pw.print("mGivenContentInsets=");
1056                    mGivenContentInsets.printShortString(pw);
1057                    pw.print(" mGivenVisibleInsets=");
1058                    mGivenVisibleInsets.printShortString(pw);
1059                    pw.println();
1060            if (mTouchableInsets != 0 || mGivenInsetsPending) {
1061                pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets);
1062                        pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending);
1063                Region region = new Region();
1064                getTouchableRegion(region);
1065                pw.print(prefix); pw.print("touchable region="); pw.println(region);
1066            }
1067            pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
1068        }
1069        pw.print(prefix); pw.print("mHasSurface="); pw.print(mHasSurface);
1070                pw.print(" mShownFrame="); mShownFrame.printShortString(pw); pw.println();
1071        if (dumpAll) {
1072            pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
1073                    pw.print(" last="); mLastFrame.printShortString(pw);
1074                    pw.println();
1075            pw.print(prefix); pw.print("mSystemDecorRect="); mSystemDecorRect.printShortString(pw);
1076                    pw.print(" last="); mLastSystemDecorRect.printShortString(pw);
1077                    pw.println();
1078        }
1079        if (mEnforceSizeCompat) {
1080            pw.print(prefix); pw.print("mCompatFrame="); mCompatFrame.printShortString(pw);
1081                    pw.println();
1082        }
1083        if (dumpAll) {
1084            pw.print(prefix); pw.print("Frames: containing=");
1085                    mContainingFrame.printShortString(pw);
1086                    pw.print(" parent="); mParentFrame.printShortString(pw);
1087                    pw.print(" display="); mDisplayFrame.printShortString(pw);
1088                    pw.println();
1089            pw.print(prefix); pw.print("    content="); mContentFrame.printShortString(pw);
1090                    pw.print(" visible="); mVisibleFrame.printShortString(pw);
1091                    pw.println();
1092            pw.print(prefix); pw.print("Cur insets: content=");
1093                    mContentInsets.printShortString(pw);
1094                    pw.print(" visible="); mVisibleInsets.printShortString(pw);
1095                    pw.println();
1096            pw.print(prefix); pw.print("Lst insets: content=");
1097                    mLastContentInsets.printShortString(pw);
1098                    pw.print(" visible="); mLastVisibleInsets.printShortString(pw);
1099                    pw.println();
1100        }
1101        mWinAnimator.dump(pw, prefix, dumpAll);
1102        if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
1103            pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
1104                    pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
1105                    pw.print(" mDestroying="); pw.print(mDestroying);
1106                    pw.print(" mRemoved="); pw.println(mRemoved);
1107        }
1108        if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
1109            pw.print(prefix); pw.print("mOrientationChanging=");
1110                    pw.print(mOrientationChanging);
1111                    pw.print(" mAppFreezing="); pw.print(mAppFreezing);
1112                    pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
1113        }
1114        if (mHScale != 1 || mVScale != 1) {
1115            pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
1116                    pw.print(" mVScale="); pw.println(mVScale);
1117        }
1118        if (mWallpaperX != -1 || mWallpaperY != -1) {
1119            pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
1120                    pw.print(" mWallpaperY="); pw.println(mWallpaperY);
1121        }
1122        if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
1123            pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
1124                    pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
1125        }
1126    }
1127
1128    String makeInputChannelName() {
1129        return Integer.toHexString(System.identityHashCode(this))
1130            + " " + mAttrs.getTitle();
1131    }
1132
1133    @Override
1134    public String toString() {
1135        if (mStringNameCache == null || mLastTitle != mAttrs.getTitle()
1136                || mWasPaused != mToken.paused) {
1137            mLastTitle = mAttrs.getTitle();
1138            mWasPaused = mToken.paused;
1139            mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this))
1140                    + " " + mLastTitle + " paused=" + mWasPaused + "}";
1141        }
1142        return mStringNameCache;
1143    }
1144}
1145