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