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