OSDN Git Service

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