OSDN Git Service

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