WindowState.java revision 84cc5e320df461f6b7f2173833e62880ecc5af8e
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.os.Trace.TRACE_TAG_WINDOW_MANAGER;
20import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
21import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
22import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
23import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
24import static android.view.WindowManager.LayoutParams.FLAG_SCALED;
25import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
26import static android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
27import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
28import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
29import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
30import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
31import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
32import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
33import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
34import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
35import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
36import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
37import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
38import static com.android.server.wm.WindowManagerService.DEBUG_ADD_REMOVE;
39import static com.android.server.wm.WindowManagerService.DEBUG_ANIM;
40import static com.android.server.wm.WindowManagerService.DEBUG_APP_TRANSITIONS;
41import static com.android.server.wm.WindowManagerService.DEBUG_CONFIGURATION;
42import static com.android.server.wm.WindowManagerService.DEBUG_FOCUS_LIGHT;
43import static com.android.server.wm.WindowManagerService.DEBUG_LAYOUT;
44import static com.android.server.wm.WindowManagerService.DEBUG_ORIENTATION;
45import static com.android.server.wm.WindowManagerService.DEBUG_POWER;
46import static com.android.server.wm.WindowManagerService.DEBUG_RESIZE;
47import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
48
49import android.app.ActivityManager;
50import android.app.AppOpsManager;
51import android.graphics.Point;
52import android.os.PowerManager;
53import android.os.RemoteCallbackList;
54import android.os.SystemClock;
55import android.os.Trace;
56import android.os.WorkSource;
57import android.util.DisplayMetrics;
58import android.util.TimeUtils;
59import android.view.Display;
60import android.view.IWindowFocusObserver;
61import android.view.IWindowId;
62
63import com.android.server.input.InputWindowHandle;
64
65import android.content.Context;
66import android.content.res.Configuration;
67import android.graphics.Matrix;
68import android.graphics.PixelFormat;
69import android.graphics.Rect;
70import android.graphics.Region;
71import android.os.IBinder;
72import android.os.RemoteException;
73import android.os.UserHandle;
74import android.util.Slog;
75import android.view.DisplayInfo;
76import android.view.Gravity;
77import android.view.IApplicationToken;
78import android.view.IWindow;
79import android.view.InputChannel;
80import android.view.InputEvent;
81import android.view.InputEventReceiver;
82import android.view.View;
83import android.view.ViewTreeObserver;
84import android.view.WindowManager;
85import android.view.WindowManagerPolicy;
86
87import java.io.PrintWriter;
88import java.util.ArrayList;
89
90class WindowList extends ArrayList<WindowState> {
91}
92
93/**
94 * A window in the window manager.
95 */
96final class WindowState implements WindowManagerPolicy.WindowState {
97    static final String TAG = "WindowState";
98
99    // The minimal size of a window within the usable area of the freeform stack.
100    // TODO(multi-window): fix the min sizes when we have mininum width/height support,
101    //                     use hard-coded min sizes for now.
102    static final int MINIMUM_VISIBLE_WIDTH_IN_DP = 48;
103    static final int MINIMUM_VISIBLE_HEIGHT_IN_DP = 32;
104
105    // The thickness of a window resize handle outside the window bounds on the free form workspace
106    // to capture touch events in that area.
107    static final int RESIZE_HANDLE_WIDTH_IN_DP = 30;
108
109    static final boolean BOUNDS_FOR_TOUCH = true;
110
111    final WindowManagerService mService;
112    final WindowManagerPolicy mPolicy;
113    final Context mContext;
114    final Session mSession;
115    final IWindow mClient;
116    final int mAppOp;
117    // UserId and appId of the owner. Don't display windows of non-current user.
118    final int mOwnerUid;
119    final IWindowId mWindowId;
120    WindowToken mToken;
121    WindowToken mRootToken;
122    AppWindowToken mAppToken;
123    AppWindowToken mTargetAppToken;
124
125    // mAttrs.flags is tested in animation without being locked. If the bits tested are ever
126    // modified they will need to be locked.
127    final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
128    final DeathRecipient mDeathRecipient;
129    final WindowState mAttachedWindow;
130    final WindowList mChildWindows = new WindowList();
131    final int mBaseLayer;
132    final int mSubLayer;
133    final boolean mLayoutAttached;
134    final boolean mIsImWindow;
135    final boolean mIsWallpaper;
136    final boolean mIsFloatingLayer;
137    int mSeq;
138    boolean mEnforceSizeCompat;
139    int mViewVisibility;
140    int mSystemUiVisibility;
141    boolean mPolicyVisibility = true;
142    boolean mPolicyVisibilityAfterAnim = true;
143    boolean mAppOpVisibility = true;
144    boolean mAppFreezing;
145    boolean mAttachedHidden;    // is our parent window hidden?
146    boolean mWallpaperVisible;  // for wallpaper, what was last vis report?
147    boolean mDragResizing;
148
149    RemoteCallbackList<IWindowFocusObserver> mFocusCallbacks;
150
151    /**
152     * The window size that was requested by the application.  These are in
153     * the application's coordinate space (without compatibility scale applied).
154     */
155    int mRequestedWidth;
156    int mRequestedHeight;
157    int mLastRequestedWidth;
158    int mLastRequestedHeight;
159
160    int mLayer;
161    boolean mHaveFrame;
162    boolean mObscured;
163    boolean mTurnOnScreen;
164
165    int mLayoutSeq = -1;
166
167    private Configuration mConfiguration = Configuration.EMPTY;
168    private Configuration mOverrideConfig = Configuration.EMPTY;
169    // Sticky answer to isConfigChanged(), remains true until new Configuration is assigned.
170    // Used only on {@link #TYPE_KEYGUARD}.
171    private boolean mConfigHasChanged;
172
173    /**
174     * Actual position of the surface shown on-screen (may be modified by animation). These are
175     * in the screen's coordinate space (WITH the compatibility scale applied).
176     */
177    final Point mShownPosition = new Point();
178
179    /**
180     * Insets that determine the actually visible area.  These are in the application's
181     * coordinate space (without compatibility scale applied).
182     */
183    final Rect mVisibleInsets = new Rect();
184    final Rect mLastVisibleInsets = new Rect();
185    boolean mVisibleInsetsChanged;
186
187    /**
188     * Insets that are covered by system windows (such as the status bar) and
189     * transient docking windows (such as the IME).  These are in the application's
190     * coordinate space (without compatibility scale applied).
191     */
192    final Rect mContentInsets = new Rect();
193    final Rect mLastContentInsets = new Rect();
194    boolean mContentInsetsChanged;
195
196    /**
197     * Insets that determine the area covered by the display overscan region.  These are in the
198     * application's coordinate space (without compatibility scale applied).
199     */
200    final Rect mOverscanInsets = new Rect();
201    final Rect mLastOverscanInsets = new Rect();
202    boolean mOverscanInsetsChanged;
203
204    /**
205     * Insets that determine the area covered by the stable system windows.  These are in the
206     * application's coordinate space (without compatibility scale applied).
207     */
208    final Rect mStableInsets = new Rect();
209    final Rect mLastStableInsets = new Rect();
210    boolean mStableInsetsChanged;
211
212    /**
213     * Outsets determine the area outside of the surface where we want to pretend that it's possible
214     * to draw anyway.
215     */
216    final Rect mOutsets = new Rect();
217    final Rect mLastOutsets = new Rect();
218    boolean mOutsetsChanged = false;
219
220    /**
221     * Set to true if we are waiting for this window to receive its
222     * given internal insets before laying out other windows based on it.
223     */
224    boolean mGivenInsetsPending;
225
226    /**
227     * These are the content insets that were given during layout for
228     * this window, to be applied to windows behind it.
229     */
230    final Rect mGivenContentInsets = new Rect();
231
232    /**
233     * These are the visible insets that were given during layout for
234     * this window, to be applied to windows behind it.
235     */
236    final Rect mGivenVisibleInsets = new Rect();
237
238    /**
239     * This is the given touchable area relative to the window frame, or null if none.
240     */
241    final Region mGivenTouchableRegion = new Region();
242
243    /**
244     * Flag indicating whether the touchable region should be adjusted by
245     * the visible insets; if false the area outside the visible insets is
246     * NOT touchable, so we must use those to adjust the frame during hit
247     * tests.
248     */
249    int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
250
251    /**
252     * This is rectangle of the window's surface that is not covered by
253     * system decorations.
254     */
255    final Rect mSystemDecorRect = new Rect();
256    final Rect mLastSystemDecorRect = new Rect();
257
258    // Current transformation being applied.
259    float mGlobalScale=1;
260    float mInvGlobalScale=1;
261    float mHScale=1, mVScale=1;
262    float mLastHScale=1, mLastVScale=1;
263    final Matrix mTmpMatrix = new Matrix();
264
265    // "Real" frame that the application sees, in display coordinate space.
266    final Rect mFrame = new Rect();
267    final Rect mLastFrame = new Rect();
268    // Frame that is scaled to the application's coordinate space when in
269    // screen size compatibility mode.
270    final Rect mCompatFrame = new Rect();
271
272    final Rect mContainingFrame = new Rect();
273
274    final Rect mParentFrame = new Rect();
275
276    // The entire screen area of the {@link TaskStack} this window is in. Usually equal to the
277    // screen area of the device.
278    final Rect mDisplayFrame = new Rect();
279
280    // The region of the display frame that the display type supports displaying content on. This
281    // is mostly a special case for TV where some displays don’t have the entire display usable.
282    // {@link WindowManager.LayoutParams#FLAG_LAYOUT_IN_OVERSCAN} flag can be used to allow
283    // window display contents to extend into the overscan region.
284    final Rect mOverscanFrame = new Rect();
285
286    // The display frame minus the stable insets. This value is always constant regardless of if
287    // the status bar or navigation bar is visible.
288    final Rect mStableFrame = new Rect();
289
290    // The area not occupied by the status and navigation bars. So, if both status and navigation
291    // bars are visible, the decor frame is equal to the stable frame.
292    final Rect mDecorFrame = new Rect();
293
294    // Equal to the decor frame if the IME (e.g. keyboard) is not present. Equal to the decor frame
295    // minus the area occupied by the IME if the IME is present.
296    final Rect mContentFrame = new Rect();
297
298    // Legacy stuff. Generally equal to the content frame expect when the IME for older apps
299    // displays hint text.
300    final Rect mVisibleFrame = new Rect();
301
302    // Frame that includes dead area outside of the surface but where we want to pretend that it's
303    // possible to draw.
304    final Rect mOutsetFrame = new Rect();
305
306    boolean mContentChanged;
307
308    // If a window showing a wallpaper: the requested offset for the
309    // wallpaper; if a wallpaper window: the currently applied offset.
310    float mWallpaperX = -1;
311    float mWallpaperY = -1;
312
313    // If a window showing a wallpaper: what fraction of the offset
314    // range corresponds to a full virtual screen.
315    float mWallpaperXStep = -1;
316    float mWallpaperYStep = -1;
317
318    // If a window showing a wallpaper: a raw pixel offset to forcibly apply
319    // to its window; if a wallpaper window: not used.
320    int mWallpaperDisplayOffsetX = Integer.MIN_VALUE;
321    int mWallpaperDisplayOffsetY = Integer.MIN_VALUE;
322
323    // Wallpaper windows: pixels offset based on above variables.
324    int mXOffset;
325    int mYOffset;
326
327    /**
328     * This is set after IWindowSession.relayout() has been called at
329     * least once for the window.  It allows us to detect the situation
330     * where we don't yet have a surface, but should have one soon, so
331     * we can give the window focus before waiting for the relayout.
332     */
333    boolean mRelayoutCalled;
334
335    /**
336     * If the application has called relayout() with changes that can
337     * impact its window's size, we need to perform a layout pass on it
338     * even if it is not currently visible for layout.  This is set
339     * when in that case until the layout is done.
340     */
341    boolean mLayoutNeeded;
342
343    /** Currently running an exit animation? */
344    boolean mExiting;
345
346    /** Currently on the mDestroySurface list? */
347    boolean mDestroying;
348
349    /** Completely remove from window manager after exit animation? */
350    boolean mRemoveOnExit;
351
352    /**
353     * Whether the app died while it was visible, if true we might need
354     * to continue to show it until it's restarted.
355     */
356    boolean mAppDied;
357
358    /**
359     * Set when the orientation is changing and this window has not yet
360     * been updated for the new orientation.
361     */
362    boolean mOrientationChanging;
363
364    /**
365     * How long we last kept the screen frozen.
366     */
367    int mLastFreezeDuration;
368
369    /** Is this window now (or just being) removed? */
370    boolean mRemoved;
371
372    /**
373     * Temp for keeping track of windows that have been removed when
374     * rebuilding window list.
375     */
376    boolean mRebuilding;
377
378    // Input channel and input window handle used by the input dispatcher.
379    final InputWindowHandle mInputWindowHandle;
380    InputChannel mInputChannel;
381    InputChannel mClientChannel;
382
383    // Used to improve performance of toString()
384    String mStringNameCache;
385    CharSequence mLastTitle;
386    boolean mWasExiting;
387
388    final WindowStateAnimator mWinAnimator;
389
390    boolean mHasSurface = false;
391
392    boolean mNotOnAppsDisplay = false;
393    DisplayContent  mDisplayContent;
394
395    /** When true this window can be displayed on screens owther than mOwnerUid's */
396    private boolean mShowToOwnerOnly;
397
398    /**
399     * Wake lock for drawing.
400     * Even though it's slightly more expensive to do so, we will use a separate wake lock
401     * for each app that is requesting to draw while dozing so that we can accurately track
402     * who is preventing the system from suspending.
403     * This lock is only acquired on first use.
404     */
405    PowerManager.WakeLock mDrawLock;
406
407    final private Rect mTmpRect = new Rect();
408
409    WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
410           WindowState attachedWindow, int appOp, int seq, WindowManager.LayoutParams a,
411           int viewVisibility, final DisplayContent displayContent) {
412        mService = service;
413        mSession = s;
414        mClient = c;
415        mAppOp = appOp;
416        mToken = token;
417        mOwnerUid = s.mUid;
418        mWindowId = new IWindowId.Stub() {
419            @Override
420            public void registerFocusObserver(IWindowFocusObserver observer) {
421                WindowState.this.registerFocusObserver(observer);
422            }
423            @Override
424            public void unregisterFocusObserver(IWindowFocusObserver observer) {
425                WindowState.this.unregisterFocusObserver(observer);
426            }
427            @Override
428            public boolean isFocused() {
429                return WindowState.this.isFocused();
430            }
431        };
432        mAttrs.copyFrom(a);
433        mViewVisibility = viewVisibility;
434        mDisplayContent = displayContent;
435        mPolicy = mService.mPolicy;
436        mContext = mService.mContext;
437        DeathRecipient deathRecipient = new DeathRecipient();
438        mSeq = seq;
439        mEnforceSizeCompat = (mAttrs.privateFlags & PRIVATE_FLAG_COMPATIBLE_WINDOW) != 0;
440        if (WindowManagerService.localLOGV) Slog.v(
441            TAG, "Window " + this + " client=" + c.asBinder()
442            + " token=" + token + " (" + mAttrs.token + ")" + " params=" + a);
443        try {
444            c.asBinder().linkToDeath(deathRecipient, 0);
445        } catch (RemoteException e) {
446            mDeathRecipient = null;
447            mAttachedWindow = null;
448            mLayoutAttached = false;
449            mIsImWindow = false;
450            mIsWallpaper = false;
451            mIsFloatingLayer = false;
452            mBaseLayer = 0;
453            mSubLayer = 0;
454            mInputWindowHandle = null;
455            mWinAnimator = null;
456            return;
457        }
458        mDeathRecipient = deathRecipient;
459
460        if ((mAttrs.type >= FIRST_SUB_WINDOW &&
461                mAttrs.type <= LAST_SUB_WINDOW)) {
462            // The multiplier here is to reserve space for multiple
463            // windows in the same type layer.
464            mBaseLayer = mPolicy.windowTypeToLayerLw(
465                    attachedWindow.mAttrs.type) * WindowManagerService.TYPE_LAYER_MULTIPLIER
466                    + WindowManagerService.TYPE_LAYER_OFFSET;
467            mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
468            mAttachedWindow = attachedWindow;
469            if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to "
470                    + mAttachedWindow);
471
472            final WindowList childWindows = mAttachedWindow.mChildWindows;
473            final int numChildWindows = childWindows.size();
474            if (numChildWindows == 0) {
475                childWindows.add(this);
476            } else {
477                boolean added = false;
478                for (int i = 0; i < numChildWindows; i++) {
479                    final int childSubLayer = childWindows.get(i).mSubLayer;
480                    if (mSubLayer < childSubLayer
481                            || (mSubLayer == childSubLayer && childSubLayer < 0)) {
482                        // We insert the child window into the list ordered by the sub-layer. For
483                        // same sub-layers, the negative one should go below others; the positive
484                        // one should go above others.
485                        childWindows.add(i, this);
486                        added = true;
487                        break;
488                    }
489                }
490                if (!added) {
491                    childWindows.add(this);
492                }
493            }
494
495            mLayoutAttached = mAttrs.type !=
496                    WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
497            mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
498                    || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
499            mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER;
500            mIsFloatingLayer = mIsImWindow || mIsWallpaper;
501        } else {
502            // The multiplier here is to reserve space for multiple
503            // windows in the same type layer.
504            mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
505                    * WindowManagerService.TYPE_LAYER_MULTIPLIER
506                    + WindowManagerService.TYPE_LAYER_OFFSET;
507            mSubLayer = 0;
508            mAttachedWindow = null;
509            mLayoutAttached = false;
510            mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
511                    || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
512            mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
513            mIsFloatingLayer = mIsImWindow || mIsWallpaper;
514        }
515
516        WindowState appWin = this;
517        while (appWin.mAttachedWindow != null) {
518            appWin = appWin.mAttachedWindow;
519        }
520        WindowToken appToken = appWin.mToken;
521        while (appToken.appWindowToken == null) {
522            WindowToken parent = mService.mTokenMap.get(appToken.token);
523            if (parent == null || appToken == parent) {
524                break;
525            }
526            appToken = parent;
527        }
528        mRootToken = appToken;
529        mAppToken = appToken.appWindowToken;
530        if (mAppToken != null) {
531            final DisplayContent appDisplay = getDisplayContent();
532            mNotOnAppsDisplay = displayContent != appDisplay;
533
534            if (mAppToken.showForAllUsers) {
535                // Windows for apps that can show for all users should also show when the
536                // device is locked.
537                mAttrs.flags |= FLAG_SHOW_WHEN_LOCKED;
538            }
539        }
540
541        mWinAnimator = new WindowStateAnimator(this);
542        mWinAnimator.mAlpha = a.alpha;
543
544        mRequestedWidth = 0;
545        mRequestedHeight = 0;
546        mLastRequestedWidth = 0;
547        mLastRequestedHeight = 0;
548        mXOffset = 0;
549        mYOffset = 0;
550        mLayer = 0;
551        mInputWindowHandle = new InputWindowHandle(
552                mAppToken != null ? mAppToken.mInputApplicationHandle : null, this,
553                displayContent.getDisplayId());
554    }
555
556    void attach() {
557        if (WindowManagerService.localLOGV) Slog.v(
558            TAG, "Attaching " + this + " token=" + mToken
559            + ", list=" + mToken.windows);
560        mSession.windowAddedLocked();
561    }
562
563    @Override
564    public int getOwningUid() {
565        return mOwnerUid;
566    }
567
568    @Override
569    public String getOwningPackage() {
570        return mAttrs.packageName;
571    }
572
573    @Override
574    public void computeFrameLw(Rect pf, Rect df, Rect of, Rect cf, Rect vf, Rect dcf, Rect sf,
575            Rect osf) {
576        if (mAppToken != null && mAppToken.mWillReplaceWindow
577                && (mExiting || !mAppToken.mReplacingRemoveRequested)) {
578            // This window is being replaced and either already got information that it's being
579            // removed or we are still waiting for some information. Because of this we don't
580            // want to apply any more changes to it, so it remains in this state until new window
581            // appears.
582            return;
583        }
584        mHaveFrame = true;
585
586        final Task task = getTask();
587        final boolean nonFullscreenTask = task != null && !task.isFullscreen();
588        final boolean freeformWorkspace = task != null && task.inFreeformWorkspace();
589        if (nonFullscreenTask) {
590            task.getBounds(mContainingFrame);
591            final WindowState imeWin = mService.mInputMethodWindow;
592            if (imeWin != null && imeWin.isVisibleNow() && mService.mInputMethodTarget == this
593                    && mContainingFrame.bottom > cf.bottom) {
594                // IME is up and obscuring this window. Adjust the window position so it is visible.
595                mContainingFrame.top -= mContainingFrame.bottom - cf.bottom;
596            }
597
598            if (freeformWorkspace) {
599                // In free form mode we have only to set the rectangle if it wasn't set already. No
600                // need to intersect it with the (visible) "content frame" since it is allowed to
601                // be outside the visible desktop.
602                if (mContainingFrame.isEmpty()) {
603                    mContainingFrame.set(cf);
604                }
605            }
606            mDisplayFrame.set(mContainingFrame);
607        } else {
608            mContainingFrame.set(pf);
609            mDisplayFrame.set(df);
610        }
611
612        final int pw = mContainingFrame.width();
613        final int ph = mContainingFrame.height();
614
615        int w,h;
616        if ((mAttrs.flags & FLAG_SCALED) != 0) {
617            if (mAttrs.width < 0) {
618                w = pw;
619            } else if (mEnforceSizeCompat) {
620                w = (int)(mAttrs.width * mGlobalScale + .5f);
621            } else {
622                w = mAttrs.width;
623            }
624            if (mAttrs.height < 0) {
625                h = ph;
626            } else if (mEnforceSizeCompat) {
627                h = (int)(mAttrs.height * mGlobalScale + .5f);
628            } else {
629                h = mAttrs.height;
630            }
631        } else {
632            if (mAttrs.width == WindowManager.LayoutParams.MATCH_PARENT) {
633                w = pw;
634            } else if (mEnforceSizeCompat) {
635                w = (int)(mRequestedWidth * mGlobalScale + .5f);
636            } else {
637                w = mRequestedWidth;
638            }
639            if (mAttrs.height == WindowManager.LayoutParams.MATCH_PARENT) {
640                h = ph;
641            } else if (mEnforceSizeCompat) {
642                h = (int)(mRequestedHeight * mGlobalScale + .5f);
643            } else {
644                h = mRequestedHeight;
645            }
646        }
647
648        if (!mParentFrame.equals(pf)) {
649            //Slog.i(TAG, "Window " + this + " content frame from " + mParentFrame
650            //        + " to " + pf);
651            mParentFrame.set(pf);
652            mContentChanged = true;
653        }
654        if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) {
655            mLastRequestedWidth = mRequestedWidth;
656            mLastRequestedHeight = mRequestedHeight;
657            mContentChanged = true;
658        }
659
660        mOverscanFrame.set(of);
661        mContentFrame.set(cf);
662        mVisibleFrame.set(vf);
663        mDecorFrame.set(dcf);
664        mStableFrame.set(sf);
665        final boolean hasOutsets = osf != null;
666        if (hasOutsets) {
667            mOutsetFrame.set(osf);
668        }
669
670        final int fw = mFrame.width();
671        final int fh = mFrame.height();
672
673        float x, y;
674        if (mEnforceSizeCompat) {
675            x = mAttrs.x * mGlobalScale;
676            y = mAttrs.y * mGlobalScale;
677        } else {
678            x = mAttrs.x;
679            y = mAttrs.y;
680        }
681
682        if (nonFullscreenTask) {
683            // Make sure window fits in containing frame since it is in a non-fullscreen stack as
684            // required by {@link Gravity#apply} call.
685            w = Math.min(w, pw);
686            h = Math.min(h, ph);
687        }
688
689        Gravity.apply(mAttrs.gravity, w, h, mContainingFrame,
690                (int) (x + mAttrs.horizontalMargin * pw),
691                (int) (y + mAttrs.verticalMargin * ph), mFrame);
692
693        // Now make sure the window fits in the overall display frame.
694        Gravity.applyDisplay(mAttrs.gravity, mDisplayFrame, mFrame);
695
696        // Calculate the outsets before the content frame gets shrinked to the window frame.
697        if (hasOutsets) {
698            mOutsets.set(Math.max(mContentFrame.left - mOutsetFrame.left, 0),
699                    Math.max(mContentFrame.top - mOutsetFrame.top, 0),
700                    Math.max(mOutsetFrame.right - mContentFrame.right, 0),
701                    Math.max(mOutsetFrame.bottom - mContentFrame.bottom, 0));
702        } else {
703            mOutsets.set(0, 0, 0, 0);
704        }
705
706        // Make sure the content and visible frames are inside of the
707        // final window frame.
708        if (freeformWorkspace && !mFrame.isEmpty()) {
709            // Keep the frame out of the blocked system area, limit it in size to the content area
710            // and make sure that there is always a minimum visible so that the user can drag it
711            // into a usable area..
712            final int height = Math.min(mFrame.height(), mContentFrame.height());
713            final int width = Math.min(mContentFrame.width(), mFrame.width());
714            final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics();
715            final int minVisibleHeight = WindowManagerService.dipToPixel(
716                    MINIMUM_VISIBLE_HEIGHT_IN_DP, displayMetrics);
717            final int minVisibleWidth = WindowManagerService.dipToPixel(
718                    MINIMUM_VISIBLE_WIDTH_IN_DP, displayMetrics);
719            final int top = Math.max(mContentFrame.top,
720                    Math.min(mFrame.top, mContentFrame.bottom - minVisibleHeight));
721            final int left = Math.max(mContentFrame.left + minVisibleWidth - width,
722                    Math.min(mFrame.left, mContentFrame.right - minVisibleWidth));
723            mFrame.set(left, top, left + width, top + height);
724            mContentFrame.set(mFrame);
725            mVisibleFrame.set(mContentFrame);
726            mStableFrame.set(mContentFrame);
727        } else if (mAttrs.type == TYPE_DOCK_DIVIDER) {
728            mDisplayContent.mDividerControllerLocked.positionDockedStackedDivider(mFrame);
729            mContentFrame.set(mFrame);
730        } else {
731            mContentFrame.set(Math.max(mContentFrame.left, mFrame.left),
732                    Math.max(mContentFrame.top, mFrame.top),
733                    Math.min(mContentFrame.right, mFrame.right),
734                    Math.min(mContentFrame.bottom, mFrame.bottom));
735
736            mVisibleFrame.set(Math.max(mVisibleFrame.left, mFrame.left),
737                    Math.max(mVisibleFrame.top, mFrame.top),
738                    Math.min(mVisibleFrame.right, mFrame.right),
739                    Math.min(mVisibleFrame.bottom, mFrame.bottom));
740
741            mStableFrame.set(Math.max(mStableFrame.left, mFrame.left),
742                    Math.max(mStableFrame.top, mFrame.top),
743                    Math.min(mStableFrame.right, mFrame.right),
744                    Math.min(mStableFrame.bottom, mFrame.bottom));
745        }
746
747        mOverscanInsets.set(Math.max(mOverscanFrame.left - mFrame.left, 0),
748                Math.max(mOverscanFrame.top - mFrame.top, 0),
749                Math.max(mFrame.right - mOverscanFrame.right, 0),
750                Math.max(mFrame.bottom - mOverscanFrame.bottom, 0));
751
752        mContentInsets.set(mContentFrame.left - mFrame.left,
753                mContentFrame.top - mFrame.top,
754                mFrame.right - mContentFrame.right,
755                mFrame.bottom - mContentFrame.bottom);
756
757        mVisibleInsets.set(mVisibleFrame.left - mFrame.left,
758                mVisibleFrame.top - mFrame.top,
759                mFrame.right - mVisibleFrame.right,
760                mFrame.bottom - mVisibleFrame.bottom);
761
762        mStableInsets.set(Math.max(mStableFrame.left - mFrame.left, 0),
763                Math.max(mStableFrame.top - mFrame.top, 0),
764                Math.max(mFrame.right - mStableFrame.right, 0),
765                Math.max(mFrame.bottom - mStableFrame.bottom, 0));
766
767        mCompatFrame.set(mFrame);
768        if (mEnforceSizeCompat) {
769            // If there is a size compatibility scale being applied to the
770            // window, we need to apply this to its insets so that they are
771            // reported to the app in its coordinate space.
772            mOverscanInsets.scale(mInvGlobalScale);
773            mContentInsets.scale(mInvGlobalScale);
774            mVisibleInsets.scale(mInvGlobalScale);
775            mStableInsets.scale(mInvGlobalScale);
776            mOutsets.scale(mInvGlobalScale);
777
778            // Also the scaled frame that we report to the app needs to be
779            // adjusted to be in its coordinate space.
780            mCompatFrame.scale(mInvGlobalScale);
781        }
782
783        if (mIsWallpaper && (fw != mFrame.width() || fh != mFrame.height())) {
784            final DisplayContent displayContent = getDisplayContent();
785            if (displayContent != null) {
786                final DisplayInfo displayInfo = displayContent.getDisplayInfo();
787                mService.mWallpaperControllerLocked.updateWallpaperOffset(
788                        this, displayInfo.logicalWidth, displayInfo.logicalHeight, false);
789            }
790        }
791
792        if (DEBUG_LAYOUT || WindowManagerService.localLOGV) Slog.v(TAG,
793                "Resolving (mRequestedWidth="
794                + mRequestedWidth + ", mRequestedheight="
795                + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
796                + "): frame=" + mFrame.toShortString()
797                + " ci=" + mContentInsets.toShortString()
798                + " vi=" + mVisibleInsets.toShortString()
799                + " vi=" + mStableInsets.toShortString()
800                + " of=" + mOutsets.toShortString());
801    }
802
803    @Override
804    public Rect getFrameLw() {
805        return mFrame;
806    }
807
808    @Override
809    public Point getShownPositionLw() {
810        return mShownPosition;
811    }
812
813    @Override
814    public Rect getDisplayFrameLw() {
815        return mDisplayFrame;
816    }
817
818    @Override
819    public Rect getOverscanFrameLw() {
820        return mOverscanFrame;
821    }
822
823    @Override
824    public Rect getContentFrameLw() {
825        return mContentFrame;
826    }
827
828    @Override
829    public Rect getVisibleFrameLw() {
830        return mVisibleFrame;
831    }
832
833    @Override
834    public boolean getGivenInsetsPendingLw() {
835        return mGivenInsetsPending;
836    }
837
838    @Override
839    public Rect getGivenContentInsetsLw() {
840        return mGivenContentInsets;
841    }
842
843    @Override
844    public Rect getGivenVisibleInsetsLw() {
845        return mGivenVisibleInsets;
846    }
847
848    @Override
849    public WindowManager.LayoutParams getAttrs() {
850        return mAttrs;
851    }
852
853    @Override
854    public boolean getNeedsMenuLw(WindowManagerPolicy.WindowState bottom) {
855        int index = -1;
856        WindowState ws = this;
857        WindowList windows = getWindowList();
858        while (true) {
859            if (ws.mAttrs.needsMenuKey != WindowManager.LayoutParams.NEEDS_MENU_UNSET) {
860                return ws.mAttrs.needsMenuKey == WindowManager.LayoutParams.NEEDS_MENU_SET_TRUE;
861            }
862            // If we reached the bottom of the range of windows we are considering,
863            // assume no menu is needed.
864            if (ws == bottom) {
865                return false;
866            }
867            // The current window hasn't specified whether menu key is needed;
868            // look behind it.
869            // First, we may need to determine the starting position.
870            if (index < 0) {
871                index = windows.indexOf(ws);
872            }
873            index--;
874            if (index < 0) {
875                return false;
876            }
877            ws = windows.get(index);
878        }
879    }
880
881    @Override
882    public int getSystemUiVisibility() {
883        return mSystemUiVisibility;
884    }
885
886    @Override
887    public int getSurfaceLayer() {
888        return mLayer;
889    }
890
891    @Override
892    public int getBaseType() {
893        WindowState win = this;
894        while (win.mAttachedWindow != null) {
895            win = win.mAttachedWindow;
896        }
897        return win.mAttrs.type;
898    }
899
900    @Override
901    public IApplicationToken getAppToken() {
902        return mAppToken != null ? mAppToken.appToken : null;
903    }
904
905    @Override
906    public boolean isVoiceInteraction() {
907        return mAppToken != null && mAppToken.voiceInteraction;
908    }
909
910    boolean setInsetsChanged() {
911        mOverscanInsetsChanged |= !mLastOverscanInsets.equals(mOverscanInsets);
912        mContentInsetsChanged |= !mLastContentInsets.equals(mContentInsets);
913        mVisibleInsetsChanged |= !mLastVisibleInsets.equals(mVisibleInsets);
914        mStableInsetsChanged |= !mLastStableInsets.equals(mStableInsets);
915        mOutsetsChanged |= !mLastOutsets.equals(mOutsets);
916        return mOverscanInsetsChanged || mContentInsetsChanged || mVisibleInsetsChanged
917                || mOutsetsChanged;
918    }
919
920    public DisplayContent getDisplayContent() {
921        if (mAppToken == null || mNotOnAppsDisplay) {
922            return mDisplayContent;
923        }
924        final TaskStack stack = getStack();
925        return stack == null ? mDisplayContent : stack.getDisplayContent();
926    }
927
928    public DisplayInfo getDisplayInfo() {
929        final DisplayContent displayContent = getDisplayContent();
930        return displayContent != null ? displayContent.getDisplayInfo() : null;
931    }
932
933    public int getDisplayId() {
934        final DisplayContent displayContent = getDisplayContent();
935        if (displayContent == null) {
936            return -1;
937        }
938        return displayContent.getDisplayId();
939    }
940
941    Task getTask() {
942        return mAppToken != null ? mAppToken.mTask : null;
943    }
944
945    TaskStack getStack() {
946        Task task = getTask();
947        if (task != null) {
948            if (task.mStack != null) {
949                return task.mStack;
950            }
951        }
952        // Some system windows (e.g. "Power off" dialog) don't have a task, but we would still
953        // associate them with some stack to enable dimming.
954        return mAttrs.type >= WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW
955                && mDisplayContent != null ? mDisplayContent.getHomeStack() : null;
956    }
957
958    /**
959     * Retrieves the visible bounds of the window.
960     * @param bounds The rect which gets the bounds.
961     * @param forTouch Pass in BOUNDS_FOR_TOUCH to get touch related bounds, otherwise visible
962     *        bounds will be returned.
963     */
964    void getVisibleBounds(Rect bounds, boolean forTouch) {
965        boolean intersectWithStackBounds = mAppToken != null && mAppToken.mCropWindowsToStack;
966        bounds.setEmpty();
967        mTmpRect.setEmpty();
968        if (intersectWithStackBounds) {
969            final TaskStack stack = getStack();
970            if (stack != null) {
971                stack.getBounds(mTmpRect);
972            } else {
973                intersectWithStackBounds = false;
974            }
975        }
976
977        bounds.set(mVisibleFrame);
978        if (intersectWithStackBounds) {
979            bounds.intersect(mTmpRect);
980        }
981
982        if (bounds.isEmpty()) {
983            bounds.set(mFrame);
984            if (intersectWithStackBounds) {
985                bounds.intersect(mTmpRect);
986            }
987            return;
988        }
989        if (forTouch && inFreeformWorkspace()) {
990            final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics();
991            final int delta = WindowManagerService.dipToPixel(
992                    RESIZE_HANDLE_WIDTH_IN_DP, displayMetrics);
993            bounds.inset(-delta, -delta);
994        }
995    }
996
997    public long getInputDispatchingTimeoutNanos() {
998        return mAppToken != null
999                ? mAppToken.inputDispatchingTimeoutNanos
1000                : WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
1001    }
1002
1003    @Override
1004    public boolean hasAppShownWindows() {
1005        return mAppToken != null && (mAppToken.firstWindowDrawn || mAppToken.startingDisplayed);
1006    }
1007
1008    boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
1009        if (dsdx < .99999f || dsdx > 1.00001f) return false;
1010        if (dtdy < .99999f || dtdy > 1.00001f) return false;
1011        if (dtdx < -.000001f || dtdx > .000001f) return false;
1012        if (dsdy < -.000001f || dsdy > .000001f) return false;
1013        return true;
1014    }
1015
1016    void prelayout() {
1017        if (mEnforceSizeCompat) {
1018            mGlobalScale = mService.mCompatibleScreenScale;
1019            mInvGlobalScale = 1/mGlobalScale;
1020        } else {
1021            mGlobalScale = mInvGlobalScale = 1;
1022        }
1023    }
1024
1025    /**
1026     * Is this window visible?  It is not visible if there is no
1027     * surface, or we are in the process of running an exit animation
1028     * that will remove the surface, or its app token has been hidden.
1029     */
1030    @Override
1031    public boolean isVisibleLw() {
1032        final AppWindowToken atoken = mAppToken;
1033        return mHasSurface && mPolicyVisibility && !mAttachedHidden
1034                && (atoken == null || !atoken.hiddenRequested)
1035                && !mExiting && !mDestroying;
1036    }
1037
1038    /**
1039     * Like {@link #isVisibleLw}, but also counts a window that is currently
1040     * "hidden" behind the keyguard as visible.  This allows us to apply
1041     * things like window flags that impact the keyguard.
1042     * XXX I am starting to think we need to have ANOTHER visibility flag
1043     * for this "hidden behind keyguard" state rather than overloading
1044     * mPolicyVisibility.  Ungh.
1045     */
1046    @Override
1047    public boolean isVisibleOrBehindKeyguardLw() {
1048        if (mRootToken.waitingToShow &&
1049                mService.mAppTransition.isTransitionSet()) {
1050            return false;
1051        }
1052        final AppWindowToken atoken = mAppToken;
1053        final boolean animating = atoken != null && atoken.mAppAnimator.animation != null;
1054        return mHasSurface && !mDestroying && !mExiting
1055                && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
1056                && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
1057                                && !mRootToken.hidden)
1058                        || mWinAnimator.mAnimation != null || animating);
1059    }
1060
1061    /**
1062     * Is this window visible, ignoring its app token?  It is not visible
1063     * if there is no surface, or we are in the process of running an exit animation
1064     * that will remove the surface.
1065     */
1066    public boolean isWinVisibleLw() {
1067        final AppWindowToken atoken = mAppToken;
1068        return mHasSurface && mPolicyVisibility && !mAttachedHidden
1069                && (atoken == null || !atoken.hiddenRequested || atoken.mAppAnimator.animating)
1070                && !mExiting && !mDestroying;
1071    }
1072
1073    /**
1074     * The same as isVisible(), but follows the current hidden state of
1075     * the associated app token, not the pending requested hidden state.
1076     */
1077    boolean isVisibleNow() {
1078        return mHasSurface && mPolicyVisibility && !mAttachedHidden
1079                && (!mRootToken.hidden || mAttrs.type == TYPE_APPLICATION_STARTING)
1080                && !mExiting && !mDestroying;
1081    }
1082
1083    /**
1084     * Can this window possibly be a drag/drop target?  The test here is
1085     * a combination of the above "visible now" with the check that the
1086     * Input Manager uses when discarding windows from input consideration.
1087     */
1088    boolean isPotentialDragTarget() {
1089        return isVisibleNow() && !mRemoved
1090                && mInputChannel != null && mInputWindowHandle != null;
1091    }
1092
1093    /**
1094     * Same as isVisible(), but we also count it as visible between the
1095     * call to IWindowSession.add() and the first relayout().
1096     */
1097    boolean isVisibleOrAdding() {
1098        final AppWindowToken atoken = mAppToken;
1099        return (mHasSurface || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
1100                && mPolicyVisibility && !mAttachedHidden
1101                && (atoken == null || !atoken.hiddenRequested)
1102                && !mExiting && !mDestroying;
1103    }
1104
1105    /**
1106     * Is this window currently on-screen?  It is on-screen either if it
1107     * is visible or it is currently running an animation before no longer
1108     * being visible.
1109     */
1110    boolean isOnScreen() {
1111        return mPolicyVisibility && isOnScreenIgnoringKeyguard();
1112    }
1113
1114    /**
1115     * Like isOnScreen(), but ignores any force hiding of the window due
1116     * to the keyguard.
1117     */
1118    boolean isOnScreenIgnoringKeyguard() {
1119        if (!mHasSurface || mDestroying) {
1120            return false;
1121        }
1122        final AppWindowToken atoken = mAppToken;
1123        if (atoken != null) {
1124            return ((!mAttachedHidden && !atoken.hiddenRequested)
1125                    || mWinAnimator.mAnimation != null || atoken.mAppAnimator.animation != null);
1126        }
1127        return !mAttachedHidden || mWinAnimator.mAnimation != null;
1128    }
1129
1130    /**
1131     * Like isOnScreen(), but we don't return true if the window is part
1132     * of a transition that has not yet been started.
1133     */
1134    boolean isReadyForDisplay() {
1135        if (mRootToken.waitingToShow && mService.mAppTransition.isTransitionSet()) {
1136            return false;
1137        }
1138        return mHasSurface && mPolicyVisibility && !mDestroying
1139                && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
1140                                && !mRootToken.hidden)
1141                        || mWinAnimator.mAnimation != null
1142                        || ((mAppToken != null) && (mAppToken.mAppAnimator.animation != null)));
1143    }
1144
1145    /**
1146     * Like isReadyForDisplay(), but ignores any force hiding of the window due
1147     * to the keyguard.
1148     */
1149    boolean isReadyForDisplayIgnoringKeyguard() {
1150        if (mRootToken.waitingToShow && mService.mAppTransition.isTransitionSet()) {
1151            return false;
1152        }
1153        final AppWindowToken atoken = mAppToken;
1154        if (atoken == null && !mPolicyVisibility) {
1155            // If this is not an app window, and the policy has asked to force
1156            // hide, then we really do want to hide.
1157            return false;
1158        }
1159        return mHasSurface && !mDestroying
1160                && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
1161                                && !mRootToken.hidden)
1162                        || mWinAnimator.mAnimation != null
1163                        || ((atoken != null) && (atoken.mAppAnimator.animation != null)
1164                                && !mWinAnimator.isDummyAnimation()));
1165    }
1166
1167    /**
1168     * Like isOnScreen, but returns false if the surface hasn't yet
1169     * been drawn.
1170     */
1171    @Override
1172    public boolean isDisplayedLw() {
1173        final AppWindowToken atoken = mAppToken;
1174        return isDrawnLw() && mPolicyVisibility
1175            && ((!mAttachedHidden &&
1176                    (atoken == null || !atoken.hiddenRequested))
1177                        || mWinAnimator.mAnimating
1178                        || (atoken != null && atoken.mAppAnimator.animation != null));
1179    }
1180
1181    /**
1182     * Return true if this window or its app token is currently animating.
1183     */
1184    @Override
1185    public boolean isAnimatingLw() {
1186        return mWinAnimator.mAnimation != null
1187                || (mAppToken != null && mAppToken.mAppAnimator.animation != null);
1188    }
1189
1190    @Override
1191    public boolean isGoneForLayoutLw() {
1192        final AppWindowToken atoken = mAppToken;
1193        return mViewVisibility == View.GONE
1194                || !mRelayoutCalled
1195                || (atoken == null && mRootToken.hidden)
1196                || (atoken != null && (atoken.hiddenRequested || atoken.hidden))
1197                || mAttachedHidden
1198                || (mExiting && !isAnimatingLw())
1199                || mDestroying;
1200    }
1201
1202    /**
1203     * Returns true if the window has a surface that it has drawn a
1204     * complete UI in to.
1205     */
1206    public boolean isDrawFinishedLw() {
1207        return mHasSurface && !mDestroying &&
1208                (mWinAnimator.mDrawState == WindowStateAnimator.COMMIT_DRAW_PENDING
1209                || mWinAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW
1210                || mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN);
1211    }
1212
1213    /**
1214     * Returns true if the window has a surface that it has drawn a
1215     * complete UI in to.
1216     */
1217    @Override
1218    public boolean isDrawnLw() {
1219        return mHasSurface && !mDestroying &&
1220                (mWinAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW
1221                || mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN);
1222    }
1223
1224    /**
1225     * Return true if the window is opaque and fully drawn.  This indicates
1226     * it may obscure windows behind it.
1227     */
1228    boolean isOpaqueDrawn() {
1229        return (mAttrs.format == PixelFormat.OPAQUE
1230                        || mAttrs.type == TYPE_WALLPAPER)
1231                && isDrawnLw() && mWinAnimator.mAnimation == null
1232                && (mAppToken == null || mAppToken.mAppAnimator.animation == null);
1233    }
1234
1235    /**
1236     * Return whether this window has moved. (Only makes
1237     * sense to call from performLayoutAndPlaceSurfacesLockedInner().)
1238     */
1239    boolean hasMoved() {
1240        return mHasSurface && mContentChanged && !mExiting && !mWinAnimator.mLastHidden
1241                && mService.okToDisplay() && (mFrame.top != mLastFrame.top
1242                        || mFrame.left != mLastFrame.left)
1243                && (mAttachedWindow == null || !mAttachedWindow.hasMoved());
1244    }
1245
1246    boolean isFullscreen(int screenWidth, int screenHeight) {
1247        return mFrame.left <= 0 && mFrame.top <= 0 &&
1248                mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
1249    }
1250
1251    boolean isConfigChanged() {
1252        final Task task = getTask();
1253        final Configuration overrideConfig =
1254                (task != null) ? task.mOverrideConfig : Configuration.EMPTY;
1255        final Configuration serviceConfig = mService.mCurConfiguration;
1256        boolean configChanged =
1257                (mConfiguration != serviceConfig && mConfiguration.diff(serviceConfig) != 0)
1258                || (mOverrideConfig != overrideConfig && !mOverrideConfig.equals(overrideConfig));
1259
1260        if ((mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
1261            // Retain configuration changed status until resetConfiguration called.
1262            mConfigHasChanged |= configChanged;
1263            configChanged = mConfigHasChanged;
1264        }
1265
1266        return configChanged;
1267    }
1268
1269    void removeLocked() {
1270        disposeInputChannel();
1271
1272        if (mAttachedWindow != null) {
1273            if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + this + " from " + mAttachedWindow);
1274            mAttachedWindow.mChildWindows.remove(this);
1275        }
1276        mWinAnimator.destroyDeferredSurfaceLocked();
1277        mWinAnimator.destroySurfaceLocked();
1278        mSession.windowRemovedLocked();
1279        try {
1280            mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
1281        } catch (RuntimeException e) {
1282            // Ignore if it has already been removed (usually because
1283            // we are doing this as part of processing a death note.)
1284        }
1285    }
1286
1287    private void setConfiguration(
1288            final Configuration newConfig, final Configuration newOverrideConfig) {
1289        mConfiguration = newConfig;
1290        mOverrideConfig = newOverrideConfig;
1291        mConfigHasChanged = false;
1292    }
1293
1294    private final class DeadWindowEventReceiver extends InputEventReceiver {
1295        DeadWindowEventReceiver(InputChannel inputChannel) {
1296            super(inputChannel, mService.mH.getLooper());
1297        }
1298        @Override
1299        public void onInputEvent(InputEvent event) {
1300            finishInputEvent(event, true);
1301        }
1302    }
1303    /**
1304     *  Dummy event receiver for windows that died visible.
1305     */
1306    private DeadWindowEventReceiver mDeadWindowEventReceiver;
1307
1308    void openInputChannel(InputChannel outInputChannel) {
1309        if (mInputChannel != null) {
1310            throw new IllegalStateException("Window already has an input channel.");
1311        }
1312        String name = makeInputChannelName();
1313        InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
1314        mInputChannel = inputChannels[0];
1315        mClientChannel = inputChannels[1];
1316        mInputWindowHandle.inputChannel = inputChannels[0];
1317        if (outInputChannel != null) {
1318            mClientChannel.transferTo(outInputChannel);
1319            mClientChannel.dispose();
1320            mClientChannel = null;
1321        } else {
1322            // If the window died visible, we setup a dummy input channel, so that taps
1323            // can still detected by input monitor channel, and we can relaunch the app.
1324            // Create dummy event receiver that simply reports all events as handled.
1325            mDeadWindowEventReceiver = new DeadWindowEventReceiver(mClientChannel);
1326        }
1327        mService.mInputManager.registerInputChannel(mInputChannel, mInputWindowHandle);
1328    }
1329
1330    void disposeInputChannel() {
1331        if (mDeadWindowEventReceiver != null) {
1332            mDeadWindowEventReceiver.dispose();
1333            mDeadWindowEventReceiver = null;
1334        }
1335
1336        // unregister server channel first otherwise it complains about broken channel
1337        if (mInputChannel != null) {
1338            mService.mInputManager.unregisterInputChannel(mInputChannel);
1339            mInputChannel.dispose();
1340            mInputChannel = null;
1341        }
1342        if (mClientChannel != null) {
1343            mClientChannel.dispose();
1344            mClientChannel = null;
1345        }
1346        mInputWindowHandle.inputChannel = null;
1347    }
1348
1349    void applyDimLayerIfNeeded() {
1350        if (!mExiting && mAppDied) {
1351            // If app died visible, apply a dim over the window to indicate that it's inactive
1352            mDisplayContent.mDimLayerController.applyDimAbove(getDimLayerUser(), mWinAnimator);
1353        } else if ((mAttrs.flags & FLAG_DIM_BEHIND) != 0
1354                && mDisplayContent != null && !mExiting && isDisplayedLw()) {
1355            mDisplayContent.mDimLayerController.applyDimBehind(getDimLayerUser(), mWinAnimator);
1356        }
1357    }
1358
1359    DimLayer.DimLayerUser getDimLayerUser() {
1360        Task task = getTask();
1361        if (task != null) {
1362            return task;
1363        }
1364        return getStack();
1365    }
1366
1367    void maybeRemoveReplacedWindow() {
1368        AppWindowToken token = mAppToken;
1369        if (token != null && token.mWillReplaceWindow && token.mReplacingWindow == this) {
1370            if (DEBUG_ADD_REMOVE) Slog.d(TAG, "Removing replacing window: " + this);
1371            token.mWillReplaceWindow = false;
1372            token.mAnimateReplacingWindow = false;
1373            token.mReplacingRemoveRequested = false;
1374            token.mReplacingWindow = null;
1375            for (int i = token.allAppWindows.size() - 1; i >= 0; i--) {
1376                WindowState win = token.allAppWindows.get(i);
1377                if (win.mExiting) {
1378                    mService.removeWindowInnerLocked(win);
1379                }
1380            }
1381        }
1382    }
1383
1384    void setDisplayLayoutNeeded() {
1385        if (mDisplayContent != null) {
1386            mDisplayContent.layoutNeeded = true;
1387        }
1388    }
1389
1390    boolean inDockedWorkspace() {
1391        return mAppToken != null && mAppToken.mTask != null && mAppToken.mTask.inDockedWorkspace();
1392    }
1393
1394    int getTouchableRegion(Region region, int flags, InputMonitor inputMonitor) {
1395        final boolean modal = (flags & (WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
1396                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) == 0;
1397        if (modal && mAppToken != null) {
1398            // Limit the outer touch to the activity stack region.
1399            flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
1400            if (!inFreeformWorkspace()) {
1401                // If this is a modal window we need to dismiss it if it's not full screen and the
1402                // touch happens outside of the frame that displays the content. This means we
1403                // need to intercept touches outside of that window. The dim layer user
1404                // associated with the window (task or stack) will give us the good bounds, as
1405                // they would be used to display the dim layer.
1406                final DimLayer.DimLayerUser dimLayerUser = getDimLayerUser();
1407                if (dimLayerUser != null) {
1408                    dimLayerUser.getBounds(mTmpRect);
1409                } else {
1410                    getVisibleBounds(mTmpRect, BOUNDS_FOR_TOUCH);
1411                }
1412            } else {
1413                // For freeform windows we the touch region to include the whole surface for the
1414                // shadows.
1415                getVisibleBounds(mTmpRect, BOUNDS_FOR_TOUCH);
1416            }
1417            region.set(mTmpRect);
1418        } else {
1419            // Not modal or full screen modal
1420            getTouchableRegion(region);
1421        }
1422        return flags;
1423    }
1424
1425    void checkPolicyVisibilityChange() {
1426        if (mPolicyVisibility != mPolicyVisibilityAfterAnim) {
1427            if (DEBUG_VISIBILITY) {
1428                Slog.v(TAG, "Policy visibility changing after anim in " +
1429                        mWinAnimator + ": " + mPolicyVisibilityAfterAnim);
1430            }
1431            mPolicyVisibility = mPolicyVisibilityAfterAnim;
1432            if (mDisplayContent != null) {
1433                mDisplayContent.layoutNeeded = true;
1434            }
1435            if (!mPolicyVisibility) {
1436                if (mService.mCurrentFocus == this) {
1437                    if (DEBUG_FOCUS_LIGHT) Slog.i(TAG,
1438                            "setAnimationLocked: setting mFocusMayChange true");
1439                    mService.mFocusMayChange = true;
1440                }
1441                // Window is no longer visible -- make sure if we were waiting
1442                // for it to be displayed before enabling the display, that
1443                // we allow the display to be enabled now.
1444                mService.enableScreenIfNeededLocked();
1445            }
1446        }
1447    }
1448
1449    void setRequestedSize(int requestedWidth, int requestedHeight) {
1450        if ((mRequestedWidth != requestedWidth || mRequestedHeight != requestedHeight)) {
1451            mLayoutNeeded = true;
1452            mRequestedWidth = requestedWidth;
1453            mRequestedHeight = requestedHeight;
1454        }
1455    }
1456
1457    void prepareWindowToDisplayDuringRelayout(Configuration outConfig) {
1458        if ((mAttrs.softInputMode & SOFT_INPUT_MASK_ADJUST)
1459                == SOFT_INPUT_ADJUST_RESIZE) {
1460            mLayoutNeeded = true;
1461        }
1462        if (isDrawnLw() && mService.okToDisplay()) {
1463            mWinAnimator.applyEnterAnimationLocked();
1464        }
1465        if ((mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0) {
1466            if (DEBUG_VISIBILITY) Slog.v(TAG, "Relayout window turning screen on: " + this);
1467            mTurnOnScreen = true;
1468        }
1469        if (isConfigChanged()) {
1470            if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + this + " visible with new config: "
1471                    + mService.mCurConfiguration);
1472            outConfig.setTo(mService.mCurConfiguration);
1473        }
1474    }
1475
1476    void adjustStartingWindowFlags() {
1477        if (mAttrs.type == TYPE_BASE_APPLICATION && mAppToken != null
1478                && mAppToken.startingWindow != null) {
1479            // Special handling of starting window over the base
1480            // window of the app: propagate lock screen flags to it,
1481            // to provide the correct semantics while starting.
1482            final int mask = FLAG_SHOW_WHEN_LOCKED | FLAG_DISMISS_KEYGUARD
1483                    | FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
1484            WindowManager.LayoutParams sa = mAppToken.startingWindow.mAttrs;
1485            sa.flags = (sa.flags & ~mask) | (mAttrs.flags & mask);
1486        }
1487    }
1488
1489    void setWindowScale(int requestedWidth, int requestedHeight) {
1490        final boolean scaledWindow = (mAttrs.flags & FLAG_SCALED) != 0;
1491
1492        if (scaledWindow) {
1493            // requested{Width|Height} Surface's physical size
1494            // attrs.{width|height} Size on screen
1495            // TODO: We don't check if attrs != null here. Is it implicitly checked?
1496            mHScale = (mAttrs.width  != requestedWidth)  ?
1497                    (mAttrs.width  / (float)requestedWidth) : 1.0f;
1498            mVScale = (mAttrs.height != requestedHeight) ?
1499                    (mAttrs.height / (float)requestedHeight) : 1.0f;
1500        } else {
1501            mHScale = mVScale = 1;
1502        }
1503    }
1504
1505    private class DeathRecipient implements IBinder.DeathRecipient {
1506        @Override
1507        public void binderDied() {
1508            try {
1509                synchronized(mService.mWindowMap) {
1510                    WindowState win = mService.windowForClientLocked(mSession, mClient, false);
1511                    Slog.i(TAG, "WIN DEATH: " + win);
1512                    if (win != null) {
1513                        if (win.mAppToken != null && !win.mAppToken.clientHidden) {
1514                            win.mAppToken.appDied = true;
1515                        }
1516                        mService.removeWindowLocked(win);
1517                    } else if (mHasSurface) {
1518                        Slog.e(TAG, "!!! LEAK !!! Window removed but surface still valid.");
1519                        mService.removeWindowLocked(WindowState.this);
1520                    }
1521                }
1522            } catch (IllegalArgumentException ex) {
1523                // This will happen if the window has already been
1524                // removed.
1525            }
1526        }
1527    }
1528
1529    /**
1530     * @return true if this window desires key events.
1531     */
1532    public final boolean canReceiveKeys() {
1533        return isVisibleOrAdding()
1534                && (mViewVisibility == View.VISIBLE)
1535                && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0);
1536    }
1537
1538    @Override
1539    public boolean hasDrawnLw() {
1540        return mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN;
1541    }
1542
1543    @Override
1544    public boolean showLw(boolean doAnimation) {
1545        return showLw(doAnimation, true);
1546    }
1547
1548    boolean showLw(boolean doAnimation, boolean requestAnim) {
1549        if (isHiddenFromUserLocked()) {
1550            return false;
1551        }
1552        if (!mAppOpVisibility) {
1553            // Being hidden due to app op request.
1554            return false;
1555        }
1556        if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
1557            // Already showing.
1558            return false;
1559        }
1560        if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
1561        if (doAnimation) {
1562            if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
1563                    + mPolicyVisibility + " mAnimation=" + mWinAnimator.mAnimation);
1564            if (!mService.okToDisplay()) {
1565                doAnimation = false;
1566            } else if (mPolicyVisibility && mWinAnimator.mAnimation == null) {
1567                // Check for the case where we are currently visible and
1568                // not animating; we do not want to do animation at such a
1569                // point to become visible when we already are.
1570                doAnimation = false;
1571            }
1572        }
1573        mPolicyVisibility = true;
1574        mPolicyVisibilityAfterAnim = true;
1575        if (doAnimation) {
1576            mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_ENTER, true);
1577        }
1578        if (requestAnim) {
1579            mService.scheduleAnimationLocked();
1580        }
1581        return true;
1582    }
1583
1584    @Override
1585    public boolean hideLw(boolean doAnimation) {
1586        return hideLw(doAnimation, true);
1587    }
1588
1589    boolean hideLw(boolean doAnimation, boolean requestAnim) {
1590        if (doAnimation) {
1591            if (!mService.okToDisplay()) {
1592                doAnimation = false;
1593            }
1594        }
1595        boolean current = doAnimation ? mPolicyVisibilityAfterAnim
1596                : mPolicyVisibility;
1597        if (!current) {
1598            // Already hiding.
1599            return false;
1600        }
1601        if (doAnimation) {
1602            mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT, false);
1603            if (mWinAnimator.mAnimation == null) {
1604                doAnimation = false;
1605            }
1606        }
1607        if (doAnimation) {
1608            mPolicyVisibilityAfterAnim = false;
1609        } else {
1610            if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this);
1611            mPolicyVisibilityAfterAnim = false;
1612            mPolicyVisibility = false;
1613            // Window is no longer visible -- make sure if we were waiting
1614            // for it to be displayed before enabling the display, that
1615            // we allow the display to be enabled now.
1616            mService.enableScreenIfNeededLocked();
1617            if (mService.mCurrentFocus == this) {
1618                if (DEBUG_FOCUS_LIGHT) Slog.i(TAG,
1619                        "WindowState.hideLw: setting mFocusMayChange true");
1620                mService.mFocusMayChange = true;
1621            }
1622        }
1623        if (requestAnim) {
1624            mService.scheduleAnimationLocked();
1625        }
1626        return true;
1627    }
1628
1629    public void setAppOpVisibilityLw(boolean state) {
1630        if (mAppOpVisibility != state) {
1631            mAppOpVisibility = state;
1632            if (state) {
1633                // If the policy visibility had last been to hide, then this
1634                // will incorrectly show at this point since we lost that
1635                // information.  Not a big deal -- for the windows that have app
1636                // ops modifies they should only be hidden by policy due to the
1637                // lock screen, and the user won't be changing this if locked.
1638                // Plus it will quickly be fixed the next time we do a layout.
1639                showLw(true, true);
1640            } else {
1641                hideLw(true, true);
1642            }
1643        }
1644    }
1645
1646    public void pokeDrawLockLw(long timeout) {
1647        if (isVisibleOrAdding()) {
1648            if (mDrawLock == null) {
1649                // We want the tag name to be somewhat stable so that it is easier to correlate
1650                // in wake lock statistics.  So in particular, we don't want to include the
1651                // window's hash code as in toString().
1652                final CharSequence tag = getWindowTag();
1653                mDrawLock = mService.mPowerManager.newWakeLock(
1654                        PowerManager.DRAW_WAKE_LOCK, "Window:" + tag);
1655                mDrawLock.setReferenceCounted(false);
1656                mDrawLock.setWorkSource(new WorkSource(mOwnerUid, mAttrs.packageName));
1657            }
1658            // Each call to acquire resets the timeout.
1659            if (DEBUG_POWER) {
1660                Slog.d(TAG, "pokeDrawLock: poking draw lock on behalf of visible window owned by "
1661                        + mAttrs.packageName);
1662            }
1663            mDrawLock.acquire(timeout);
1664        } else if (DEBUG_POWER) {
1665            Slog.d(TAG, "pokeDrawLock: suppressed draw lock request for invisible window "
1666                    + "owned by " + mAttrs.packageName);
1667        }
1668    }
1669
1670    @Override
1671    public boolean isAlive() {
1672        return mClient.asBinder().isBinderAlive();
1673    }
1674
1675    boolean isClosing() {
1676        return mExiting || (mService.mClosingApps.contains(mAppToken));
1677    }
1678
1679    boolean isAnimatingWithSavedSurface() {
1680        return mAppToken != null && mAppToken.mAnimatingWithSavedSurface;
1681    }
1682
1683    boolean shouldSaveSurface() {
1684        if (ActivityManager.isLowRamDeviceStatic()) {
1685            // Don't save surfaces on Svelte devices.
1686            return false;
1687        }
1688
1689        Task task = getTask();
1690        if (task == null || task.inHomeStack()
1691                || task.getTopAppWindowToken() != mAppToken) {
1692            // Don't save surfaces for home stack apps. These usually resume and draw
1693            // first frame very fast. Saving surfaces are mostly a waste of memory.
1694            // Don't save if the window is not the topmost window.
1695            return false;
1696        }
1697
1698        return mAppToken.shouldSaveSurface();
1699    }
1700
1701    @Override
1702    public boolean isDefaultDisplay() {
1703        final DisplayContent displayContent = getDisplayContent();
1704        if (displayContent == null) {
1705            // Only a window that was on a non-default display can be detached from it.
1706            return false;
1707        }
1708        return displayContent.isDefaultDisplay;
1709    }
1710
1711    @Override
1712    public boolean isDimming() {
1713        final DimLayer.DimLayerUser dimLayerUser = getDimLayerUser();
1714        return dimLayerUser != null && mDisplayContent != null &&
1715                mDisplayContent.mDimLayerController.isDimming(dimLayerUser, mWinAnimator);
1716    }
1717
1718    public void setShowToOwnerOnlyLocked(boolean showToOwnerOnly) {
1719        mShowToOwnerOnly = showToOwnerOnly;
1720    }
1721
1722    boolean isHiddenFromUserLocked() {
1723        // Attached windows are evaluated based on the window that they are attached to.
1724        WindowState win = this;
1725        while (win.mAttachedWindow != null) {
1726            win = win.mAttachedWindow;
1727        }
1728        if (win.mAttrs.type < WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW
1729                && win.mAppToken != null && win.mAppToken.showForAllUsers) {
1730            // Save some cycles by not calling getDisplayInfo unless it is an application
1731            // window intended for all users.
1732            final DisplayContent displayContent = win.getDisplayContent();
1733            if (displayContent == null) {
1734                return true;
1735            }
1736            final DisplayInfo displayInfo = displayContent.getDisplayInfo();
1737            if (win.mFrame.left <= 0 && win.mFrame.top <= 0
1738                    && win.mFrame.right >= displayInfo.appWidth
1739                    && win.mFrame.bottom >= displayInfo.appHeight) {
1740                // Is a fullscreen window, like the clock alarm. Show to everyone.
1741                return false;
1742            }
1743        }
1744
1745        return win.mShowToOwnerOnly
1746                && !mService.isCurrentProfileLocked(UserHandle.getUserId(win.mOwnerUid));
1747    }
1748
1749    private static void applyInsets(Region outRegion, Rect frame, Rect inset) {
1750        outRegion.set(
1751                frame.left + inset.left, frame.top + inset.top,
1752                frame.right - inset.right, frame.bottom - inset.bottom);
1753    }
1754
1755    public void getTouchableRegion(Region outRegion) {
1756        final Rect frame = mFrame;
1757        switch (mTouchableInsets) {
1758            default:
1759            case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
1760                outRegion.set(frame);
1761                break;
1762            case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT:
1763                applyInsets(outRegion, frame, mGivenContentInsets);
1764                break;
1765            case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE:
1766                applyInsets(outRegion, frame, mGivenVisibleInsets);
1767                break;
1768            case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION: {
1769                final Region givenTouchableRegion = mGivenTouchableRegion;
1770                outRegion.set(givenTouchableRegion);
1771                outRegion.translate(frame.left, frame.top);
1772                break;
1773            }
1774        }
1775    }
1776
1777    WindowList getWindowList() {
1778        final DisplayContent displayContent = getDisplayContent();
1779        return displayContent == null ? null : displayContent.getWindowList();
1780    }
1781
1782    /**
1783     * Report a focus change.  Must be called with no locks held, and consistently
1784     * from the same serialized thread (such as dispatched from a handler).
1785     */
1786    public void reportFocusChangedSerialized(boolean focused, boolean inTouchMode) {
1787        try {
1788            mClient.windowFocusChanged(focused, inTouchMode);
1789        } catch (RemoteException e) {
1790        }
1791        if (mFocusCallbacks != null) {
1792            final int N = mFocusCallbacks.beginBroadcast();
1793            for (int i=0; i<N; i++) {
1794                IWindowFocusObserver obs = mFocusCallbacks.getBroadcastItem(i);
1795                try {
1796                    if (focused) {
1797                        obs.focusGained(mWindowId.asBinder());
1798                    } else {
1799                        obs.focusLost(mWindowId.asBinder());
1800                    }
1801                } catch (RemoteException e) {
1802                }
1803            }
1804            mFocusCallbacks.finishBroadcast();
1805        }
1806    }
1807
1808    void reportResized() {
1809        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wm.reportResized_" + getWindowTag());
1810        try {
1811            if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, "Reporting new frame to " + this
1812                    + ": " + mCompatFrame);
1813            final boolean configChanged = isConfigChanged();
1814            final Task task = getTask();
1815            final Configuration overrideConfig =
1816                    (task != null) ? task.mOverrideConfig : Configuration.EMPTY;
1817            if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION) && configChanged) {
1818                Slog.i(TAG, "Sending new config to window " + this + ": "
1819                        + mWinAnimator.mSurfaceW + "x" + mWinAnimator.mSurfaceH + " / config="
1820                        + mService.mCurConfiguration + " overrideConfig=" + overrideConfig);
1821            }
1822            setConfiguration(mService.mCurConfiguration, overrideConfig);
1823            if (DEBUG_ORIENTATION && mWinAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING)
1824                Slog.i(TAG, "Resizing " + this + " WITH DRAW PENDING");
1825
1826            final Rect frame = mFrame;
1827            final Rect overscanInsets = mLastOverscanInsets;
1828            final Rect contentInsets = mLastContentInsets;
1829            final Rect visibleInsets = mLastVisibleInsets;
1830            final Rect stableInsets = mLastStableInsets;
1831            final Rect outsets = mLastOutsets;
1832            final boolean reportDraw = mWinAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING;
1833            final Configuration newConfig = configChanged ? mConfiguration : null;
1834            if (mAttrs.type != WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
1835                    && mClient instanceof IWindow.Stub) {
1836                // To prevent deadlock simulate one-way call if win.mClient is a local object.
1837                mService.mH.post(new Runnable() {
1838                    @Override
1839                    public void run() {
1840                        try {
1841                            mClient.resized(frame, overscanInsets, contentInsets,
1842                                    visibleInsets, stableInsets, outsets, reportDraw, newConfig);
1843                        } catch (RemoteException e) {
1844                            // Not a remote call, RemoteException won't be raised.
1845                        }
1846                    }
1847                });
1848            } else {
1849                mClient.resized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets,
1850                        outsets, reportDraw, newConfig);
1851            }
1852
1853            //TODO (multidisplay): Accessibility supported only for the default display.
1854            if (mService.mAccessibilityController != null
1855                    && getDisplayId() == Display.DEFAULT_DISPLAY) {
1856                mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
1857            }
1858
1859            mOverscanInsetsChanged = false;
1860            mContentInsetsChanged = false;
1861            mVisibleInsetsChanged = false;
1862            mStableInsetsChanged = false;
1863            mOutsetsChanged = false;
1864            mWinAnimator.mSurfaceResized = false;
1865        } catch (RemoteException e) {
1866            mOrientationChanging = false;
1867            mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
1868                    - mService.mDisplayFreezeTime);
1869            // We are assuming the hosting process is dead or in a zombie state.
1870            Slog.w(TAG, "Failed to report 'resized' to the client of " + this
1871                    + ", removing this window.");
1872            mService.mPendingRemove.add(this);
1873            mService.mWindowPlacerLocked.requestTraversal();
1874        }
1875        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
1876    }
1877
1878    public void registerFocusObserver(IWindowFocusObserver observer) {
1879        synchronized(mService.mWindowMap) {
1880            if (mFocusCallbacks == null) {
1881                mFocusCallbacks = new RemoteCallbackList<IWindowFocusObserver>();
1882            }
1883            mFocusCallbacks.register(observer);
1884        }
1885    }
1886
1887    public void unregisterFocusObserver(IWindowFocusObserver observer) {
1888        synchronized(mService.mWindowMap) {
1889            if (mFocusCallbacks != null) {
1890                mFocusCallbacks.unregister(observer);
1891            }
1892        }
1893    }
1894
1895    public boolean isFocused() {
1896        synchronized(mService.mWindowMap) {
1897            return mService.mCurrentFocus == this;
1898        }
1899    }
1900
1901    boolean inFreeformWorkspace() {
1902        final Task task = getTask();
1903        return task != null && task.inFreeformWorkspace();
1904    }
1905
1906    boolean isDragResizeChanged() {
1907        return mDragResizing != computeDragResizing();
1908    }
1909
1910    private boolean computeDragResizing() {
1911        final Task task = getTask();
1912        if (task == null) {
1913            return false;
1914        }
1915        if (task.isDragResizing()) {
1916            return true;
1917        }
1918        return mDisplayContent.mDividerControllerLocked.isResizing() &&
1919                !task.inFreeformWorkspace() && !task.isFullscreen();
1920    }
1921
1922    void setDragResizing() {
1923        mDragResizing = computeDragResizing();
1924    }
1925
1926    boolean isDragResizing() {
1927        return mDragResizing;
1928    }
1929
1930    void dump(PrintWriter pw, String prefix, boolean dumpAll) {
1931        final TaskStack stack = getStack();
1932        pw.print(prefix); pw.print("mDisplayId="); pw.print(getDisplayId());
1933                if (stack != null) {
1934                    pw.print(" stackId="); pw.print(stack.mStackId);
1935                }
1936                pw.print(" mSession="); pw.print(mSession);
1937                pw.print(" mClient="); pw.println(mClient.asBinder());
1938        pw.print(prefix); pw.print("mOwnerUid="); pw.print(mOwnerUid);
1939                pw.print(" mShowToOwnerOnly="); pw.print(mShowToOwnerOnly);
1940                pw.print(" package="); pw.print(mAttrs.packageName);
1941                pw.print(" appop="); pw.println(AppOpsManager.opToName(mAppOp));
1942        pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
1943        pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
1944                pw.print(" h="); pw.print(mRequestedHeight);
1945                pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
1946        if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) {
1947            pw.print(prefix); pw.print("LastRequested w="); pw.print(mLastRequestedWidth);
1948                    pw.print(" h="); pw.println(mLastRequestedHeight);
1949        }
1950        if (mAttachedWindow != null || mLayoutAttached) {
1951            pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow);
1952                    pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
1953        }
1954        if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
1955            pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
1956                    pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
1957                    pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
1958                    pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
1959        }
1960        if (dumpAll) {
1961            pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
1962                    pw.print(" mSubLayer="); pw.print(mSubLayer);
1963                    pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
1964                    pw.print((mTargetAppToken != null ?
1965                            mTargetAppToken.mAppAnimator.animLayerAdjustment
1966                          : (mAppToken != null ? mAppToken.mAppAnimator.animLayerAdjustment : 0)));
1967                    pw.print("="); pw.print(mWinAnimator.mAnimLayer);
1968                    pw.print(" mLastLayer="); pw.println(mWinAnimator.mLastLayer);
1969        }
1970        if (dumpAll) {
1971            pw.print(prefix); pw.print("mToken="); pw.println(mToken);
1972            pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
1973            if (mAppToken != null) {
1974                pw.print(prefix); pw.print("mAppToken="); pw.print(mAppToken);
1975                pw.print(" mAppDied=");pw.println(mAppDied);
1976            }
1977            if (mTargetAppToken != null) {
1978                pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken);
1979            }
1980            pw.print(prefix); pw.print("mViewVisibility=0x");
1981            pw.print(Integer.toHexString(mViewVisibility));
1982            pw.print(" mHaveFrame="); pw.print(mHaveFrame);
1983            pw.print(" mObscured="); pw.println(mObscured);
1984            pw.print(prefix); pw.print("mSeq="); pw.print(mSeq);
1985            pw.print(" mSystemUiVisibility=0x");
1986            pw.println(Integer.toHexString(mSystemUiVisibility));
1987        }
1988        if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || !mAppOpVisibility
1989                || mAttachedHidden) {
1990            pw.print(prefix); pw.print("mPolicyVisibility=");
1991                    pw.print(mPolicyVisibility);
1992                    pw.print(" mPolicyVisibilityAfterAnim=");
1993                    pw.print(mPolicyVisibilityAfterAnim);
1994                    pw.print(" mAppOpVisibility=");
1995                    pw.print(mAppOpVisibility);
1996                    pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
1997        }
1998        if (!mRelayoutCalled || mLayoutNeeded) {
1999            pw.print(prefix); pw.print("mRelayoutCalled="); pw.print(mRelayoutCalled);
2000                    pw.print(" mLayoutNeeded="); pw.println(mLayoutNeeded);
2001        }
2002        if (mXOffset != 0 || mYOffset != 0) {
2003            pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
2004                    pw.print(" y="); pw.println(mYOffset);
2005        }
2006        if (dumpAll) {
2007            pw.print(prefix); pw.print("mGivenContentInsets=");
2008                    mGivenContentInsets.printShortString(pw);
2009                    pw.print(" mGivenVisibleInsets=");
2010                    mGivenVisibleInsets.printShortString(pw);
2011                    pw.println();
2012            if (mTouchableInsets != 0 || mGivenInsetsPending) {
2013                pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets);
2014                        pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending);
2015                Region region = new Region();
2016                getTouchableRegion(region);
2017                pw.print(prefix); pw.print("touchable region="); pw.println(region);
2018            }
2019            pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
2020            if (mOverrideConfig != Configuration.EMPTY) {
2021                pw.print(prefix); pw.print("mOverrideConfig="); pw.println(mOverrideConfig);
2022            }
2023        }
2024        pw.print(prefix); pw.print("mHasSurface="); pw.print(mHasSurface);
2025                pw.print(" mShownPosition="); mShownPosition.printShortString(pw);
2026                pw.print(" isReadyForDisplay()="); pw.println(isReadyForDisplay());
2027        if (dumpAll) {
2028            pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
2029                    pw.print(" last="); mLastFrame.printShortString(pw);
2030                    pw.println();
2031            pw.print(prefix); pw.print("mSystemDecorRect="); mSystemDecorRect.printShortString(pw);
2032                    pw.print(" last="); mLastSystemDecorRect.printShortString(pw);
2033                    if (mWinAnimator.mHasClipRect) {
2034                        pw.print(" mLastClipRect=");
2035                        mWinAnimator.mLastClipRect.printShortString(pw);
2036                    }
2037                    pw.println();
2038        }
2039        if (mEnforceSizeCompat) {
2040            pw.print(prefix); pw.print("mCompatFrame="); mCompatFrame.printShortString(pw);
2041                    pw.println();
2042        }
2043        if (dumpAll) {
2044            pw.print(prefix); pw.print("Frames: containing=");
2045                    mContainingFrame.printShortString(pw);
2046                    pw.print(" parent="); mParentFrame.printShortString(pw);
2047                    pw.println();
2048            pw.print(prefix); pw.print("    display="); mDisplayFrame.printShortString(pw);
2049                    pw.print(" overscan="); mOverscanFrame.printShortString(pw);
2050                    pw.println();
2051            pw.print(prefix); pw.print("    content="); mContentFrame.printShortString(pw);
2052                    pw.print(" visible="); mVisibleFrame.printShortString(pw);
2053                    pw.println();
2054            pw.print(prefix); pw.print("    decor="); mDecorFrame.printShortString(pw);
2055                    pw.println();
2056            pw.print(prefix); pw.print("    outset="); mOutsetFrame.printShortString(pw);
2057                    pw.println();
2058            pw.print(prefix); pw.print("Cur insets: overscan=");
2059                    mOverscanInsets.printShortString(pw);
2060                    pw.print(" content="); mContentInsets.printShortString(pw);
2061                    pw.print(" visible="); mVisibleInsets.printShortString(pw);
2062                    pw.print(" stable="); mStableInsets.printShortString(pw);
2063                    pw.print(" outsets="); mOutsets.printShortString(pw);
2064                    pw.println();
2065            pw.print(prefix); pw.print("Lst insets: overscan=");
2066                    mLastOverscanInsets.printShortString(pw);
2067                    pw.print(" content="); mLastContentInsets.printShortString(pw);
2068                    pw.print(" visible="); mLastVisibleInsets.printShortString(pw);
2069                    pw.print(" stable="); mLastStableInsets.printShortString(pw);
2070                    pw.print(" physical="); mLastOutsets.printShortString(pw);
2071                    pw.print(" outset="); mLastOutsets.printShortString(pw);
2072                    pw.println();
2073        }
2074        pw.print(prefix); pw.print(mWinAnimator); pw.println(":");
2075        mWinAnimator.dump(pw, prefix + "  ", dumpAll);
2076        if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
2077            pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
2078                    pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
2079                    pw.print(" mDestroying="); pw.print(mDestroying);
2080                    pw.print(" mRemoved="); pw.println(mRemoved);
2081        }
2082        if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
2083            pw.print(prefix); pw.print("mOrientationChanging=");
2084                    pw.print(mOrientationChanging);
2085                    pw.print(" mAppFreezing="); pw.print(mAppFreezing);
2086                    pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
2087        }
2088        if (mLastFreezeDuration != 0) {
2089            pw.print(prefix); pw.print("mLastFreezeDuration=");
2090                    TimeUtils.formatDuration(mLastFreezeDuration, pw); pw.println();
2091        }
2092        if (mHScale != 1 || mVScale != 1) {
2093            pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
2094                    pw.print(" mVScale="); pw.println(mVScale);
2095        }
2096        if (mWallpaperX != -1 || mWallpaperY != -1) {
2097            pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
2098                    pw.print(" mWallpaperY="); pw.println(mWallpaperY);
2099        }
2100        if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
2101            pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
2102                    pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
2103        }
2104        if (mWallpaperDisplayOffsetX != Integer.MIN_VALUE
2105                || mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
2106            pw.print(prefix); pw.print("mWallpaperDisplayOffsetX=");
2107                    pw.print(mWallpaperDisplayOffsetX);
2108                    pw.print(" mWallpaperDisplayOffsetY=");
2109                    pw.println(mWallpaperDisplayOffsetY);
2110        }
2111        if (mDrawLock != null) {
2112            pw.print(prefix); pw.println("mDrawLock=" + mDrawLock);
2113        }
2114    }
2115
2116    String makeInputChannelName() {
2117        return Integer.toHexString(System.identityHashCode(this))
2118            + " " + getWindowTag();
2119    }
2120
2121    private CharSequence getWindowTag() {
2122        CharSequence tag = mAttrs.getTitle();
2123        if (tag == null || tag.length() <= 0) {
2124            tag = mAttrs.packageName;
2125        }
2126        return tag;
2127    }
2128
2129    @Override
2130    public String toString() {
2131        final CharSequence title = getWindowTag();
2132        if (mStringNameCache == null || mLastTitle != title || mWasExiting != mExiting) {
2133            mLastTitle = title;
2134            mWasExiting = mExiting;
2135            mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this))
2136                    + " u" + UserHandle.getUserId(mSession.mUid)
2137                    + " " + mLastTitle + (mExiting ? " EXITING}" : "}");
2138        }
2139        return mStringNameCache;
2140    }
2141
2142    void transformFromScreenToSurfaceSpace(Rect rect) {
2143         if (mHScale >= 0) {
2144            rect.right = rect.left + (int)((rect.right - rect.left) / mHScale);
2145        }
2146        if (mVScale >= 0) {
2147            rect.bottom = rect.top + (int)((rect.bottom - rect.top) / mVScale);
2148        }
2149    }
2150}
2151