blob: 2c359fc97124bfcafd5687c96b7e1f76e9502a28 [file] [log] [blame]
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001/*
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
17package com.android.server.wm;
18
Wale Ogunwale053c8e42015-11-16 14:27:21 -080019import android.app.ActivityManager;
20import android.app.AppOpsManager;
21import android.content.Context;
22import android.content.res.Configuration;
23import android.graphics.Matrix;
24import android.graphics.PixelFormat;
25import android.graphics.Point;
26import android.graphics.Rect;
27import android.graphics.Region;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -070028import android.os.Binder;
Wale Ogunwale9d147902016-07-16 11:58:55 -070029import android.os.Debug;
Wale Ogunwale053c8e42015-11-16 14:27:21 -080030import android.os.IBinder;
31import android.os.PowerManager;
32import android.os.RemoteCallbackList;
33import android.os.RemoteException;
34import android.os.SystemClock;
35import android.os.Trace;
36import android.os.UserHandle;
37import android.os.WorkSource;
38import android.util.DisplayMetrics;
39import android.util.Slog;
40import android.util.TimeUtils;
41import android.view.Display;
42import android.view.DisplayInfo;
43import android.view.Gravity;
44import android.view.IApplicationToken;
45import android.view.IWindow;
46import android.view.IWindowFocusObserver;
47import android.view.IWindowId;
48import android.view.InputChannel;
49import android.view.InputEvent;
50import android.view.InputEventReceiver;
51import android.view.View;
52import android.view.ViewTreeObserver;
Wale Ogunwaleadde52e2016-07-16 13:11:55 -070053import android.view.WindowInfo;
Wale Ogunwale053c8e42015-11-16 14:27:21 -080054import android.view.WindowManager;
55import android.view.WindowManagerPolicy;
56
Jorim Jaggi9511b0f2016-01-29 19:12:44 -080057import com.android.server.input.InputWindowHandle;
58
Wale Ogunwale053c8e42015-11-16 14:27:21 -080059import java.io.PrintWriter;
60import java.util.ArrayList;
Wale Ogunwalee4343ef2016-07-19 08:00:46 -070061import java.util.Comparator;
62import java.util.LinkedList;
Wale Ogunwale053c8e42015-11-16 14:27:21 -080063
Wale Ogunwaled045c822015-12-02 09:14:28 -080064import static android.app.ActivityManager.StackId;
Wale Ogunwalea9f9b372016-02-04 18:04:39 -080065import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
Filip Gruszczynski84fa3352016-01-25 16:28:49 -080066import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
Wale Ogunwalecad05a02015-09-25 10:41:44 -070067import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
Wale Ogunwaleadde52e2016-07-16 13:11:55 -070068import static android.view.Display.DEFAULT_DISPLAY;
Wale Ogunwale053c8e42015-11-16 14:27:21 -080069import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT;
70import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
71import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
72import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE;
Wale Ogunwalef9c81492015-02-25 18:06:17 -080073import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
Filip Gruszczynski84cc5e32015-11-03 18:05:47 -080074import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070075import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
Filip Gruszczynski84cc5e32015-11-03 18:05:47 -080076import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
Jorim Jaggi5f23a572016-04-22 15:05:50 -070077import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
Wale Ogunwale053c8e42015-11-16 14:27:21 -080078import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
79import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
Filip Gruszczynski84cc5e32015-11-03 18:05:47 -080080import static android.view.WindowManager.LayoutParams.FLAG_SCALED;
Wale Ogunwale945d1972016-03-23 13:16:41 -070081import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
Chong Zhang4d7369a2016-04-25 16:09:14 -070082import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
Wale Ogunwale6dfdfd62015-04-15 12:01:38 -070083import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
Filip Gruszczynski84cc5e32015-11-03 18:05:47 -080084import static android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
Wale Ogunwalef9c81492015-02-25 18:06:17 -080085import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
Robert Carr31e28482015-12-02 16:53:18 -080086import static android.view.WindowManager.LayoutParams.MATCH_PARENT;
Wale Ogunwalef9c81492015-02-25 18:06:17 -080087import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
Wale Ogunwalef9c81492015-02-25 18:06:17 -080088import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
Jorim Jaggi9511b0f2016-01-29 19:12:44 -080089import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME;
Robert Carra1eb4392015-12-10 12:43:51 -080090import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH;
Filip Gruszczynski84cc5e32015-11-03 18:05:47 -080091import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
92import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
Robert Carrd1a010f2016-04-07 22:36:22 -070093import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
Wale Ogunwalef9c81492015-02-25 18:06:17 -080094import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
Filip Gruszczynski84cc5e32015-11-03 18:05:47 -080095import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
Chong Zhangfea963e2016-08-15 17:14:16 -070096import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION;
Filip Gruszczynski466f3212015-09-21 17:57:57 -070097import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
Wale Ogunwalef9c81492015-02-25 18:06:17 -080098import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
99import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
100import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
Chong Zhang4d7369a2016-04-25 16:09:14 -0700101import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700102import static android.view.WindowManagerPolicy.TRANSIT_ENTER;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700103import static android.view.WindowManagerPolicy.TRANSIT_EXIT;
104import static android.view.WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
Jorim Jaggi0b46f3c2016-03-14 12:21:37 +0100105import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
106import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800107import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
108import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
109import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
110import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION;
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700111import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800112import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
Wale Ogunwaleadde52e2016-07-16 13:11:55 -0700113import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800114import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
115import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
116import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
117import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RESIZE;
Wale Ogunwale9d147902016-07-16 11:58:55 -0700118import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
119import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800120import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700121import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700122import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
Wale Ogunwaleadde52e2016-07-16 13:11:55 -0700123import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800124import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
125import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700126import static com.android.server.wm.WindowManagerService.H.SEND_NEW_CONFIGURATION;
Wale Ogunwalee4343ef2016-07-19 08:00:46 -0700127import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
128import static com.android.server.wm.WindowManagerService.TYPE_LAYER_OFFSET;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700129import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
130import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700131import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_TIMEOUT;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700132import static com.android.server.wm.WindowManagerService.localLOGV;
Wale Ogunwale9d147902016-07-16 11:58:55 -0700133import static com.android.server.wm.WindowStateAnimator.COMMIT_DRAW_PENDING;
134import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN;
135import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800136
Craig Mautner59c00972012-07-30 12:10:24 -0700137class WindowList extends ArrayList<WindowState> {
Wale Ogunwale33fde7d2016-03-05 22:38:51 -0800138 WindowList() {}
139 WindowList(WindowList windowList) {
140 super(windowList);
141 }
Craig Mautner59c00972012-07-30 12:10:24 -0700142}
143
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800144/**
145 * A window in the window manager.
146 */
Wale Ogunwalee4343ef2016-07-19 08:00:46 -0700147class WindowState extends WindowContainer implements WindowManagerPolicy.WindowState {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800148 static final String TAG = TAG_WITH_CLASS_NAME ? "WindowState" : TAG_WM;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800149
Skuhne81c524a2015-08-12 13:34:14 -0700150 // The minimal size of a window within the usable area of the freeform stack.
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700151 // TODO(multi-window): fix the min sizes when we have mininum width/height support,
152 // use hard-coded min sizes for now.
153 static final int MINIMUM_VISIBLE_WIDTH_IN_DP = 48;
154 static final int MINIMUM_VISIBLE_HEIGHT_IN_DP = 32;
Skuhnef932e562015-08-20 12:07:30 -0700155
156 // The thickness of a window resize handle outside the window bounds on the free form workspace
157 // to capture touch events in that area.
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700158 static final int RESIZE_HANDLE_WIDTH_IN_DP = 30;
Skuhnef932e562015-08-20 12:07:30 -0700159
Robert Carr7098dbd2016-02-01 12:31:01 -0800160 static final boolean DEBUG_DISABLE_SAVING_SURFACES = false;
161
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800162 final WindowManagerService mService;
Craig Mautnere7ae2502012-03-26 17:11:19 -0700163 final WindowManagerPolicy mPolicy;
164 final Context mContext;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800165 final Session mSession;
166 final IWindow mClient;
Dianne Hackbornc2293022013-02-06 23:14:49 -0800167 final int mAppOp;
168 // UserId and appId of the owner. Don't display windows of non-current user.
169 final int mOwnerUid;
Dianne Hackborne3f23a32013-03-01 13:25:35 -0800170 final IWindowId mWindowId;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800171 WindowToken mToken;
Wale Ogunwalea6cc3612016-08-04 07:25:33 -0700172 // The same object as mToken if this is an app window and null for non-app windows.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800173 AppWindowToken mAppToken;
Craig Mautnerd09cc4b2012-04-04 10:23:31 -0700174
175 // mAttrs.flags is tested in animation without being locked. If the bits tested are ever
176 // modified they will need to be locked.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800177 final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
178 final DeathRecipient mDeathRecipient;
Wale Ogunwalee4343ef2016-07-19 08:00:46 -0700179 private boolean mIsChildWindow;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800180 final int mBaseLayer;
181 final int mSubLayer;
182 final boolean mLayoutAttached;
183 final boolean mIsImWindow;
184 final boolean mIsWallpaper;
185 final boolean mIsFloatingLayer;
Dianne Hackborn9a230e02011-10-06 11:51:27 -0700186 int mSeq;
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700187 boolean mEnforceSizeCompat;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800188 int mViewVisibility;
Dianne Hackborn9a230e02011-10-06 11:51:27 -0700189 int mSystemUiVisibility;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800190 boolean mPolicyVisibility = true;
191 boolean mPolicyVisibilityAfterAnim = true;
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -0800192 boolean mAppOpVisibility = true;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800193 boolean mAppFreezing;
Wale Ogunwale9d147902016-07-16 11:58:55 -0700194 boolean mHidden; // Used to determine if to show child windows.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800195 boolean mWallpaperVisible; // for wallpaper, what was last vis report?
Chong Zhang0275e392015-09-17 10:41:44 -0700196 boolean mDragResizing;
Jorim Jaggic662d8e2016-02-05 16:54:54 -0800197 boolean mDragResizingChangeReported;
Jorim Jaggidcf467c2015-11-05 13:59:32 +0100198 int mResizeMode;
Dianne Hackbornffb3d932011-05-17 17:44:51 -0700199
Dianne Hackborne3f23a32013-03-01 13:25:35 -0800200 RemoteCallbackList<IWindowFocusObserver> mFocusCallbacks;
201
Dianne Hackbornffb3d932011-05-17 17:44:51 -0700202 /**
203 * The window size that was requested by the application. These are in
204 * the application's coordinate space (without compatibility scale applied).
205 */
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800206 int mRequestedWidth;
207 int mRequestedHeight;
Dianne Hackborn1743b642012-03-12 17:04:43 -0700208 int mLastRequestedWidth;
209 int mLastRequestedHeight;
Dianne Hackbornffb3d932011-05-17 17:44:51 -0700210
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800211 int mLayer;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800212 boolean mHaveFrame;
213 boolean mObscured;
214 boolean mTurnOnScreen;
215
216 int mLayoutSeq = -1;
Craig Mautnera2c77052012-03-26 12:14:43 -0700217
Jorim Jaggi26c8c422016-05-09 19:57:25 -0700218 private final Configuration mTmpConfig = new Configuration();
Robert Carrc24d8f92016-02-29 16:24:33 -0800219 // Represents the changes from our override configuration applied
220 // to the global configuration. This is the only form of configuration
221 // which is suitable for delivery to the client.
222 private Configuration mMergedConfiguration = new Configuration();
Craig Mautnere8552142012-11-07 13:55:47 -0800223 // Sticky answer to isConfigChanged(), remains true until new Configuration is assigned.
224 // Used only on {@link #TYPE_KEYGUARD}.
225 private boolean mConfigHasChanged;
Craig Mautnera2c77052012-03-26 12:14:43 -0700226
Dianne Hackbornffb3d932011-05-17 17:44:51 -0700227 /**
Filip Gruszczynski2a6a2c22015-10-14 12:00:53 -0700228 * Actual position of the surface shown on-screen (may be modified by animation). These are
229 * in the screen's coordinate space (WITH the compatibility scale applied).
Dianne Hackbornffb3d932011-05-17 17:44:51 -0700230 */
Filip Gruszczynski2a6a2c22015-10-14 12:00:53 -0700231 final Point mShownPosition = new Point();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800232
233 /**
Dianne Hackbornffb3d932011-05-17 17:44:51 -0700234 * Insets that determine the actually visible area. These are in the application's
235 * coordinate space (without compatibility scale applied).
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800236 */
237 final Rect mVisibleInsets = new Rect();
238 final Rect mLastVisibleInsets = new Rect();
239 boolean mVisibleInsetsChanged;
240
241 /**
Dianne Hackborn5c58de32012-04-28 19:52:37 -0700242 * Insets that are covered by system windows (such as the status bar) and
243 * transient docking windows (such as the IME). These are in the application's
Dianne Hackbornffb3d932011-05-17 17:44:51 -0700244 * coordinate space (without compatibility scale applied).
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800245 */
246 final Rect mContentInsets = new Rect();
247 final Rect mLastContentInsets = new Rect();
248 boolean mContentInsetsChanged;
249
250 /**
Dianne Hackbornc4aad012013-02-22 15:05:25 -0800251 * Insets that determine the area covered by the display overscan region. These are in the
252 * application's coordinate space (without compatibility scale applied).
253 */
254 final Rect mOverscanInsets = new Rect();
255 final Rect mLastOverscanInsets = new Rect();
256 boolean mOverscanInsetsChanged;
257
258 /**
Adrian Roosfa104232014-06-20 16:10:14 -0700259 * Insets that determine the area covered by the stable system windows. These are in the
260 * application's coordinate space (without compatibility scale applied).
261 */
262 final Rect mStableInsets = new Rect();
263 final Rect mLastStableInsets = new Rect();
264 boolean mStableInsetsChanged;
265
266 /**
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700267 * Outsets determine the area outside of the surface where we want to pretend that it's possible
268 * to draw anyway.
269 */
270 final Rect mOutsets = new Rect();
271 final Rect mLastOutsets = new Rect();
272 boolean mOutsetsChanged = false;
273
274 /**
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800275 * Set to true if we are waiting for this window to receive its
276 * given internal insets before laying out other windows based on it.
277 */
278 boolean mGivenInsetsPending;
279
280 /**
281 * These are the content insets that were given during layout for
282 * this window, to be applied to windows behind it.
283 */
284 final Rect mGivenContentInsets = new Rect();
285
286 /**
287 * These are the visible insets that were given during layout for
288 * this window, to be applied to windows behind it.
289 */
290 final Rect mGivenVisibleInsets = new Rect();
291
292 /**
293 * This is the given touchable area relative to the window frame, or null if none.
294 */
295 final Region mGivenTouchableRegion = new Region();
296
297 /**
298 * Flag indicating whether the touchable region should be adjusted by
299 * the visible insets; if false the area outside the visible insets is
300 * NOT touchable, so we must use those to adjust the frame during hit
301 * tests.
302 */
303 int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
304
305 // Current transformation being applied.
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400306 float mGlobalScale=1;
Dianne Hackbornffb3d932011-05-17 17:44:51 -0700307 float mInvGlobalScale=1;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800308 float mHScale=1, mVScale=1;
309 float mLastHScale=1, mLastVScale=1;
310 final Matrix mTmpMatrix = new Matrix();
311
Dianne Hackbornffb3d932011-05-17 17:44:51 -0700312 // "Real" frame that the application sees, in display coordinate space.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800313 final Rect mFrame = new Rect();
314 final Rect mLastFrame = new Rect();
Robert Carr31aa98b2016-07-20 15:29:03 -0700315 boolean mFrameSizeChanged = false;
Dianne Hackbornffb3d932011-05-17 17:44:51 -0700316 // Frame that is scaled to the application's coordinate space when in
317 // screen size compatibility mode.
318 final Rect mCompatFrame = new Rect();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800319
320 final Rect mContainingFrame = new Rect();
Wale Ogunwalec6061fa2014-10-21 13:15:11 -0700321
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800322 final Rect mParentFrame = new Rect();
Wale Ogunwalec6061fa2014-10-21 13:15:11 -0700323
Wale Ogunwale94596652015-02-06 19:27:34 -0800324 // The entire screen area of the {@link TaskStack} this window is in. Usually equal to the
325 // screen area of the device.
Wale Ogunwalec6061fa2014-10-21 13:15:11 -0700326 final Rect mDisplayFrame = new Rect();
327
328 // The region of the display frame that the display type supports displaying content on. This
329 // is mostly a special case for TV where some displays don’t have the entire display usable.
330 // {@link WindowManager.LayoutParams#FLAG_LAYOUT_IN_OVERSCAN} flag can be used to allow
331 // window display contents to extend into the overscan region.
332 final Rect mOverscanFrame = new Rect();
333
334 // The display frame minus the stable insets. This value is always constant regardless of if
335 // the status bar or navigation bar is visible.
Adrian Roosfa104232014-06-20 16:10:14 -0700336 final Rect mStableFrame = new Rect();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800337
Wale Ogunwalec6061fa2014-10-21 13:15:11 -0700338 // The area not occupied by the status and navigation bars. So, if both status and navigation
339 // bars are visible, the decor frame is equal to the stable frame.
340 final Rect mDecorFrame = new Rect();
341
342 // Equal to the decor frame if the IME (e.g. keyboard) is not present. Equal to the decor frame
343 // minus the area occupied by the IME if the IME is present.
344 final Rect mContentFrame = new Rect();
345
346 // Legacy stuff. Generally equal to the content frame expect when the IME for older apps
347 // displays hint text.
348 final Rect mVisibleFrame = new Rect();
349
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700350 // Frame that includes dead area outside of the surface but where we want to pretend that it's
351 // possible to draw.
352 final Rect mOutsetFrame = new Rect();
353
Jorim Jaggidc249c42015-12-15 14:57:31 -0800354 /**
355 * Usually empty. Set to the task's tempInsetFrame. See
356 *{@link android.app.IActivityManager#resizeDockedStack}.
357 */
358 final Rect mInsetFrame = new Rect();
359
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800360 boolean mContentChanged;
361
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800362 // If a window showing a wallpaper: the requested offset for the
363 // wallpaper; if a wallpaper window: the currently applied offset.
364 float mWallpaperX = -1;
365 float mWallpaperY = -1;
366
367 // If a window showing a wallpaper: what fraction of the offset
368 // range corresponds to a full virtual screen.
369 float mWallpaperXStep = -1;
370 float mWallpaperYStep = -1;
371
Dianne Hackborn067e5f62014-09-07 23:14:30 -0700372 // If a window showing a wallpaper: a raw pixel offset to forcibly apply
373 // to its window; if a wallpaper window: not used.
374 int mWallpaperDisplayOffsetX = Integer.MIN_VALUE;
375 int mWallpaperDisplayOffsetY = Integer.MIN_VALUE;
376
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800377 // Wallpaper windows: pixels offset based on above variables.
378 int mXOffset;
379 int mYOffset;
380
Craig Mautner2268e7e2012-12-13 15:40:00 -0800381 /**
382 * This is set after IWindowSession.relayout() has been called at
383 * least once for the window. It allows us to detect the situation
384 * where we don't yet have a surface, but should have one soon, so
385 * we can give the window focus before waiting for the relayout.
386 */
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800387 boolean mRelayoutCalled;
388
Robert Carrfed10072016-05-26 11:48:49 -0700389 boolean mInRelayout;
390
Craig Mautner0bf6ec92012-12-18 08:33:27 -0800391 /**
392 * If the application has called relayout() with changes that can
393 * impact its window's size, we need to perform a layout pass on it
394 * even if it is not currently visible for layout. This is set
395 * when in that case until the layout is done.
396 */
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -0800397 boolean mLayoutNeeded;
398
Craig Mautner0bf6ec92012-12-18 08:33:27 -0800399 /** Currently running an exit animation? */
Wale Ogunwalec48a3542016-02-19 15:18:45 -0800400 boolean mAnimatingExit;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800401
Craig Mautner0bf6ec92012-12-18 08:33:27 -0800402 /** Currently on the mDestroySurface list? */
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800403 boolean mDestroying;
404
Craig Mautner0bf6ec92012-12-18 08:33:27 -0800405 /** Completely remove from window manager after exit animation? */
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800406 boolean mRemoveOnExit;
407
Craig Mautner0bf6ec92012-12-18 08:33:27 -0800408 /**
Chong Zhang112eb8c2015-11-02 11:17:00 -0800409 * Whether the app died while it was visible, if true we might need
410 * to continue to show it until it's restarted.
411 */
412 boolean mAppDied;
413
414 /**
Craig Mautner0bf6ec92012-12-18 08:33:27 -0800415 * Set when the orientation is changing and this window has not yet
416 * been updated for the new orientation.
417 */
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800418 boolean mOrientationChanging;
419
Dianne Hackborna57c6952013-03-29 14:46:40 -0700420 /**
Robert Carr237028a2016-07-26 10:39:45 -0700421 * The orientation during the last visible call to relayout. If our
422 * current orientation is different, the window can't be ready
423 * to be shown.
424 */
425 int mLastVisibleLayoutRotation = -1;
426
427 /**
Dianne Hackborna57c6952013-03-29 14:46:40 -0700428 * How long we last kept the screen frozen.
429 */
430 int mLastFreezeDuration;
431
Craig Mautner0bf6ec92012-12-18 08:33:27 -0800432 /** Is this window now (or just being) removed? */
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800433 boolean mRemoved;
434
Craig Mautner0bf6ec92012-12-18 08:33:27 -0800435 /**
Wale Ogunwalec48a3542016-02-19 15:18:45 -0800436 * It is save to remove the window and destroy the surface because the client requested removal
437 * or some other higher level component said so (e.g. activity manager).
438 * TODO: We should either have different booleans for the removal reason or use a bit-field.
Robert Carre12aece2016-02-02 22:43:27 -0800439 */
Wale Ogunwalec48a3542016-02-19 15:18:45 -0800440 boolean mWindowRemovalAllowed;
Robert Carre12aece2016-02-02 22:43:27 -0800441
442 /**
Craig Mautner0bf6ec92012-12-18 08:33:27 -0800443 * Temp for keeping track of windows that have been removed when
444 * rebuilding window list.
445 */
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800446 boolean mRebuilding;
447
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800448 // Input channel and input window handle used by the input dispatcher.
Jeff Brown9302c872011-07-13 22:51:29 -0700449 final InputWindowHandle mInputWindowHandle;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800450 InputChannel mInputChannel;
Chong Zhang112eb8c2015-11-02 11:17:00 -0800451 InputChannel mClientChannel;
Craig Mautner164d4bb2012-11-26 13:51:23 -0800452
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800453 // Used to improve performance of toString()
454 String mStringNameCache;
455 CharSequence mLastTitle;
Dianne Hackborn529e7442012-11-01 14:22:28 -0700456 boolean mWasExiting;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800457
Craig Mautnera2c77052012-03-26 12:14:43 -0700458 final WindowStateAnimator mWinAnimator;
459
Craig Mautnerc8bc97e2012-04-02 12:54:54 -0700460 boolean mHasSurface = false;
461
Craig Mautner19ab8282014-05-07 10:35:34 -0700462 boolean mNotOnAppsDisplay = false;
Craig Mautner59c00972012-07-30 12:10:24 -0700463 DisplayContent mDisplayContent;
Craig Mautner6881a102012-07-27 13:04:51 -0700464
Craig Mautner88400d32012-09-30 12:35:45 -0700465 /** When true this window can be displayed on screens owther than mOwnerUid's */
466 private boolean mShowToOwnerOnly;
Craig Mautner9dc52bc2012-08-06 14:15:42 -0700467
Robert Carr13f7be9e2015-12-02 18:39:45 -0800468 // Whether the window has a saved surface from last pause, which can be
469 // used to start an entering animation earlier.
Chong Zhang92147042016-05-09 12:47:11 -0700470 private boolean mSurfaceSaved = false;
471
Chong Zhang8e4bda92016-05-04 15:08:18 -0700472 // Whether we're performing an entering animation with a saved surface. This flag is
473 // true during the time we're showing a window with a previously saved surface. It's
474 // cleared when surface is destroyed, saved, or re-drawn by the app.
Chong Zhang92147042016-05-09 12:47:11 -0700475 private boolean mAnimatingWithSavedSurface;
476
477 // Whether the window was visible when we set the app to invisible last time. WM uses
478 // this as a hint to restore the surface (if available) for early animation next time
479 // the app is brought visible.
480 boolean mWasVisibleBeforeClientHidden;
Robert Carr13f7be9e2015-12-02 18:39:45 -0800481
Robert Carra1eb4392015-12-10 12:43:51 -0800482 // This window will be replaced due to relaunch. This allows window manager
483 // to differentiate between simple removal of a window and replacement. In the latter case it
484 // will preserve the old window until the new one is drawn.
485 boolean mWillReplaceWindow = false;
486 // If true, the replaced window was already requested to be removed.
487 boolean mReplacingRemoveRequested = false;
488 // Whether the replacement of the window should trigger app transition animation.
489 boolean mAnimateReplacingWindow = false;
490 // If not null, the window that will be used to replace the old one. This is being set when
491 // the window is added and unset when this window reports its first draw.
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700492 WindowState mReplacementWindow = null;
Robert Carrb439a632016-04-07 22:52:10 -0700493 // For the new window in the replacement transition, if we have
494 // requested to replace without animation, then we should
495 // make sure we also don't apply an enter animation for
496 // the new window.
497 boolean mSkipEnterAnimationForSeamlessReplacement = false;
Chong Zhangbd0d9372015-12-28 15:18:29 -0800498 // Whether this window is being moved via the resize API
499 boolean mMovedByResize;
Robert Carr0d00c2e2016-02-29 17:45:02 -0800500
Jeff Brownc2932a12014-11-20 18:04:05 -0800501 /**
502 * Wake lock for drawing.
503 * Even though it's slightly more expensive to do so, we will use a separate wake lock
504 * for each app that is requesting to draw while dozing so that we can accurately track
505 * who is preventing the system from suspending.
506 * This lock is only acquired on first use.
507 */
508 PowerManager.WakeLock mDrawLock;
509
Wale Ogunwale2b19b602015-09-18 15:14:59 -0700510 final private Rect mTmpRect = new Rect();
511
Jorim Jaggi8fa45222016-02-19 19:54:39 -0800512 /**
Jorim Jaggi5e6968d2016-02-19 18:02:13 -0800513 * See {@link #notifyMovedInStack}.
514 */
515 private boolean mJustMovedInStack;
516
517 /**
Jorim Jaggi8fa45222016-02-19 19:54:39 -0800518 * Whether the window was resized by us while it was gone for layout.
519 */
520 boolean mResizedWhileGone = false;
521
Andrii Kulianeb1d3222016-05-16 15:17:55 -0700522 /** @see #isResizedWhileNotDragResizing(). */
523 private boolean mResizedWhileNotDragResizing;
524
525 /** @see #isResizedWhileNotDragResizingReported(). */
526 private boolean mResizedWhileNotDragResizingReported;
Jorim Jaggif3df0aa2016-04-06 15:56:33 -0700527
Robert Carr6da3cc02016-06-16 15:17:07 -0700528 /**
529 * During seamless rotation we have two phases, first the old window contents
530 * are rotated to look as if they didn't move in the new coordinate system. Then we
531 * have to freeze updates to this layer (to preserve the transformation) until
532 * the resize actually occurs. This is true from when the transformation is set
533 * and false until the transaction to resize is sent.
534 */
535 boolean mSeamlesslyRotated = false;
536
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700537 private static final Region sEmptyRegion = new Region();
538
Wale Ogunwalee4343ef2016-07-19 08:00:46 -0700539 /**
540 * Compares to window sub-layers and returns -1 if the first is lesser than the second in terms
541 * of z-order and 1 otherwise.
542 */
543 private static final Comparator<WindowContainer> sWindowSubLayerComparator = (w1, w2) -> {
544 final int layer1 = ((WindowState)w1).mSubLayer;
545 final int layer2 = ((WindowState)w2).mSubLayer;
546 if (layer1 < layer2 || (layer1 == layer2 && layer2 < 0 )) {
547 // We insert the child window into the list ordered by the sub-layer.
548 // For same sub-layers, the negative one should go below others; the positive one should
549 // go above others.
550 return -1;
551 }
552 return 1;
553 };
554
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800555 WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
Wale Ogunwale7ed4d372016-07-09 15:28:55 -0700556 WindowState parentWindow, int appOp, int seq, WindowManager.LayoutParams a,
Wale Ogunwaleb699ce02016-07-18 12:05:30 -0700557 int viewVisibility, final DisplayContent displayContent, int ownerId) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800558 mService = service;
559 mSession = s;
560 mClient = c;
Dianne Hackbornc2293022013-02-06 23:14:49 -0800561 mAppOp = appOp;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800562 mToken = token;
Wale Ogunwalea6cc3612016-08-04 07:25:33 -0700563 mAppToken = mToken.asAppWindowToken();
Wale Ogunwaleb699ce02016-07-18 12:05:30 -0700564 mOwnerUid = ownerId;
Dianne Hackborne3f23a32013-03-01 13:25:35 -0800565 mWindowId = new IWindowId.Stub() {
566 @Override
567 public void registerFocusObserver(IWindowFocusObserver observer) {
568 WindowState.this.registerFocusObserver(observer);
569 }
570 @Override
571 public void unregisterFocusObserver(IWindowFocusObserver observer) {
572 WindowState.this.unregisterFocusObserver(observer);
573 }
574 @Override
575 public boolean isFocused() {
576 return WindowState.this.isFocused();
577 }
578 };
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800579 mAttrs.copyFrom(a);
580 mViewVisibility = viewVisibility;
Craig Mautner59c00972012-07-30 12:10:24 -0700581 mDisplayContent = displayContent;
Craig Mautnere7ae2502012-03-26 17:11:19 -0700582 mPolicy = mService.mPolicy;
583 mContext = mService.mContext;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800584 DeathRecipient deathRecipient = new DeathRecipient();
Dianne Hackborn9a230e02011-10-06 11:51:27 -0700585 mSeq = seq;
Adam Lesinski95c42972013-10-02 10:13:27 -0700586 mEnforceSizeCompat = (mAttrs.privateFlags & PRIVATE_FLAG_COMPATIBLE_WINDOW) != 0;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700587 if (localLOGV) Slog.v(
Craig Mautnerd87946b2012-03-29 18:00:19 -0700588 TAG, "Window " + this + " client=" + c.asBinder()
Craig Mautnerad09bcc2012-10-08 13:33:11 -0700589 + " token=" + token + " (" + mAttrs.token + ")" + " params=" + a);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800590 try {
591 c.asBinder().linkToDeath(deathRecipient, 0);
592 } catch (RemoteException e) {
593 mDeathRecipient = null;
Wale Ogunwalee4343ef2016-07-19 08:00:46 -0700594 mIsChildWindow = false;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800595 mLayoutAttached = false;
596 mIsImWindow = false;
597 mIsWallpaper = false;
598 mIsFloatingLayer = false;
599 mBaseLayer = 0;
600 mSubLayer = 0;
Jeff Brown9302c872011-07-13 22:51:29 -0700601 mInputWindowHandle = null;
Craig Mautnera2c77052012-03-26 12:14:43 -0700602 mWinAnimator = null;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800603 return;
604 }
605 mDeathRecipient = deathRecipient;
606
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700607 if (mAttrs.type >= FIRST_SUB_WINDOW && mAttrs.type <= LAST_SUB_WINDOW) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800608 // The multiplier here is to reserve space for multiple
609 // windows in the same type layer.
Wale Ogunwalee4343ef2016-07-19 08:00:46 -0700610 mBaseLayer = mPolicy.windowTypeToLayerLw(parentWindow.mAttrs.type)
611 * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
Craig Mautnere7ae2502012-03-26 17:11:19 -0700612 mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
Wale Ogunwalee4343ef2016-07-19 08:00:46 -0700613 mIsChildWindow = true;
takeda.masayuki18735092012-12-12 11:06:24 +0900614
Wale Ogunwalee4343ef2016-07-19 08:00:46 -0700615 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + parentWindow);
616 parentWindow.addChild(this, sWindowSubLayerComparator);
takeda.masayuki18735092012-12-12 11:06:24 +0900617
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800618 mLayoutAttached = mAttrs.type !=
619 WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
Wale Ogunwale7ed4d372016-07-09 15:28:55 -0700620 mIsImWindow = parentWindow.mAttrs.type == TYPE_INPUT_METHOD
621 || parentWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
622 mIsWallpaper = parentWindow.mAttrs.type == TYPE_WALLPAPER;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800623 } else {
624 // The multiplier here is to reserve space for multiple
625 // windows in the same type layer.
Craig Mautnere7ae2502012-03-26 17:11:19 -0700626 mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
Wale Ogunwalee4343ef2016-07-19 08:00:46 -0700627 * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800628 mSubLayer = 0;
Wale Ogunwalee4343ef2016-07-19 08:00:46 -0700629 mIsChildWindow = false;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800630 mLayoutAttached = false;
631 mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
632 || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
633 mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800634 }
Wale Ogunwalee4343ef2016-07-19 08:00:46 -0700635 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800636
Craig Mautner19ab8282014-05-07 10:35:34 -0700637 if (mAppToken != null) {
638 final DisplayContent appDisplay = getDisplayContent();
639 mNotOnAppsDisplay = displayContent != appDisplay;
Wale Ogunwale6dfdfd62015-04-15 12:01:38 -0700640
641 if (mAppToken.showForAllUsers) {
642 // Windows for apps that can show for all users should also show when the
643 // device is locked.
644 mAttrs.flags |= FLAG_SHOW_WHEN_LOCKED;
645 }
Craig Mautner19ab8282014-05-07 10:35:34 -0700646 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800647
Craig Mautner322e4032012-07-13 13:35:20 -0700648 mWinAnimator = new WindowStateAnimator(this);
649 mWinAnimator.mAlpha = a.alpha;
650
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800651 mRequestedWidth = 0;
652 mRequestedHeight = 0;
Dianne Hackborn1743b642012-03-12 17:04:43 -0700653 mLastRequestedWidth = 0;
654 mLastRequestedHeight = 0;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800655 mXOffset = 0;
656 mYOffset = 0;
657 mLayer = 0;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800658 mInputWindowHandle = new InputWindowHandle(
Craig Mautner59c00972012-07-30 12:10:24 -0700659 mAppToken != null ? mAppToken.mInputApplicationHandle : null, this,
660 displayContent.getDisplayId());
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800661 }
662
663 void attach() {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700664 if (localLOGV) Slog.v(TAG, "Attaching " + this + " token=" + mToken);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800665 mSession.windowAddedLocked();
666 }
667
Craig Mautnera2c77052012-03-26 12:14:43 -0700668 @Override
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800669 public int getOwningUid() {
Dianne Hackbornc2293022013-02-06 23:14:49 -0800670 return mOwnerUid;
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800671 }
672
673 @Override
674 public String getOwningPackage() {
675 return mAttrs.packageName;
676 }
677
Jorim Jaggif5834272016-04-04 20:25:41 -0700678 /**
679 * Subtracts the insets calculated by intersecting {@param layoutFrame} with {@param insetFrame}
680 * from {@param frame}. In other words, it applies the insets that would result if
681 * {@param frame} would be shifted to {@param layoutFrame} and then applying the insets from
Andrii Kuliandaea3572016-04-08 13:20:51 -0700682 * {@param insetFrame}. Also it respects {@param displayFrame} in case window has minimum
683 * width/height applied and insets should be overridden.
Jorim Jaggif5834272016-04-04 20:25:41 -0700684 */
Andrii Kuliandaea3572016-04-08 13:20:51 -0700685 private void subtractInsets(Rect frame, Rect layoutFrame, Rect insetFrame, Rect displayFrame) {
686 final int left = Math.max(0, insetFrame.left - Math.max(layoutFrame.left, displayFrame.left));
687 final int top = Math.max(0, insetFrame.top - Math.max(layoutFrame.top, displayFrame.top));
688 final int right = Math.max(0, Math.min(layoutFrame.right, displayFrame.right) - insetFrame.right);
689 final int bottom = Math.max(0, Math.min(layoutFrame.bottom, displayFrame.bottom) - insetFrame.bottom);
Jorim Jaggif5834272016-04-04 20:25:41 -0700690 frame.inset(left, top, right, bottom);
691 }
692
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800693 @Override
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700694 public void computeFrameLw(Rect pf, Rect df, Rect of, Rect cf, Rect vf, Rect dcf, Rect sf,
695 Rect osf) {
Wale Ogunwalec48a3542016-02-19 15:18:45 -0800696 if (mWillReplaceWindow && (mAnimatingExit || !mReplacingRemoveRequested)) {
Filip Gruszczynski55a309f2015-09-04 17:15:01 -0700697 // This window is being replaced and either already got information that it's being
698 // removed or we are still waiting for some information. Because of this we don't
699 // want to apply any more changes to it, so it remains in this state until new window
700 // appears.
701 return;
702 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800703 mHaveFrame = true;
704
Wale Ogunwale5a2f2cb2015-09-17 12:31:55 -0700705 final Task task = getTask();
Andrii Kulian933076d2016-03-29 17:04:42 -0700706 final boolean fullscreenTask = !isInMultiWindowMode();
Robert Carre6275582016-02-29 15:45:45 -0800707 final boolean windowsAreFloating = task != null && task.isFloating();
Wale Ogunwale79f268d2015-12-18 08:25:47 -0800708
Chong Zhangae35fef2016-03-16 15:56:55 -0700709 // If the task has temp inset bounds set, we have to make sure all its windows uses
710 // the temp inset frame. Otherwise different display frames get applied to the main
711 // window and the child window, making them misaligned.
712 if (fullscreenTask) {
713 mInsetFrame.setEmpty();
714 } else {
715 task.getTempInsetBounds(mInsetFrame);
716 }
717
Jorim Jaggif5834272016-04-04 20:25:41 -0700718 // Denotes the actual frame used to calculate the insets and to perform the layout. When
719 // resizing in docked mode, we'd like to freeze the layout, so we also need to freeze the
720 // insets temporarily. By the notion of a task having a different layout frame, we can
721 // achieve that while still moving the task around.
722 final Rect layoutContainingFrame;
723 final Rect layoutDisplayFrame;
724
725 // The offset from the layout containing frame to the actual containing frame.
726 final int layoutXDiff;
727 final int layoutYDiff;
Wale Ogunwale7cd4b012016-05-07 12:41:22 -0700728 if (fullscreenTask || layoutInParentFrame()) {
Wale Ogunwale79f268d2015-12-18 08:25:47 -0800729 // We use the parent frame as the containing frame for fullscreen and child windows
730 mContainingFrame.set(pf);
731 mDisplayFrame.set(df);
Jorim Jaggif5834272016-04-04 20:25:41 -0700732 layoutDisplayFrame = df;
733 layoutContainingFrame = pf;
734 layoutXDiff = 0;
735 layoutYDiff = 0;
Wale Ogunwale79f268d2015-12-18 08:25:47 -0800736 } else {
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700737 task.getBounds(mContainingFrame);
Jorim Jaggi0429f352015-12-22 16:29:16 +0100738 if (mAppToken != null && !mAppToken.mFrozenBounds.isEmpty()) {
739
740 // If the bounds are frozen, we still want to translate the window freely and only
741 // freeze the size.
742 Rect frozen = mAppToken.mFrozenBounds.peek();
743 mContainingFrame.right = mContainingFrame.left + frozen.width();
744 mContainingFrame.bottom = mContainingFrame.top + frozen.height();
745 }
Wale Ogunwalef9c81492015-02-25 18:06:17 -0800746 final WindowState imeWin = mService.mInputMethodWindow;
Robert Carrfc03b2b2016-03-31 15:22:02 -0700747 // IME is up and obscuring this window. Adjust the window position so it is visible.
748 if (imeWin != null && imeWin.isVisibleNow() && mService.mInputMethodTarget == this) {
749 if (windowsAreFloating && mContainingFrame.bottom > cf.bottom) {
750 // In freeform we want to move the top up directly.
751 // TODO: Investigate why this is cf not pf.
752 mContainingFrame.top -= mContainingFrame.bottom - cf.bottom;
753 } else if (mContainingFrame.bottom > pf.bottom) {
754 // But in docked we want to behave like fullscreen
755 // and behave as if the task were given smaller bounds
756 // for the purposes of layout.
757 mContainingFrame.bottom = pf.bottom;
758 }
Craig Mautnerc5a6e442013-06-05 17:22:35 -0700759 }
Skuhne81c524a2015-08-12 13:34:14 -0700760
Robert Carre6275582016-02-29 15:45:45 -0800761 if (windowsAreFloating) {
Chong Zhang65d15d02016-03-14 13:59:32 -0700762 // In floating modes (e.g. freeform, pinned) we have only to set the rectangle
763 // if it wasn't set already. No need to intersect it with the (visible)
Robert Carre6275582016-02-29 15:45:45 -0800764 // "content frame" since it is allowed to be outside the visible desktop.
Skuhne81c524a2015-08-12 13:34:14 -0700765 if (mContainingFrame.isEmpty()) {
766 mContainingFrame.set(cf);
767 }
Doris Liu06d582d2015-06-01 13:18:43 -0700768 }
Wale Ogunwale94596652015-02-06 19:27:34 -0800769 mDisplayFrame.set(mContainingFrame);
Jorim Jaggif5834272016-04-04 20:25:41 -0700770 layoutXDiff = !mInsetFrame.isEmpty() ? mInsetFrame.left - mContainingFrame.left : 0;
771 layoutYDiff = !mInsetFrame.isEmpty() ? mInsetFrame.top - mContainingFrame.top : 0;
772 layoutContainingFrame = !mInsetFrame.isEmpty() ? mInsetFrame : mContainingFrame;
Andrii Kuliandaea3572016-04-08 13:20:51 -0700773 mTmpRect.set(0, 0, mDisplayContent.getDisplayInfo().logicalWidth,
774 mDisplayContent.getDisplayInfo().logicalHeight);
775 subtractInsets(mDisplayFrame, layoutContainingFrame, df, mTmpRect);
Robert Carrfd2bd1b2016-04-07 13:52:43 -0700776 if (!layoutInParentFrame()) {
Andrii Kuliandaea3572016-04-08 13:20:51 -0700777 subtractInsets(mContainingFrame, layoutContainingFrame, pf, mTmpRect);
778 subtractInsets(mInsetFrame, layoutContainingFrame, pf, mTmpRect);
Robert Carrfd2bd1b2016-04-07 13:52:43 -0700779 }
Jorim Jaggif5834272016-04-04 20:25:41 -0700780 layoutDisplayFrame = df;
781 layoutDisplayFrame.intersect(layoutContainingFrame);
Craig Mautner967212c2013-04-13 21:10:58 -0700782 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800783
Craig Mautner967212c2013-04-13 21:10:58 -0700784 final int pw = mContainingFrame.width();
785 final int ph = mContainingFrame.height();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800786
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800787 if (!mParentFrame.equals(pf)) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800788 //Slog.i(TAG_WM, "Window " + this + " content frame from " + mParentFrame
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800789 // + " to " + pf);
790 mParentFrame.set(pf);
791 mContentChanged = true;
792 }
Dianne Hackborn1743b642012-03-12 17:04:43 -0700793 if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) {
794 mLastRequestedWidth = mRequestedWidth;
795 mLastRequestedHeight = mRequestedHeight;
796 mContentChanged = true;
797 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800798
Craig Mautnereda67292013-04-28 13:50:14 -0700799 mOverscanFrame.set(of);
800 mContentFrame.set(cf);
801 mVisibleFrame.set(vf);
John Spurlock46646232013-09-30 22:32:42 -0400802 mDecorFrame.set(dcf);
Adrian Roosfa104232014-06-20 16:10:14 -0700803 mStableFrame.set(sf);
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700804 final boolean hasOutsets = osf != null;
805 if (hasOutsets) {
806 mOutsetFrame.set(osf);
807 }
Dianne Hackbornc4aad012013-02-22 15:05:25 -0800808
Craig Mautnereda67292013-04-28 13:50:14 -0700809 final int fw = mFrame.width();
810 final int fh = mFrame.height();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800811
Jorim Jaggif5834272016-04-04 20:25:41 -0700812 applyGravityAndUpdateFrame(layoutContainingFrame, layoutDisplayFrame);
813
Filip Gruszczynskiaaf18112015-06-05 13:37:40 -0700814 // Calculate the outsets before the content frame gets shrinked to the window frame.
815 if (hasOutsets) {
816 mOutsets.set(Math.max(mContentFrame.left - mOutsetFrame.left, 0),
817 Math.max(mContentFrame.top - mOutsetFrame.top, 0),
818 Math.max(mOutsetFrame.right - mContentFrame.right, 0),
819 Math.max(mOutsetFrame.bottom - mContentFrame.bottom, 0));
820 } else {
821 mOutsets.set(0, 0, 0, 0);
822 }
823
Craig Mautnera248eee2013-05-07 11:41:27 -0700824 // Make sure the content and visible frames are inside of the
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800825 // final window frame.
Robert Carre6275582016-02-29 15:45:45 -0800826 if (windowsAreFloating && !mFrame.isEmpty()) {
Skuhne81c524a2015-08-12 13:34:14 -0700827 // Keep the frame out of the blocked system area, limit it in size to the content area
828 // and make sure that there is always a minimum visible so that the user can drag it
829 // into a usable area..
830 final int height = Math.min(mFrame.height(), mContentFrame.height());
831 final int width = Math.min(mContentFrame.width(), mFrame.width());
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700832 final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics();
Kazuhiro Inaba63e24d12016-07-14 13:02:55 +0900833 final int minVisibleHeight = Math.min(height, WindowManagerService.dipToPixel(
834 MINIMUM_VISIBLE_HEIGHT_IN_DP, displayMetrics));
835 final int minVisibleWidth = Math.min(width, WindowManagerService.dipToPixel(
836 MINIMUM_VISIBLE_WIDTH_IN_DP, displayMetrics));
Skuhne81c524a2015-08-12 13:34:14 -0700837 final int top = Math.max(mContentFrame.top,
838 Math.min(mFrame.top, mContentFrame.bottom - minVisibleHeight));
839 final int left = Math.max(mContentFrame.left + minVisibleWidth - width,
840 Math.min(mFrame.left, mContentFrame.right - minVisibleWidth));
841 mFrame.set(left, top, left + width, top + height);
842 mContentFrame.set(mFrame);
843 mVisibleFrame.set(mContentFrame);
844 mStableFrame.set(mContentFrame);
Filip Gruszczynski466f3212015-09-21 17:57:57 -0700845 } else if (mAttrs.type == TYPE_DOCK_DIVIDER) {
Jorim Jaggi192086e2016-03-11 17:17:03 +0100846 mDisplayContent.getDockedDividerController().positionDockedStackedDivider(mFrame);
847 mContentFrame.set(mFrame);
848 if (!mFrame.equals(mLastFrame)) {
849 mMovedByResize = true;
Filip Gruszczynskiae100802015-11-11 15:58:03 -0800850 }
Skuhne81c524a2015-08-12 13:34:14 -0700851 } else {
Jorim Jaggi656f6502016-04-11 21:08:17 -0700852 mContentFrame.set(Math.max(mContentFrame.left, mFrame.left),
853 Math.max(mContentFrame.top, mFrame.top),
854 Math.min(mContentFrame.right, mFrame.right),
855 Math.min(mContentFrame.bottom, mFrame.bottom));
Dianne Hackbornc4aad012013-02-22 15:05:25 -0800856
Jorim Jaggi656f6502016-04-11 21:08:17 -0700857 mVisibleFrame.set(Math.max(mVisibleFrame.left, mFrame.left),
858 Math.max(mVisibleFrame.top, mFrame.top),
859 Math.min(mVisibleFrame.right, mFrame.right),
860 Math.min(mVisibleFrame.bottom, mFrame.bottom));
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800861
Jorim Jaggi656f6502016-04-11 21:08:17 -0700862 mStableFrame.set(Math.max(mStableFrame.left, mFrame.left),
863 Math.max(mStableFrame.top, mFrame.top),
864 Math.min(mStableFrame.right, mFrame.right),
865 Math.min(mStableFrame.bottom, mFrame.bottom));
Skuhne81c524a2015-08-12 13:34:14 -0700866 }
Adrian Roosfa104232014-06-20 16:10:14 -0700867
Jorim Jaggi899327f2016-02-25 20:44:18 -0500868 if (fullscreenTask && !windowsAreFloating) {
869 // Windows that are not fullscreen can be positioned outside of the display frame,
870 // but that is not a reason to provide them with overscan insets.
Jorim Jaggif5834272016-04-04 20:25:41 -0700871 mOverscanInsets.set(Math.max(mOverscanFrame.left - layoutContainingFrame.left, 0),
872 Math.max(mOverscanFrame.top - layoutContainingFrame.top, 0),
873 Math.max(layoutContainingFrame.right - mOverscanFrame.right, 0),
874 Math.max(layoutContainingFrame.bottom - mOverscanFrame.bottom, 0));
Filip Gruszczynski01ef404d52016-01-28 18:14:27 -0800875 }
Craig Mautnereda67292013-04-28 13:50:14 -0700876
Jorim Jaggi81fe2d12015-12-21 14:45:18 +0100877 if (mAttrs.type == TYPE_DOCK_DIVIDER) {
Jorim Jaggi81fe2d12015-12-21 14:45:18 +0100878 // For the docked divider, we calculate the stable insets like a full-screen window
879 // so it can use it to calculate the snap positions.
880 mStableInsets.set(Math.max(mStableFrame.left - mDisplayFrame.left, 0),
881 Math.max(mStableFrame.top - mDisplayFrame.top, 0),
882 Math.max(mDisplayFrame.right - mStableFrame.right, 0),
883 Math.max(mDisplayFrame.bottom - mStableFrame.bottom, 0));
Jorim Jaggi2e95a482016-01-14 17:36:55 -0800884
885 // The divider doesn't care about insets in any case, so set it to empty so we don't
886 // trigger a relayout when moving it.
887 mContentInsets.setEmpty();
888 mVisibleInsets.setEmpty();
Jorim Jaggi81fe2d12015-12-21 14:45:18 +0100889 } else {
Andrii Kuliand9003372016-04-04 17:46:59 -0700890 getDisplayContent().getLogicalDisplayRect(mTmpRect);
Andrii Kuliana9d168c2016-03-23 13:19:32 -0700891 // Override right and/or bottom insets in case if the frame doesn't fit the screen in
892 // non-fullscreen mode.
Jorim Jaggi656f6502016-04-11 21:08:17 -0700893 boolean overrideRightInset = !fullscreenTask && mFrame.right > mTmpRect.right;
894 boolean overrideBottomInset = !fullscreenTask && mFrame.bottom > mTmpRect.bottom;
895 mContentInsets.set(mContentFrame.left - mFrame.left,
896 mContentFrame.top - mFrame.top,
Andrii Kuliand9003372016-04-04 17:46:59 -0700897 overrideRightInset ? mTmpRect.right - mContentFrame.right
Jorim Jaggi656f6502016-04-11 21:08:17 -0700898 : mFrame.right - mContentFrame.right,
Andrii Kuliand9003372016-04-04 17:46:59 -0700899 overrideBottomInset ? mTmpRect.bottom - mContentFrame.bottom
Jorim Jaggi656f6502016-04-11 21:08:17 -0700900 : mFrame.bottom - mContentFrame.bottom);
Jorim Jaggi2e95a482016-01-14 17:36:55 -0800901
Jorim Jaggi656f6502016-04-11 21:08:17 -0700902 mVisibleInsets.set(mVisibleFrame.left - mFrame.left,
903 mVisibleFrame.top - mFrame.top,
Andrii Kuliand9003372016-04-04 17:46:59 -0700904 overrideRightInset ? mTmpRect.right - mVisibleFrame.right
Jorim Jaggi656f6502016-04-11 21:08:17 -0700905 : mFrame.right - mVisibleFrame.right,
Andrii Kuliand9003372016-04-04 17:46:59 -0700906 overrideBottomInset ? mTmpRect.bottom - mVisibleFrame.bottom
Jorim Jaggi656f6502016-04-11 21:08:17 -0700907 : mFrame.bottom - mVisibleFrame.bottom);
Jorim Jaggi2e95a482016-01-14 17:36:55 -0800908
Jorim Jaggi656f6502016-04-11 21:08:17 -0700909 mStableInsets.set(Math.max(mStableFrame.left - mFrame.left, 0),
910 Math.max(mStableFrame.top - mFrame.top, 0),
Andrii Kuliand9003372016-04-04 17:46:59 -0700911 overrideRightInset ? Math.max(mTmpRect.right - mStableFrame.right, 0)
Jorim Jaggi656f6502016-04-11 21:08:17 -0700912 : Math.max(mFrame.right - mStableFrame.right, 0),
Andrii Kuliand9003372016-04-04 17:46:59 -0700913 overrideBottomInset ? Math.max(mTmpRect.bottom - mStableFrame.bottom, 0)
Jorim Jaggi656f6502016-04-11 21:08:17 -0700914 : Math.max(mFrame.bottom - mStableFrame.bottom, 0));
Jorim Jaggi81fe2d12015-12-21 14:45:18 +0100915 }
Adrian Roosfa104232014-06-20 16:10:14 -0700916
Jorim Jaggi656f6502016-04-11 21:08:17 -0700917 // Offset the actual frame by the amount layout frame is off.
918 mFrame.offset(-layoutXDiff, -layoutYDiff);
919 mCompatFrame.offset(-layoutXDiff, -layoutYDiff);
Jorim Jaggif5834272016-04-04 20:25:41 -0700920 mContentFrame.offset(-layoutXDiff, -layoutYDiff);
921 mVisibleFrame.offset(-layoutXDiff, -layoutYDiff);
922 mStableFrame.offset(-layoutXDiff, -layoutYDiff);
923
Craig Mautnereda67292013-04-28 13:50:14 -0700924 mCompatFrame.set(mFrame);
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400925 if (mEnforceSizeCompat) {
Dianne Hackbornffb3d932011-05-17 17:44:51 -0700926 // If there is a size compatibility scale being applied to the
927 // window, we need to apply this to its insets so that they are
928 // reported to the app in its coordinate space.
Craig Mautnereda67292013-04-28 13:50:14 -0700929 mOverscanInsets.scale(mInvGlobalScale);
930 mContentInsets.scale(mInvGlobalScale);
931 mVisibleInsets.scale(mInvGlobalScale);
Adrian Roosfa104232014-06-20 16:10:14 -0700932 mStableInsets.scale(mInvGlobalScale);
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700933 mOutsets.scale(mInvGlobalScale);
Dianne Hackbornffb3d932011-05-17 17:44:51 -0700934
935 // Also the scaled frame that we report to the app needs to be
936 // adjusted to be in its coordinate space.
937 mCompatFrame.scale(mInvGlobalScale);
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400938 }
939
Craig Mautnereda67292013-04-28 13:50:14 -0700940 if (mIsWallpaper && (fw != mFrame.width() || fh != mFrame.height())) {
Craig Mautnerdf88d732014-01-27 09:21:32 -0800941 final DisplayContent displayContent = getDisplayContent();
942 if (displayContent != null) {
943 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700944 mService.mWallpaperControllerLocked.updateWallpaperOffset(
945 this, displayInfo.logicalWidth, displayInfo.logicalHeight, false);
Craig Mautnerdf88d732014-01-27 09:21:32 -0800946 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800947 }
948
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700949 if (DEBUG_LAYOUT || localLOGV) Slog.v(TAG,
Craig Mautnerb3b36ba2013-05-20 13:21:10 -0700950 "Resolving (mRequestedWidth="
951 + mRequestedWidth + ", mRequestedheight="
952 + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
953 + "): frame=" + mFrame.toShortString()
954 + " ci=" + mContentInsets.toShortString()
Adrian Roosfa104232014-06-20 16:10:14 -0700955 + " vi=" + mVisibleInsets.toShortString()
Andrii Kuliana9d168c2016-03-23 13:19:32 -0700956 + " si=" + mStableInsets.toShortString()
Filip Gruszczynski2217f612015-05-26 11:32:08 -0700957 + " of=" + mOutsets.toShortString());
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800958 }
959
Craig Mautnera2c77052012-03-26 12:14:43 -0700960 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800961 public Rect getFrameLw() {
962 return mFrame;
963 }
964
Craig Mautnera2c77052012-03-26 12:14:43 -0700965 @Override
Filip Gruszczynski2a6a2c22015-10-14 12:00:53 -0700966 public Point getShownPositionLw() {
967 return mShownPosition;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800968 }
969
Craig Mautnera2c77052012-03-26 12:14:43 -0700970 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800971 public Rect getDisplayFrameLw() {
972 return mDisplayFrame;
973 }
974
Craig Mautnera2c77052012-03-26 12:14:43 -0700975 @Override
Dianne Hackbornc4aad012013-02-22 15:05:25 -0800976 public Rect getOverscanFrameLw() {
977 return mOverscanFrame;
978 }
979
980 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800981 public Rect getContentFrameLw() {
982 return mContentFrame;
983 }
984
Craig Mautnera2c77052012-03-26 12:14:43 -0700985 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800986 public Rect getVisibleFrameLw() {
987 return mVisibleFrame;
988 }
989
Craig Mautnera2c77052012-03-26 12:14:43 -0700990 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800991 public boolean getGivenInsetsPendingLw() {
992 return mGivenInsetsPending;
993 }
994
Craig Mautnera2c77052012-03-26 12:14:43 -0700995 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800996 public Rect getGivenContentInsetsLw() {
997 return mGivenContentInsets;
998 }
999
Craig Mautnera2c77052012-03-26 12:14:43 -07001000 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001001 public Rect getGivenVisibleInsetsLw() {
1002 return mGivenVisibleInsets;
1003 }
1004
Craig Mautnera2c77052012-03-26 12:14:43 -07001005 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001006 public WindowManager.LayoutParams getAttrs() {
1007 return mAttrs;
1008 }
1009
Craig Mautner812d2ca2012-09-27 15:35:34 -07001010 @Override
Dianne Hackborn73ab6a42011-12-13 11:16:23 -08001011 public boolean getNeedsMenuLw(WindowManagerPolicy.WindowState bottom) {
1012 int index = -1;
1013 WindowState ws = this;
Craig Mautner59c00972012-07-30 12:10:24 -07001014 WindowList windows = getWindowList();
Dianne Hackborn73ab6a42011-12-13 11:16:23 -08001015 while (true) {
Wale Ogunwale393b1c12014-10-18 16:22:01 -07001016 if (ws.mAttrs.needsMenuKey != WindowManager.LayoutParams.NEEDS_MENU_UNSET) {
1017 return ws.mAttrs.needsMenuKey == WindowManager.LayoutParams.NEEDS_MENU_SET_TRUE;
Dianne Hackborn73ab6a42011-12-13 11:16:23 -08001018 }
1019 // If we reached the bottom of the range of windows we are considering,
1020 // assume no menu is needed.
1021 if (ws == bottom) {
1022 return false;
1023 }
1024 // The current window hasn't specified whether menu key is needed;
1025 // look behind it.
1026 // First, we may need to determine the starting position.
1027 if (index < 0) {
Craig Mautner59c00972012-07-30 12:10:24 -07001028 index = windows.indexOf(ws);
Dianne Hackborn73ab6a42011-12-13 11:16:23 -08001029 }
1030 index--;
1031 if (index < 0) {
1032 return false;
1033 }
Craig Mautner59c00972012-07-30 12:10:24 -07001034 ws = windows.get(index);
Dianne Hackborn73ab6a42011-12-13 11:16:23 -08001035 }
1036 }
1037
Craig Mautner19d59bc2012-09-04 11:15:56 -07001038 @Override
Dianne Hackborn9a230e02011-10-06 11:51:27 -07001039 public int getSystemUiVisibility() {
1040 return mSystemUiVisibility;
1041 }
1042
Craig Mautner19d59bc2012-09-04 11:15:56 -07001043 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001044 public int getSurfaceLayer() {
1045 return mLayer;
1046 }
1047
Craig Mautner812d2ca2012-09-27 15:35:34 -07001048 @Override
Selim Cinekd6623612015-05-22 18:56:22 -07001049 public int getBaseType() {
Wale Ogunwalecaa53af2016-07-17 14:50:26 -07001050 return getTopParentWindow().mAttrs.type;
Selim Cinekd6623612015-05-22 18:56:22 -07001051 }
1052
1053 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001054 public IApplicationToken getAppToken() {
1055 return mAppToken != null ? mAppToken.appToken : null;
1056 }
Craig Mautner19d59bc2012-09-04 11:15:56 -07001057
Dianne Hackborne30e02f2014-05-27 18:24:45 -07001058 @Override
1059 public boolean isVoiceInteraction() {
Filip Gruszczynski0689ae92015-10-01 12:30:31 -07001060 return mAppToken != null && mAppToken.voiceInteraction;
Dianne Hackborne30e02f2014-05-27 18:24:45 -07001061 }
1062
Robert Carr31aa98b2016-07-20 15:29:03 -07001063 boolean setReportResizeHints() {
Craig Mautner4c5eb222013-11-18 12:59:05 -08001064 mOverscanInsetsChanged |= !mLastOverscanInsets.equals(mOverscanInsets);
1065 mContentInsetsChanged |= !mLastContentInsets.equals(mContentInsets);
1066 mVisibleInsetsChanged |= !mLastVisibleInsets.equals(mVisibleInsets);
Adrian Roosfa104232014-06-20 16:10:14 -07001067 mStableInsetsChanged |= !mLastStableInsets.equals(mStableInsets);
Filip Gruszczynski2217f612015-05-26 11:32:08 -07001068 mOutsetsChanged |= !mLastOutsets.equals(mOutsets);
Robert Carr31aa98b2016-07-20 15:29:03 -07001069 mFrameSizeChanged |= (mLastFrame.width() != mFrame.width()) ||
1070 (mLastFrame.height() != mFrame.height());
Filip Gruszczynski2217f612015-05-26 11:32:08 -07001071 return mOverscanInsetsChanged || mContentInsetsChanged || mVisibleInsetsChanged
Robert Carr31aa98b2016-07-20 15:29:03 -07001072 || mOutsetsChanged || mFrameSizeChanged;
Craig Mautner4c5eb222013-11-18 12:59:05 -08001073 }
1074
Craig Mautnerdf88d732014-01-27 09:21:32 -08001075 public DisplayContent getDisplayContent() {
Chad Jonesf391ebc2014-06-12 17:45:05 -07001076 if (mAppToken == null || mNotOnAppsDisplay) {
Craig Mautnerbe634952014-06-12 13:39:24 -07001077 return mDisplayContent;
1078 }
1079 final TaskStack stack = getStack();
1080 return stack == null ? mDisplayContent : stack.getDisplayContent();
Craig Mautnerdf88d732014-01-27 09:21:32 -08001081 }
1082
Chong Zhang09b21ef2015-09-14 10:20:21 -07001083 public DisplayInfo getDisplayInfo() {
1084 final DisplayContent displayContent = getDisplayContent();
1085 return displayContent != null ? displayContent.getDisplayInfo() : null;
1086 }
1087
Craig Mautner19d59bc2012-09-04 11:15:56 -07001088 public int getDisplayId() {
Craig Mautnerdf88d732014-01-27 09:21:32 -08001089 final DisplayContent displayContent = getDisplayContent();
1090 if (displayContent == null) {
1091 return -1;
1092 }
1093 return displayContent.getDisplayId();
Craig Mautner19d59bc2012-09-04 11:15:56 -07001094 }
1095
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001096 Task getTask() {
Wale Ogunwale5a2f2cb2015-09-17 12:31:55 -07001097 return mAppToken != null ? mAppToken.mTask : null;
Wale Ogunwalee4a0c572015-06-30 08:40:31 -07001098 }
1099
1100 TaskStack getStack() {
1101 Task task = getTask();
1102 if (task != null) {
1103 if (task.mStack != null) {
1104 return task.mStack;
Craig Mautnerf06b8c12013-04-18 14:27:28 -07001105 }
Craig Mautnerd9a22882013-03-16 15:00:36 -07001106 }
Filip Gruszczynski0689ae92015-10-01 12:30:31 -07001107 // Some system windows (e.g. "Power off" dialog) don't have a task, but we would still
1108 // associate them with some stack to enable dimming.
1109 return mAttrs.type >= WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW
1110 && mDisplayContent != null ? mDisplayContent.getHomeStack() : null;
Craig Mautnerd9a22882013-03-16 15:00:36 -07001111 }
1112
Skuhnef932e562015-08-20 12:07:30 -07001113 /**
Wale Ogunwale61b009e2015-09-16 15:43:05 -07001114 * Retrieves the visible bounds of the window.
Skuhnef932e562015-08-20 12:07:30 -07001115 * @param bounds The rect which gets the bounds.
Skuhnef932e562015-08-20 12:07:30 -07001116 */
Chong Zhang4c9ba52a2015-11-10 18:36:33 -08001117 void getVisibleBounds(Rect bounds) {
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001118 final Task task = getTask();
1119 boolean intersectWithStackBounds = task != null && task.cropWindowsToStackBounds();
Wale Ogunwale61b009e2015-09-16 15:43:05 -07001120 bounds.setEmpty();
Wale Ogunwale2b19b602015-09-18 15:14:59 -07001121 mTmpRect.setEmpty();
1122 if (intersectWithStackBounds) {
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08001123 final TaskStack stack = task.mStack;
Wale Ogunwale61b009e2015-09-16 15:43:05 -07001124 if (stack != null) {
Chong Zhang4c9ba52a2015-11-10 18:36:33 -08001125 stack.getDimBounds(mTmpRect);
Wale Ogunwale2b19b602015-09-18 15:14:59 -07001126 } else {
1127 intersectWithStackBounds = false;
Wale Ogunwale61b009e2015-09-16 15:43:05 -07001128 }
1129 }
Wale Ogunwale2b19b602015-09-18 15:14:59 -07001130
Chong Zhang9184ec62015-09-24 12:32:21 -07001131 bounds.set(mVisibleFrame);
1132 if (intersectWithStackBounds) {
1133 bounds.intersect(mTmpRect);
Wale Ogunwale2b19b602015-09-18 15:14:59 -07001134 }
1135
Wale Ogunwale61b009e2015-09-16 15:43:05 -07001136 if (bounds.isEmpty()) {
1137 bounds.set(mFrame);
Wale Ogunwale2b19b602015-09-18 15:14:59 -07001138 if (intersectWithStackBounds) {
1139 bounds.intersect(mTmpRect);
1140 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -08001141 return;
Craig Mautner4cd0c13f2013-04-16 15:55:52 -07001142 }
Craig Mautner4cd0c13f2013-04-16 15:55:52 -07001143 }
1144
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001145 public long getInputDispatchingTimeoutNanos() {
1146 return mAppToken != null
1147 ? mAppToken.inputDispatchingTimeoutNanos
1148 : WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
1149 }
1150
Craig Mautnere8552142012-11-07 13:55:47 -08001151 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001152 public boolean hasAppShownWindows() {
Craig Mautnerf4120952012-06-21 18:25:39 -07001153 return mAppToken != null && (mAppToken.firstWindowDrawn || mAppToken.startingDisplayed);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001154 }
1155
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001156 boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
1157 if (dsdx < .99999f || dsdx > 1.00001f) return false;
1158 if (dtdy < .99999f || dtdy > 1.00001f) return false;
1159 if (dtdx < -.000001f || dtdx > .000001f) return false;
1160 if (dsdy < -.000001f || dsdy > .000001f) return false;
1161 return true;
1162 }
1163
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001164 void prelayout() {
1165 if (mEnforceSizeCompat) {
1166 mGlobalScale = mService.mCompatibleScreenScale;
Dianne Hackbornffb3d932011-05-17 17:44:51 -07001167 mInvGlobalScale = 1/mGlobalScale;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001168 } else {
Dianne Hackbornffb3d932011-05-17 17:44:51 -07001169 mGlobalScale = mInvGlobalScale = 1;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001170 }
1171 }
1172
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001173 // TODO: Sigh...another is visible method...tried to consolidate with other isVisible methods
1174 // below, but failed. Need to figure-out a good way to handle this long term...
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001175 @Override
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001176 boolean isVisible() {
1177 // If we're animating with a saved surface, we're already visible.
1178 // Return true so that the alpha doesn't get cleared.
1179 if (!mAppFreezing && isDrawnLw()
1180 && (mViewVisibility == View.VISIBLE || isAnimatingWithSavedSurface()
1181 || (mWinAnimator.isAnimationSet() && !mService.mAppTransition.isTransitionSet()))) {
1182 return true;
1183 }
1184
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001185 return super.isVisible();
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001186 }
1187
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001188 /**
Wale Ogunwale329b7e52016-01-15 15:00:57 -08001189 * Does the minimal check for visibility. Callers generally want to use one of the public
1190 * methods as they perform additional checks on the app token.
1191 * TODO: See if there are other places we can use this check below instead of duplicating...
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001192 */
Wale Ogunwale329b7e52016-01-15 15:00:57 -08001193 private boolean isVisibleUnchecked() {
Wale Ogunwale9d147902016-07-16 11:58:55 -07001194 return mHasSurface && mPolicyVisibility && !isParentWindowHidden()
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001195 && !mAnimatingExit && !mDestroying && (!mIsWallpaper || mWallpaperVisible);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001196 }
1197
1198 /**
Wale Ogunwale329b7e52016-01-15 15:00:57 -08001199 * Is this window visible? It is not visible if there is no surface, or we are in the process
1200 * of running an exit animation that will remove the surface, or its app token has been hidden.
1201 */
1202 @Override
1203 public boolean isVisibleLw() {
1204 return (mAppToken == null || !mAppToken.hiddenRequested) && isVisibleUnchecked();
1205 }
1206
1207 /**
1208 * Like {@link #isVisibleLw}, but also counts a window that is currently "hidden" behind the
1209 * keyguard as visible. This allows us to apply things like window flags that impact the
1210 * keyguard. XXX I am starting to think we need to have ANOTHER visibility flag for this
1211 * "hidden behind keyguard" state rather than overloading mPolicyVisibility. Ungh.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001212 */
Craig Mautner88400d32012-09-30 12:35:45 -07001213 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001214 public boolean isVisibleOrBehindKeyguardLw() {
Wale Ogunwalea6cc3612016-08-04 07:25:33 -07001215 if (mToken.waitingToShow && mService.mAppTransition.isTransitionSet()) {
Dianne Hackbornbc1aa7b2011-09-20 11:20:31 -07001216 return false;
1217 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001218 final AppWindowToken atoken = mAppToken;
Filip Gruszczynski0689ae92015-10-01 12:30:31 -07001219 final boolean animating = atoken != null && atoken.mAppAnimator.animation != null;
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001220 return mHasSurface && !mDestroying && !mAnimatingExit
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001221 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
Wale Ogunwalea6cc3612016-08-04 07:25:33 -07001222 && ((!isParentWindowHidden() && mViewVisibility == View.VISIBLE && !mToken.hidden)
Craig Mautnera2c77052012-03-26 12:14:43 -07001223 || mWinAnimator.mAnimation != null || animating);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001224 }
1225
1226 /**
Wale Ogunwale329b7e52016-01-15 15:00:57 -08001227 * Is this window visible, ignoring its app token? It is not visible if there is no surface,
1228 * or we are in the process of running an exit animation that will remove the surface.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001229 */
1230 public boolean isWinVisibleLw() {
Wale Ogunwale329b7e52016-01-15 15:00:57 -08001231 return (mAppToken == null || !mAppToken.hiddenRequested || mAppToken.mAppAnimator.animating)
1232 && isVisibleUnchecked();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001233 }
1234
1235 /**
Wale Ogunwale329b7e52016-01-15 15:00:57 -08001236 * The same as isVisible(), but follows the current hidden state of the associated app token,
1237 * not the pending requested hidden state.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001238 */
1239 boolean isVisibleNow() {
Wale Ogunwalea6cc3612016-08-04 07:25:33 -07001240 return (!mToken.hidden || mAttrs.type == TYPE_APPLICATION_STARTING)
Wale Ogunwale329b7e52016-01-15 15:00:57 -08001241 && isVisibleUnchecked();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001242 }
1243
1244 /**
1245 * Can this window possibly be a drag/drop target? The test here is
1246 * a combination of the above "visible now" with the check that the
1247 * Input Manager uses when discarding windows from input consideration.
1248 */
1249 boolean isPotentialDragTarget() {
Jeff Browncc4f7db2011-08-30 20:34:48 -07001250 return isVisibleNow() && !mRemoved
1251 && mInputChannel != null && mInputWindowHandle != null;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001252 }
1253
1254 /**
1255 * Same as isVisible(), but we also count it as visible between the
1256 * call to IWindowSession.add() and the first relayout().
1257 */
1258 boolean isVisibleOrAdding() {
1259 final AppWindowToken atoken = mAppToken;
Craig Mautnerbf08af32012-05-16 19:43:42 -07001260 return (mHasSurface || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
Wale Ogunwale9d147902016-07-16 11:58:55 -07001261 && mPolicyVisibility && !isParentWindowHidden()
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001262 && (atoken == null || !atoken.hiddenRequested)
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001263 && !mAnimatingExit && !mDestroying;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001264 }
1265
1266 /**
1267 * Is this window currently on-screen? It is on-screen either if it
1268 * is visible or it is currently running an animation before no longer
1269 * being visible.
1270 */
1271 boolean isOnScreen() {
Jorim Jaggi44f60cc2014-11-07 20:33:51 +01001272 return mPolicyVisibility && isOnScreenIgnoringKeyguard();
1273 }
1274
1275 /**
1276 * Like isOnScreen(), but ignores any force hiding of the window due
1277 * to the keyguard.
1278 */
1279 boolean isOnScreenIgnoringKeyguard() {
1280 if (!mHasSurface || mDestroying) {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001281 return false;
1282 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001283 final AppWindowToken atoken = mAppToken;
1284 if (atoken != null) {
Wale Ogunwale9d147902016-07-16 11:58:55 -07001285 return ((!isParentWindowHidden() && !atoken.hiddenRequested)
Craig Mautnerccc9e9b2012-12-11 09:40:34 -08001286 || mWinAnimator.mAnimation != null || atoken.mAppAnimator.animation != null);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001287 }
Wale Ogunwale9d147902016-07-16 11:58:55 -07001288 return !isParentWindowHidden() || mWinAnimator.mAnimation != null;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001289 }
1290
1291 /**
Chong Zhang8e4bda92016-05-04 15:08:18 -07001292 * Whether this window's drawn state might affect the drawn states of the app token.
1293 *
1294 * @param visibleOnly Whether we should consider only the windows that's currently
1295 * visible in layout. If true, windows that has not relayout to VISIBLE
1296 * would always return false.
1297 *
1298 * @return true if the window should be considered while evaluating allDrawn flags.
1299 */
1300 boolean mightAffectAllDrawn(boolean visibleOnly) {
Chong Zhange292eb32016-05-21 09:23:55 -07001301 final boolean isViewVisible = (mAppToken == null || !mAppToken.clientHidden)
1302 && (mViewVisibility == View.VISIBLE) && !mWindowRemovalAllowed;
Chong Zhang8e4bda92016-05-04 15:08:18 -07001303 return (isOnScreenIgnoringKeyguard() && (!visibleOnly || isViewVisible)
Chong Zhangfea963e2016-08-15 17:14:16 -07001304 || mWinAnimator.mAttrType == TYPE_BASE_APPLICATION
1305 || mWinAnimator.mAttrType == TYPE_DRAWN_APPLICATION)
Chong Zhang8e4bda92016-05-04 15:08:18 -07001306 && !mAnimatingExit && !mDestroying;
1307 }
1308
1309 /**
1310 * Whether this window is "interesting" when evaluating allDrawn. If it's interesting,
1311 * it must be drawn before allDrawn can become true.
1312 */
1313 boolean isInteresting() {
1314 return mAppToken != null && !mAppDied
1315 && (!mAppToken.mAppAnimator.freezingScreen || !mAppFreezing);
1316 }
1317
1318 /**
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001319 * Like isOnScreen(), but we don't return true if the window is part
1320 * of a transition that has not yet been started.
1321 */
1322 boolean isReadyForDisplay() {
Wale Ogunwalea6cc3612016-08-04 07:25:33 -07001323 if (mToken.waitingToShow && mService.mAppTransition.isTransitionSet()) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001324 return false;
1325 }
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001326 return mHasSurface && mPolicyVisibility && !mDestroying
Wale Ogunwalea6cc3612016-08-04 07:25:33 -07001327 && ((!isParentWindowHidden() && mViewVisibility == View.VISIBLE && !mToken.hidden)
Craig Mautnera2c77052012-03-26 12:14:43 -07001328 || mWinAnimator.mAnimation != null
Craig Mautner59431632012-04-04 11:56:44 -07001329 || ((mAppToken != null) && (mAppToken.mAppAnimator.animation != null)));
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001330 }
1331
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001332 /**
Dianne Hackborn6e2281d2012-06-19 17:48:32 -07001333 * Like isReadyForDisplay(), but ignores any force hiding of the window due
1334 * to the keyguard.
1335 */
1336 boolean isReadyForDisplayIgnoringKeyguard() {
Wale Ogunwalea6cc3612016-08-04 07:25:33 -07001337 if (mToken.waitingToShow && mService.mAppTransition.isTransitionSet()) {
Dianne Hackborn6e2281d2012-06-19 17:48:32 -07001338 return false;
1339 }
1340 final AppWindowToken atoken = mAppToken;
1341 if (atoken == null && !mPolicyVisibility) {
1342 // If this is not an app window, and the policy has asked to force
1343 // hide, then we really do want to hide.
1344 return false;
1345 }
1346 return mHasSurface && !mDestroying
Wale Ogunwalea6cc3612016-08-04 07:25:33 -07001347 && ((!isParentWindowHidden() && mViewVisibility == View.VISIBLE && !mToken.hidden)
Dianne Hackborn6e2281d2012-06-19 17:48:32 -07001348 || mWinAnimator.mAnimation != null
Craig Mautner9c5bf3b2012-06-22 15:19:13 -07001349 || ((atoken != null) && (atoken.mAppAnimator.animation != null)
Chong Zhang83caa362016-08-14 18:47:54 -07001350 && !mWinAnimator.isDummyAnimation())
1351 || isAnimatingWithSavedSurface());
Dianne Hackborn6e2281d2012-06-19 17:48:32 -07001352 }
1353
1354 /**
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001355 * Like isOnScreen, but returns false if the surface hasn't yet
1356 * been drawn.
1357 */
Craig Mautnere6f7d5052012-10-08 10:34:17 -07001358 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001359 public boolean isDisplayedLw() {
1360 final AppWindowToken atoken = mAppToken;
Craig Mautnerbf90eaa2012-03-15 11:28:53 -07001361 return isDrawnLw() && mPolicyVisibility
Wale Ogunwale9d147902016-07-16 11:58:55 -07001362 && ((!isParentWindowHidden() &&
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001363 (atoken == null || !atoken.hiddenRequested))
Craig Mautnere6f7d5052012-10-08 10:34:17 -07001364 || mWinAnimator.mAnimating
1365 || (atoken != null && atoken.mAppAnimator.animation != null));
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001366 }
1367
Dianne Hackborn5c58de32012-04-28 19:52:37 -07001368 /**
Craig Mautnerae446592012-12-06 19:05:05 -08001369 * Return true if this window or its app token is currently animating.
Dianne Hackborn5c58de32012-04-28 19:52:37 -07001370 */
Craig Mautnere6f7d5052012-10-08 10:34:17 -07001371 @Override
Dianne Hackborn5c58de32012-04-28 19:52:37 -07001372 public boolean isAnimatingLw() {
Craig Mautnerae446592012-12-06 19:05:05 -08001373 return mWinAnimator.mAnimation != null
1374 || (mAppToken != null && mAppToken.mAppAnimator.animation != null);
Dianne Hackborn5c58de32012-04-28 19:52:37 -07001375 }
1376
Craig Mautner812d2ca2012-09-27 15:35:34 -07001377 @Override
Dianne Hackborncfbf7de2012-01-12 14:05:03 -08001378 public boolean isGoneForLayoutLw() {
1379 final AppWindowToken atoken = mAppToken;
1380 return mViewVisibility == View.GONE
1381 || !mRelayoutCalled
Wale Ogunwalea6cc3612016-08-04 07:25:33 -07001382 || (atoken == null && mToken.hidden)
Jorim Jaggi8fa45222016-02-19 19:54:39 -08001383 || (atoken != null && atoken.hiddenRequested)
Wale Ogunwale9d147902016-07-16 11:58:55 -07001384 || isParentWindowHidden()
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001385 || (mAnimatingExit && !isAnimatingLw())
Craig Mautner0e415c62013-04-29 16:10:58 -07001386 || mDestroying;
Dianne Hackborncfbf7de2012-01-12 14:05:03 -08001387 }
1388
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001389 /**
1390 * Returns true if the window has a surface that it has drawn a
1391 * complete UI in to.
1392 */
Craig Mautnerccc9e9b2012-12-11 09:40:34 -08001393 public boolean isDrawFinishedLw() {
1394 return mHasSurface && !mDestroying &&
Wale Ogunwale9d147902016-07-16 11:58:55 -07001395 (mWinAnimator.mDrawState == COMMIT_DRAW_PENDING
1396 || mWinAnimator.mDrawState == READY_TO_SHOW
1397 || mWinAnimator.mDrawState == HAS_DRAWN);
Craig Mautnerccc9e9b2012-12-11 09:40:34 -08001398 }
1399
1400 /**
1401 * Returns true if the window has a surface that it has drawn a
1402 * complete UI in to.
1403 */
Adrian Roos76d2fe42015-07-09 14:54:08 -07001404 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001405 public boolean isDrawnLw() {
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07001406 return mHasSurface && !mDestroying &&
Wale Ogunwale9d147902016-07-16 11:58:55 -07001407 (mWinAnimator.mDrawState == READY_TO_SHOW
1408 || mWinAnimator.mDrawState == HAS_DRAWN);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001409 }
1410
1411 /**
1412 * Return true if the window is opaque and fully drawn. This indicates
1413 * it may obscure windows behind it.
1414 */
1415 boolean isOpaqueDrawn() {
Chong Zhang66bf071d2016-02-05 14:42:36 -08001416 // When there is keyguard, wallpaper could be placed over the secure app
1417 // window but invisible. We need to check wallpaper visibility explicitly
1418 // to determine if it's occluding apps.
1419 return ((!mIsWallpaper && mAttrs.format == PixelFormat.OPAQUE)
1420 || (mIsWallpaper && mWallpaperVisible))
Craig Mautnera2c77052012-03-26 12:14:43 -07001421 && isDrawnLw() && mWinAnimator.mAnimation == null
Craig Mautner59431632012-04-04 11:56:44 -07001422 && (mAppToken == null || mAppToken.mAppAnimator.animation == null);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001423 }
1424
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001425 @Override
1426 void onMovedByResize() {
1427 if (DEBUG_RESIZE) Slog.d(TAG, "onMovedByResize: Moving " + this);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001428 mMovedByResize = true;
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001429 super.onMovedByResize();
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001430 }
1431
1432 boolean onAppVisibilityChanged(boolean visible, boolean runningAppAnimation) {
1433 boolean changed = false;
1434
1435 for (int i = mChildren.size() - 1; i >= 0; --i) {
1436 final WindowState c = (WindowState) mChildren.get(i);
1437 changed |= c.onAppVisibilityChanged(visible, runningAppAnimation);
1438 }
1439
1440 if (mAttrs.type == TYPE_APPLICATION_STARTING) {
1441 // Starting window that's exiting will be removed when the animation finishes.
1442 // Mark all relevant flags for that onExitAnimationDone will proceed all the way
1443 // to actually remove it.
1444 if (!visible && isVisibleNow() && mAppToken.mAppAnimator.isAnimating()) {
1445 mAnimatingExit = true;
1446 mRemoveOnExit = true;
1447 mWindowRemovalAllowed = true;
1448 }
1449 return changed;
1450 }
1451
1452 if (visible != isVisibleNow()) {
1453 if (!runningAppAnimation) {
1454 final AccessibilityController accessibilityController =
1455 mService.mAccessibilityController;
1456 final int winTransit = visible ? TRANSIT_ENTER : TRANSIT_EXIT;
1457 mWinAnimator.applyAnimationLocked(winTransit, visible);
1458 //TODO (multidisplay): Magnification is supported only for the default
1459 if (accessibilityController != null && getDisplayId() == DEFAULT_DISPLAY) {
1460 accessibilityController.onWindowTransitionLocked(this, winTransit);
1461 }
1462 }
1463 changed = true;
1464 setDisplayLayoutNeeded();
1465 }
1466
1467 return changed;
1468 }
1469
1470 boolean onSetAppExiting() {
1471 final DisplayContent displayContent = getDisplayContent();
1472 boolean changed = false;
1473
1474 if (isVisibleNow()) {
1475 mWinAnimator.applyAnimationLocked(TRANSIT_EXIT, false);
1476 //TODO (multidisplay): Magnification is supported only for the default
1477 if (mService.mAccessibilityController != null && isDefaultDisplay()) {
1478 mService.mAccessibilityController.onWindowTransitionLocked(this, TRANSIT_EXIT);
1479 }
1480 changed = true;
1481 if (displayContent != null) {
1482 displayContent.layoutNeeded = true;
1483 }
1484 }
1485
1486 for (int i = mChildren.size() - 1; i >= 0; --i) {
1487 final WindowState c = (WindowState) mChildren.get(i);
1488 changed |= c.onSetAppExiting();
1489 }
1490
1491 return changed;
1492 }
1493
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001494 @Override
1495 void onResize() {
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001496 // Some windows won't go through the resizing process, if they don't have a surface, so
1497 // destroy all saved surfaces here.
1498 destroySavedSurface();
1499
1500 final ArrayList<WindowState> resizingWindows = mService.mResizingWindows;
1501 if (mHasSurface && !resizingWindows.contains(this)) {
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001502 if (DEBUG_RESIZE) Slog.d(TAG, "onResize: Resizing " + this);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001503 resizingWindows.add(this);
1504
1505 // If we are not drag resizing, force recreating of a new surface so updating
1506 // the content and positioning that surface will be in sync.
1507 //
1508 // As we use this flag as a hint to freeze surface boundary updates, we'd like to only
1509 // apply this to TYPE_BASE_APPLICATION, windows of TYPE_APPLICATION like dialogs, could
1510 // appear to not be drag resizing while they resize, but we'd still like to manipulate
1511 // their frame to update crop, etc...
1512 //
1513 // Anyway we don't need to synchronize position and content updates for these
1514 // windows since they aren't at the base layer and could be moved around anyway.
1515 if (!computeDragResizing() && mAttrs.type == TYPE_BASE_APPLICATION &&
1516 !getTask().mStack.getBoundsAnimating() && !isGoneForLayoutLw() &&
1517 !getTask().inPinnedWorkspace()) {
1518 setResizedWhileNotDragResizing(true);
1519 }
1520 }
1521 if (isGoneForLayoutLw()) {
1522 mResizedWhileGone = true;
1523 }
1524
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001525 super.onResize();
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001526 }
1527
1528 void onUnfreezeBounds() {
1529 for (int i = mChildren.size() - 1; i >= 0; --i) {
1530 final WindowState c = (WindowState) mChildren.get(i);
1531 c.onUnfreezeBounds();
1532 }
1533
1534 if (!mHasSurface) {
1535 return;
1536 }
1537
1538 mLayoutNeeded = true;
1539 setDisplayLayoutNeeded();
1540 if (!mService.mResizingWindows.contains(this)) {
1541 mService.mResizingWindows.add(this);
1542 }
1543 }
1544
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001545 /**
Craig Mautner4557c082015-04-27 13:07:40 -07001546 * Return whether this window has moved. (Only makes
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001547 * sense to call from performLayoutAndPlaceSurfacesLockedInner().)
1548 */
Craig Mautner4557c082015-04-27 13:07:40 -07001549 boolean hasMoved() {
Chong Zhangbd0d9372015-12-28 15:18:29 -08001550 return mHasSurface && (mContentChanged || mMovedByResize)
Jorim Jaggi192086e2016-03-11 17:17:03 +01001551 && !mAnimatingExit && mService.okToDisplay()
Chong Zhangbd0d9372015-12-28 15:18:29 -08001552 && (mFrame.top != mLastFrame.top || mFrame.left != mLastFrame.left)
Wale Ogunwalee4343ef2016-07-19 08:00:46 -07001553 && (!mIsChildWindow || !getParentWindow().hasMoved());
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001554 }
1555
Chong Zhang0abb20f2015-11-19 14:17:31 -08001556 boolean isObscuringFullscreen(final DisplayInfo displayInfo) {
1557 Task task = getTask();
1558 if (task != null && task.mStack != null && !task.mStack.isFullscreen()) {
1559 return false;
1560 }
1561 if (!isOpaqueDrawn() || !isFrameFullscreen(displayInfo)) {
1562 return false;
1563 }
1564 return true;
1565 }
1566
1567 boolean isFrameFullscreen(final DisplayInfo displayInfo) {
1568 return mFrame.left <= 0 && mFrame.top <= 0
1569 && mFrame.right >= displayInfo.appWidth && mFrame.bottom >= displayInfo.appHeight;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001570 }
1571
Craig Mautner812d2ca2012-09-27 15:35:34 -07001572 boolean isConfigChanged() {
Jorim Jaggi26c8c422016-05-09 19:57:25 -07001573 getMergedConfig(mTmpConfig);
1574
1575 // If the merged configuration is still empty, it means that we haven't issues the
1576 // configuration to the client yet and we need to return true so the configuration updates.
1577 boolean configChanged = mMergedConfiguration.equals(Configuration.EMPTY)
1578 || mTmpConfig.diff(mMergedConfiguration) != 0;
Craig Mautnere8552142012-11-07 13:55:47 -08001579
Jorim Jaggi380ecb82014-03-14 17:25:20 +01001580 if ((mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
Craig Mautnere8552142012-11-07 13:55:47 -08001581 // Retain configuration changed status until resetConfiguration called.
1582 mConfigHasChanged |= configChanged;
1583 configChanged = mConfigHasChanged;
1584 }
1585
1586 return configChanged;
Craig Mautner812d2ca2012-09-27 15:35:34 -07001587 }
1588
Jorim Jaggib72c9ad2016-04-11 18:27:58 -07001589 boolean isAdjustedForMinimizedDock() {
1590 return mAppToken != null && mAppToken.mTask != null
1591 && mAppToken.mTask.mStack.isAdjustedForMinimizedDock();
1592 }
1593
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001594 void onWindowReplacementTimeout() {
1595 if (mWillReplaceWindow) {
1596 // Since the window already timed out, remove it immediately now.
1597 // Use WindowState#remove() instead of WindowState#removeIfPossible(), as the latter
1598 // delays removal on certain conditions, which will leave the stale window in the
1599 // stack and marked mWillReplaceWindow=false, so the window will never be removed.
1600 //
1601 // Also removes child windows.
1602 remove();
1603 } else {
1604 for (int i = mChildren.size() - 1; i >= 0; --i) {
1605 final WindowState c = (WindowState) mChildren.get(i);
1606 c.onWindowReplacementTimeout();
1607 }
1608 }
1609 }
1610
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001611 @Override
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001612 void forceWindowsScaleableInTransaction(boolean force) {
1613 if (mWinAnimator != null && mWinAnimator.hasSurface()) {
1614 mWinAnimator.mSurfaceController.forceScaleableInTransaction(force);
1615 }
1616
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001617 super.forceWindowsScaleableInTransaction(force);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001618 }
1619
Wale Ogunwalee4343ef2016-07-19 08:00:46 -07001620 @Override
1621 void remove() {
1622 super.remove();
1623
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07001624 if (mRemoved) {
1625 // Nothing to do.
Wale Ogunwalee4343ef2016-07-19 08:00:46 -07001626 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "WS.remove: " + this + " Already removed...");
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07001627 return;
1628 }
1629
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07001630 mRemoved = true;
1631
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001632 mWillReplaceWindow = false;
1633 if (mReplacementWindow != null) {
1634 mReplacementWindow.mSkipEnterAnimationForSeamlessReplacement = false;
1635 }
1636
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07001637 if (mService.mInputMethodTarget == this) {
1638 mService.moveInputMethodWindowsIfNeededLocked(false);
1639 }
1640
1641 final int type = mAttrs.type;
1642 if (WindowManagerService.excludeWindowTypeFromTapOutTask(type)) {
1643 final DisplayContent displaycontent = getDisplayContent();
1644 displaycontent.mTapExcludedWindows.remove(this);
1645 }
1646 mPolicy.removeWindowLw(this);
1647
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001648 disposeInputChannel();
Craig Mautner164d4bb2012-11-26 13:51:23 -08001649
Craig Mautner96868332012-12-04 14:29:11 -08001650 mWinAnimator.destroyDeferredSurfaceLocked();
1651 mWinAnimator.destroySurfaceLocked();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001652 mSession.windowRemovedLocked();
1653 try {
1654 mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
1655 } catch (RuntimeException e) {
1656 // Ignore if it has already been removed (usually because
1657 // we are doing this as part of processing a death note.)
1658 }
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07001659
1660 mService.postWindowRemoveCleanupLocked(this);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001661 }
Jeff Browncc4f7db2011-08-30 20:34:48 -07001662
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001663 void removeIfPossible() {
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001664 for (int i = mChildren.size() - 1; i >= 0; --i) {
1665 final WindowState c = (WindowState) mChildren.get(i);
1666 c.removeIfPossible(false /*keepVisibleDeadWindow*/);
1667 }
Wale Ogunwale92fc3722016-08-05 12:19:08 -07001668 removeIfPossible(false /*keepVisibleDeadWindow*/);
1669 }
1670
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001671 void removeIfPossible(boolean keepVisibleDeadWindow) {
1672 mWindowRemovalAllowed = true;
1673 if (DEBUG_ADD_REMOVE) Slog.v(TAG,
1674 "removeIfPossible: " + this + " callers=" + Debug.getCallers(5));
1675
1676 final boolean startingWindow = mAttrs.type == TYPE_APPLICATION_STARTING;
1677 if (startingWindow && DEBUG_STARTING_WINDOW) Slog.d(TAG_WM,
1678 "Starting window removed " + this);
1679
1680 if (localLOGV || DEBUG_FOCUS || DEBUG_FOCUS_LIGHT && this == mService.mCurrentFocus)
1681 Slog.v(TAG_WM, "Remove " + this + " client="
1682 + Integer.toHexString(System.identityHashCode(mClient.asBinder()))
1683 + ", surfaceController=" + mWinAnimator.mSurfaceController + " Callers="
1684 + Debug.getCallers(5));
1685
1686 final long origId = Binder.clearCallingIdentity();
1687
1688 disposeInputChannel();
1689
1690 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Remove " + this
1691 + ": mSurfaceController=" + mWinAnimator.mSurfaceController
1692 + " mAnimatingExit=" + mAnimatingExit
1693 + " mRemoveOnExit=" + mRemoveOnExit
1694 + " mHasSurface=" + mHasSurface
1695 + " surfaceShowing=" + mWinAnimator.getShown()
1696 + " isAnimationSet=" + mWinAnimator.isAnimationSet()
1697 + " app-animation="
1698 + (mAppToken != null ? mAppToken.mAppAnimator.animation : null)
1699 + " mWillReplaceWindow=" + mWillReplaceWindow
1700 + " inPendingTransaction="
1701 + (mAppToken != null ? mAppToken.inPendingTransaction : false)
1702 + " mDisplayFrozen=" + mService.mDisplayFrozen
1703 + " callers=" + Debug.getCallers(6));
1704
1705 // Visibility of the removed window. Will be used later to update orientation later on.
1706 boolean wasVisible = false;
1707
1708 // First, see if we need to run an animation. If we do, we have to hold off on removing the
1709 // window until the animation is done. If the display is frozen, just remove immediately,
1710 // since the animation wouldn't be seen.
1711 if (mHasSurface && mService.okToDisplay()) {
1712 if (mWillReplaceWindow) {
1713 // This window is going to be replaced. We need to keep it around until the new one
1714 // gets added, then we will get rid of this one.
1715 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1716 "Preserving " + this + " until the new one is " + "added");
1717 // TODO: We are overloading mAnimatingExit flag to prevent the window state from
1718 // been removed. We probably need another flag to indicate that window removal
1719 // should be deffered vs. overloading the flag that says we are playing an exit
1720 // animation.
1721 mAnimatingExit = true;
1722 mReplacingRemoveRequested = true;
1723 Binder.restoreCallingIdentity(origId);
1724 return;
1725 }
1726
1727 if (isAnimatingWithSavedSurface() && !mAppToken.allDrawnExcludingSaved) {
1728 // We started enter animation early with a saved surface, now the app asks to remove
1729 // this window. If we remove it now and the app is not yet drawn, we'll show a
1730 // flicker. Delay the removal now until it's really drawn.
1731 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
1732 "removeWindowLocked: delay removal of " + this + " due to early animation");
1733 // Do not set mAnimatingExit to true here, it will cause the surface to be hidden
1734 // immediately after the enter animation is done. If the app is not yet drawn then
1735 // it will show up as a flicker.
1736 setupWindowForRemoveOnExit();
1737 Binder.restoreCallingIdentity(origId);
1738 return;
1739 }
1740 // If we are not currently running the exit animation, we need to see about starting one
1741 wasVisible = isWinVisibleLw();
1742
1743 if (keepVisibleDeadWindow) {
1744 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1745 "Not removing " + this + " because app died while it's visible");
1746
1747 mAppDied = true;
1748 setDisplayLayoutNeeded();
1749 mService.mWindowPlacerLocked.performSurfacePlacement();
1750
1751 // Set up a replacement input channel since the app is now dead.
1752 // We need to catch tapping on the dead window to restart the app.
1753 openInputChannel(null);
1754 mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
1755
1756 Binder.restoreCallingIdentity(origId);
1757 return;
1758 }
1759
1760 if (wasVisible) {
1761 final int transit = (!startingWindow) ? TRANSIT_EXIT : TRANSIT_PREVIEW_DONE;
1762
1763 // Try starting an animation.
1764 if (mWinAnimator.applyAnimationLocked(transit, false)) {
1765 mAnimatingExit = true;
1766 }
1767 //TODO (multidisplay): Magnification is supported only for the default display.
1768 if (mService.mAccessibilityController != null
1769 && getDisplayId() == Display.DEFAULT_DISPLAY) {
1770 mService.mAccessibilityController.onWindowTransitionLocked(this, transit);
1771 }
1772 }
1773 final boolean isAnimating =
1774 mWinAnimator.isAnimationSet() && !mWinAnimator.isDummyAnimation();
1775 final boolean lastWindowIsStartingWindow = startingWindow && mAppToken != null
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001776 && mAppToken.isLastWindow(this);
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001777 // We delay the removal of a window if it has a showing surface that can be used to run
1778 // exit animation and it is marked as exiting.
1779 // Also, If isn't the an animating starting window that is the last window in the app.
1780 // We allow the removal of the non-animating starting window now as there is no
1781 // additional window or animation that will trigger its removal.
1782 if (mWinAnimator.getShown() && mAnimatingExit
1783 && (!lastWindowIsStartingWindow || isAnimating)) {
1784 // The exit animation is running or should run... wait for it!
1785 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1786 "Not removing " + this + " due to exit animation ");
1787 setupWindowForRemoveOnExit();
1788 if (mAppToken != null) {
1789 mAppToken.updateReportedVisibilityLocked();
1790 }
1791 Binder.restoreCallingIdentity(origId);
1792 return;
1793 }
1794 }
1795
1796 remove();
1797 // Removing a visible window will effect the computed orientation
1798 // So just update orientation if needed.
1799 if (wasVisible && mService.updateOrientationFromAppTokensLocked(false)) {
1800 mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
1801 }
1802 mService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
1803 Binder.restoreCallingIdentity(origId);
1804 }
1805
Wale Ogunwaled1c37912016-08-16 03:19:39 -07001806 @Override
1807 boolean detachFromDisplay() {
1808 // We are in the middle of changing the state of displays/stacks/tasks. We need
1809 // to finish that, before we let layout interfere with it.
1810 // Also removes child windows.
1811 removeIfPossible();
1812 return true;
1813 }
1814
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07001815 private void setupWindowForRemoveOnExit() {
1816 mRemoveOnExit = true;
1817 setDisplayLayoutNeeded();
1818 // Request a focus update as this window's input channel is already gone. Otherwise
1819 // we could have no focused window in input manager.
1820 final boolean focusChanged = mService.updateFocusedWindowLocked(
1821 UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
1822 mService.mWindowPlacerLocked.performSurfacePlacement();
1823 if (focusChanged) {
1824 mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
1825 }
1826 }
1827
Filip Gruszczynski10a80e02015-11-06 09:21:17 -08001828 void setHasSurface(boolean hasSurface) {
1829 mHasSurface = hasSurface;
1830 }
1831
Filip Gruszczynski92e432c2015-12-15 19:17:09 -08001832 int getAnimLayerAdjustment() {
Wale Ogunwale455fac52016-07-21 07:24:49 -07001833 final boolean isImeType =
1834 mAttrs.type == TYPE_INPUT_METHOD || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
1835 if (isImeType && mService.mInputMethodTarget != null) {
1836 final AppWindowToken appToken = mService.mInputMethodTarget.mAppToken;
1837 if (appToken != null) {
1838 return appToken.mAppAnimator.animLayerAdjustment;
1839 }
Filip Gruszczynski92e432c2015-12-15 19:17:09 -08001840 }
Wale Ogunwale455fac52016-07-21 07:24:49 -07001841
1842 if (mAppToken != null) {
1843 return mAppToken.mAppAnimator.animLayerAdjustment;
1844 }
1845
1846 // Nothing is animating, so there is no animation adjustment.
1847 return 0;
Filip Gruszczynski92e432c2015-12-15 19:17:09 -08001848 }
1849
1850 void scheduleAnimationIfDimming() {
1851 if (mDisplayContent == null) {
1852 return;
1853 }
1854 final DimLayer.DimLayerUser dimLayerUser = getDimLayerUser();
1855 if (dimLayerUser != null && mDisplayContent.mDimLayerController.isDimming(
1856 dimLayerUser, mWinAnimator)) {
1857 // Force an animation pass just to update the mDimLayer layer.
1858 mService.scheduleAnimationLocked();
1859 }
1860 }
1861
Jorim Jaggi5e6968d2016-02-19 18:02:13 -08001862 /**
1863 * Notifies this window that the corresponding task has just moved in the stack.
1864 * <p>
1865 * This is used to fix the following: If we moved in the stack, and if the last clip rect was
1866 * empty, meaning that our task was completely offscreen, we need to keep it invisible because
1867 * the actual app transition that updates the visibility is delayed by a few transactions.
1868 * Instead of messing around with the ordering and timing how transitions and transactions are
1869 * executed, we introduce this little hack which prevents this window of getting visible again
1870 * with the wrong bounds until the app transitions has started.
1871 * <p>
1872 * This method notifies the window about that we just moved in the stack so we can apply this
1873 * logic in {@link WindowStateAnimator#updateSurfaceWindowCrop}
1874 */
1875 void notifyMovedInStack() {
1876 mJustMovedInStack = true;
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001877
1878 for (int i = mChildren.size() - 1; i >= 0; --i) {
1879 final WindowState c = (WindowState) mChildren.get(i);
1880 c.notifyMovedInStack();
1881 }
Jorim Jaggi5e6968d2016-02-19 18:02:13 -08001882 }
1883
1884 /**
1885 * See {@link #notifyMovedInStack}.
1886 *
1887 * @return Whether we just got moved in the corresponding stack.
1888 */
1889 boolean hasJustMovedInStack() {
1890 return mJustMovedInStack;
1891 }
1892
1893 /**
1894 * Resets that we just moved in the corresponding stack. See {@link #notifyMovedInStack}.
1895 */
1896 void resetJustMovedInStack() {
1897 mJustMovedInStack = false;
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001898
1899 for (int i = mChildren.size() - 1; i >= 0; i--) {
1900 final WindowState c = (WindowState) mChildren.get(i);
1901 c.resetJustMovedInStack();
1902 }
Jorim Jaggi5e6968d2016-02-19 18:02:13 -08001903 }
1904
Chong Zhangacf11402015-11-04 16:23:10 -08001905 private final class DeadWindowEventReceiver extends InputEventReceiver {
1906 DeadWindowEventReceiver(InputChannel inputChannel) {
1907 super(inputChannel, mService.mH.getLooper());
1908 }
1909 @Override
1910 public void onInputEvent(InputEvent event) {
1911 finishInputEvent(event, true);
1912 }
1913 }
1914 /**
1915 * Dummy event receiver for windows that died visible.
1916 */
1917 private DeadWindowEventReceiver mDeadWindowEventReceiver;
1918
Chong Zhang112eb8c2015-11-02 11:17:00 -08001919 void openInputChannel(InputChannel outInputChannel) {
Jeff Browncc4f7db2011-08-30 20:34:48 -07001920 if (mInputChannel != null) {
1921 throw new IllegalStateException("Window already has an input channel.");
1922 }
Chong Zhang112eb8c2015-11-02 11:17:00 -08001923 String name = makeInputChannelName();
1924 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
1925 mInputChannel = inputChannels[0];
1926 mClientChannel = inputChannels[1];
1927 mInputWindowHandle.inputChannel = inputChannels[0];
1928 if (outInputChannel != null) {
1929 mClientChannel.transferTo(outInputChannel);
1930 mClientChannel.dispose();
1931 mClientChannel = null;
Chong Zhangacf11402015-11-04 16:23:10 -08001932 } else {
1933 // If the window died visible, we setup a dummy input channel, so that taps
1934 // can still detected by input monitor channel, and we can relaunch the app.
1935 // Create dummy event receiver that simply reports all events as handled.
1936 mDeadWindowEventReceiver = new DeadWindowEventReceiver(mClientChannel);
Chong Zhang112eb8c2015-11-02 11:17:00 -08001937 }
1938 mService.mInputManager.registerInputChannel(mInputChannel, mInputWindowHandle);
Jeff Browncc4f7db2011-08-30 20:34:48 -07001939 }
1940
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001941 void disposeInputChannel() {
Chong Zhangacf11402015-11-04 16:23:10 -08001942 if (mDeadWindowEventReceiver != null) {
1943 mDeadWindowEventReceiver.dispose();
1944 mDeadWindowEventReceiver = null;
1945 }
1946
1947 // unregister server channel first otherwise it complains about broken channel
1948 if (mInputChannel != null) {
1949 mService.mInputManager.unregisterInputChannel(mInputChannel);
1950 mInputChannel.dispose();
1951 mInputChannel = null;
1952 }
Chong Zhang112eb8c2015-11-02 11:17:00 -08001953 if (mClientChannel != null) {
1954 mClientChannel.dispose();
1955 mClientChannel = null;
1956 }
Jeff Browncc4f7db2011-08-30 20:34:48 -07001957 mInputWindowHandle.inputChannel = null;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001958 }
1959
Chong Zhang112eb8c2015-11-02 11:17:00 -08001960 void applyDimLayerIfNeeded() {
Chong Zhangeb917322015-11-10 14:05:40 -08001961 // When the app is terminated (eg. from Recents), the task might have already been
1962 // removed with the window pending removal. Don't apply dim in such cases, as there
1963 // will be no more updateDimLayer() calls, which leaves the dimlayer invalid.
1964 final AppWindowToken token = mAppToken;
1965 if (token != null && token.removed) {
1966 return;
1967 }
1968
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001969 if (!mAnimatingExit && mAppDied) {
Chong Zhang112eb8c2015-11-02 11:17:00 -08001970 // If app died visible, apply a dim over the window to indicate that it's inactive
1971 mDisplayContent.mDimLayerController.applyDimAbove(getDimLayerUser(), mWinAnimator);
1972 } else if ((mAttrs.flags & FLAG_DIM_BEHIND) != 0
Robert Carr9fe459d2016-04-07 23:32:28 -07001973 && mDisplayContent != null && !mAnimatingExit && isVisibleUnchecked()) {
Chong Zhang112eb8c2015-11-02 11:17:00 -08001974 mDisplayContent.mDimLayerController.applyDimBehind(getDimLayerUser(), mWinAnimator);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001975 }
1976 }
1977
Filip Gruszczynski0689ae92015-10-01 12:30:31 -07001978 DimLayer.DimLayerUser getDimLayerUser() {
1979 Task task = getTask();
1980 if (task != null) {
1981 return task;
1982 }
1983 return getStack();
1984 }
1985
Wale Ogunwale9bc47732016-08-10 14:44:22 -07001986 /** Returns true if the replacement window was removed. */
1987 boolean removeReplacedWindowIfNeeded(WindowState replacement) {
1988 if (mWillReplaceWindow && mReplacementWindow == replacement && replacement.hasDrawnLw()) {
1989 replacement.mSkipEnterAnimationForSeamlessReplacement = false;
1990 removeReplacedWindow();
1991 return true;
1992 }
1993
1994 for (int i = mChildren.size() - 1; i >= 0; --i) {
1995 final WindowState c = (WindowState) mChildren.get(i);
1996 if (c.removeReplacedWindowIfNeeded(replacement)) {
1997 return true;
1998 }
1999 }
2000 return false;
2001 }
2002
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07002003 void removeReplacedWindow() {
2004 if (DEBUG_ADD_REMOVE) Slog.d(TAG, "Removing replaced window: " + this);
2005 if (isDimming()) {
2006 transferDimToReplacement();
Robert Carra1eb4392015-12-10 12:43:51 -08002007 }
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07002008 mWillReplaceWindow = false;
2009 mAnimateReplacingWindow = false;
2010 mReplacingRemoveRequested = false;
Wale Ogunwale9bc47732016-08-10 14:44:22 -07002011 mReplacementWindow = null;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07002012 if (mAnimatingExit || !mAnimateReplacingWindow) {
2013 remove();
Filip Gruszczynski76cc44f2015-09-03 16:03:10 -07002014 }
2015 }
2016
Wale Ogunwale9bc47732016-08-10 14:44:22 -07002017 boolean setReplacementWindowIfNeeded(WindowState replacementCandidate) {
2018 boolean replacementSet = false;
2019
2020 if (mWillReplaceWindow && mReplacementWindow == null
2021 && getWindowTag().toString().equals(replacementCandidate.getWindowTag().toString())) {
2022
2023 mReplacementWindow = replacementCandidate;
2024 replacementCandidate.mSkipEnterAnimationForSeamlessReplacement = !mAnimateReplacingWindow;
2025 replacementSet = true;
2026 }
2027
2028 for (int i = mChildren.size() - 1; i >= 0; --i) {
2029 final WindowState c = (WindowState) mChildren.get(i);
2030 replacementSet |= c.setReplacementWindowIfNeeded(replacementCandidate);
2031 }
2032
2033 return replacementSet;
2034 }
2035
Filip Gruszczynskie92179d2015-09-26 16:12:30 -07002036 void setDisplayLayoutNeeded() {
2037 if (mDisplayContent != null) {
2038 mDisplayContent.layoutNeeded = true;
2039 }
2040 }
2041
Robert Carrfed10072016-05-26 11:48:49 -07002042 // TODO: Strange usage of word workspace here and above.
2043 boolean inPinnedWorkspace() {
2044 final Task task = getTask();
2045 return task != null && task.inPinnedWorkspace();
2046 }
2047
Chong Zhang5117e272016-05-03 12:47:34 -07002048 void applyAdjustForImeIfNeeded() {
2049 final Task task = getTask();
2050 if (task != null && task.mStack != null && task.mStack.isAdjustedForIme()) {
2051 task.mStack.applyAdjustForImeIfNeeded(task);
2052 }
2053 }
2054
Wale Ogunwale053c8e42015-11-16 14:27:21 -08002055 int getTouchableRegion(Region region, int flags) {
2056 final boolean modal = (flags & (FLAG_NOT_TOUCH_MODAL | FLAG_NOT_FOCUSABLE)) == 0;
Filip Gruszczynski9cac3b42015-10-30 14:20:37 -07002057 if (modal && mAppToken != null) {
2058 // Limit the outer touch to the activity stack region.
Wale Ogunwale053c8e42015-11-16 14:27:21 -08002059 flags |= FLAG_NOT_TOUCH_MODAL;
Chong Zhang4c9ba52a2015-11-10 18:36:33 -08002060 // If this is a modal window we need to dismiss it if it's not full screen and the
2061 // touch happens outside of the frame that displays the content. This means we
2062 // need to intercept touches outside of that window. The dim layer user
2063 // associated with the window (task or stack) will give us the good bounds, as
2064 // they would be used to display the dim layer.
2065 final DimLayer.DimLayerUser dimLayerUser = getDimLayerUser();
2066 if (dimLayerUser != null) {
2067 dimLayerUser.getDimBounds(mTmpRect);
Filip Gruszczynski9cac3b42015-10-30 14:20:37 -07002068 } else {
Chong Zhang4c9ba52a2015-11-10 18:36:33 -08002069 getVisibleBounds(mTmpRect);
2070 }
2071 if (inFreeformWorkspace()) {
Filip Gruszczynski9cac3b42015-10-30 14:20:37 -07002072 // For freeform windows we the touch region to include the whole surface for the
2073 // shadows.
Chong Zhang4c9ba52a2015-11-10 18:36:33 -08002074 final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics();
2075 final int delta = WindowManagerService.dipToPixel(
2076 RESIZE_HANDLE_WIDTH_IN_DP, displayMetrics);
2077 mTmpRect.inset(-delta, -delta);
Filip Gruszczynski9cac3b42015-10-30 14:20:37 -07002078 }
2079 region.set(mTmpRect);
Wale Ogunwale053c8e42015-11-16 14:27:21 -08002080 cropRegionToStackBoundsIfNeeded(region);
Filip Gruszczynski9cac3b42015-10-30 14:20:37 -07002081 } else {
2082 // Not modal or full screen modal
2083 getTouchableRegion(region);
2084 }
2085 return flags;
2086 }
2087
Filip Gruszczynski14b4e572015-11-03 15:53:55 -08002088 void checkPolicyVisibilityChange() {
2089 if (mPolicyVisibility != mPolicyVisibilityAfterAnim) {
2090 if (DEBUG_VISIBILITY) {
2091 Slog.v(TAG, "Policy visibility changing after anim in " +
2092 mWinAnimator + ": " + mPolicyVisibilityAfterAnim);
2093 }
2094 mPolicyVisibility = mPolicyVisibilityAfterAnim;
Filip Gruszczynski63a35e22015-11-05 15:38:59 -08002095 setDisplayLayoutNeeded();
Filip Gruszczynski14b4e572015-11-03 15:53:55 -08002096 if (!mPolicyVisibility) {
2097 if (mService.mCurrentFocus == this) {
2098 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG,
2099 "setAnimationLocked: setting mFocusMayChange true");
2100 mService.mFocusMayChange = true;
2101 }
2102 // Window is no longer visible -- make sure if we were waiting
2103 // for it to be displayed before enabling the display, that
2104 // we allow the display to be enabled now.
2105 mService.enableScreenIfNeededLocked();
2106 }
2107 }
2108 }
2109
2110 void setRequestedSize(int requestedWidth, int requestedHeight) {
2111 if ((mRequestedWidth != requestedWidth || mRequestedHeight != requestedHeight)) {
2112 mLayoutNeeded = true;
2113 mRequestedWidth = requestedWidth;
2114 mRequestedHeight = requestedHeight;
2115 }
2116 }
2117
Filip Gruszczynski84cc5e32015-11-03 18:05:47 -08002118 void prepareWindowToDisplayDuringRelayout(Configuration outConfig) {
2119 if ((mAttrs.softInputMode & SOFT_INPUT_MASK_ADJUST)
2120 == SOFT_INPUT_ADJUST_RESIZE) {
2121 mLayoutNeeded = true;
2122 }
2123 if (isDrawnLw() && mService.okToDisplay()) {
2124 mWinAnimator.applyEnterAnimationLocked();
2125 }
2126 if ((mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0) {
2127 if (DEBUG_VISIBILITY) Slog.v(TAG, "Relayout window turning screen on: " + this);
2128 mTurnOnScreen = true;
2129 }
2130 if (isConfigChanged()) {
Robert Carrc24d8f92016-02-29 16:24:33 -08002131 final Configuration newConfig = updateConfiguration();
Filip Gruszczynski84cc5e32015-11-03 18:05:47 -08002132 if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + this + " visible with new config: "
Robert Carrc24d8f92016-02-29 16:24:33 -08002133 + newConfig);
2134 outConfig.setTo(newConfig);
Filip Gruszczynski84cc5e32015-11-03 18:05:47 -08002135 }
2136 }
2137
2138 void adjustStartingWindowFlags() {
2139 if (mAttrs.type == TYPE_BASE_APPLICATION && mAppToken != null
2140 && mAppToken.startingWindow != null) {
2141 // Special handling of starting window over the base
2142 // window of the app: propagate lock screen flags to it,
2143 // to provide the correct semantics while starting.
2144 final int mask = FLAG_SHOW_WHEN_LOCKED | FLAG_DISMISS_KEYGUARD
2145 | FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
2146 WindowManager.LayoutParams sa = mAppToken.startingWindow.mAttrs;
2147 sa.flags = (sa.flags & ~mask) | (mAttrs.flags & mask);
2148 }
2149 }
2150
2151 void setWindowScale(int requestedWidth, int requestedHeight) {
2152 final boolean scaledWindow = (mAttrs.flags & FLAG_SCALED) != 0;
2153
2154 if (scaledWindow) {
2155 // requested{Width|Height} Surface's physical size
2156 // attrs.{width|height} Size on screen
2157 // TODO: We don't check if attrs != null here. Is it implicitly checked?
2158 mHScale = (mAttrs.width != requestedWidth) ?
2159 (mAttrs.width / (float)requestedWidth) : 1.0f;
2160 mVScale = (mAttrs.height != requestedHeight) ?
2161 (mAttrs.height / (float)requestedHeight) : 1.0f;
2162 } else {
2163 mHScale = mVScale = 1;
2164 }
2165 }
2166
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002167 private class DeathRecipient implements IBinder.DeathRecipient {
Craig Mautnere8552142012-11-07 13:55:47 -08002168 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002169 public void binderDied() {
2170 try {
2171 synchronized(mService.mWindowMap) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07002172 final WindowState win = mService.windowForClientLocked(mSession, mClient, false);
Craig Mautnerd87946b2012-03-29 18:00:19 -07002173 Slog.i(TAG, "WIN DEATH: " + win);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002174 if (win != null) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07002175 win.removeIfPossible(shouldKeepVisibleDeadAppWindow());
Wale Ogunwalea9f9b372016-02-04 18:04:39 -08002176 if (win.mAttrs.type == TYPE_DOCK_DIVIDER) {
2177 // The owner of the docked divider died :( We reset the docked stack,
Jorim Jaggidcb68142016-02-09 21:51:30 -08002178 // just in case they have the divider at an unstable position. Better
2179 // also reset drag resizing state, because the owner can't do it
2180 // anymore.
Wale Ogunwalea9f9b372016-02-04 18:04:39 -08002181 final TaskStack stack = mService.mStackIdToStack.get(DOCKED_STACK_ID);
2182 if (stack != null) {
2183 stack.resetDockedStackToMiddle();
2184 }
Jorim Jaggidcb68142016-02-09 21:51:30 -08002185 mService.setDockedStackResizing(false);
Wale Ogunwalea9f9b372016-02-04 18:04:39 -08002186 }
Craig Mautnerb3b36ba2013-05-20 13:21:10 -07002187 } else if (mHasSurface) {
Craig Mautnera99764e2013-03-06 10:22:16 -08002188 Slog.e(TAG, "!!! LEAK !!! Window removed but surface still valid.");
Wale Ogunwale92fc3722016-08-05 12:19:08 -07002189 WindowState.this.removeIfPossible();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002190 }
2191 }
2192 } catch (IllegalArgumentException ex) {
Wale Ogunwalee42d0e12016-05-02 16:40:59 -07002193 // This will happen if the window has already been removed.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002194 }
2195 }
2196 }
2197
Wale Ogunwale3fd20fe2016-01-23 17:41:28 -08002198 /**
2199 * Returns true if this window is visible and belongs to a dead app and shouldn't be removed,
2200 * because we want to preserve its location on screen to be re-activated later when the user
2201 * interacts with it.
2202 */
2203 boolean shouldKeepVisibleDeadAppWindow() {
Wale Ogunwalee42d0e12016-05-02 16:40:59 -07002204 if (!isWinVisibleLw() || mAppToken == null || mAppToken.clientHidden) {
Wale Ogunwale3fd20fe2016-01-23 17:41:28 -08002205 // Not a visible app window or the app isn't dead.
2206 return false;
2207 }
2208
Wale Ogunwale51d1d912016-05-04 13:27:18 -07002209 if (mAttrs.token != mClient.asBinder()) {
2210 // The window was add by a client using another client's app token. We don't want to
2211 // keep the dead window around for this case since this is meant for 'real' apps.
2212 return false;
2213 }
2214
Wale Ogunwale3fd20fe2016-01-23 17:41:28 -08002215 if (mAttrs.type == TYPE_APPLICATION_STARTING) {
2216 // We don't keep starting windows since they were added by the window manager before
2217 // the app even launched.
2218 return false;
2219 }
2220
2221 final TaskStack stack = getStack();
2222 return stack != null && StackId.keepVisibleDeadAppWindowOnScreen(stack.mStackId);
2223 }
2224
Wale Ogunwaled045c822015-12-02 09:14:28 -08002225 /** @return true if this window desires key events. */
2226 boolean canReceiveKeys() {
Craig Mautner58106812012-12-28 12:27:40 -08002227 return isVisibleOrAdding()
Chong Zhange292eb32016-05-21 09:23:55 -07002228 && (mViewVisibility == View.VISIBLE) && !mRemoveOnExit
Wale Ogunwaled045c822015-12-02 09:14:28 -08002229 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0)
Jorim Jaggib72c9ad2016-04-11 18:27:58 -07002230 && (mAppToken == null || mAppToken.windowsAreFocusable())
2231 && !isAdjustedForMinimizedDock();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002232 }
2233
Craig Mautner749a7bb2012-04-02 13:49:53 -07002234 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002235 public boolean hasDrawnLw() {
Craig Mautner749a7bb2012-04-02 13:49:53 -07002236 return mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002237 }
2238
Craig Mautner749a7bb2012-04-02 13:49:53 -07002239 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002240 public boolean showLw(boolean doAnimation) {
2241 return showLw(doAnimation, true);
2242 }
2243
2244 boolean showLw(boolean doAnimation, boolean requestAnim) {
Craig Mautner5962b122012-10-05 14:45:52 -07002245 if (isHiddenFromUserLocked()) {
Craig Mautner9dc52bc2012-08-06 14:15:42 -07002246 return false;
2247 }
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -08002248 if (!mAppOpVisibility) {
2249 // Being hidden due to app op request.
2250 return false;
2251 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002252 if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
Craig Mautnere32c3072012-03-12 15:25:35 -07002253 // Already showing.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002254 return false;
2255 }
Craig Mautnerd87946b2012-03-29 18:00:19 -07002256 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002257 if (doAnimation) {
Craig Mautnerd87946b2012-03-29 18:00:19 -07002258 if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
Craig Mautnera2c77052012-03-26 12:14:43 -07002259 + mPolicyVisibility + " mAnimation=" + mWinAnimator.mAnimation);
Craig Mautner2fb98b12012-03-20 17:24:00 -07002260 if (!mService.okToDisplay()) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002261 doAnimation = false;
Craig Mautnera2c77052012-03-26 12:14:43 -07002262 } else if (mPolicyVisibility && mWinAnimator.mAnimation == null) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002263 // Check for the case where we are currently visible and
2264 // not animating; we do not want to do animation at such a
2265 // point to become visible when we already are.
2266 doAnimation = false;
2267 }
2268 }
2269 mPolicyVisibility = true;
2270 mPolicyVisibilityAfterAnim = true;
2271 if (doAnimation) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002272 mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_ENTER, true);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002273 }
2274 if (requestAnim) {
Craig Mautner96868332012-12-04 14:29:11 -08002275 mService.scheduleAnimationLocked();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002276 }
2277 return true;
2278 }
2279
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002280 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002281 public boolean hideLw(boolean doAnimation) {
2282 return hideLw(doAnimation, true);
2283 }
2284
2285 boolean hideLw(boolean doAnimation, boolean requestAnim) {
2286 if (doAnimation) {
Craig Mautner2fb98b12012-03-20 17:24:00 -07002287 if (!mService.okToDisplay()) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002288 doAnimation = false;
2289 }
2290 }
Wale Ogunwale9bc47732016-08-10 14:44:22 -07002291 boolean current = doAnimation ? mPolicyVisibilityAfterAnim : mPolicyVisibility;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002292 if (!current) {
Craig Mautnere32c3072012-03-12 15:25:35 -07002293 // Already hiding.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002294 return false;
2295 }
2296 if (doAnimation) {
Craig Mautnerc2f9be02012-03-27 17:32:29 -07002297 mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT, false);
Craig Mautnera2c77052012-03-26 12:14:43 -07002298 if (mWinAnimator.mAnimation == null) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002299 doAnimation = false;
2300 }
2301 }
Wale Ogunwale9bc47732016-08-10 14:44:22 -07002302 mPolicyVisibilityAfterAnim = false;
2303 if (!doAnimation) {
Craig Mautnerd87946b2012-03-29 18:00:19 -07002304 if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002305 mPolicyVisibility = false;
2306 // Window is no longer visible -- make sure if we were waiting
2307 // for it to be displayed before enabling the display, that
2308 // we allow the display to be enabled now.
2309 mService.enableScreenIfNeededLocked();
2310 if (mService.mCurrentFocus == this) {
Filip Gruszczynski14b4e572015-11-03 15:53:55 -08002311 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG,
Craig Mautner58458122013-09-14 14:59:50 -07002312 "WindowState.hideLw: setting mFocusMayChange true");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002313 mService.mFocusMayChange = true;
2314 }
2315 }
2316 if (requestAnim) {
Craig Mautner96868332012-12-04 14:29:11 -08002317 mService.scheduleAnimationLocked();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002318 }
2319 return true;
2320 }
2321
Craig Mautnerfb32c6e2013-02-12 15:08:44 -08002322 public void setAppOpVisibilityLw(boolean state) {
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -08002323 if (mAppOpVisibility != state) {
2324 mAppOpVisibility = state;
2325 if (state) {
2326 // If the policy visibility had last been to hide, then this
2327 // will incorrectly show at this point since we lost that
2328 // information. Not a big deal -- for the windows that have app
2329 // ops modifies they should only be hidden by policy due to the
2330 // lock screen, and the user won't be changing this if locked.
2331 // Plus it will quickly be fixed the next time we do a layout.
Craig Mautnerfb32c6e2013-02-12 15:08:44 -08002332 showLw(true, true);
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -08002333 } else {
Craig Mautnerfb32c6e2013-02-12 15:08:44 -08002334 hideLw(true, true);
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -08002335 }
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -08002336 }
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -08002337 }
2338
Jeff Brownc2932a12014-11-20 18:04:05 -08002339 public void pokeDrawLockLw(long timeout) {
2340 if (isVisibleOrAdding()) {
2341 if (mDrawLock == null) {
2342 // We want the tag name to be somewhat stable so that it is easier to correlate
2343 // in wake lock statistics. So in particular, we don't want to include the
2344 // window's hash code as in toString().
Wale Ogunwalecad05a02015-09-25 10:41:44 -07002345 final CharSequence tag = getWindowTag();
Jeff Brownc2932a12014-11-20 18:04:05 -08002346 mDrawLock = mService.mPowerManager.newWakeLock(
2347 PowerManager.DRAW_WAKE_LOCK, "Window:" + tag);
2348 mDrawLock.setReferenceCounted(false);
2349 mDrawLock.setWorkSource(new WorkSource(mOwnerUid, mAttrs.packageName));
2350 }
2351 // Each call to acquire resets the timeout.
2352 if (DEBUG_POWER) {
2353 Slog.d(TAG, "pokeDrawLock: poking draw lock on behalf of visible window owned by "
2354 + mAttrs.packageName);
2355 }
2356 mDrawLock.acquire(timeout);
2357 } else if (DEBUG_POWER) {
2358 Slog.d(TAG, "pokeDrawLock: suppressed draw lock request for invisible window "
2359 + "owned by " + mAttrs.packageName);
2360 }
2361 }
2362
Dianne Hackbornf87d1962012-04-04 12:48:24 -07002363 @Override
2364 public boolean isAlive() {
2365 return mClient.asBinder().isBinderAlive();
2366 }
2367
Craig Mautnera987d432012-10-11 14:07:58 -07002368 boolean isClosing() {
Wale Ogunwalec48a3542016-02-19 15:18:45 -08002369 return mAnimatingExit || (mService.mClosingApps.contains(mAppToken));
Craig Mautnera987d432012-10-11 14:07:58 -07002370 }
2371
Chong Zhangbef461f2015-10-27 11:38:24 -07002372 boolean isAnimatingWithSavedSurface() {
Chong Zhang92147042016-05-09 12:47:11 -07002373 return mAnimatingWithSavedSurface;
2374 }
2375
Wale Ogunwaled1c37912016-08-16 03:19:39 -07002376 @Override
Wale Ogunwale9bc47732016-08-10 14:44:22 -07002377 boolean isAnimating() {
2378 if (mWinAnimator.isAnimationSet() || mAnimatingExit) {
2379 return true;
2380 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -07002381 return super.isAnimating();
Wale Ogunwale9bc47732016-08-10 14:44:22 -07002382 }
2383
Chong Zhang8e4bda92016-05-04 15:08:18 -07002384 boolean isAnimatingInvisibleWithSavedSurface() {
Wale Ogunwale9bc47732016-08-10 14:44:22 -07002385 if (mAnimatingWithSavedSurface
2386 && (mViewVisibility != View.VISIBLE || mWindowRemovalAllowed)) {
2387 return true;
2388 }
2389 for (int i = mChildren.size() - 1; i >= 0; --i) {
2390 final WindowState c = (WindowState) mChildren.get(i);
2391 if (c.isAnimatingInvisibleWithSavedSurface()) {
2392 return true;
2393 }
2394 }
2395 return false;
2396 }
2397
2398 void stopUsingSavedSurface() {
2399 for (int i = mChildren.size() - 1; i >= 0; --i) {
2400 final WindowState c = (WindowState) mChildren.get(i);
2401 c.stopUsingSavedSurface();
2402 }
2403
2404 if (!isAnimatingInvisibleWithSavedSurface()) {
2405 return;
2406 }
2407
2408 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.d(TAG, "stopUsingSavedSurface: " + this);
2409 clearAnimatingWithSavedSurface();
2410 mDestroying = true;
2411 mWinAnimator.hide("stopUsingSavedSurface");
2412 mService.mWallpaperControllerLocked.hideWallpapers(this);
2413 }
2414
2415 void markSavedSurfaceExiting() {
2416 if (isAnimatingInvisibleWithSavedSurface()) {
2417 mAnimatingExit = true;
2418 mWinAnimator.mAnimating = true;
2419 }
2420 for (int i = mChildren.size() - 1; i >= 0; --i) {
2421 final WindowState c = (WindowState) mChildren.get(i);
2422 c.markSavedSurfaceExiting();
2423 }
2424 }
2425
2426 void addWinAnimatorToList(ArrayList<WindowStateAnimator> animators) {
2427 animators.add(mWinAnimator);
2428
2429 for (int i = mChildren.size() - 1; i >= 0; --i) {
2430 final WindowState c = (WindowState) mChildren.get(i);
2431 c.addWinAnimatorToList(animators);
2432 }
2433 }
2434
Wale Ogunwaled1c37912016-08-16 03:19:39 -07002435 void sendAppVisibilityToClients() {
2436 super.sendAppVisibilityToClients();
Wale Ogunwale9bc47732016-08-10 14:44:22 -07002437
Wale Ogunwaled1c37912016-08-16 03:19:39 -07002438 final boolean clientHidden = mAppToken.clientHidden;
Wale Ogunwale9bc47732016-08-10 14:44:22 -07002439 if (mAttrs.type == TYPE_APPLICATION_STARTING && clientHidden) {
2440 // Don't hide the starting window.
2441 return;
2442 }
2443
2444 try {
2445 if (DEBUG_VISIBILITY) Slog.v(TAG,
2446 "Setting visibility of " + this + ": " + (!clientHidden));
2447 mClient.dispatchAppVisibility(!clientHidden);
2448 } catch (RemoteException e) {
2449 }
Chong Zhang8e4bda92016-05-04 15:08:18 -07002450 }
2451
Chong Zhang92147042016-05-09 12:47:11 -07002452 public void setVisibleBeforeClientHidden() {
2453 mWasVisibleBeforeClientHidden |=
2454 (mViewVisibility == View.VISIBLE || mAnimatingWithSavedSurface);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07002455
Wale Ogunwaled1c37912016-08-16 03:19:39 -07002456 super.setVisibleBeforeClientHidden();
Chong Zhang92147042016-05-09 12:47:11 -07002457 }
2458
Wale Ogunwale9bc47732016-08-10 14:44:22 -07002459 public void clearWasVisibleBeforeClientHidden() {
Chong Zhang92147042016-05-09 12:47:11 -07002460 mWasVisibleBeforeClientHidden = false;
Wale Ogunwale9bc47732016-08-10 14:44:22 -07002461 for (int i = mChildren.size() - 1; i >= 0; --i) {
2462 final WindowState c = (WindowState) mChildren.get(i);
2463 c.clearWasVisibleBeforeClientHidden();
2464 }
Chong Zhang92147042016-05-09 12:47:11 -07002465 }
2466
2467 public boolean wasVisibleBeforeClientHidden() {
2468 return mWasVisibleBeforeClientHidden;
Chong Zhangbef461f2015-10-27 11:38:24 -07002469 }
2470
Wale Ogunwale9bc47732016-08-10 14:44:22 -07002471 void onStartFreezingScreen() {
2472 mAppFreezing = true;
2473 for (int i = mChildren.size() - 1; i >= 0; --i) {
2474 final WindowState c = (WindowState) mChildren.get(i);
2475 c.onStartFreezingScreen();
2476 }
2477 }
2478
2479 boolean onStopFreezingScreen() {
2480 boolean unfrozeWindows = false;
2481 for (int i = mChildren.size() - 1; i >= 0; --i) {
2482 final WindowState c = (WindowState) mChildren.get(i);
2483 unfrozeWindows |= c.onStopFreezingScreen();
2484 }
2485
2486 if (!mAppFreezing) {
2487 return unfrozeWindows;
2488 }
2489
2490 if (mHasSurface && !mOrientationChanging
2491 && mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
2492 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "set mOrientationChanging of " + this);
2493 mOrientationChanging = true;
2494 mService.mWindowPlacerLocked.mOrientationChangeComplete = false;
2495 }
2496 mLastFreezeDuration = 0;
2497 setDisplayLayoutNeeded();
2498 return true;
2499 }
2500
Chong Zhangeb22e8e2016-01-20 19:52:22 -08002501 private boolean shouldSaveSurface() {
Chong Zhang6c71c0b2016-04-01 15:10:31 -07002502 if (mWinAnimator.mSurfaceController == null) {
2503 // Don't bother if the surface controller is gone for any reason.
2504 return false;
2505 }
2506
Chong Zhang92147042016-05-09 12:47:11 -07002507 if (!mWasVisibleBeforeClientHidden) {
2508 return false;
2509 }
2510
Wale Ogunwale945d1972016-03-23 13:16:41 -07002511 if ((mAttrs.flags & FLAG_SECURE) != 0) {
2512 // We don't save secure surfaces since their content shouldn't be shown while the app
2513 // isn't on screen and content might leak through during the transition animation with
2514 // saved surface.
2515 return false;
2516 }
2517
Chong Zhangdb20b5f2015-10-23 14:01:43 -07002518 if (ActivityManager.isLowRamDeviceStatic()) {
2519 // Don't save surfaces on Svelte devices.
Chong Zhangeb22e8e2016-01-20 19:52:22 -08002520 return false;
2521 }
2522
Chong Zhangeb22e8e2016-01-20 19:52:22 -08002523 Task task = getTask();
2524 if (task == null || task.inHomeStack()) {
Chong Zhangdb20b5f2015-10-23 14:01:43 -07002525 // Don't save surfaces for home stack apps. These usually resume and draw
2526 // first frame very fast. Saving surfaces are mostly a waste of memory.
Chong Zhangeb22e8e2016-01-20 19:52:22 -08002527 return false;
Chong Zhangdb20b5f2015-10-23 14:01:43 -07002528 }
Chong Zhangeb22e8e2016-01-20 19:52:22 -08002529
2530 final AppWindowToken taskTop = task.getTopVisibleAppToken();
2531 if (taskTop != null && taskTop != mAppToken) {
2532 // Don't save if the window is not the topmost window.
2533 return false;
2534 }
2535
Jorim Jaggi8fa45222016-02-19 19:54:39 -08002536 if (mResizedWhileGone) {
2537 // Somebody resized our window while we were gone for layout, which means that the
2538 // client got an old size, so we have an outdated surface here.
2539 return false;
2540 }
2541
Robert Carr7098dbd2016-02-01 12:31:01 -08002542 if (DEBUG_DISABLE_SAVING_SURFACES) {
2543 return false;
2544 }
2545
Chong Zhangeb22e8e2016-01-20 19:52:22 -08002546 return mAppToken.shouldSaveSurface();
2547 }
2548
Wale Ogunwale9bc47732016-08-10 14:44:22 -07002549 boolean destroySurface(boolean cleanupOnResume, boolean appStopped) {
2550 boolean destroyedSomething = false;
2551 for (int i = mChildren.size() - 1; i >= 0; --i) {
2552 final WindowState c = (WindowState) mChildren.get(i);
2553 destroyedSomething |= c.destroySurface(cleanupOnResume, appStopped);
2554 }
2555
2556 if (appStopped || mWindowRemovalAllowed || cleanupOnResume) {
2557
2558 mWinAnimator.destroyPreservedSurfaceLocked();
2559
2560 if (mDestroying) {
2561 if (DEBUG_ADD_REMOVE) Slog.e(TAG_WM, "win=" + this
2562 + " destroySurfaces: appStopped=" + appStopped
2563 + " win.mWindowRemovalAllowed=" + mWindowRemovalAllowed
2564 + " win.mRemoveOnExit=" + mRemoveOnExit);
2565
2566 if (!cleanupOnResume || mRemoveOnExit) {
2567 destroyOrSaveSurface();
2568 }
2569 if (mRemoveOnExit) {
2570 remove();
2571 }
2572 if (cleanupOnResume) {
2573 requestUpdateWallpaperIfNeeded();
2574 }
2575 mDestroying = false;
2576 destroyedSomething = true;
2577 }
2578 }
2579 return destroyedSomething;
2580 }
Chris Craik3131bde2016-05-06 13:39:08 -07002581
Chong Zhangeb22e8e2016-01-20 19:52:22 -08002582 void destroyOrSaveSurface() {
2583 mSurfaceSaved = shouldSaveSurface();
2584 if (mSurfaceSaved) {
2585 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
2586 Slog.v(TAG, "Saving surface: " + this);
2587 }
Chris Craik3131bde2016-05-06 13:39:08 -07002588 // Previous user of the surface may have set a transparent region signaling a portion
2589 // doesn't need to be composited, so reset to default empty state.
2590 mSession.setTransparentRegion(mClient, sEmptyRegion);
Chong Zhangeb22e8e2016-01-20 19:52:22 -08002591
2592 mWinAnimator.hide("saved surface");
2593 mWinAnimator.mDrawState = WindowStateAnimator.NO_SURFACE;
2594 setHasSurface(false);
Chong Zhang47e36a32016-02-29 16:44:33 -08002595 // The client should have disconnected at this point, but if it doesn't,
2596 // we need to make sure it's disconnected. Otherwise when we reuse the surface
2597 // the client can't reconnect to the buffer queue, and rendering will fail.
2598 if (mWinAnimator.mSurfaceController != null) {
2599 mWinAnimator.mSurfaceController.disconnectInTransaction();
2600 }
Chong Zhang8e4bda92016-05-04 15:08:18 -07002601 mAnimatingWithSavedSurface = false;
Chong Zhangeb22e8e2016-01-20 19:52:22 -08002602 } else {
Robert Carr13f7be9e2015-12-02 18:39:45 -08002603 mWinAnimator.destroySurfaceLocked();
2604 }
Chong Zhang92147042016-05-09 12:47:11 -07002605 // Clear animating flags now, since the surface is now gone. (Note this is true even
2606 // if the surface is saved, to outside world the surface is still NO_SURFACE.)
2607 mAnimatingExit = false;
Robert Carr13f7be9e2015-12-02 18:39:45 -08002608 }
Chong Zhangdb20b5f2015-10-23 14:01:43 -07002609
Chong Zhang92147042016-05-09 12:47:11 -07002610 void destroySavedSurface() {
Wale Ogunwale9bc47732016-08-10 14:44:22 -07002611 for (int i = mChildren.size() - 1; i >= 0; --i) {
2612 final WindowState c = (WindowState) mChildren.get(i);
2613 c.destroySavedSurface();
2614 }
2615
Robert Carr13f7be9e2015-12-02 18:39:45 -08002616 if (mSurfaceSaved) {
Wale Ogunwale9bc47732016-08-10 14:44:22 -07002617 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, "Destroying saved surface: " + this);
Robert Carr13f7be9e2015-12-02 18:39:45 -08002618 mWinAnimator.destroySurfaceLocked();
Robert Carr237028a2016-07-26 10:39:45 -07002619 mSurfaceSaved = false;
Robert Carr13f7be9e2015-12-02 18:39:45 -08002620 }
Chong Zhang92147042016-05-09 12:47:11 -07002621 mWasVisibleBeforeClientHidden = false;
Robert Carr13f7be9e2015-12-02 18:39:45 -08002622 }
2623
Wale Ogunwale9bc47732016-08-10 14:44:22 -07002624 /** Returns -1 if there are no interesting windows or number of interesting windows not drawn.*/
2625 int restoreSavedSurfaceForInterestingWindow() {
2626 int interestingNotDrawn = -1;
2627 for (int i = mChildren.size() - 1; i >= 0; --i) {
2628 final WindowState c = (WindowState) mChildren.get(i);
2629 final int childInterestingNotDrawn = c.restoreSavedSurfaceForInterestingWindow();
2630 if (childInterestingNotDrawn != -1) {
2631 if (interestingNotDrawn == -1) {
2632 interestingNotDrawn = childInterestingNotDrawn;
2633 } else {
2634 interestingNotDrawn += childInterestingNotDrawn;
2635 }
2636 }
Chong Zhang4113ffa2016-02-18 12:39:13 -08002637 }
Robert Carr237028a2016-07-26 10:39:45 -07002638
Wale Ogunwale9bc47732016-08-10 14:44:22 -07002639 if (mAttrs.type == TYPE_APPLICATION_STARTING
2640 || mAppDied || !wasVisibleBeforeClientHidden()
2641 || (mAppToken.mAppAnimator.freezingScreen && mAppFreezing)) {
2642 // Window isn't interesting...
2643 return interestingNotDrawn;
2644 }
2645
2646 restoreSavedSurface();
2647
2648 if (!isDrawnLw()) {
2649 if (interestingNotDrawn == -1) {
2650 interestingNotDrawn = 1;
2651 } else {
2652 interestingNotDrawn++;
2653 }
2654 }
2655 return interestingNotDrawn;
2656 }
2657
2658 /** Returns true if the saved surface was restored. */
2659 boolean restoreSavedSurface() {
2660 if (!mSurfaceSaved) {
2661 return false;
2662 }
2663
2664 // Sometimes we save surfaces due to layout invisible directly after rotation occurs.
2665 // However this means the surface was never laid out in the new orientation.
2666 // We can only restore to the last rotation we were laid out as visible in.
Robert Carr237028a2016-07-26 10:39:45 -07002667 if (mLastVisibleLayoutRotation != mService.mRotation) {
2668 destroySavedSurface();
Wale Ogunwale9bc47732016-08-10 14:44:22 -07002669 return false;
Robert Carr237028a2016-07-26 10:39:45 -07002670 }
Chong Zhangeb22e8e2016-01-20 19:52:22 -08002671 mSurfaceSaved = false;
Robert Carr237028a2016-07-26 10:39:45 -07002672
Chong Zhang6c71c0b2016-04-01 15:10:31 -07002673 if (mWinAnimator.mSurfaceController != null) {
2674 setHasSurface(true);
Wale Ogunwale9d147902016-07-16 11:58:55 -07002675 mWinAnimator.mDrawState = READY_TO_SHOW;
Chong Zhang92147042016-05-09 12:47:11 -07002676 mAnimatingWithSavedSurface = true;
Chong Zhang6c71c0b2016-04-01 15:10:31 -07002677
Chong Zhang6e9872b2016-08-17 10:19:05 -07002678 requestUpdateWallpaperIfNeeded();
2679
Chong Zhang6c71c0b2016-04-01 15:10:31 -07002680 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
2681 Slog.v(TAG, "Restoring saved surface: " + this);
2682 }
2683 } else {
2684 // mSurfaceController shouldn't be null if mSurfaceSaved was still true at
2685 // this point. Even if we destroyed the saved surface because of rotation
2686 // or resize, mSurfaceSaved flag should have been cleared. So this is a wtf.
2687 Slog.wtf(TAG, "Failed to restore saved surface: surface gone! " + this);
Chong Zhangeb22e8e2016-01-20 19:52:22 -08002688 }
Wale Ogunwale9bc47732016-08-10 14:44:22 -07002689
2690 return true;
Chong Zhangeb22e8e2016-01-20 19:52:22 -08002691 }
2692
Chong Zhang92147042016-05-09 12:47:11 -07002693 boolean canRestoreSurface() {
Wale Ogunwale9bc47732016-08-10 14:44:22 -07002694 if (mWasVisibleBeforeClientHidden && mSurfaceSaved) {
2695 return true;
2696 }
2697
2698 for (int i = mChildren.size() - 1; i >= 0; --i) {
2699 final WindowState c = (WindowState) mChildren.get(i);
2700 if (c.canRestoreSurface()) {
2701 return true;
2702 }
2703 }
2704
2705 return false;
Chong Zhang92147042016-05-09 12:47:11 -07002706 }
2707
2708 boolean hasSavedSurface() {
Robert Carr13f7be9e2015-12-02 18:39:45 -08002709 return mSurfaceSaved;
2710 }
2711
Chong Zhang92147042016-05-09 12:47:11 -07002712 void clearHasSavedSurface() {
2713 mSurfaceSaved = false;
2714 mAnimatingWithSavedSurface = false;
Chong Zhangf58631a2016-05-24 16:02:10 -07002715 if (mWasVisibleBeforeClientHidden) {
2716 mAppToken.destroySavedSurfaces();
2717 }
Chong Zhang92147042016-05-09 12:47:11 -07002718 }
2719
Chong Zhangcbbcc0f2016-05-17 20:46:58 -07002720 boolean clearAnimatingWithSavedSurface() {
Chong Zhang92147042016-05-09 12:47:11 -07002721 if (mAnimatingWithSavedSurface) {
2722 // App has drawn something to its windows, we're no longer animating with
2723 // the saved surfaces.
2724 if (DEBUG_ANIM) Slog.d(TAG,
2725 "clearAnimatingWithSavedSurface(): win=" + this);
2726 mAnimatingWithSavedSurface = false;
Chong Zhangcbbcc0f2016-05-17 20:46:58 -07002727 return true;
Chong Zhang92147042016-05-09 12:47:11 -07002728 }
Chong Zhangcbbcc0f2016-05-17 20:46:58 -07002729 return false;
Chong Zhang92147042016-05-09 12:47:11 -07002730 }
2731
Craig Mautner69b08182012-09-05 13:07:13 -07002732 @Override
2733 public boolean isDefaultDisplay() {
Craig Mautnerdf88d732014-01-27 09:21:32 -08002734 final DisplayContent displayContent = getDisplayContent();
2735 if (displayContent == null) {
2736 // Only a window that was on a non-default display can be detached from it.
2737 return false;
2738 }
Winson Chung47a3e652014-05-21 16:03:42 -07002739 return displayContent.isDefaultDisplay;
Craig Mautner69b08182012-09-05 13:07:13 -07002740 }
2741
Adrian Rooscd3884d2015-02-18 17:25:23 +01002742 @Override
2743 public boolean isDimming() {
Filip Gruszczynski0689ae92015-10-01 12:30:31 -07002744 final DimLayer.DimLayerUser dimLayerUser = getDimLayerUser();
2745 return dimLayerUser != null && mDisplayContent != null &&
Chong Zhang112eb8c2015-11-02 11:17:00 -08002746 mDisplayContent.mDimLayerController.isDimming(dimLayerUser, mWinAnimator);
Adrian Rooscd3884d2015-02-18 17:25:23 +01002747 }
2748
Craig Mautner88400d32012-09-30 12:35:45 -07002749 public void setShowToOwnerOnlyLocked(boolean showToOwnerOnly) {
2750 mShowToOwnerOnly = showToOwnerOnly;
2751 }
2752
Craig Mautner5962b122012-10-05 14:45:52 -07002753 boolean isHiddenFromUserLocked() {
Wale Ogunwalecaa53af2016-07-17 14:50:26 -07002754 // Child windows are evaluated based on their parent window.
2755 final WindowState win = getTopParentWindow();
Craig Mautner341220f2012-10-16 15:20:09 -07002756 if (win.mAttrs.type < WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW
Wale Ogunwale6dfdfd62015-04-15 12:01:38 -07002757 && win.mAppToken != null && win.mAppToken.showForAllUsers) {
Jorim Jaggidbe44ac2016-04-22 19:50:13 -07002758
2759 // All window frames that are fullscreen extend above status bar, but some don't extend
2760 // below navigation bar. Thus, check for display frame for top/left and stable frame for
2761 // bottom right.
2762 if (win.mFrame.left <= win.mDisplayFrame.left
2763 && win.mFrame.top <= win.mDisplayFrame.top
2764 && win.mFrame.right >= win.mStableFrame.right
2765 && win.mFrame.bottom >= win.mStableFrame.bottom) {
Craig Mautner5962b122012-10-05 14:45:52 -07002766 // Is a fullscreen window, like the clock alarm. Show to everyone.
2767 return false;
2768 }
2769 }
2770
Craig Mautner341220f2012-10-16 15:20:09 -07002771 return win.mShowToOwnerOnly
Kenny Guy2a764942014-04-02 13:29:20 +01002772 && !mService.isCurrentProfileLocked(UserHandle.getUserId(win.mOwnerUid));
Craig Mautner9dc52bc2012-08-06 14:15:42 -07002773 }
2774
Dianne Hackbornffb3d932011-05-17 17:44:51 -07002775 private static void applyInsets(Region outRegion, Rect frame, Rect inset) {
2776 outRegion.set(
2777 frame.left + inset.left, frame.top + inset.top,
2778 frame.right - inset.right, frame.bottom - inset.bottom);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002779 }
2780
Wale Ogunwale053c8e42015-11-16 14:27:21 -08002781 void getTouchableRegion(Region outRegion) {
Dianne Hackbornffb3d932011-05-17 17:44:51 -07002782 final Rect frame = mFrame;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002783 switch (mTouchableInsets) {
2784 default:
Wale Ogunwale053c8e42015-11-16 14:27:21 -08002785 case TOUCHABLE_INSETS_FRAME:
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002786 outRegion.set(frame);
2787 break;
Wale Ogunwale053c8e42015-11-16 14:27:21 -08002788 case TOUCHABLE_INSETS_CONTENT:
Dianne Hackbornffb3d932011-05-17 17:44:51 -07002789 applyInsets(outRegion, frame, mGivenContentInsets);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002790 break;
Wale Ogunwale053c8e42015-11-16 14:27:21 -08002791 case TOUCHABLE_INSETS_VISIBLE:
Dianne Hackbornffb3d932011-05-17 17:44:51 -07002792 applyInsets(outRegion, frame, mGivenVisibleInsets);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002793 break;
Wale Ogunwale053c8e42015-11-16 14:27:21 -08002794 case TOUCHABLE_INSETS_REGION: {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002795 final Region givenTouchableRegion = mGivenTouchableRegion;
2796 outRegion.set(givenTouchableRegion);
2797 outRegion.translate(frame.left, frame.top);
2798 break;
2799 }
2800 }
Wale Ogunwale053c8e42015-11-16 14:27:21 -08002801 cropRegionToStackBoundsIfNeeded(outRegion);
2802 }
2803
2804 void cropRegionToStackBoundsIfNeeded(Region region) {
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002805 final Task task = getTask();
2806 if (task == null || !task.cropWindowsToStackBounds()) {
Wale Ogunwale053c8e42015-11-16 14:27:21 -08002807 return;
2808 }
2809
Wale Ogunwaleb1faf602016-01-27 09:12:31 -08002810 final TaskStack stack = task.mStack;
Wale Ogunwale053c8e42015-11-16 14:27:21 -08002811 if (stack == null) {
2812 return;
2813 }
2814
2815 stack.getDimBounds(mTmpRect);
2816 region.op(mTmpRect, Region.Op.INTERSECT);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08002817 }
2818
Craig Mautner59c00972012-07-30 12:10:24 -07002819 WindowList getWindowList() {
Craig Mautnerdf88d732014-01-27 09:21:32 -08002820 final DisplayContent displayContent = getDisplayContent();
2821 return displayContent == null ? null : displayContent.getWindowList();
Craig Mautner59c00972012-07-30 12:10:24 -07002822 }
2823
Dianne Hackborne3f23a32013-03-01 13:25:35 -08002824 /**
2825 * Report a focus change. Must be called with no locks held, and consistently
2826 * from the same serialized thread (such as dispatched from a handler).
2827 */
2828 public void reportFocusChangedSerialized(boolean focused, boolean inTouchMode) {
2829 try {
2830 mClient.windowFocusChanged(focused, inTouchMode);
2831 } catch (RemoteException e) {
2832 }
2833 if (mFocusCallbacks != null) {
2834 final int N = mFocusCallbacks.beginBroadcast();
2835 for (int i=0; i<N; i++) {
2836 IWindowFocusObserver obs = mFocusCallbacks.getBroadcastItem(i);
2837 try {
2838 if (focused) {
2839 obs.focusGained(mWindowId.asBinder());
2840 } else {
2841 obs.focusLost(mWindowId.asBinder());
2842 }
2843 } catch (RemoteException e) {
2844 }
2845 }
2846 mFocusCallbacks.finishBroadcast();
2847 }
2848 }
2849
Robert Carrc24d8f92016-02-29 16:24:33 -08002850 /**
2851 * Update our current configurations, based on task configuration.
2852 *
2853 * @return A configuration suitable for sending to the client.
2854 */
2855 private Configuration updateConfiguration() {
Robert Carrc24d8f92016-02-29 16:24:33 -08002856 final boolean configChanged = isConfigChanged();
Jorim Jaggi26c8c422016-05-09 19:57:25 -07002857 getMergedConfig(mMergedConfiguration);
2858 mConfigHasChanged = false;
Robert Carrc24d8f92016-02-29 16:24:33 -08002859 if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION) && configChanged) {
2860 Slog.i(TAG, "Sending new config to window " + this + ": " +
Jorim Jaggi26c8c422016-05-09 19:57:25 -07002861 " / mergedConfig=" + mMergedConfiguration);
Robert Carrc24d8f92016-02-29 16:24:33 -08002862 }
Robert Carrc24d8f92016-02-29 16:24:33 -08002863 return mMergedConfiguration;
2864 }
2865
Jorim Jaggi26c8c422016-05-09 19:57:25 -07002866 private void getMergedConfig(Configuration outConfig) {
2867 if (mAppToken != null && mAppToken.mFrozenMergedConfig.size() > 0) {
2868 outConfig.setTo(mAppToken.mFrozenMergedConfig.peek());
2869 return;
2870 }
2871 final Task task = getTask();
2872 final Configuration overrideConfig = task != null
2873 ? task.mOverrideConfig
2874 : Configuration.EMPTY;
2875 final Configuration serviceConfig = mService.mCurConfiguration;
2876 outConfig.setTo(serviceConfig);
2877 if (overrideConfig != Configuration.EMPTY) {
2878 outConfig.updateFrom(overrideConfig);
2879 }
2880 }
2881
Craig Mautnerdf88d732014-01-27 09:21:32 -08002882 void reportResized() {
Wale Ogunwalecad05a02015-09-25 10:41:44 -07002883 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wm.reportResized_" + getWindowTag());
Craig Mautnerdf88d732014-01-27 09:21:32 -08002884 try {
Craig Mautnerd1c2c542014-02-06 10:31:41 -08002885 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, "Reporting new frame to " + this
2886 + ": " + mCompatFrame);
Robert Carrc24d8f92016-02-29 16:24:33 -08002887 final Configuration newConfig = isConfigChanged() ? updateConfiguration() : null;
Craig Mautnerd1c2c542014-02-06 10:31:41 -08002888 if (DEBUG_ORIENTATION && mWinAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING)
2889 Slog.i(TAG, "Resizing " + this + " WITH DRAW PENDING");
2890
Craig Mautnerdf88d732014-01-27 09:21:32 -08002891 final Rect frame = mFrame;
2892 final Rect overscanInsets = mLastOverscanInsets;
2893 final Rect contentInsets = mLastContentInsets;
2894 final Rect visibleInsets = mLastVisibleInsets;
Adrian Roosfa104232014-06-20 16:10:14 -07002895 final Rect stableInsets = mLastStableInsets;
Filip Gruszczynski2217f612015-05-26 11:32:08 -07002896 final Rect outsets = mLastOutsets;
Craig Mautnerd1c2c542014-02-06 10:31:41 -08002897 final boolean reportDraw = mWinAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING;
Chet Haase8eb48d22014-09-24 07:31:29 -07002898 if (mAttrs.type != WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
2899 && mClient instanceof IWindow.Stub) {
Craig Mautnerdf88d732014-01-27 09:21:32 -08002900 // To prevent deadlock simulate one-way call if win.mClient is a local object.
2901 mService.mH.post(new Runnable() {
2902 @Override
2903 public void run() {
2904 try {
Jorim Jaggi253a20f2015-11-03 12:38:42 +01002905 dispatchResized(frame, overscanInsets, contentInsets, visibleInsets,
2906 stableInsets, outsets, reportDraw, newConfig);
Craig Mautnerdf88d732014-01-27 09:21:32 -08002907 } catch (RemoteException e) {
2908 // Not a remote call, RemoteException won't be raised.
2909 }
2910 }
2911 });
2912 } else {
Jorim Jaggi253a20f2015-11-03 12:38:42 +01002913 dispatchResized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets,
Filip Gruszczynski2217f612015-05-26 11:32:08 -07002914 outsets, reportDraw, newConfig);
Craig Mautnerdf88d732014-01-27 09:21:32 -08002915 }
Svetoslav4604abc2014-06-10 18:59:30 -07002916
2917 //TODO (multidisplay): Accessibility supported only for the default display.
2918 if (mService.mAccessibilityController != null
2919 && getDisplayId() == Display.DEFAULT_DISPLAY) {
Svetoslavf7174e82014-06-12 11:29:35 -07002920 mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
Svetoslav4604abc2014-06-10 18:59:30 -07002921 }
2922
Craig Mautnerdf88d732014-01-27 09:21:32 -08002923 mOverscanInsetsChanged = false;
2924 mContentInsetsChanged = false;
2925 mVisibleInsetsChanged = false;
Adrian Roosfa104232014-06-20 16:10:14 -07002926 mStableInsetsChanged = false;
Filip Gruszczynski2217f612015-05-26 11:32:08 -07002927 mOutsetsChanged = false;
Robert Carr31aa98b2016-07-20 15:29:03 -07002928 mFrameSizeChanged = false;
Andrii Kulianeb1d3222016-05-16 15:17:55 -07002929 mResizedWhileNotDragResizingReported = true;
Craig Mautnerdf88d732014-01-27 09:21:32 -08002930 mWinAnimator.mSurfaceResized = false;
2931 } catch (RemoteException e) {
2932 mOrientationChanging = false;
2933 mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
2934 - mService.mDisplayFreezeTime);
tiger_huang950ee772014-07-11 18:41:48 +08002935 // We are assuming the hosting process is dead or in a zombie state.
2936 Slog.w(TAG, "Failed to report 'resized' to the client of " + this
2937 + ", removing this window.");
2938 mService.mPendingRemove.add(this);
Filip Gruszczynski24966d42015-09-05 15:00:00 -07002939 mService.mWindowPlacerLocked.requestTraversal();
Craig Mautnerdf88d732014-01-27 09:21:32 -08002940 }
Wale Ogunwalecad05a02015-09-25 10:41:44 -07002941 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
Craig Mautnerdf88d732014-01-27 09:21:32 -08002942 }
2943
Jorim Jaggi2e95a482016-01-14 17:36:55 -08002944 Rect getBackdropFrame(Rect frame) {
Chong Zhangd153c4f2015-11-06 20:26:40 -08002945 // When the task is docked, we send fullscreen sized backDropFrame as soon as resizing
2946 // start even if we haven't received the relayout window, so that the client requests
2947 // the relayout sooner. When dragging stops, backDropFrame needs to stay fullscreen
2948 // until the window to small size, otherwise the multithread renderer will shift last
2949 // one or more frame to wrong offset. So here we send fullscreen backdrop if either
2950 // isDragResizing() or isDragResizeChanged() is true.
Filip Gruszczynski84fa3352016-01-25 16:28:49 -08002951 boolean resizing = isDragResizing() || isDragResizeChanged();
2952 if (StackId.useWindowFrameForBackdrop(getStackId()) || !resizing) {
2953 return frame;
2954 }
Jorim Jaggi2e95a482016-01-14 17:36:55 -08002955 DisplayInfo displayInfo = getDisplayInfo();
2956 mTmpRect.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
Filip Gruszczynski84fa3352016-01-25 16:28:49 -08002957 return mTmpRect;
2958 }
2959
Jorim Jaggi86905582016-02-09 21:36:09 -08002960 @Override
2961 public int getStackId() {
Filip Gruszczynski84fa3352016-01-25 16:28:49 -08002962 final TaskStack stack = getStack();
2963 if (stack == null) {
2964 return INVALID_STACK_ID;
2965 }
2966 return stack.mStackId;
Jorim Jaggi2e95a482016-01-14 17:36:55 -08002967 }
2968
2969 private void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets,
2970 Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
2971 Configuration newConfig) throws RemoteException {
Chong Zhangedaf3052016-04-22 15:04:31 -07002972 final boolean forceRelayout = isDragResizeChanged() || mResizedWhileNotDragResizing;
2973
Jorim Jaggidc249c42015-12-15 14:57:31 -08002974 mClient.resized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets, outsets,
Jorim Jaggia4a58ef2016-01-27 02:10:08 -08002975 reportDraw, newConfig, getBackdropFrame(frame),
Chong Zhangedaf3052016-04-22 15:04:31 -07002976 forceRelayout, mPolicy.isNavBarForcedShownLw(this));
Jorim Jaggic662d8e2016-02-05 16:54:54 -08002977 mDragResizingChangeReported = true;
Jorim Jaggi253a20f2015-11-03 12:38:42 +01002978 }
2979
Dianne Hackborne3f23a32013-03-01 13:25:35 -08002980 public void registerFocusObserver(IWindowFocusObserver observer) {
2981 synchronized(mService.mWindowMap) {
2982 if (mFocusCallbacks == null) {
2983 mFocusCallbacks = new RemoteCallbackList<IWindowFocusObserver>();
2984 }
2985 mFocusCallbacks.register(observer);
2986 }
2987 }
2988
2989 public void unregisterFocusObserver(IWindowFocusObserver observer) {
2990 synchronized(mService.mWindowMap) {
2991 if (mFocusCallbacks != null) {
2992 mFocusCallbacks.unregister(observer);
2993 }
2994 }
2995 }
2996
2997 public boolean isFocused() {
2998 synchronized(mService.mWindowMap) {
2999 return mService.mCurrentFocus == this;
3000 }
3001 }
3002
Filip Gruszczynski1a1d8312015-08-26 17:00:47 -07003003 boolean inFreeformWorkspace() {
Wale Ogunwale5a2f2cb2015-09-17 12:31:55 -07003004 final Task task = getTask();
Chong Zhang09b21ef2015-09-14 10:20:21 -07003005 return task != null && task.inFreeformWorkspace();
3006 }
3007
Wale Ogunwale9185fb02016-03-11 18:06:14 -08003008 @Override
Andrii Kulian933076d2016-03-29 17:04:42 -07003009 public boolean isInMultiWindowMode() {
Wale Ogunwale9185fb02016-03-11 18:06:14 -08003010 final Task task = getTask();
3011 return task != null && !task.isFullscreen();
3012 }
3013
Chong Zhang3005e752015-09-18 18:46:28 -07003014 boolean isDragResizeChanged() {
Filip Gruszczynski3ddc5d62015-09-23 15:01:30 -07003015 return mDragResizing != computeDragResizing();
3016 }
3017
Wale Ogunwaled1c37912016-08-16 03:19:39 -07003018 @Override
Wale Ogunwale9bc47732016-08-10 14:44:22 -07003019 void setWaitingForDrawnIfResizingChanged() {
3020 if (isDragResizeChanged()) {
3021 mService.mWaitingForDrawn.add(this);
3022 }
Wale Ogunwaled1c37912016-08-16 03:19:39 -07003023 super.setWaitingForDrawnIfResizingChanged();
Wale Ogunwale9bc47732016-08-10 14:44:22 -07003024 }
3025
Jorim Jaggic662d8e2016-02-05 16:54:54 -08003026 /**
3027 * @return Whether we reported a drag resize change to the application or not already.
3028 */
3029 boolean isDragResizingChangeReported() {
3030 return mDragResizingChangeReported;
3031 }
3032
3033 /**
3034 * Resets the state whether we reported a drag resize change to the app.
3035 */
Wale Ogunwaled1c37912016-08-16 03:19:39 -07003036 @Override
Jorim Jaggic662d8e2016-02-05 16:54:54 -08003037 void resetDragResizingChangeReported() {
3038 mDragResizingChangeReported = false;
Wale Ogunwaled1c37912016-08-16 03:19:39 -07003039 super.resetDragResizingChangeReported();
Jorim Jaggic662d8e2016-02-05 16:54:54 -08003040 }
3041
Andrii Kulianeb1d3222016-05-16 15:17:55 -07003042 /**
3043 * Set whether we got resized but drag resizing flag was false.
3044 * @see #isResizedWhileNotDragResizing().
3045 */
3046 void setResizedWhileNotDragResizing(boolean resizedWhileNotDragResizing) {
3047 mResizedWhileNotDragResizing = resizedWhileNotDragResizing;
3048 mResizedWhileNotDragResizingReported = !resizedWhileNotDragResizing;
3049 }
3050
3051 /**
3052 * Indicates whether we got resized but drag resizing flag was false. In this case, we also
3053 * need to recreate the surface and defer surface bound updates in order to make sure the
3054 * buffer contents and the positioning/size stay in sync.
3055 */
3056 boolean isResizedWhileNotDragResizing() {
3057 return mResizedWhileNotDragResizing;
3058 }
3059
3060 /**
3061 * @return Whether we reported "resize while not drag resizing" to the application.
3062 * @see #isResizedWhileNotDragResizing()
3063 */
3064 boolean isResizedWhileNotDragResizingReported() {
3065 return mResizedWhileNotDragResizingReported;
3066 }
3067
Jorim Jaggidcf467c2015-11-05 13:59:32 +01003068 int getResizeMode() {
3069 return mResizeMode;
3070 }
3071
Jorim Jaggi192086e2016-03-11 17:17:03 +01003072 boolean computeDragResizing() {
Wale Ogunwale5a2f2cb2015-09-17 12:31:55 -07003073 final Task task = getTask();
Filip Gruszczynski3ddc5d62015-09-23 15:01:30 -07003074 if (task == null) {
3075 return false;
3076 }
Jorim Jaggidd6e4c12016-02-17 22:13:43 -08003077 if (mAttrs.width != MATCH_PARENT || mAttrs.height != MATCH_PARENT) {
3078
3079 // Floating windows never enter drag resize mode.
3080 return false;
3081 }
Filip Gruszczynski3ddc5d62015-09-23 15:01:30 -07003082 if (task.isDragResizing()) {
3083 return true;
3084 }
Jorim Jaggi0429f352015-12-22 16:29:16 +01003085
3086 // If the bounds are currently frozen, it means that the layout size that the app sees
3087 // and the bounds we clip this window to might be different. In order to avoid holes, we
3088 // simulate that we are still resizing so the app fills the hole with the resizing
3089 // background.
3090 return (mDisplayContent.mDividerControllerLocked.isResizing()
3091 || mAppToken != null && !mAppToken.mFrozenBounds.isEmpty()) &&
Jorim Jaggi899327f2016-02-25 20:44:18 -05003092 !task.inFreeformWorkspace() && !isGoneForLayoutLw();
Jorim Jaggi9511b0f2016-01-29 19:12:44 -08003093
Chong Zhang3005e752015-09-18 18:46:28 -07003094 }
3095
3096 void setDragResizing() {
Jorim Jaggic662d8e2016-02-05 16:54:54 -08003097 final boolean resizing = computeDragResizing();
3098 if (resizing == mDragResizing) {
3099 return;
3100 }
3101 mDragResizing = resizing;
Jorim Jaggi0b46f3c2016-03-14 12:21:37 +01003102 final Task task = getTask();
3103 if (task != null && task.isDragResizing()) {
3104 mResizeMode = task.getDragResizeMode();
3105 } else {
3106 mResizeMode = mDragResizing && mDisplayContent.mDividerControllerLocked.isResizing()
3107 ? DRAG_RESIZE_MODE_DOCKED_DIVIDER
3108 : DRAG_RESIZE_MODE_FREEFORM;
3109 }
Chong Zhang3005e752015-09-18 18:46:28 -07003110 }
3111
3112 boolean isDragResizing() {
3113 return mDragResizing;
Skuhnef932e562015-08-20 12:07:30 -07003114 }
3115
Robert Carr2487ce72016-04-07 15:18:45 -07003116 boolean isDockedResizing() {
3117 return mDragResizing && getResizeMode() == DRAG_RESIZE_MODE_DOCKED_DIVIDER;
3118 }
3119
Dianne Hackborna44abeb2011-08-08 19:24:01 -07003120 void dump(PrintWriter pw, String prefix, boolean dumpAll) {
Wale Ogunwale30cc7bf2015-02-04 16:47:57 -08003121 final TaskStack stack = getStack();
Craig Mautnerdf88d732014-01-27 09:21:32 -08003122 pw.print(prefix); pw.print("mDisplayId="); pw.print(getDisplayId());
Wale Ogunwale30cc7bf2015-02-04 16:47:57 -08003123 if (stack != null) {
3124 pw.print(" stackId="); pw.print(stack.mStackId);
3125 }
Wale Ogunwale4c5aa5172016-04-19 11:29:05 -07003126 if (mNotOnAppsDisplay) {
3127 pw.print(" mNotOnAppsDisplay="); pw.print(mNotOnAppsDisplay);
3128 }
Craig Mautner59c00972012-07-30 12:10:24 -07003129 pw.print(" mSession="); pw.print(mSession);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003130 pw.print(" mClient="); pw.println(mClient.asBinder());
Craig Mautner88400d32012-09-30 12:35:45 -07003131 pw.print(prefix); pw.print("mOwnerUid="); pw.print(mOwnerUid);
Dianne Hackbornc2293022013-02-06 23:14:49 -08003132 pw.print(" mShowToOwnerOnly="); pw.print(mShowToOwnerOnly);
3133 pw.print(" package="); pw.print(mAttrs.packageName);
3134 pw.print(" appop="); pw.println(AppOpsManager.opToName(mAppOp));
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003135 pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07003136 pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
3137 pw.print(" h="); pw.print(mRequestedHeight);
3138 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
Dianne Hackborn1743b642012-03-12 17:04:43 -07003139 if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) {
3140 pw.print(prefix); pw.print("LastRequested w="); pw.print(mLastRequestedWidth);
3141 pw.print(" h="); pw.println(mLastRequestedHeight);
3142 }
Wale Ogunwalee4343ef2016-07-19 08:00:46 -07003143 if (mIsChildWindow || mLayoutAttached) {
3144 pw.print(prefix); pw.print("mParentWindow="); pw.print(getParentWindow());
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003145 pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
3146 }
3147 if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
3148 pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
3149 pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
3150 pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
3151 pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
3152 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07003153 if (dumpAll) {
3154 pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
3155 pw.print(" mSubLayer="); pw.print(mSubLayer);
3156 pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
Wale Ogunwale455fac52016-07-21 07:24:49 -07003157 pw.print(getAnimLayerAdjustment());
Craig Mautnerc2f9be02012-03-27 17:32:29 -07003158 pw.print("="); pw.print(mWinAnimator.mAnimLayer);
3159 pw.print(" mLastLayer="); pw.println(mWinAnimator.mLastLayer);
Dianne Hackborn6d05fd32011-11-19 14:36:15 -08003160 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07003161 if (dumpAll) {
3162 pw.print(prefix); pw.print("mToken="); pw.println(mToken);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07003163 if (mAppToken != null) {
Wale Ogunwale6bab4cf2016-04-07 12:23:08 -07003164 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
3165 pw.print(prefix); pw.print(" isAnimatingWithSavedSurface()=");
Chong Zhangbfc2f8f2016-01-29 15:50:34 -08003166 pw.print(isAnimatingWithSavedSurface());
Chong Zhang112eb8c2015-11-02 11:17:00 -08003167 pw.print(" mAppDied=");pw.println(mAppDied);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07003168 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07003169 pw.print(prefix); pw.print("mViewVisibility=0x");
3170 pw.print(Integer.toHexString(mViewVisibility));
Dianne Hackborna44abeb2011-08-08 19:24:01 -07003171 pw.print(" mHaveFrame="); pw.print(mHaveFrame);
3172 pw.print(" mObscured="); pw.println(mObscured);
Dianne Hackborn9a230e02011-10-06 11:51:27 -07003173 pw.print(prefix); pw.print("mSeq="); pw.print(mSeq);
3174 pw.print(" mSystemUiVisibility=0x");
3175 pw.println(Integer.toHexString(mSystemUiVisibility));
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003176 }
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -08003177 if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || !mAppOpVisibility
Wale Ogunwale9d147902016-07-16 11:58:55 -07003178 || isParentWindowHidden()) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003179 pw.print(prefix); pw.print("mPolicyVisibility=");
3180 pw.print(mPolicyVisibility);
3181 pw.print(" mPolicyVisibilityAfterAnim=");
3182 pw.print(mPolicyVisibilityAfterAnim);
Dianne Hackbornb6b23ec2013-02-11 19:29:06 -08003183 pw.print(" mAppOpVisibility=");
3184 pw.print(mAppOpVisibility);
Wale Ogunwale9d147902016-07-16 11:58:55 -07003185 pw.print(" parentHidden="); pw.println(isParentWindowHidden());
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003186 }
Dianne Hackbornb7ff51b2012-01-23 19:15:27 -08003187 if (!mRelayoutCalled || mLayoutNeeded) {
3188 pw.print(prefix); pw.print("mRelayoutCalled="); pw.print(mRelayoutCalled);
3189 pw.print(" mLayoutNeeded="); pw.println(mLayoutNeeded);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003190 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003191 if (mXOffset != 0 || mYOffset != 0) {
3192 pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
3193 pw.print(" y="); pw.println(mYOffset);
3194 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07003195 if (dumpAll) {
3196 pw.print(prefix); pw.print("mGivenContentInsets=");
3197 mGivenContentInsets.printShortString(pw);
3198 pw.print(" mGivenVisibleInsets=");
3199 mGivenVisibleInsets.printShortString(pw);
3200 pw.println();
3201 if (mTouchableInsets != 0 || mGivenInsetsPending) {
3202 pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets);
3203 pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -07003204 Region region = new Region();
3205 getTouchableRegion(region);
3206 pw.print(prefix); pw.print("touchable region="); pw.println(region);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07003207 }
Jorim Jaggi26c8c422016-05-09 19:57:25 -07003208 pw.print(prefix); pw.print("mMergedConfiguration="); pw.println(mMergedConfiguration);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003209 }
Craig Mautnerc8bc97e2012-04-02 12:54:54 -07003210 pw.print(prefix); pw.print("mHasSurface="); pw.print(mHasSurface);
Filip Gruszczynski2a6a2c22015-10-14 12:00:53 -07003211 pw.print(" mShownPosition="); mShownPosition.printShortString(pw);
Chong Zhanga8975bd2016-01-28 17:13:47 -08003212 pw.print(" isReadyForDisplay()="); pw.print(isReadyForDisplay());
Wale Ogunwale9017ec02016-02-25 08:55:25 -08003213 pw.print(" hasSavedSurface()="); pw.print(hasSavedSurface());
3214 pw.print(" mWindowRemovalAllowed="); pw.println(mWindowRemovalAllowed);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07003215 if (dumpAll) {
3216 pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
3217 pw.print(" last="); mLastFrame.printShortString(pw);
3218 pw.println();
3219 }
Dianne Hackbornffb3d932011-05-17 17:44:51 -07003220 if (mEnforceSizeCompat) {
3221 pw.print(prefix); pw.print("mCompatFrame="); mCompatFrame.printShortString(pw);
Dianne Hackbornffb3d932011-05-17 17:44:51 -07003222 pw.println();
3223 }
Dianne Hackborna44abeb2011-08-08 19:24:01 -07003224 if (dumpAll) {
Dianne Hackborn5c58de32012-04-28 19:52:37 -07003225 pw.print(prefix); pw.print("Frames: containing=");
Dianne Hackborna44abeb2011-08-08 19:24:01 -07003226 mContainingFrame.printShortString(pw);
Dianne Hackborn5c58de32012-04-28 19:52:37 -07003227 pw.print(" parent="); mParentFrame.printShortString(pw);
Dianne Hackbornc4aad012013-02-22 15:05:25 -08003228 pw.println();
3229 pw.print(prefix); pw.print(" display="); mDisplayFrame.printShortString(pw);
3230 pw.print(" overscan="); mOverscanFrame.printShortString(pw);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07003231 pw.println();
Dianne Hackborn85afd1b2012-05-13 13:31:06 -07003232 pw.print(prefix); pw.print(" content="); mContentFrame.printShortString(pw);
Dianne Hackborn5c58de32012-04-28 19:52:37 -07003233 pw.print(" visible="); mVisibleFrame.printShortString(pw);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07003234 pw.println();
John Spurlock46646232013-09-30 22:32:42 -04003235 pw.print(prefix); pw.print(" decor="); mDecorFrame.printShortString(pw);
3236 pw.println();
Filip Gruszczynski2217f612015-05-26 11:32:08 -07003237 pw.print(prefix); pw.print(" outset="); mOutsetFrame.printShortString(pw);
3238 pw.println();
Dianne Hackbornc4aad012013-02-22 15:05:25 -08003239 pw.print(prefix); pw.print("Cur insets: overscan=");
3240 mOverscanInsets.printShortString(pw);
3241 pw.print(" content="); mContentInsets.printShortString(pw);
Dianne Hackborn5c58de32012-04-28 19:52:37 -07003242 pw.print(" visible="); mVisibleInsets.printShortString(pw);
Adrian Roosfa104232014-06-20 16:10:14 -07003243 pw.print(" stable="); mStableInsets.printShortString(pw);
Wale Ogunwale6bab4cf2016-04-07 12:23:08 -07003244 pw.print(" surface="); mAttrs.surfaceInsets.printShortString(pw);
Filip Gruszczynski2217f612015-05-26 11:32:08 -07003245 pw.print(" outsets="); mOutsets.printShortString(pw);
Dianne Hackborn5c58de32012-04-28 19:52:37 -07003246 pw.println();
Dianne Hackbornc4aad012013-02-22 15:05:25 -08003247 pw.print(prefix); pw.print("Lst insets: overscan=");
3248 mLastOverscanInsets.printShortString(pw);
3249 pw.print(" content="); mLastContentInsets.printShortString(pw);
Dianne Hackborn5c58de32012-04-28 19:52:37 -07003250 pw.print(" visible="); mLastVisibleInsets.printShortString(pw);
Adrian Roosfa104232014-06-20 16:10:14 -07003251 pw.print(" stable="); mLastStableInsets.printShortString(pw);
Filip Gruszczynski2217f612015-05-26 11:32:08 -07003252 pw.print(" physical="); mLastOutsets.printShortString(pw);
3253 pw.print(" outset="); mLastOutsets.printShortString(pw);
Dianne Hackborna44abeb2011-08-08 19:24:01 -07003254 pw.println();
3255 }
Dianne Hackborn529e7442012-11-01 14:22:28 -07003256 pw.print(prefix); pw.print(mWinAnimator); pw.println(":");
3257 mWinAnimator.dump(pw, prefix + " ", dumpAll);
Wale Ogunwalec48a3542016-02-19 15:18:45 -08003258 if (mAnimatingExit || mRemoveOnExit || mDestroying || mRemoved) {
3259 pw.print(prefix); pw.print("mAnimatingExit="); pw.print(mAnimatingExit);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003260 pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
3261 pw.print(" mDestroying="); pw.print(mDestroying);
3262 pw.print(" mRemoved="); pw.println(mRemoved);
3263 }
3264 if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
3265 pw.print(prefix); pw.print("mOrientationChanging=");
3266 pw.print(mOrientationChanging);
3267 pw.print(" mAppFreezing="); pw.print(mAppFreezing);
3268 pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
3269 }
Dianne Hackborna57c6952013-03-29 14:46:40 -07003270 if (mLastFreezeDuration != 0) {
3271 pw.print(prefix); pw.print("mLastFreezeDuration=");
3272 TimeUtils.formatDuration(mLastFreezeDuration, pw); pw.println();
3273 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003274 if (mHScale != 1 || mVScale != 1) {
3275 pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
3276 pw.print(" mVScale="); pw.println(mVScale);
3277 }
3278 if (mWallpaperX != -1 || mWallpaperY != -1) {
3279 pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
3280 pw.print(" mWallpaperY="); pw.println(mWallpaperY);
3281 }
3282 if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
3283 pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
3284 pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
3285 }
Dianne Hackborn067e5f62014-09-07 23:14:30 -07003286 if (mWallpaperDisplayOffsetX != Integer.MIN_VALUE
3287 || mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
3288 pw.print(prefix); pw.print("mWallpaperDisplayOffsetX=");
3289 pw.print(mWallpaperDisplayOffsetX);
3290 pw.print(" mWallpaperDisplayOffsetY=");
3291 pw.println(mWallpaperDisplayOffsetY);
3292 }
Jeff Brownc2932a12014-11-20 18:04:05 -08003293 if (mDrawLock != null) {
Wale Ogunwale85b90ab2015-04-27 20:54:47 -07003294 pw.print(prefix); pw.println("mDrawLock=" + mDrawLock);
Jeff Brownc2932a12014-11-20 18:04:05 -08003295 }
Jorim Jaggi9511b0f2016-01-29 19:12:44 -08003296 if (isDragResizing()) {
3297 pw.print(prefix); pw.println("isDragResizing=" + isDragResizing());
3298 }
3299 if (computeDragResizing()) {
3300 pw.print(prefix); pw.println("computeDragResizing=" + computeDragResizing());
3301 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003302 }
Craig Mautner164d4bb2012-11-26 13:51:23 -08003303
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003304 String makeInputChannelName() {
3305 return Integer.toHexString(System.identityHashCode(this))
Wale Ogunwalecad05a02015-09-25 10:41:44 -07003306 + " " + getWindowTag();
3307 }
3308
Robert Carra1eb4392015-12-10 12:43:51 -08003309 CharSequence getWindowTag() {
Wale Ogunwalecad05a02015-09-25 10:41:44 -07003310 CharSequence tag = mAttrs.getTitle();
3311 if (tag == null || tag.length() <= 0) {
3312 tag = mAttrs.packageName;
3313 }
3314 return tag;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003315 }
3316
3317 @Override
3318 public String toString() {
Wale Ogunwalecad05a02015-09-25 10:41:44 -07003319 final CharSequence title = getWindowTag();
Wale Ogunwalec48a3542016-02-19 15:18:45 -08003320 if (mStringNameCache == null || mLastTitle != title || mWasExiting != mAnimatingExit) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08003321 mLastTitle = title;
Wale Ogunwalec48a3542016-02-19 15:18:45 -08003322 mWasExiting = mAnimatingExit;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003323 mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this))
Wale Ogunwalee4343ef2016-07-19 08:00:46 -07003324 + " u" + UserHandle.getUserId(mOwnerUid)
Wale Ogunwalec48a3542016-02-19 15:18:45 -08003325 + " " + mLastTitle + (mAnimatingExit ? " EXITING}" : "}");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08003326 }
3327 return mStringNameCache;
3328 }
Robert Carr58f29132015-10-29 14:19:05 -07003329
Chia-I Wue6bcaf12016-05-27 10:58:48 +08003330 void transformClipRectFromScreenToSurfaceSpace(Rect clipRect) {
Robert Carr58f29132015-10-29 14:19:05 -07003331 if (mHScale >= 0) {
Chia-I Wue6bcaf12016-05-27 10:58:48 +08003332 clipRect.left = (int) (clipRect.left / mHScale);
3333 clipRect.right = (int) Math.ceil(clipRect.right / mHScale);
Robert Carr58f29132015-10-29 14:19:05 -07003334 }
3335 if (mVScale >= 0) {
Chia-I Wue6bcaf12016-05-27 10:58:48 +08003336 clipRect.top = (int) (clipRect.top / mVScale);
3337 clipRect.bottom = (int) Math.ceil(clipRect.bottom / mVScale);
Robert Carr58f29132015-10-29 14:19:05 -07003338 }
3339 }
Robert Carr31e28482015-12-02 16:53:18 -08003340
Jorim Jaggif5834272016-04-04 20:25:41 -07003341 void applyGravityAndUpdateFrame(Rect containingFrame, Rect displayFrame) {
3342 final int pw = containingFrame.width();
3343 final int ph = containingFrame.height();
Robert Carr31e28482015-12-02 16:53:18 -08003344 final Task task = getTask();
Andrii Kulian933076d2016-03-29 17:04:42 -07003345 final boolean nonFullscreenTask = isInMultiWindowMode();
Jorim Jaggi5f23a572016-04-22 15:05:50 -07003346 final boolean noLimits = (mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) != 0;
3347
3348 // We need to fit it to the display if either
3349 // a) The task is fullscreen, or we don't have a task (we assume fullscreen for the taskless
3350 // windows)
Robert Carr6f44db12016-07-21 14:54:43 -07003351 // b) If it's a secondary app window, we also need to fit it to the display unless
3352 // FLAG_LAYOUT_NO_LIMITS is set. This is so we place Popups, dialogs, and similar windows on screen,
Jorim Jaggi5f23a572016-04-22 15:05:50 -07003353 // but SurfaceViews want to be always at a specific location so we don't fit it to the
3354 // display.
3355 final boolean fitToDisplay = (task == null || !nonFullscreenTask)
Robert Carr6f44db12016-07-21 14:54:43 -07003356 || ((mAttrs.type != TYPE_BASE_APPLICATION) && !noLimits);
Robert Carr31e28482015-12-02 16:53:18 -08003357 float x, y;
3358 int w,h;
3359
3360 if ((mAttrs.flags & FLAG_SCALED) != 0) {
3361 if (mAttrs.width < 0) {
3362 w = pw;
3363 } else if (mEnforceSizeCompat) {
3364 w = (int)(mAttrs.width * mGlobalScale + .5f);
3365 } else {
3366 w = mAttrs.width;
3367 }
3368 if (mAttrs.height < 0) {
3369 h = ph;
3370 } else if (mEnforceSizeCompat) {
3371 h = (int)(mAttrs.height * mGlobalScale + .5f);
3372 } else {
3373 h = mAttrs.height;
3374 }
3375 } else {
3376 if (mAttrs.width == MATCH_PARENT) {
3377 w = pw;
3378 } else if (mEnforceSizeCompat) {
3379 w = (int)(mRequestedWidth * mGlobalScale + .5f);
3380 } else {
3381 w = mRequestedWidth;
3382 }
3383 if (mAttrs.height == MATCH_PARENT) {
3384 h = ph;
3385 } else if (mEnforceSizeCompat) {
3386 h = (int)(mRequestedHeight * mGlobalScale + .5f);
3387 } else {
3388 h = mRequestedHeight;
3389 }
3390 }
3391
3392 if (mEnforceSizeCompat) {
3393 x = mAttrs.x * mGlobalScale;
3394 y = mAttrs.y * mGlobalScale;
3395 } else {
3396 x = mAttrs.x;
3397 y = mAttrs.y;
3398 }
3399
Robert Carr1d2bacb2016-03-30 14:29:35 -07003400 if (nonFullscreenTask && !layoutInParentFrame()) {
Wale Ogunwale79f268d2015-12-18 08:25:47 -08003401 // Make sure window fits in containing frame since it is in a non-fullscreen task as
Robert Carr31e28482015-12-02 16:53:18 -08003402 // required by {@link Gravity#apply} call.
3403 w = Math.min(w, pw);
3404 h = Math.min(h, ph);
3405 }
3406
3407 // Set mFrame
Jorim Jaggif5834272016-04-04 20:25:41 -07003408 Gravity.apply(mAttrs.gravity, w, h, containingFrame,
Robert Carr31e28482015-12-02 16:53:18 -08003409 (int) (x + mAttrs.horizontalMargin * pw),
3410 (int) (y + mAttrs.verticalMargin * ph), mFrame);
3411
3412 // Now make sure the window fits in the overall display frame.
Robert Carre6275582016-02-29 15:45:45 -08003413 if (fitToDisplay) {
Jorim Jaggif5834272016-04-04 20:25:41 -07003414 Gravity.applyDisplay(mAttrs.gravity, displayFrame, mFrame);
Robert Carre6275582016-02-29 15:45:45 -08003415 }
Robert Carr6e18c5e2016-02-29 15:57:13 -08003416
3417 // We need to make sure we update the CompatFrame as it is used for
3418 // cropping decisions, etc, on systems where we lack a decor layer.
3419 mCompatFrame.set(mFrame);
3420 if (mEnforceSizeCompat) {
3421 // See comparable block in computeFrameLw.
3422 mCompatFrame.scale(mInvGlobalScale);
3423 }
Robert Carr31e28482015-12-02 16:53:18 -08003424 }
Robert Carr51a1b872015-12-08 14:03:13 -08003425
3426 boolean isChildWindow() {
Wale Ogunwalee4343ef2016-07-19 08:00:46 -07003427 return mIsChildWindow;
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07003428 }
3429
3430 /**
3431 * Returns the bottom child window in regards to z-order of this window or null if no children.
3432 */
3433 WindowState getBottomChild() {
3434 // Child windows are z-ordered based on sub-layer using {@link #sWindowSubLayerComparator}
3435 // and the child with the lowest z-order will be at the head of the list.
Wale Ogunwale9bc47732016-08-10 14:44:22 -07003436 WindowContainer c = mChildren.peekFirst();
3437 return c == null ? null : (WindowState)c;
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07003438 }
3439
Robert Carrf3b72c72016-03-21 18:16:39 -07003440 boolean layoutInParentFrame() {
Wale Ogunwalee4343ef2016-07-19 08:00:46 -07003441 return mIsChildWindow
3442 && (mAttrs.privateFlags & PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME) != 0;
Robert Carrf3b72c72016-03-21 18:16:39 -07003443 }
3444
Wale Ogunwalecaa53af2016-07-17 14:50:26 -07003445 /** Returns the parent window if this is a child of another window, else null. */
3446 WindowState getParentWindow() {
Wale Ogunwalee4343ef2016-07-19 08:00:46 -07003447 // NOTE: We are not calling getParent() directly as the WindowState might be a child of a
3448 // WindowContainer that isn't a WindowState.
3449 return (mIsChildWindow) ? ((WindowState) super.getParent()) : null;
Wale Ogunwalecaa53af2016-07-17 14:50:26 -07003450 }
3451
3452 /** Returns the topmost parent window if this is a child of another window, else this. */
3453 WindowState getTopParentWindow() {
3454 WindowState w = this;
Wale Ogunwalea6cc3612016-08-04 07:25:33 -07003455 while (w != null && w.mIsChildWindow) {
Wale Ogunwalecaa53af2016-07-17 14:50:26 -07003456 w = w.getParentWindow();
3457 }
3458 return w;
3459 }
3460
Wale Ogunwale9d147902016-07-16 11:58:55 -07003461 boolean isParentWindowHidden() {
Wale Ogunwalee4343ef2016-07-19 08:00:46 -07003462 final WindowState parent = getParentWindow();
3463 return (parent == null) ? false : parent.mHidden;
Wale Ogunwale9d147902016-07-16 11:58:55 -07003464 }
3465
Wale Ogunwale9bc47732016-08-10 14:44:22 -07003466 void setWillReplaceWindow(boolean animate) {
3467 for (int i = mChildren.size() - 1; i >= 0; i--) {
3468 final WindowState c = (WindowState) mChildren.get(i);
3469 c.setWillReplaceWindow(animate);
3470 }
3471
Wale Ogunwale6d8e06b2016-01-05 10:43:25 -08003472 if ((mAttrs.privateFlags & PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH) != 0
3473 || mAttrs.type == TYPE_APPLICATION_STARTING) {
3474 // We don't set replacing on starting windows since they are added by window manager and
3475 // not the client so won't be replaced by the client.
3476 return;
Robert Carra1eb4392015-12-10 12:43:51 -08003477 }
Wale Ogunwale6d8e06b2016-01-05 10:43:25 -08003478
3479 mWillReplaceWindow = true;
Wale Ogunwale9bc47732016-08-10 14:44:22 -07003480 mReplacementWindow = null;
Wale Ogunwale6d8e06b2016-01-05 10:43:25 -08003481 mAnimateReplacingWindow = animate;
Robert Carra1eb4392015-12-10 12:43:51 -08003482 }
Chong Zhangf596cd52016-01-05 13:42:44 -08003483
Wale Ogunwale9bc47732016-08-10 14:44:22 -07003484 void clearWillReplaceWindow() {
Chong Zhangf596cd52016-01-05 13:42:44 -08003485 mWillReplaceWindow = false;
Wale Ogunwale9bc47732016-08-10 14:44:22 -07003486 mReplacementWindow = null;
Chong Zhangf596cd52016-01-05 13:42:44 -08003487 mAnimateReplacingWindow = false;
Wale Ogunwale9bc47732016-08-10 14:44:22 -07003488
3489 for (int i = mChildren.size() - 1; i >= 0; i--) {
3490 final WindowState c = (WindowState) mChildren.get(i);
3491 c.clearWillReplaceWindow();
3492 }
3493 }
3494
3495 boolean waitingForReplacement() {
3496 if (mWillReplaceWindow) {
3497 return true;
3498 }
3499
3500 for (int i = mChildren.size() - 1; i >= 0; i--) {
3501 final WindowState c = (WindowState) mChildren.get(i);
3502 if (c.waitingForReplacement()) {
3503 return true;
3504 }
3505 }
3506 return false;
Chong Zhangf596cd52016-01-05 13:42:44 -08003507 }
Vladislav Kaznacheev989b58a2016-02-10 12:19:33 -08003508
Chong Zhang4d7369a2016-04-25 16:09:14 -07003509 void requestUpdateWallpaperIfNeeded() {
3510 if (mDisplayContent != null && (mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
3511 mDisplayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
3512 mDisplayContent.layoutNeeded = true;
3513 mService.mWindowPlacerLocked.requestTraversal();
3514 }
Wale Ogunwale9bc47732016-08-10 14:44:22 -07003515
3516 for (int i = mChildren.size() - 1; i >= 0; i--) {
3517 final WindowState c = (WindowState) mChildren.get(i);
3518 c.requestUpdateWallpaperIfNeeded();
3519 }
Chong Zhang4d7369a2016-04-25 16:09:14 -07003520 }
3521
Vladislav Kaznacheev989b58a2016-02-10 12:19:33 -08003522 float translateToWindowX(float x) {
3523 float winX = x - mFrame.left;
3524 if (mEnforceSizeCompat) {
3525 winX *= mGlobalScale;
3526 }
3527 return winX;
3528 }
3529
3530 float translateToWindowY(float y) {
3531 float winY = y - mFrame.top;
3532 if (mEnforceSizeCompat) {
3533 winY *= mGlobalScale;
3534 }
3535 return winY;
3536 }
Robert Carrd1a010f2016-04-07 22:36:22 -07003537
Robert Carr9fe459d2016-04-07 23:32:28 -07003538 void transferDimToReplacement() {
3539 final DimLayer.DimLayerUser dimLayerUser = getDimLayerUser();
3540 if (dimLayerUser != null && mDisplayContent != null) {
3541 mDisplayContent.mDimLayerController.applyDim(dimLayerUser,
Wale Ogunwale9bc47732016-08-10 14:44:22 -07003542 mReplacementWindow.mWinAnimator,
Robert Carr9fe459d2016-04-07 23:32:28 -07003543 (mAttrs.flags & FLAG_DIM_BEHIND) != 0 ? true : false);
3544 }
3545 }
3546
Robert Carrd1a010f2016-04-07 22:36:22 -07003547 // During activity relaunch due to resize, we sometimes use window replacement
3548 // for only child windows (as the main window is handled by window preservation)
3549 // and the big surface.
3550 //
Chong Zhangfea963e2016-08-15 17:14:16 -07003551 // Though windows of TYPE_APPLICATION or TYPE_DRAWN_APPLICATION (as opposed to
3552 // TYPE_BASE_APPLICATION) are not children in the sense of an attached window,
3553 // we also want to replace them at such phases, as they won't be covered by window
3554 // preservation, and in general we expect them to return following relaunch.
Robert Carrd1a010f2016-04-07 22:36:22 -07003555 boolean shouldBeReplacedWithChildren() {
Chong Zhang921f8e32016-08-17 14:26:57 -07003556 return mIsChildWindow || mAttrs.type == TYPE_APPLICATION
Chong Zhangfea963e2016-08-15 17:14:16 -07003557 || mAttrs.type == TYPE_DRAWN_APPLICATION;
Robert Carrd1a010f2016-04-07 22:36:22 -07003558 }
Robert Carrfd10cd12016-06-29 16:41:50 -07003559
Wale Ogunwale9bc47732016-08-10 14:44:22 -07003560 void setWillReplaceChildWindows() {
3561 if (shouldBeReplacedWithChildren()) {
3562 setWillReplaceWindow(false /* animate */);
3563 }
3564 for (int i = mChildren.size() - 1; i >= 0; i--) {
3565 final WindowState c = (WindowState) mChildren.get(i);
3566 c.setWillReplaceChildWindows();
3567 }
3568 }
3569
3570 WindowState getReplacingWindow() {
3571 if (mAnimatingExit && mWillReplaceWindow && mAnimateReplacingWindow) {
3572 return this;
3573 }
3574 for (int i = mChildren.size() - 1; i >= 0; i--) {
3575 final WindowState c = (WindowState) mChildren.get(i);
3576 final WindowState replacing = c.getReplacingWindow();
3577 if (replacing != null) {
3578 return replacing;
3579 }
3580 }
3581 return null;
3582 }
3583
Robert Carrfd10cd12016-06-29 16:41:50 -07003584 public int getRotationAnimationHint() {
3585 if (mAppToken != null) {
3586 return mAppToken.mRotationAnimationHint;
3587 } else {
3588 return -1;
3589 }
3590 }
Wale Ogunwale9d147902016-07-16 11:58:55 -07003591
3592 // This must be called while inside a transaction.
3593 boolean performShowLocked() {
3594 if (isHiddenFromUserLocked()) {
3595 if (DEBUG_VISIBILITY) Slog.w(TAG, "hiding " + this + ", belonging to " + mOwnerUid);
3596 hideLw(false);
3597 return false;
3598 }
3599
3600 logPerformShow("performShow on ");
3601
3602 if (mWinAnimator.mDrawState != READY_TO_SHOW || !isReadyForDisplayIgnoringKeyguard()) {
3603 return false;
3604 }
3605
3606 logPerformShow("Showing ");
3607
3608 mService.enableScreenIfNeededLocked();
3609 mWinAnimator.applyEnterAnimationLocked();
3610
3611 // Force the show in the next prepareSurfaceLocked() call.
3612 mWinAnimator.mLastAlpha = -1;
3613 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM) Slog.v(TAG,
3614 "performShowLocked: mDrawState=HAS_DRAWN in " + this);
3615 mWinAnimator.mDrawState = HAS_DRAWN;
3616 mService.scheduleAnimationLocked();
3617
3618 if (mHidden) {
3619 mHidden = false;
3620 final DisplayContent displayContent = getDisplayContent();
3621
Wale Ogunwalee4343ef2016-07-19 08:00:46 -07003622 for (int i = mChildren.size() - 1; i >= 0; --i) {
3623 final WindowState c = (WindowState) mChildren.get(i);
Wale Ogunwale9d147902016-07-16 11:58:55 -07003624 if (c.mWinAnimator.mSurfaceController != null) {
3625 c.performShowLocked();
3626 // It hadn't been shown, which means layout not performed on it, so now we
3627 // want to make sure to do a layout. If called from within the transaction
3628 // loop, this will cause it to restart with a new layout.
3629 if (displayContent != null) {
3630 displayContent.layoutNeeded = true;
3631 }
3632 }
3633 }
3634 }
3635
3636 if (mAttrs.type != TYPE_APPLICATION_STARTING && mAppToken != null) {
3637 mAppToken.onFirstWindowDrawn(this, mWinAnimator);
3638 }
3639
3640 if (mAttrs.type == TYPE_INPUT_METHOD) {
3641 mDisplayContent.mDividerControllerLocked.resetImeHideRequested();
3642 }
3643
3644 return true;
3645 }
3646
3647 void logPerformShow(String prefix) {
3648 if (DEBUG_VISIBILITY
3649 || (DEBUG_STARTING_WINDOW && mAttrs.type == TYPE_APPLICATION_STARTING)) {
3650 Slog.v(TAG, prefix + this
3651 + ": mDrawState=" + mWinAnimator.drawStateToString()
3652 + " readyForDisplay=" + isReadyForDisplayIgnoringKeyguard()
3653 + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING)
3654 + " during animation: policyVis=" + mPolicyVisibility
3655 + " parentHidden=" + isParentWindowHidden()
3656 + " tok.hiddenRequested="
3657 + (mAppToken != null ? mAppToken.hiddenRequested : false)
3658 + " tok.hidden=" + (mAppToken != null ? mAppToken.hidden : false)
3659 + " animating=" + mWinAnimator.mAnimating
3660 + " tok animating="
3661 + (mWinAnimator.mAppAnimator != null ? mWinAnimator.mAppAnimator.animating : false)
3662 + " Callers=" + Debug.getCallers(4));
3663 }
3664 }
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07003665
3666 WindowInfo getWindowInfo() {
3667 WindowInfo windowInfo = WindowInfo.obtain();
3668 windowInfo.type = mAttrs.type;
3669 windowInfo.layer = mLayer;
3670 windowInfo.token = mClient.asBinder();
3671 windowInfo.title = mAttrs.accessibilityTitle;
3672 windowInfo.accessibilityIdOfAnchor = mAttrs.accessibilityIdOfAnchor;
3673 windowInfo.focused = isFocused();
3674
Wale Ogunwalee4343ef2016-07-19 08:00:46 -07003675 if (mIsChildWindow) {
3676 windowInfo.parentToken = getParentWindow().mClient.asBinder();
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07003677 }
3678
Wale Ogunwalee4343ef2016-07-19 08:00:46 -07003679 final int childCount = mChildren.size();
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07003680 if (childCount > 0) {
3681 if (windowInfo.childTokens == null) {
Wale Ogunwalee4343ef2016-07-19 08:00:46 -07003682 windowInfo.childTokens = new ArrayList(childCount);
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07003683 }
3684 for (int j = 0; j < childCount; j++) {
Wale Ogunwalee4343ef2016-07-19 08:00:46 -07003685 final WindowState child = (WindowState) mChildren.get(j);
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07003686 windowInfo.childTokens.add(child.mClient.asBinder());
3687 }
3688 }
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07003689 return windowInfo;
3690 }
3691
Wale Ogunwale9bc47732016-08-10 14:44:22 -07003692 int getHighestAnimLayer() {
3693 int highest = mWinAnimator.mAnimLayer;
3694 for (int i = mChildren.size() - 1; i >= 0; i--) {
3695 final WindowState c = (WindowState) mChildren.get(i);
3696 final int childLayer = c.getHighestAnimLayer();
3697 if (childLayer > highest) {
3698 highest = childLayer;
3699 }
3700 }
3701 return highest;
3702 }
3703
3704 int adjustAnimLayer(int adj) {
3705 int highestAnimLayer = mWinAnimator.mAnimLayer = mLayer + adj;
3706 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG_WM,
3707 "adjustAnimLayer win=" + this + " anim layer: " + mWinAnimator.mAnimLayer);
Wale Ogunwalee4343ef2016-07-19 08:00:46 -07003708 for (int i = mChildren.size() - 1; i >= 0; i--) {
3709 final WindowState childWindow = (WindowState) mChildren.get(i);
3710 childWindow.adjustAnimLayer(adj);
Wale Ogunwale9bc47732016-08-10 14:44:22 -07003711 if (childWindow.mWinAnimator.mAnimLayer > highestAnimLayer) {
3712 highestAnimLayer = childWindow.mWinAnimator.mAnimLayer;
3713 }
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07003714 }
Wale Ogunwale9bc47732016-08-10 14:44:22 -07003715 return highestAnimLayer;
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07003716 }
3717
3718 // TODO: come-up with a better name for this method that represents what it does.
3719 // Or, it is probably not going to matter anyways if we are successful in getting rid of
3720 // the WindowList concept.
Wale Ogunwale92fc3722016-08-05 12:19:08 -07003721 int reAddWindow(int index) {
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07003722 final WindowList windows = getWindowList();
3723 // Adding child windows relies on child windows being ordered by mSubLayer using
3724 // {@link #sWindowSubLayerComparator}.
Wale Ogunwalee4343ef2016-07-19 08:00:46 -07003725 final int childCount = mChildren.size();
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07003726 boolean winAdded = false;
3727 for (int j = 0; j < childCount; j++) {
Wale Ogunwalee4343ef2016-07-19 08:00:46 -07003728 final WindowState child = (WindowState) mChildren.get(j);
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07003729 if (!winAdded && child.mSubLayer >= 0) {
3730 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM,
3731 "Re-adding child window at " + index + ": " + child);
3732 mRebuilding = false;
3733 windows.add(index, this);
3734 index++;
3735 winAdded = true;
3736 }
3737 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Re-adding window at " + index + ": " + child);
3738 child.mRebuilding = false;
3739 windows.add(index, child);
3740 index++;
3741 }
3742 if (!winAdded) {
3743 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Re-adding window at " + index + ": " + this);
3744 mRebuilding = false;
3745 windows.add(index, this);
3746 index++;
3747 }
3748 mService.mWindowsChanged = true;
3749 return index;
3750 }
3751
3752 int removeFromWindowList(int interestingPos) {
3753 final WindowList windows = getWindowList();
3754 int wpos = windows.indexOf(this);
3755 if (wpos < 0) {
3756 return interestingPos;
3757 }
3758
3759 if (wpos < interestingPos) interestingPos--;
3760 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Temp removing at " + wpos + ": " + this);
3761 windows.remove(wpos);
3762 mService.mWindowsChanged = true;
Wale Ogunwalee4343ef2016-07-19 08:00:46 -07003763 int childCount = mChildren.size();
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07003764 while (childCount > 0) {
3765 childCount--;
Wale Ogunwalee4343ef2016-07-19 08:00:46 -07003766 final WindowState cw = (WindowState) mChildren.get(childCount);
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07003767 int cpos = windows.indexOf(cw);
3768 if (cpos >= 0) {
3769 if (cpos < interestingPos) interestingPos--;
3770 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM,
3771 "Temp removing child at " + cpos + ": " + cw);
3772 windows.remove(cpos);
3773 }
3774 }
3775 return interestingPos;
3776 }
3777
Wale Ogunwale9bc47732016-08-10 14:44:22 -07003778 boolean isWindowAnimationSet() {
3779 if (mWinAnimator.isWindowAnimationSet()) {
3780 return true;
3781 }
3782 for (int i = mChildren.size() - 1; i >= 0; --i) {
3783 final WindowState c = (WindowState) mChildren.get(i);
3784 if (c.isWindowAnimationSet()) {
3785 return true;
3786 }
3787 }
3788 return false;
3789 }
3790
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07003791 void onExitAnimationDone() {
3792 if (DEBUG_ANIM) Slog.v(TAG, "onExitAnimationDone in " + this
3793 + ": exiting=" + mAnimatingExit + " remove=" + mRemoveOnExit
3794 + " windowAnimating=" + mWinAnimator.isWindowAnimationSet());
3795
Wale Ogunwalee4343ef2016-07-19 08:00:46 -07003796 if (!mChildren.isEmpty()) {
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07003797 // Copying to a different list as multiple children can be removed.
Wale Ogunwalee4343ef2016-07-19 08:00:46 -07003798 // TODO: Not sure if we really need to copy this into a different list.
3799 final LinkedList childWindows = new LinkedList(mChildren);
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07003800 for (int i = childWindows.size() - 1; i >= 0; i--) {
Wale Ogunwalee4343ef2016-07-19 08:00:46 -07003801 ((WindowState)childWindows.get(i)).onExitAnimationDone();
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07003802 }
3803 }
3804
3805 if (mWinAnimator.mEnteringAnimation) {
3806 mWinAnimator.mEnteringAnimation = false;
3807 mService.requestTraversal();
3808 // System windows don't have an activity and an app token as a result, but need a way
3809 // to be informed about their entrance animation end.
3810 if (mAppToken == null) {
3811 try {
3812 mClient.dispatchWindowShown();
3813 } catch (RemoteException e) {
3814 }
3815 }
3816 }
3817
3818 if (!mWinAnimator.isWindowAnimationSet()) {
3819 //TODO (multidisplay): Accessibility is supported only for the default display.
3820 if (mService.mAccessibilityController != null && getDisplayId() == DEFAULT_DISPLAY) {
3821 mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
3822 }
3823 }
3824
3825 if (!mAnimatingExit) {
3826 return;
3827 }
3828
3829 if (mWinAnimator.isWindowAnimationSet()) {
3830 return;
3831 }
3832
Wale Ogunwale9f25bee2016-08-02 07:23:47 -07003833 if (localLOGV || DEBUG_ADD_REMOVE) Slog.v(TAG,
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07003834 "Exit animation finished in " + this + ": remove=" + mRemoveOnExit);
3835
3836 mDestroying = true;
3837
3838 final boolean hasSurface = mWinAnimator.hasSurface();
3839 if (hasSurface) {
3840 mWinAnimator.hide("onExitAnimationDone");
3841 }
3842
3843 // If we have an app token, we ask it to destroy the surface for us, so that it can take
3844 // care to ensure the activity has actually stopped and the surface is not still in use.
3845 // Otherwise we add the service to mDestroySurface and allow it to be processed in our next
3846 // transaction.
3847 if (mAppToken != null) {
3848 mAppToken.destroySurfaces();
3849 } else {
3850 if (hasSurface) {
3851 mService.mDestroySurface.add(this);
3852 }
3853 if (mRemoveOnExit) {
3854 mService.mPendingRemove.add(this);
3855 mRemoveOnExit = false;
3856 }
3857 }
3858 mAnimatingExit = false;
3859 mService.mWallpaperControllerLocked.hideWallpapers(this);
3860 }
Dan Willemsen117197f2016-07-30 13:02:59 -07003861
Wale Ogunwale9bc47732016-08-10 14:44:22 -07003862 boolean clearAnimatingFlags() {
3863 boolean didSomething = false;
3864 // We don't want to clear it out for windows that get replaced, because the
3865 // animation depends on the flag to remove the replaced window.
3866 //
3867 // We also don't clear the mAnimatingExit flag for windows which have the
3868 // mRemoveOnExit flag. This indicates an explicit remove request has been issued
3869 // by the client. We should let animation proceed and not clear this flag or
3870 // they won't eventually be removed by WindowStateAnimator#finishExit.
3871 if (!mWillReplaceWindow && !mRemoveOnExit) {
3872 // Clear mAnimating flag together with mAnimatingExit. When animation
3873 // changes from exiting to entering, we need to clear this flag until the
3874 // new animation gets applied, so that isAnimationStarting() becomes true
3875 // until then.
3876 // Otherwise applySurfaceChangesTransaction will fail to skip surface
3877 // placement for this window during this period, one or more frame will
3878 // show up with wrong position or scale.
3879 if (mAnimatingExit) {
3880 mAnimatingExit = false;
3881 didSomething = true;
3882 }
3883 if (mWinAnimator.mAnimating) {
3884 mWinAnimator.mAnimating = false;
3885 didSomething = true;
3886 }
3887 if (mDestroying) {
3888 mDestroying = false;
3889 mService.mDestroySurface.remove(this);
3890 didSomething = true;
3891 }
3892 }
3893
3894 for (int i = mChildren.size() - 1; i >= 0; --i) {
3895 didSomething |= ((WindowState) mChildren.get(i)).clearAnimatingFlags();
3896 }
3897
3898 return didSomething;
3899 }
3900
Winson4b4ba902016-07-27 19:45:52 -07003901 public boolean isRtl() {
3902 return mMergedConfiguration.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
3903 }
Wale Ogunwalee4da0c12016-07-29 12:47:02 -07003904
3905 void hideWallpaperWindow(boolean wasDeferred, String reason) {
Wale Ogunwale9bc47732016-08-10 14:44:22 -07003906 for (int j = mChildren.size() - 1; j >= 0; --j) {
3907 final WindowState c = (WindowState) mChildren.get(j);
3908 c.hideWallpaperWindow(wasDeferred, reason);
3909 }
Wale Ogunwalee4da0c12016-07-29 12:47:02 -07003910 if (!mWinAnimator.mLastHidden || wasDeferred) {
3911 mWinAnimator.hide(reason);
3912 dispatchWallpaperVisibility(false);
3913 final DisplayContent displayContent = getDisplayContent();
3914 if (displayContent != null) {
3915 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
3916 }
3917 }
3918 }
3919
3920 /**
3921 * Check wallpaper window for visibility change and notify window if so.
3922 * @param visible Current visibility.
3923 */
3924 void dispatchWallpaperVisibility(final boolean visible) {
3925 final boolean hideAllowed =
3926 mService.mWallpaperControllerLocked.mDeferredHideWallpaper == null;
3927
3928 // Only send notification if the visibility actually changed and we are not trying to hide
3929 // the wallpaper when we are deferring hiding of the wallpaper.
3930 if (mWallpaperVisible != visible && (hideAllowed || visible)) {
3931 mWallpaperVisible = visible;
3932 try {
3933 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
3934 "Updating vis of wallpaper " + this
3935 + ": " + visible + " from:\n" + Debug.getCallers(4, " "));
3936 mClient.dispatchAppVisibility(visible);
3937 } catch (RemoteException e) {
3938 }
3939 }
3940 }
3941
Wale Ogunwale9bc47732016-08-10 14:44:22 -07003942 boolean hasVisibleNotDrawnWallpaper() {
3943 if (mWallpaperVisible && !isDrawnLw()) {
3944 return true;
3945 }
3946 for (int j = mChildren.size() - 1; j >= 0; --j) {
3947 final WindowState c = (WindowState) mChildren.get(j);
3948 if (c.hasVisibleNotDrawnWallpaper()) {
3949 return true;
3950 }
3951 }
3952 return false;
3953 }
3954
Wale Ogunwalee4da0c12016-07-29 12:47:02 -07003955 /** Places this window after the input window in the window list. */
3956 void addWindowToListAfter(WindowState pos) {
3957 final WindowList windows = pos.getWindowList();
3958 final int i = windows.indexOf(pos);
3959 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
3960 "Adding window " + this + " at " + (i+1) + " of " + windows.size()
3961 + " (after " + pos + ")");
3962 windows.add(i+1, this);
3963 mService.mWindowsChanged = true;
3964 }
3965
3966 /** Places this window before the input window in the window list. */
3967 void addWindowToListBefore(WindowState pos) {
3968 final WindowList windows = pos.getWindowList();
3969 int i = windows.indexOf(pos);
3970 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
3971 "Adding window " + this + " at " + i + " of " + windows.size()
3972 + " (before " + pos + ")");
3973 if (i < 0) {
3974 Slog.w(TAG_WM, "addWindowToListBefore: Unable to find " + pos + " in " + windows);
3975 i = 0;
3976 }
3977 windows.add(i, this);
3978 mService.mWindowsChanged = true;
3979 }
3980
3981 /** Adds this non-app window to the window list. */
3982 void addNonAppWindowToList() {
3983 final WindowList windows = getWindowList();
3984
3985 // Figure out where window should go, based on layer.
3986 int i;
3987 for (i = windows.size() - 1; i >= 0; i--) {
3988 final WindowState otherWin = windows.get(i);
3989 if (otherWin.getBaseType() != TYPE_WALLPAPER && otherWin.mBaseLayer <= mBaseLayer) {
3990 // Wallpaper wanders through the window list, for example to position itself
3991 // directly behind keyguard. Because of this it will break the ordering based on
3992 // WindowState.mBaseLayer. There might windows with higher mBaseLayer behind it and
3993 // we don't want the new window to appear above them. An example of this is adding
3994 // of the docked stack divider. Consider a scenario with the following ordering (top
3995 // to bottom): keyguard, wallpaper, assist preview, apps. We want the dock divider
3996 // to land below the assist preview, so the dock divider must ignore the wallpaper,
3997 // with which it shares the base layer.
3998 break;
3999 }
4000 }
4001
4002 i++;
4003 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
4004 "Free window: Adding window " + this + " at " + i + " of " + windows.size());
4005 windows.add(i, this);
4006 mService.mWindowsChanged = true;
4007 }
Wale Ogunwale9bc47732016-08-10 14:44:22 -07004008
4009 void updateReportedVisibility(UpdateReportedVisibilityResults results) {
4010 for (int i = mChildren.size() - 1; i >= 0; --i) {
4011 final WindowState c = (WindowState) mChildren.get(i);
4012 c.updateReportedVisibility(results);
4013 }
4014
4015 if (mAppFreezing || mViewVisibility != View.VISIBLE
4016 || mAttrs.type == TYPE_APPLICATION_STARTING
4017 || mDestroying) {
4018 return;
4019 }
4020 if (DEBUG_VISIBILITY) {
4021 Slog.v(TAG, "Win " + this + ": isDrawn=" + isDrawnLw()
4022 + ", isAnimationSet=" + mWinAnimator.isAnimationSet());
4023 if (!isDrawnLw()) {
4024 Slog.v(TAG, "Not displayed: s=" + mWinAnimator.mSurfaceController
4025 + " pv=" + mPolicyVisibility
4026 + " mDrawState=" + mWinAnimator.mDrawState
4027 + " ph=" + isParentWindowHidden()
4028 + " th=" + (mAppToken != null ? mAppToken.hiddenRequested : false)
4029 + " a=" + mWinAnimator.mAnimating);
4030 }
4031 }
4032
4033 results.numInteresting++;
4034 if (isDrawnLw()) {
4035 results.numDrawn++;
4036 if (!mWinAnimator.isAnimationSet()) {
4037 results.numVisible++;
4038 }
4039 results.nowGone = false;
4040 } else if (mWinAnimator.isAnimationSet()) {
4041 results.nowGone = false;
4042 }
4043 }
4044
4045 // TODO: Hack to work around the number of states AppWindowToken needs to access without having
4046 // access to its windows children. Need to investigate re-writing
4047 // {@link AppWindowToken#updateReportedVisibilityLocked} so this can be removed.
4048 static final class UpdateReportedVisibilityResults {
4049 int numInteresting;
4050 int numVisible;
4051 int numDrawn;
4052 boolean nowGone = true;
4053
4054 void reset() {
4055 numInteresting = 0;
4056 numVisible = 0;
4057 numDrawn = 0;
4058 nowGone = true;
4059 }
4060 }
satokcef37fb2011-10-24 21:49:38 +09004061}