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