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