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