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