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