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