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