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