OSDN Git Service

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