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