OSDN Git Service

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