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