blob: 7299bdf2940245ba65ac913199d4055477292805 [file] [log] [blame]
Craig Mautner59c00972012-07-30 12:10:24 -07001/*
2 * Copyright (C) 2012 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 Ogunwale3797c222015-10-27 14:21:58 -070019import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
Wale Ogunwale51362492016-09-08 17:49:17 -070020import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
Wale Ogunwale3797c222015-10-27 14:21:58 -070021import static android.app.ActivityManager.StackId.HOME_STACK_ID;
22import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
Wale Ogunwalea77e1462016-09-28 10:09:46 -070023import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
Wale Ogunwale51362492016-09-08 17:49:17 -070024import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
25import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
Wale Ogunwale19e452e2016-10-12 12:36:29 -070026import static android.view.Display.DEFAULT_DISPLAY;
27import static android.view.Display.FLAG_PRIVATE;
Andrii Kulian4dfb9c42016-10-11 20:06:27 -070028import static android.view.Surface.ROTATION_0;
29import static android.view.Surface.ROTATION_180;
30import static android.view.Surface.ROTATION_270;
31import static android.view.Surface.ROTATION_90;
Wale Ogunwale10124582016-09-15 20:25:50 -070032import static android.view.WindowManager.DOCKED_BOTTOM;
33import static android.view.WindowManager.DOCKED_INVALID;
34import static android.view.WindowManager.DOCKED_TOP;
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -080035import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
36import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
37import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -070038import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
Wale Ogunwaleec731152016-09-08 20:18:57 -070039import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
40import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
Svetoslav Ganovaa076532016-08-01 19:16:43 -070041import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
Wale Ogunwaleec731152016-09-08 20:18:57 -070042import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
43import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
Wale Ogunwale10124582016-09-15 20:25:50 -070044import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -070045import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
46import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
Wale Ogunwalec69694a2016-10-18 13:51:15 -070047import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -070048import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
Wale Ogunwaleec731152016-09-08 20:18:57 -070049import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080050import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
Wale Ogunwale51362492016-09-08 17:49:17 -070051import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080052import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -070053import static com.android.server.wm.WindowManagerService.H.WINDOW_HIDE_TIMEOUT;
Wale Ogunwale19e452e2016-10-12 12:36:29 -070054import static com.android.server.wm.WindowManagerService.dipToPixel;
55import static com.android.server.wm.WindowManagerService.localLOGV;
Wale Ogunwale231b06e2015-09-16 12:03:09 -070056import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP;
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -070057
Andrii Kulian3a507b52016-09-19 18:14:12 -070058import android.annotation.NonNull;
Wale Ogunwale3797c222015-10-27 14:21:58 -070059import android.app.ActivityManager.StackId;
Andrii Kulian441e4492016-09-29 15:25:00 -070060import android.content.res.Configuration;
Andrii Kulian4dfb9c42016-10-11 20:06:27 -070061import android.graphics.Matrix;
Craig Mautnerc00204b2013-03-05 15:02:14 -080062import android.graphics.Rect;
Andrii Kulian4dfb9c42016-10-11 20:06:27 -070063import android.graphics.RectF;
Craig Mautner6601b7b2013-04-29 10:29:11 -070064import android.graphics.Region;
Jorim Jaggid47e7e12016-03-01 09:57:38 +010065import android.graphics.Region.Op;
Wale Ogunwaleb699ce02016-07-18 12:05:30 -070066import android.hardware.display.DisplayManagerInternal;
Wale Ogunwale9adfe572016-09-08 20:43:58 -070067import android.os.Debug;
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -070068import android.os.Handler;
Wale Ogunwale02319a62016-09-26 15:21:22 -070069import android.os.IBinder;
Chong Zhang8e89b312015-09-09 15:09:30 -070070import android.util.DisplayMetrics;
Craig Mautnerde4ef022013-04-07 19:01:33 -070071import android.util.Slog;
Craig Mautnerb47bbc32012-08-22 17:41:48 -070072import android.view.Display;
Craig Mautner59c00972012-07-30 12:10:24 -070073import android.view.DisplayInfo;
Wale Ogunwaleec731152016-09-08 20:18:57 -070074import android.view.IWindow;
Wale Ogunwale19e452e2016-10-12 12:36:29 -070075
Wale Ogunwale9adfe572016-09-08 20:43:58 -070076import com.android.internal.util.FastPrintWriter;
Craig Mautner59c00972012-07-30 12:10:24 -070077
Robert Carr3b716242016-08-16 16:02:21 -070078import java.io.FileDescriptor;
Craig Mautner59c00972012-07-30 12:10:24 -070079import java.io.PrintWriter;
Wale Ogunwale9adfe572016-09-08 20:43:58 -070080import java.io.StringWriter;
Craig Mautner59c00972012-07-30 12:10:24 -070081import java.util.ArrayList;
Wale Ogunwale9adfe572016-09-08 20:43:58 -070082import java.util.Arrays;
Wale Ogunwale19e452e2016-10-12 12:36:29 -070083import java.util.Comparator;
Wale Ogunwale02319a62016-09-26 15:21:22 -070084import java.util.HashMap;
85import java.util.Iterator;
Andrii Kulian3a507b52016-09-19 18:14:12 -070086import java.util.List;
Craig Mautner59c00972012-07-30 12:10:24 -070087
Craig Mautner59c00972012-07-30 12:10:24 -070088/**
89 * Utility class for keeping track of the WindowStates and other pertinent contents of a
90 * particular Display.
91 *
92 * IMPORTANT: No method from this class should ever be used without holding
93 * WindowManagerService.mWindowMap.
94 */
Wale Ogunwale19e452e2016-10-12 12:36:29 -070095class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowContainer> {
Craig Mautner59c00972012-07-30 12:10:24 -070096
97 /** Unique identifier of this stack. */
98 private final int mDisplayId;
99
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700100 // The display only has 2 child window containers. mTaskStackContainers which contains all
101 // window containers that are related to apps (Activities) and mNonAppWindowContainers which
102 // contains all window containers not related to apps (e.g. Status bar).
103 private final TaskStackContainers mTaskStackContainers = new TaskStackContainers();
104 private final NonAppWindowContainers mNonAppWindowContainers = new NonAppWindowContainers();
105
Craig Mautner59c00972012-07-30 12:10:24 -0700106 /** Z-ordered (bottom-most first) list of all Window objects. Assigned to an element
107 * from mDisplayWindows; */
Craig Mautnerdc548482014-02-05 13:35:24 -0800108 private final WindowList mWindows = new WindowList();
Craig Mautner59c00972012-07-30 12:10:24 -0700109
Wale Ogunwale02319a62016-09-26 15:21:22 -0700110 // Mapping from a token IBinder to a WindowToken object on this display.
111 private final HashMap<IBinder, WindowToken> mTokenMap = new HashMap();
112
Craig Mautner59c00972012-07-30 12:10:24 -0700113 int mInitialDisplayWidth = 0;
114 int mInitialDisplayHeight = 0;
Dianne Hackborndde331c2012-08-03 14:01:57 -0700115 int mInitialDisplayDensity = 0;
Craig Mautner59c00972012-07-30 12:10:24 -0700116 int mBaseDisplayWidth = 0;
117 int mBaseDisplayHeight = 0;
Dianne Hackborndde331c2012-08-03 14:01:57 -0700118 int mBaseDisplayDensity = 0;
Jeff Brownd46747a2015-04-15 19:02:36 -0700119 boolean mDisplayScalingDisabled;
Craig Mautner2d5618c2012-10-18 13:55:47 -0700120 private final DisplayInfo mDisplayInfo = new DisplayInfo();
121 private final Display mDisplay;
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700122 private final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Craig Mautner59c00972012-07-30 12:10:24 -0700123
Craig Mautner6601b7b2013-04-29 10:29:11 -0700124 Rect mBaseDisplayRect = new Rect();
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700125 private Rect mContentRect = new Rect();
Craig Mautner6601b7b2013-04-29 10:29:11 -0700126
Craig Mautner39834192012-09-02 07:47:24 -0700127 // Accessed directly by all users.
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700128 private boolean mLayoutNeeded;
Craig Mautner76a71652012-09-03 23:23:58 -0700129 int pendingLayoutChanges;
Craig Mautner69b08182012-09-05 13:07:13 -0700130 final boolean isDefaultDisplay;
Craig Mautner39834192012-09-02 07:47:24 -0700131
Craig Mautnerdc548482014-02-05 13:35:24 -0800132 /** Window tokens that are in the process of exiting, but still on screen for animations. */
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700133 final ArrayList<WindowToken> mExitingTokens = new ArrayList<>();
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800134
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800135 /** A special TaskStack with id==HOME_STACK_ID that moves to the bottom whenever any TaskStack
136 * (except a future lockscreen TaskStack) moves to the top. */
Craig Mautnerde4ef022013-04-07 19:01:33 -0700137 private TaskStack mHomeStack = null;
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700138
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700139 /** Detect user tapping outside of current focused task bounds .*/
140 TaskTapPointerEventListener mTapDetector;
Craig Mautnercf910b02013-04-23 11:23:27 -0700141
Craig Mautner6601b7b2013-04-29 10:29:11 -0700142 /** Detect user tapping outside of current focused stack bounds .*/
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700143 private Region mTouchExcludeRegion = new Region();
Craig Mautner6601b7b2013-04-29 10:29:11 -0700144
Craig Mautner6601b7b2013-04-29 10:29:11 -0700145 /** Save allocating when calculating rects */
Filip Gruszczynski912d9192015-12-01 16:14:04 -0800146 private final Rect mTmpRect = new Rect();
147 private final Rect mTmpRect2 = new Rect();
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700148 private final RectF mTmpRectF = new RectF();
149 private final Matrix mTmpMatrix = new Matrix();
Filip Gruszczynski912d9192015-12-01 16:14:04 -0800150 private final Region mTmpRegion = new Region();
Craig Mautner6601b7b2013-04-29 10:29:11 -0700151
Craig Mautner9d808b12013-08-06 18:00:25 -0700152 final WindowManagerService mService;
153
Craig Mautner95da1082014-02-24 17:54:35 -0800154 /** Remove this display when animation on it has completed. */
Wale Ogunwaled4a00a02016-10-10 11:29:17 -0700155 private boolean mDeferredRemoval;
Craig Mautner1bf2b872014-02-05 15:37:40 -0800156
Filip Gruszczynski466f3212015-09-21 17:57:57 -0700157 final DockedStackDividerController mDividerControllerLocked;
158
Chong Zhang112eb8c2015-11-02 11:17:00 -0800159 final DimLayerController mDimLayerController;
Filip Gruszczynski0689ae92015-10-01 12:30:31 -0700160
Filip Gruszczynskiecf67222015-12-11 15:16:36 -0800161 final ArrayList<WindowState> mTapExcludedWindows = new ArrayList<>();
162
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700163 /** Used when rebuilding window list to keep track of windows that have been removed. */
164 private WindowState[] mRebuildTmp = new WindowState[20];
165
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700166 private final TaskForResizePointSearchResult mTmpTaskForResizePointSearchResult =
167 new TaskForResizePointSearchResult();
168 private final GetWindowOnDisplaySearchResult mTmpGetWindowOnDisplaySearchResult =
169 new GetWindowOnDisplaySearchResult();
170
Wale Ogunwale601a3f02016-10-17 08:39:39 -0700171 // True if this display is in the process of being removed. Used to determine if the removal of
172 // the display's direct children should be allowed.
173 private boolean mRemovingDisplay = false;
174
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700175 private final WindowLayersController mLayersController;
176 int mInputMethodAnimLayerAdjustment;
177
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800178 /**
Craig Mautner2d5618c2012-10-18 13:55:47 -0700179 * @param display May not be null.
Craig Mautnerdf88d732014-01-27 09:21:32 -0800180 * @param service You know.
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700181 * @param layersController window layer controller used to assign layer to the windows on this
182 * display.
Craig Mautner2d5618c2012-10-18 13:55:47 -0700183 */
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700184 DisplayContent(Display display, WindowManagerService service,
185 WindowLayersController layersController) {
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700186 mDisplay = display;
187 mDisplayId = display.getDisplayId();
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700188 mLayersController = layersController;
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700189 display.getDisplayInfo(mDisplayInfo);
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700190 display.getMetrics(mDisplayMetrics);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700191 isDefaultDisplay = mDisplayId == DEFAULT_DISPLAY;
Craig Mautner9d808b12013-08-06 18:00:25 -0700192 mService = service;
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -0700193 initializeDisplayBaseInfo();
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800194 mDividerControllerLocked = new DockedStackDividerController(service, this);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800195 mDimLayerController = new DimLayerController(this);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700196
197 // These are the only direct children we should ever have and they are permanent.
198 super.addChild(mTaskStackContainers, null);
199 super.addChild(mNonAppWindowContainers, null);
Craig Mautner59c00972012-07-30 12:10:24 -0700200 }
201
202 int getDisplayId() {
203 return mDisplayId;
204 }
205
206 WindowList getWindowList() {
207 return mWindows;
208 }
209
Wale Ogunwale02319a62016-09-26 15:21:22 -0700210 WindowToken getWindowToken(IBinder binder) {
211 return mTokenMap.get(binder);
212 }
213
214 AppWindowToken getAppWindowToken(IBinder binder) {
215 final WindowToken token = getWindowToken(binder);
216 if (token == null) {
217 return null;
218 }
219 return token.asAppWindowToken();
220 }
221
222 void setWindowToken(IBinder binder, WindowToken token) {
223 final DisplayContent dc = mService.mRoot.getWindowTokenDisplay(token);
224 if (dc != null) {
225 // We currently don't support adding a window token to the display if the display
226 // already has the binder mapped to another token. If there is a use case for supporting
227 // this moving forward we will either need to merge the WindowTokens some how or have
228 // the binder map to a list of window tokens.
229 throw new IllegalArgumentException("Can't map token=" + token + " to display=" + this
230 + " already mapped to display=" + dc + " tokens=" + dc.mTokenMap);
231 }
232 mTokenMap.put(binder, token);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700233
234 if (token.asAppWindowToken() == null) {
235 // Add non-app token to container hierarchy on the display. App tokens are added through
236 // the parent container managing them (e.g. Tasks).
237 mNonAppWindowContainers.addChild(token, null);
238 }
Wale Ogunwale02319a62016-09-26 15:21:22 -0700239 }
240
241 WindowToken removeWindowToken(IBinder binder) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700242 final WindowToken token = mTokenMap.remove(binder);
243 if (token != null && token.asAppWindowToken() == null) {
244 mNonAppWindowContainers.removeChild(token);
245 }
246 return token;
Wale Ogunwale02319a62016-09-26 15:21:22 -0700247 }
248
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700249 Display getDisplay() {
250 return mDisplay;
251 }
252
Craig Mautner59c00972012-07-30 12:10:24 -0700253 DisplayInfo getDisplayInfo() {
254 return mDisplayInfo;
255 }
256
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700257 DisplayMetrics getDisplayMetrics() {
258 return mDisplayMetrics;
259 }
260
Jorim Jaggi61f39a72015-10-29 16:54:18 +0100261 DockedStackDividerController getDockedDividerController() {
262 return mDividerControllerLocked;
263 }
264
Jeff Browna506a6e2013-06-04 00:02:38 -0700265 /**
266 * Returns true if the specified UID has access to this display.
267 */
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700268 boolean hasAccess(int uid) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700269 return mDisplay.hasAccess(uid);
270 }
271
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700272 boolean isPrivate() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700273 return (mDisplay.getFlags() & FLAG_PRIVATE) != 0;
keunyounga446bf02013-06-21 19:07:57 -0700274 }
275
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700276 TaskStack getHomeStack() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700277 if (mHomeStack == null && mDisplayId == DEFAULT_DISPLAY) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800278 Slog.e(TAG_WM, "getHomeStack: Returning null from this=" + this);
Craig Mautnere0a38842013-12-16 16:14:02 -0800279 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700280 return mHomeStack;
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700281 }
282
Chong Zhangd9d35bd2016-08-04 17:55:21 -0700283 TaskStack getStackById(int stackId) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700284 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
285 final TaskStack stack = mTaskStackContainers.get(i);
Chong Zhangd9d35bd2016-08-04 17:55:21 -0700286 if (stack.mStackId == stackId) {
287 return stack;
288 }
289 }
290 return null;
291 }
292
Andrii Kulian441e4492016-09-29 15:25:00 -0700293 @Override
294 void onConfigurationChanged(Configuration newParentConfig) {
295 super.onConfigurationChanged(newParentConfig);
296
Andrii Kulian3a507b52016-09-19 18:14:12 -0700297 // The display size information is heavily dependent on the resources in the current
298 // configuration, so we need to reconfigure it every time the configuration changes.
299 // See {@link PhoneWindowManager#setInitialDisplaySize}...sigh...
300 mService.reconfigureDisplayLocked(this);
301
302 getDockedDividerController().onConfigurationChanged();
Andrii Kulian441e4492016-09-29 15:25:00 -0700303 }
Andrii Kulian3a507b52016-09-19 18:14:12 -0700304
Andrii Kulian441e4492016-09-29 15:25:00 -0700305 /**
306 * Callback used to trigger bounds update after configuration change and get ids of stacks whose
307 * bounds were updated.
308 */
309 void updateStackBoundsAfterConfigChange(@NonNull List<Integer> changedStackList) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700310 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
311 final TaskStack stack = mTaskStackContainers.get(i);
Andrii Kulian441e4492016-09-29 15:25:00 -0700312 if (stack.updateBoundsAfterConfigChange()) {
Andrii Kulian3a507b52016-09-19 18:14:12 -0700313 changedStackList.add(stack.mStackId);
314 }
315 }
316 }
317
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700318 @Override
319 boolean fillsParent() {
320 return true;
321 }
322
323 @Override
324 boolean isVisible() {
325 return true;
326 }
327
328 @Override
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700329 void onAppTransitionDone() {
Wale Ogunwale10124582016-09-15 20:25:50 -0700330 super.onAppTransitionDone();
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700331 rebuildAppWindowList();
332 }
333
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700334 @Override
Wale Ogunwale51362492016-09-08 17:49:17 -0700335 int getOrientation() {
Wale Ogunwale51362492016-09-08 17:49:17 -0700336 if (mService.isStackVisibleLocked(DOCKED_STACK_ID)
337 || mService.isStackVisibleLocked(FREEFORM_WORKSPACE_STACK_ID)) {
338 // Apps and their containers are not allowed to specify an orientation while the docked
339 // or freeform stack is visible...except for the home stack/task if the docked stack is
340 // minimized and it actually set something.
Andrii Kulian8072d112016-09-16 11:11:01 -0700341 if (mHomeStack != null && mHomeStack.isVisible()
342 && mDividerControllerLocked.isMinimizedDock()) {
Wale Ogunwale51362492016-09-08 17:49:17 -0700343 final int orientation = mHomeStack.getOrientation();
344 if (orientation != SCREEN_ORIENTATION_UNSET) {
345 return orientation;
346 }
347 }
348 return SCREEN_ORIENTATION_UNSPECIFIED;
349 }
350
Wale Ogunwale10124582016-09-15 20:25:50 -0700351 final int orientation = super.getOrientation();
Wale Ogunwalea77e1462016-09-28 10:09:46 -0700352 if (orientation != SCREEN_ORIENTATION_UNSET && orientation != SCREEN_ORIENTATION_BEHIND) {
Wale Ogunwale10124582016-09-15 20:25:50 -0700353 if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
354 "App is requesting an orientation, return " + orientation);
355 return orientation;
Wale Ogunwale51362492016-09-08 17:49:17 -0700356 }
357
358 if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
359 "No app is requesting an orientation, return " + mService.mLastOrientation);
360 // The next app has not been requested to be visible, so we keep the current orientation
361 // to prevent freezing/unfreezing the display too early.
362 return mService.mLastOrientation;
363 }
364
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700365 void updateDisplayInfo() {
Craig Mautner722285e2012-09-07 13:55:58 -0700366 mDisplay.getDisplayInfo(mDisplayInfo);
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700367 mDisplay.getMetrics(mDisplayMetrics);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700368 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
369 mTaskStackContainers.get(i).updateDisplayInfo(null);
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800370 }
Craig Mautner722285e2012-09-07 13:55:58 -0700371 }
372
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -0700373 void initializeDisplayBaseInfo() {
Wale Ogunwaleb699ce02016-07-18 12:05:30 -0700374 final DisplayManagerInternal displayManagerInternal = mService.mDisplayManagerInternal;
375 if (displayManagerInternal != null) {
376 // Bootstrap the default logical display from the display manager.
377 final DisplayInfo newDisplayInfo = displayManagerInternal.getDisplayInfo(mDisplayId);
378 if (newDisplayInfo != null) {
379 mDisplayInfo.copyFrom(newDisplayInfo);
380 }
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -0700381 }
Wale Ogunwaleb699ce02016-07-18 12:05:30 -0700382
Filip Gruszczynski608797e2015-11-12 19:08:20 -0800383 mBaseDisplayWidth = mInitialDisplayWidth = mDisplayInfo.logicalWidth;
384 mBaseDisplayHeight = mInitialDisplayHeight = mDisplayInfo.logicalHeight;
385 mBaseDisplayDensity = mInitialDisplayDensity = mDisplayInfo.logicalDensityDpi;
386 mBaseDisplayRect.set(0, 0, mBaseDisplayWidth, mBaseDisplayHeight);
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -0700387 }
388
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700389 void getLogicalDisplayRect(Rect out) {
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700390 // Uses same calculation as in LogicalDisplay#configureDisplayInTransactionLocked.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800391 final int orientation = mDisplayInfo.rotation;
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700392 boolean rotated = (orientation == ROTATION_90 || orientation == ROTATION_270);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800393 final int physWidth = rotated ? mBaseDisplayHeight : mBaseDisplayWidth;
394 final int physHeight = rotated ? mBaseDisplayWidth : mBaseDisplayHeight;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700395 int width = mDisplayInfo.logicalWidth;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800396 int left = (physWidth - width) / 2;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700397 int height = mDisplayInfo.logicalHeight;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800398 int top = (physHeight - height) / 2;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700399 out.set(left, top, left + width, top + height);
400 }
401
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700402 private void getLogicalDisplayRect(Rect out, int orientation) {
403 getLogicalDisplayRect(out);
404
405 // Rotate the Rect if needed.
406 final int currentRotation = mDisplayInfo.rotation;
407 final int rotationDelta = deltaRotation(currentRotation, orientation);
408 if (rotationDelta == ROTATION_90 || rotationDelta == ROTATION_270) {
409 createRotationMatrix(rotationDelta, mBaseDisplayWidth, mBaseDisplayHeight, mTmpMatrix);
410 mTmpRectF.set(out);
411 mTmpMatrix.mapRect(mTmpRectF);
412 mTmpRectF.round(out);
413 }
414 }
415
Chong Zhangf66db432016-01-13 10:39:51 -0800416 void getContentRect(Rect out) {
417 out.set(mContentRect);
418 }
419
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700420 /** Refer to {@link WindowManagerService#attachStack(int, int, boolean)} */
421 void attachStack(TaskStack stack, boolean onTop) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700422 mTaskStackContainers.attachStack(stack, onTop);
Craig Mautnerc00204b2013-03-05 15:02:14 -0800423 }
424
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800425 void moveStack(TaskStack stack, boolean toTop) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700426 mTaskStackContainers.moveStack(stack, toTop);
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700427 }
Wale Ogunwale1e60e0c2015-10-28 13:36:10 -0700428
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700429 @Override
430 protected void addChild(DisplayChildWindowContainer child,
431 Comparator<DisplayChildWindowContainer> comparator) {
432 throw new UnsupportedOperationException("See DisplayChildWindowContainer");
433 }
Wale Ogunwale1e60e0c2015-10-28 13:36:10 -0700434
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700435 @Override
436 protected void addChild(DisplayChildWindowContainer child, int index) {
437 throw new UnsupportedOperationException("See DisplayChildWindowContainer");
438 }
439
440 @Override
441 protected void removeChild(DisplayChildWindowContainer child) {
Wale Ogunwale601a3f02016-10-17 08:39:39 -0700442 // Only allow removal of direct children from this display if the display is in the process
443 // of been removed.
444 if (mRemovingDisplay) {
445 super.removeChild(child);
446 return;
447 }
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700448 throw new UnsupportedOperationException("See DisplayChildWindowContainer");
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800449 }
450
451 /**
452 * Propagate the new bounds to all child stacks.
453 * @param contentRect The bounds to apply at the top level.
454 */
455 void resize(Rect contentRect) {
456 mContentRect.set(contentRect);
457 }
458
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700459 int taskIdFromPoint(int x, int y) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700460 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
461 final TaskStack stack = mTaskStackContainers.get(stackNdx);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700462 final int taskId = stack.taskIdFromPoint(x, y);
463 if (taskId != -1) {
464 return taskId;
Craig Mautner967212c2013-04-13 21:10:58 -0700465 }
466 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800467 return -1;
Craig Mautnercf910b02013-04-23 11:23:27 -0700468 }
469
Chong Zhang8e89b312015-09-09 15:09:30 -0700470 /**
Chong Zhangd8ceb852015-11-11 14:53:41 -0800471 * Find the task whose outside touch area (for resizing) (x, y) falls within.
Chong Zhang9184ec62015-09-24 12:32:21 -0700472 * Returns null if the touch doesn't fall into a resizing area.
Chong Zhang8e89b312015-09-09 15:09:30 -0700473 */
Wale Ogunwale15ead902016-09-02 14:30:11 -0700474 Task findTaskForResizePoint(int x, int y) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700475 final int delta = dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700476 mTmpTaskForResizePointSearchResult.reset();
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700477 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
478 final TaskStack stack = mTaskStackContainers.get(stackNdx);
Wale Ogunwale3797c222015-10-27 14:21:58 -0700479 if (!StackId.isTaskResizeAllowed(stack.mStackId)) {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700480 return null;
Chong Zhang8e89b312015-09-09 15:09:30 -0700481 }
Chong Zhang9184ec62015-09-24 12:32:21 -0700482
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700483 stack.findTaskForResizePoint(x, y, delta, mTmpTaskForResizePointSearchResult);
484 if (mTmpTaskForResizePointSearchResult.searchDone) {
485 return mTmpTaskForResizePointSearchResult.taskForResize;
Chong Zhang8e89b312015-09-09 15:09:30 -0700486 }
487 }
Chong Zhang9184ec62015-09-24 12:32:21 -0700488 return null;
Chong Zhang8e89b312015-09-09 15:09:30 -0700489 }
490
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700491 void setTouchExcludeRegion(Task focusedTask) {
Craig Mautner6601b7b2013-04-29 10:29:11 -0700492 mTouchExcludeRegion.set(mBaseDisplayRect);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700493 final int delta = dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700494 mTmpRect2.setEmpty();
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700495 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
496 final TaskStack stack = mTaskStackContainers.get(stackNdx);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700497 stack.setTouchExcludeRegion(
498 focusedTask, delta, mTouchExcludeRegion, mContentRect, mTmpRect2);
Craig Mautner6601b7b2013-04-29 10:29:11 -0700499 }
Chong Zhangd8ceb852015-11-11 14:53:41 -0800500 // If we removed the focused task above, add it back and only leave its
501 // outside touch area in the exclusion. TapDectector is not interested in
502 // any touch inside the focused task itself.
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700503 if (!mTmpRect2.isEmpty()) {
Chong Zhangd8ceb852015-11-11 14:53:41 -0800504 mTouchExcludeRegion.op(mTmpRect2, Region.Op.UNION);
505 }
Filip Gruszczynski912d9192015-12-01 16:14:04 -0800506 final WindowState inputMethod = mService.mInputMethodWindow;
507 if (inputMethod != null && inputMethod.isVisibleLw()) {
508 // If the input method is visible and the user is typing, we don't want these touch
509 // events to be intercepted and used to change focus. This would likely cause a
510 // disappearance of the input method.
511 inputMethod.getTouchableRegion(mTmpRegion);
512 mTouchExcludeRegion.op(mTmpRegion, Region.Op.UNION);
513 }
Filip Gruszczynskiecf67222015-12-11 15:16:36 -0800514 for (int i = mTapExcludedWindows.size() - 1; i >= 0; i--) {
515 WindowState win = mTapExcludedWindows.get(i);
516 win.getTouchableRegion(mTmpRegion);
517 mTouchExcludeRegion.op(mTmpRegion, Region.Op.UNION);
518 }
Jorim Jaggid47e7e12016-03-01 09:57:38 +0100519 if (getDockedStackVisibleForUserLocked() != null) {
520 mDividerControllerLocked.getTouchRegion(mTmpRect);
Jorim Jaggi7f19cb82016-03-25 19:37:44 -0700521 mTmpRegion.set(mTmpRect);
Jorim Jaggid47e7e12016-03-01 09:57:38 +0100522 mTouchExcludeRegion.op(mTmpRegion, Op.UNION);
523 }
Craig Mautner1bef3892015-02-17 15:09:47 -0800524 if (mTapDetector != null) {
Chong Zhang2e2c81a2016-07-15 11:28:17 -0700525 mTapDetector.setTouchExcludeRegion(mTouchExcludeRegion);
Craig Mautner1bef3892015-02-17 15:09:47 -0800526 }
Craig Mautner6601b7b2013-04-29 10:29:11 -0700527 }
528
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700529 void switchUser() {
Craig Mautner858d8a62013-04-23 17:08:34 -0700530 final WindowList windows = getWindowList();
531 for (int i = 0; i < windows.size(); i++) {
532 final WindowState win = windows.get(i);
533 if (win.isHiddenFromUserLocked()) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800534 if (DEBUG_VISIBILITY) Slog.w(TAG_WM, "user changing, hiding " + win
Wale Ogunwale498e8c92015-02-13 09:42:46 -0800535 + ", attrs=" + win.mAttrs.type + ", belonging to " + win.mOwnerUid);
Craig Mautner858d8a62013-04-23 17:08:34 -0700536 win.hideLw(false);
537 }
538 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700539
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700540 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
541 mTaskStackContainers.get(stackNdx).switchUser();
Craig Mautner858d8a62013-04-23 17:08:34 -0700542 }
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700543
544 rebuildAppWindowList();
Craig Mautner858d8a62013-04-23 17:08:34 -0700545 }
546
Craig Mautner05d29032013-05-03 13:40:13 -0700547 void resetAnimationBackgroundAnimator() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700548 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
549 mTaskStackContainers.get(stackNdx).resetAnimationBackgroundAnimator();
Craig Mautner05d29032013-05-03 13:40:13 -0700550 }
551 }
552
553 boolean animateDimLayers() {
Chong Zhang112eb8c2015-11-02 11:17:00 -0800554 return mDimLayerController.animateDimLayers();
Craig Mautner05d29032013-05-03 13:40:13 -0700555 }
556
557 void resetDimming() {
Chong Zhang112eb8c2015-11-02 11:17:00 -0800558 mDimLayerController.resetDimming();
Craig Mautner05d29032013-05-03 13:40:13 -0700559 }
560
561 boolean isDimming() {
Chong Zhang112eb8c2015-11-02 11:17:00 -0800562 return mDimLayerController.isDimming();
Craig Mautner05d29032013-05-03 13:40:13 -0700563 }
564
565 void stopDimmingIfNeeded() {
Chong Zhang112eb8c2015-11-02 11:17:00 -0800566 mDimLayerController.stopDimmingIfNeeded();
Craig Mautner05d29032013-05-03 13:40:13 -0700567 }
568
Wale Ogunwale10124582016-09-15 20:25:50 -0700569 @Override
570 void removeIfPossible() {
571 if (isAnimating()) {
572 mDeferredRemoval = true;
573 return;
Craig Mautner2eb15342013-08-07 13:13:35 -0700574 }
Wale Ogunwale10124582016-09-15 20:25:50 -0700575 removeImmediately();
Craig Mautner2eb15342013-08-07 13:13:35 -0700576 }
577
Wale Ogunwale10124582016-09-15 20:25:50 -0700578 @Override
579 void removeImmediately() {
Wale Ogunwale601a3f02016-10-17 08:39:39 -0700580 mRemovingDisplay = true;
581 try {
582 super.removeImmediately();
583 if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Removing display=" + this);
584 mDimLayerController.close();
585 if (mDisplayId == DEFAULT_DISPLAY) {
586 mService.unregisterPointerEventListener(mTapDetector);
587 mService.unregisterPointerEventListener(mService.mMousePositionTracker);
588 }
589 } finally {
590 mRemovingDisplay = false;
Craig Mautner95da1082014-02-24 17:54:35 -0800591 }
Craig Mautner95da1082014-02-24 17:54:35 -0800592 }
593
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700594 /** Returns true if a removal action is still being deferred. */
Wale Ogunwale10124582016-09-15 20:25:50 -0700595 @Override
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700596 boolean checkCompleteDeferredRemoval() {
Wale Ogunwale10124582016-09-15 20:25:50 -0700597 final boolean stillDeferringRemoval = super.checkCompleteDeferredRemoval();
598
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700599 if (!stillDeferringRemoval && mDeferredRemoval) {
Wale Ogunwale10124582016-09-15 20:25:50 -0700600 removeImmediately();
Craig Mautner95da1082014-02-24 17:54:35 -0800601 mService.onDisplayRemoved(mDisplayId);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700602 return false;
Craig Mautner95da1082014-02-24 17:54:35 -0800603 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700604 return true;
Craig Mautner95da1082014-02-24 17:54:35 -0800605 }
606
Wale Ogunwale10124582016-09-15 20:25:50 -0700607 boolean animateForIme(float interpolatedValue, float animationTarget,
608 float dividerAnimationTarget) {
609 boolean updated = false;
610
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700611 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
612 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale10124582016-09-15 20:25:50 -0700613 if (stack == null || !stack.isAdjustedForIme()) {
614 continue;
615 }
616
617 if (interpolatedValue >= 1f && animationTarget == 0f && dividerAnimationTarget == 0f) {
618 stack.resetAdjustedForIme(true /* adjustBoundsNow */);
619 updated = true;
620 } else {
621 mDividerControllerLocked.mLastAnimationProgress =
622 mDividerControllerLocked.getInterpolatedAnimationValue(interpolatedValue);
623 mDividerControllerLocked.mLastDividerProgress =
624 mDividerControllerLocked.getInterpolatedDividerValue(interpolatedValue);
625 updated |= stack.updateAdjustForIme(
626 mDividerControllerLocked.mLastAnimationProgress,
627 mDividerControllerLocked.mLastDividerProgress,
628 false /* force */);
629 }
630 if (interpolatedValue >= 1f) {
631 stack.endImeAdjustAnimation();
632 }
633 }
634
635 return updated;
636 }
637
638 boolean clearImeAdjustAnimation() {
639 boolean changed = false;
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700640 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
641 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale10124582016-09-15 20:25:50 -0700642 if (stack != null && stack.isAdjustedForIme()) {
643 stack.resetAdjustedForIme(true /* adjustBoundsNow */);
644 changed = true;
645 }
646 }
647 return changed;
648 }
649
650 void beginImeAdjustAnimation() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700651 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
652 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale10124582016-09-15 20:25:50 -0700653 if (stack.isVisible() && stack.isAdjustedForIme()) {
654 stack.beginImeAdjustAnimation();
655 }
656 }
657 }
658
659 void adjustForImeIfNeeded() {
660 final WindowState imeWin = mService.mInputMethodWindow;
661 final boolean imeVisible = imeWin != null && imeWin.isVisibleLw() && imeWin.isDisplayedLw()
662 && !mDividerControllerLocked.isImeHideRequested();
663 final boolean dockVisible = mService.isStackVisibleLocked(DOCKED_STACK_ID);
664 final TaskStack imeTargetStack = mService.getImeFocusStackLocked();
665 final int imeDockSide = (dockVisible && imeTargetStack != null) ?
666 imeTargetStack.getDockSide() : DOCKED_INVALID;
667 final boolean imeOnTop = (imeDockSide == DOCKED_TOP);
668 final boolean imeOnBottom = (imeDockSide == DOCKED_BOTTOM);
669 final boolean dockMinimized = mDividerControllerLocked.isMinimizedDock();
670 final int imeHeight = mService.mPolicy.getInputMethodWindowVisibleHeightLw();
671 final boolean imeHeightChanged = imeVisible &&
672 imeHeight != mDividerControllerLocked.getImeHeightAdjustedFor();
673
674 // The divider could be adjusted for IME position, or be thinner than usual,
675 // or both. There are three possible cases:
676 // - If IME is visible, and focus is on top, divider is not moved for IME but thinner.
677 // - If IME is visible, and focus is on bottom, divider is moved for IME and thinner.
678 // - If IME is not visible, divider is not moved and is normal width.
679
680 if (imeVisible && dockVisible && (imeOnTop || imeOnBottom) && !dockMinimized) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700681 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
682 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale10124582016-09-15 20:25:50 -0700683 final boolean isDockedOnBottom = stack.getDockSide() == DOCKED_BOTTOM;
684 if (stack.isVisible() && (imeOnBottom || isDockedOnBottom)) {
685 stack.setAdjustedForIme(imeWin, imeOnBottom && imeHeightChanged);
686 } else {
687 stack.resetAdjustedForIme(false);
688 }
689 }
690 mDividerControllerLocked.setAdjustedForIme(
691 imeOnBottom /*ime*/, true /*divider*/, true /*animate*/, imeWin, imeHeight);
692 } else {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700693 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
694 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale10124582016-09-15 20:25:50 -0700695 stack.resetAdjustedForIme(!dockVisible);
696 }
697 mDividerControllerLocked.setAdjustedForIme(
698 false /*ime*/, false /*divider*/, dockVisible /*animate*/, imeWin, imeHeight);
699 }
700 }
701
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700702 void setInputMethodAnimLayerAdjustment(int adj) {
703 if (DEBUG_LAYERS) Slog.v(TAG_WM, "Setting im layer adj to " + adj);
704 mInputMethodAnimLayerAdjustment = adj;
705 final WindowState imw = mService.mInputMethodWindow;
706 if (imw != null) {
707 imw.adjustAnimLayer(adj);
708 }
709 for (int i = mService.mInputMethodDialogs.size() - 1; i >= 0; i--) {
710 final WindowState dialog = mService.mInputMethodDialogs.get(i);
711 // TODO: This and other places setting mAnimLayer can probably use WS.adjustAnimLayer,
712 // but need to make sure we are not setting things twice for child windows that are
713 // already in the list.
714 dialog.mWinAnimator.mAnimLayer = dialog.mLayer + adj;
715 if (DEBUG_LAYERS) Slog.v(TAG_WM, "IM win " + imw
716 + " anim layer: " + dialog.mWinAnimator.mAnimLayer);
717 }
718 }
719
Wale Ogunwale10124582016-09-15 20:25:50 -0700720 void prepareFreezingTaskBounds() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700721 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
722 final TaskStack stack = mTaskStackContainers.get(stackNdx);
Wale Ogunwale10124582016-09-15 20:25:50 -0700723 stack.prepareFreezingTaskBounds();
724 }
725 }
726
Wale Ogunwale94744212015-09-21 19:01:47 -0700727 void rotateBounds(int oldRotation, int newRotation, Rect bounds) {
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700728 getLogicalDisplayRect(mTmpRect, newRotation);
729
730 // Compute a transform matrix to undo the coordinate space transformation,
731 // and present the window at the same physical position it previously occupied.
732 final int deltaRotation = deltaRotation(newRotation, oldRotation);
733 createRotationMatrix(deltaRotation, mTmpRect.width(), mTmpRect.height(), mTmpMatrix);
734
735 mTmpRectF.set(bounds);
736 mTmpMatrix.mapRect(mTmpRectF);
737 mTmpRectF.round(bounds);
Wale Ogunwale94744212015-09-21 19:01:47 -0700738 }
739
Wale Ogunwale4a02d812015-02-12 23:01:38 -0800740 static int deltaRotation(int oldRotation, int newRotation) {
741 int delta = newRotation - oldRotation;
742 if (delta < 0) delta += 4;
743 return delta;
744 }
745
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700746 private static void createRotationMatrix(int rotation, float displayWidth, float displayHeight,
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700747 Matrix outMatrix) {
748 // For rotations without Z-ordering we don't need the target rectangle's position.
749 createRotationMatrix(rotation, 0 /* rectLeft */, 0 /* rectTop */, displayWidth,
750 displayHeight, outMatrix);
751 }
752
753 static void createRotationMatrix(int rotation, float rectLeft, float rectTop,
754 float displayWidth, float displayHeight, Matrix outMatrix) {
755 switch (rotation) {
756 case ROTATION_0:
757 outMatrix.reset();
758 break;
759 case ROTATION_270:
760 outMatrix.setRotate(270, 0, 0);
761 outMatrix.postTranslate(0, displayHeight);
762 outMatrix.postTranslate(rectTop, 0);
763 break;
764 case ROTATION_180:
765 outMatrix.reset();
766 break;
767 case ROTATION_90:
768 outMatrix.setRotate(90, 0, 0);
769 outMatrix.postTranslate(displayWidth, 0);
770 outMatrix.postTranslate(-rectTop, rectLeft);
771 break;
772 }
773 }
774
Craig Mautnera91f9e22012-09-14 16:22:08 -0700775 public void dump(String prefix, PrintWriter pw) {
776 pw.print(prefix); pw.print("Display: mDisplayId="); pw.println(mDisplayId);
777 final String subPrefix = " " + prefix;
778 pw.print(subPrefix); pw.print("init="); pw.print(mInitialDisplayWidth); pw.print("x");
779 pw.print(mInitialDisplayHeight); pw.print(" "); pw.print(mInitialDisplayDensity);
780 pw.print("dpi");
781 if (mInitialDisplayWidth != mBaseDisplayWidth
782 || mInitialDisplayHeight != mBaseDisplayHeight
783 || mInitialDisplayDensity != mBaseDisplayDensity) {
784 pw.print(" base=");
785 pw.print(mBaseDisplayWidth); pw.print("x"); pw.print(mBaseDisplayHeight);
786 pw.print(" "); pw.print(mBaseDisplayDensity); pw.print("dpi");
787 }
Jeff Brownd46747a2015-04-15 19:02:36 -0700788 if (mDisplayScalingDisabled) {
789 pw.println(" noscale");
790 }
Craig Mautnera91f9e22012-09-14 16:22:08 -0700791 pw.print(" cur=");
792 pw.print(mDisplayInfo.logicalWidth);
793 pw.print("x"); pw.print(mDisplayInfo.logicalHeight);
794 pw.print(" app=");
795 pw.print(mDisplayInfo.appWidth);
796 pw.print("x"); pw.print(mDisplayInfo.appHeight);
797 pw.print(" rng="); pw.print(mDisplayInfo.smallestNominalAppWidth);
798 pw.print("x"); pw.print(mDisplayInfo.smallestNominalAppHeight);
799 pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth);
800 pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight);
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700801 pw.println(subPrefix + "deferred=" + mDeferredRemoval
802 + " mLayoutNeeded=" + mLayoutNeeded);
Wale Ogunwaleb429e682016-01-06 12:36:34 -0800803
Craig Mautnerdc548482014-02-05 13:35:24 -0800804 pw.println();
Craig Mautnere8b85fd2014-10-22 09:23:25 -0700805 pw.println(" Application tokens in top down Z order:");
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700806 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
807 final TaskStack stack = mTaskStackContainers.get(stackNdx);
Wale Ogunwaleb429e682016-01-06 12:36:34 -0800808 stack.dump(prefix + " ", pw);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700809 }
Wale Ogunwaleb429e682016-01-06 12:36:34 -0800810
Craig Mautnerdc548482014-02-05 13:35:24 -0800811 pw.println();
812 if (!mExitingTokens.isEmpty()) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700813 pw.println();
814 pw.println(" Exiting tokens:");
Wale Ogunwaleb429e682016-01-06 12:36:34 -0800815 for (int i = mExitingTokens.size() - 1; i >= 0; i--) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700816 final WindowToken token = mExitingTokens.get(i);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700817 pw.print(" Exiting #"); pw.print(i);
818 pw.print(' '); pw.print(token);
819 pw.println(':');
820 token.dump(pw, " ");
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800821 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700822 }
Craig Mautner59c00972012-07-30 12:10:24 -0700823 pw.println();
Chong Zhang112eb8c2015-11-02 11:17:00 -0800824 mDimLayerController.dump(prefix + " ", pw);
Jorim Jaggi31f71702016-05-04 16:43:04 -0700825 pw.println();
826 mDividerControllerLocked.dump(prefix + " ", pw);
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700827
828 if (mInputMethodAnimLayerAdjustment != 0) {
829 pw.println(subPrefix
830 + "mInputMethodAnimLayerAdjustment=" + mInputMethodAnimLayerAdjustment);
831 }
Craig Mautner59c00972012-07-30 12:10:24 -0700832 }
Craig Mautnere0a38842013-12-16 16:14:02 -0800833
834 @Override
835 public String toString() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700836 return "Display " + mDisplayId + " info=" + mDisplayInfo + " stacks=" + mChildren;
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700837 }
838
839 String getName() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700840 return "Display " + mDisplayId + " name=\"" + mDisplayInfo.name + "\"";
Craig Mautnere0a38842013-12-16 16:14:02 -0800841 }
Filip Gruszczynski466f3212015-09-21 17:57:57 -0700842
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800843 /**
844 * @return The docked stack, but only if it is visible, and {@code null} otherwise.
845 */
Filip Gruszczynski3ddc5d62015-09-23 15:01:30 -0700846 TaskStack getDockedStackLocked() {
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700847 final TaskStack stack = mService.mStackIdToStack.get(DOCKED_STACK_ID);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700848 return (stack != null && stack.isVisible()) ? stack : null;
Filip Gruszczynski466f3212015-09-21 17:57:57 -0700849 }
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -0800850
851 /**
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800852 * Like {@link #getDockedStackLocked}, but also returns the docked stack if it's currently not
853 * visible, as long as it's not hidden because the current user doesn't have any tasks there.
854 */
855 TaskStack getDockedStackVisibleForUserLocked() {
856 final TaskStack stack = mService.mStackIdToStack.get(DOCKED_STACK_ID);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700857 return (stack != null && stack.isVisible(true /* ignoreKeyguard */)) ? stack : null;
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800858 }
859
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700860 /** Find the visible, touch-deliverable window under the given point */
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -0800861 WindowState getTouchableWinAtPointLocked(float xf, float yf) {
862 WindowState touchedWin = null;
863 final int x = (int) xf;
864 final int y = (int) yf;
865
866 for (int i = mWindows.size() - 1; i >= 0; i--) {
867 WindowState window = mWindows.get(i);
868 final int flags = window.mAttrs.flags;
869 if (!window.isVisibleLw()) {
870 continue;
871 }
872 if ((flags & FLAG_NOT_TOUCHABLE) != 0) {
873 continue;
874 }
875
876 window.getVisibleBounds(mTmpRect);
877 if (!mTmpRect.contains(x, y)) {
878 continue;
879 }
880
881 window.getTouchableRegion(mTmpRegion);
882
883 final int touchFlags = flags & (FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL);
884 if (mTmpRegion.contains(x, y) || touchFlags == 0) {
885 touchedWin = window;
886 break;
887 }
888 }
889
890 return touchedWin;
891 }
Jorim Jaggi6626f542016-08-22 13:08:44 -0700892
Svetoslav Ganovaa076532016-08-01 19:16:43 -0700893 boolean canAddToastWindowForUid(int uid) {
894 // We allow one toast window per UID being shown at a time.
895 WindowList windows = getWindowList();
896 final int windowCount = windows.size();
897 for (int i = 0; i < windowCount; i++) {
898 WindowState window = windows.get(i);
899 if (window.mAttrs.type == TYPE_TOAST && window.mOwnerUid == uid
Svet Ganov62a40f82016-09-29 00:43:51 -0700900 && !window.mPermanentlyHidden && !window.mAnimatingExit
901 && !window.mRemoveOnExit) {
Svetoslav Ganovaa076532016-08-01 19:16:43 -0700902 return false;
903 }
904 }
905 return true;
906 }
907
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700908 void scheduleToastWindowsTimeoutIfNeededLocked(WindowState oldFocus, WindowState newFocus) {
Svetoslav Ganovaa076532016-08-01 19:16:43 -0700909 if (oldFocus == null || (newFocus != null && newFocus.mOwnerUid == oldFocus.mOwnerUid)) {
910 return;
911 }
912 final int lostFocusUid = oldFocus.mOwnerUid;
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700913 final WindowList windows = getWindowList();
Svetoslav Ganovaa076532016-08-01 19:16:43 -0700914 final int windowCount = windows.size();
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700915 final Handler handler = mService.mH;
Svetoslav Ganovaa076532016-08-01 19:16:43 -0700916 for (int i = 0; i < windowCount; i++) {
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700917 final WindowState window = windows.get(i);
Svetoslav Ganovaa076532016-08-01 19:16:43 -0700918 if (window.mAttrs.type == TYPE_TOAST && window.mOwnerUid == lostFocusUid) {
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700919 if (!handler.hasMessages(WINDOW_HIDE_TIMEOUT, window)) {
920 handler.sendMessageDelayed(handler.obtainMessage(WINDOW_HIDE_TIMEOUT, window),
Svetoslav Ganovaa076532016-08-01 19:16:43 -0700921 window.mAttrs.hideTimeoutMilliseconds);
922 }
923 }
924 }
925 }
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -0700926
927 WindowState findFocusedWindow() {
928 final AppWindowToken focusedApp = mService.mFocusedApp;
929
930 for (int i = mWindows.size() - 1; i >= 0; i--) {
931 final WindowState win = mWindows.get(i);
932
933 if (DEBUG_FOCUS) Slog.v(TAG_WM, "Looking for focus: " + i + " = " + win
934 + ", flags=" + win.mAttrs.flags + ", canReceive=" + win.canReceiveKeys());
935
936 if (!win.canReceiveKeys()) {
937 continue;
938 }
939
940 final AppWindowToken wtoken = win.mAppToken;
941
942 // If this window's application has been removed, just skip it.
943 if (wtoken != null && (wtoken.removed || wtoken.sendingToBottom)) {
944 if (DEBUG_FOCUS) Slog.v(TAG_WM, "Skipping " + wtoken + " because "
945 + (wtoken.removed ? "removed" : "sendingToBottom"));
946 continue;
947 }
948
949 if (focusedApp == null) {
950 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp=null"
951 + " using new focus @ " + i + " = " + win);
952 return win;
953 }
954
955 if (!focusedApp.windowsAreFocusable()) {
956 // Current focused app windows aren't focusable...
957 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp windows not"
958 + " focusable using new focus @ " + i + " = " + win);
959 return win;
960 }
961
962 // Descend through all of the app tokens and find the first that either matches
963 // win.mAppToken (return win) or mFocusedApp (return null).
964 if (wtoken != null && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
Wale Ogunwale10124582016-09-15 20:25:50 -0700965 if (focusedApp.compareTo(wtoken) > 0) {
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -0700966 // App stack below focused app stack. No focus for you!!!
967 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM,
968 "findFocusedWindow: Reached focused app=" + focusedApp);
969 return null;
970 }
971 }
972
973 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: Found new focus @ "
974 + i + " = " + win);
975 return win;
976 }
977
978 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: No focusable windows.");
979 return null;
980 }
Wale Ogunwaleec731152016-09-08 20:18:57 -0700981
982 int addAppWindowToWindowList(final WindowState win) {
983 final IWindow client = win.mClient;
984
985 WindowList tokenWindowList = getTokenWindowsOnDisplay(win.mToken);
986 if (!tokenWindowList.isEmpty()) {
987 return addAppWindowExisting(win, tokenWindowList);
988 }
989
990 // No windows from this token on this display
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700991 if (localLOGV) Slog.v(TAG_WM, "Figuring out where to add app window "
Wale Ogunwaleec731152016-09-08 20:18:57 -0700992 + client.asBinder() + " (token=" + this + ")");
993
994 final WindowToken wToken = win.mToken;
995
996 // Figure out where the window should go, based on the order of applications.
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700997 mTmpGetWindowOnDisplaySearchResult.reset();
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700998 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
999 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001000 stack.getWindowOnDisplayBeforeToken(this, wToken, mTmpGetWindowOnDisplaySearchResult);
1001 if (mTmpGetWindowOnDisplaySearchResult.reachedToken) {
Wale Ogunwaleec731152016-09-08 20:18:57 -07001002 // We have reach the token we are interested in. End search.
1003 break;
1004 }
1005 }
1006
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001007 WindowState pos = mTmpGetWindowOnDisplaySearchResult.foundWindow;
Wale Ogunwaleec731152016-09-08 20:18:57 -07001008
1009 // We now know the index into the apps. If we found an app window above, that gives us the
1010 // position; else we need to look some more.
1011 if (pos != null) {
1012 // Move behind any windows attached to this one.
Wale Ogunwale02319a62016-09-26 15:21:22 -07001013 final WindowToken atoken = getWindowToken(pos.mClient.asBinder());
Wale Ogunwaleec731152016-09-08 20:18:57 -07001014 if (atoken != null) {
1015 tokenWindowList = getTokenWindowsOnDisplay(atoken);
1016 final int NC = tokenWindowList.size();
1017 if (NC > 0) {
1018 WindowState bottom = tokenWindowList.get(0);
1019 if (bottom.mSubLayer < 0) {
1020 pos = bottom;
1021 }
1022 }
1023 }
1024 addWindowToListBefore(win, pos);
1025 return 0;
1026 }
1027
1028 // Continue looking down until we find the first token that has windows on this display.
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001029 mTmpGetWindowOnDisplaySearchResult.reset();
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001030 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
1031 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001032 stack.getWindowOnDisplayAfterToken(this, wToken, mTmpGetWindowOnDisplaySearchResult);
1033 if (mTmpGetWindowOnDisplaySearchResult.foundWindow != null) {
Wale Ogunwaleec731152016-09-08 20:18:57 -07001034 // We have found a window after the token. End search.
1035 break;
1036 }
1037 }
1038
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001039 pos = mTmpGetWindowOnDisplaySearchResult.foundWindow;
Wale Ogunwaleec731152016-09-08 20:18:57 -07001040
1041 if (pos != null) {
1042 // Move in front of any windows attached to this one.
Wale Ogunwale02319a62016-09-26 15:21:22 -07001043 final WindowToken atoken = getWindowToken(pos.mClient.asBinder());
Wale Ogunwaleec731152016-09-08 20:18:57 -07001044 if (atoken != null) {
1045 final WindowState top = atoken.getTopWindow();
1046 if (top != null && top.mSubLayer >= 0) {
1047 pos = top;
1048 }
1049 }
1050 addWindowToListAfter(win, pos);
1051 return 0;
1052 }
1053
1054 // Just search for the start of this layer.
1055 final int myLayer = win.mBaseLayer;
1056 int i;
1057 for (i = mWindows.size() - 1; i >= 0; --i) {
1058 final WindowState w = mWindows.get(i);
1059 // Dock divider shares the base layer with application windows, but we want to always
1060 // keep it above the application windows. The sharing of the base layer is intended
1061 // for window animations, which need to be above the dock divider for the duration
1062 // of the animation.
1063 if (w.mBaseLayer <= myLayer && w.mAttrs.type != TYPE_DOCK_DIVIDER) {
1064 break;
1065 }
1066 }
1067 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1068 "Based on layer: Adding window " + win + " at " + (i + 1) + " of "
1069 + mWindows.size());
1070 mWindows.add(i + 1, win);
1071 mService.mWindowsChanged = true;
1072 return 0;
1073 }
1074
1075 /** Adds this non-app window to the window list. */
1076 void addNonAppWindowToWindowList(WindowState win) {
1077 // Figure out where window should go, based on layer.
1078 int i;
1079 for (i = mWindows.size() - 1; i >= 0; i--) {
1080 final WindowState otherWin = mWindows.get(i);
1081 if (otherWin.getBaseType() != TYPE_WALLPAPER && otherWin.mBaseLayer <= win.mBaseLayer) {
1082 // Wallpaper wanders through the window list, for example to position itself
1083 // directly behind keyguard. Because of this it will break the ordering based on
1084 // WindowState.mBaseLayer. There might windows with higher mBaseLayer behind it and
1085 // we don't want the new window to appear above them. An example of this is adding
1086 // of the docked stack divider. Consider a scenario with the following ordering (top
1087 // to bottom): keyguard, wallpaper, assist preview, apps. We want the dock divider
1088 // to land below the assist preview, so the dock divider must ignore the wallpaper,
1089 // with which it shares the base layer.
1090 break;
1091 }
1092 }
1093
1094 i++;
1095 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1096 "Free window: Adding window " + this + " at " + i + " of " + mWindows.size());
1097 mWindows.add(i, win);
1098 mService.mWindowsChanged = true;
1099 }
1100
Wale Ogunwaleb9a07c32016-10-12 14:55:56 -07001101 void addToWindowList(WindowState win, int index) {
1102 mWindows.add(index, win);
1103 }
1104
Wale Ogunwaleec731152016-09-08 20:18:57 -07001105 void addChildWindowToWindowList(WindowState win) {
1106 final WindowState parentWindow = win.getParentWindow();
1107
1108 WindowList windowsOnSameDisplay = getTokenWindowsOnDisplay(win.mToken);
1109
1110 // Figure out this window's ordering relative to the parent window.
1111 final int wCount = windowsOnSameDisplay.size();
1112 final int sublayer = win.mSubLayer;
1113 int largestSublayer = Integer.MIN_VALUE;
1114 WindowState windowWithLargestSublayer = null;
1115 int i;
1116 for (i = 0; i < wCount; i++) {
1117 WindowState w = windowsOnSameDisplay.get(i);
1118 final int wSublayer = w.mSubLayer;
1119 if (wSublayer >= largestSublayer) {
1120 largestSublayer = wSublayer;
1121 windowWithLargestSublayer = w;
1122 }
1123 if (sublayer < 0) {
1124 // For negative sublayers, we go below all windows in the same sublayer.
1125 if (wSublayer >= sublayer) {
1126 addWindowToListBefore(win, wSublayer >= 0 ? parentWindow : w);
1127 break;
1128 }
1129 } else {
1130 // For positive sublayers, we go above all windows in the same sublayer.
1131 if (wSublayer > sublayer) {
1132 addWindowToListBefore(win, w);
1133 break;
1134 }
1135 }
1136 }
1137 if (i >= wCount) {
1138 if (sublayer < 0) {
1139 addWindowToListBefore(win, parentWindow);
1140 } else {
1141 addWindowToListAfter(win,
1142 largestSublayer >= 0 ? windowWithLargestSublayer : parentWindow);
1143 }
1144 }
1145 }
1146
Wale Ogunwalec69694a2016-10-18 13:51:15 -07001147 /** Updates the layer assignment of windows on this display. */
1148 void assignWindowLayers(boolean setLayoutNeeded) {
1149 mLayersController.assignWindowLayers(mWindows);
1150 if (setLayoutNeeded) {
1151 setLayoutNeeded();
1152 }
1153 }
1154
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001155 /**
1156 * Z-orders the display window list so that:
1157 * <ul>
1158 * <li>Any windows that are currently below the wallpaper window stay below the wallpaper
1159 * window.
1160 * <li>Exiting application windows are at the bottom, but above the wallpaper window.
1161 * <li>All other application windows are above the exiting application windows and ordered based
1162 * on the ordering of their stacks and tasks on the display.
1163 * <li>Non-application windows are at the very top.
1164 * </ul>
1165 * <p>
1166 * NOTE: This isn't a complete picture of what the user see. Further manipulation of the window
1167 * surface layering is done in {@link WindowLayersController}.
1168 */
1169 void rebuildAppWindowList() {
1170 int count = mWindows.size();
1171 int i;
1172 int lastBelow = -1;
1173 int numRemoved = 0;
1174
1175 if (mRebuildTmp.length < count) {
1176 mRebuildTmp = new WindowState[count + 10];
1177 }
1178
1179 // First remove all existing app windows.
1180 i = 0;
1181 while (i < count) {
1182 final WindowState w = mWindows.get(i);
1183 if (w.mAppToken != null) {
1184 final WindowState win = mWindows.remove(i);
1185 win.mRebuilding = true;
1186 mRebuildTmp[numRemoved] = win;
1187 mService.mWindowsChanged = true;
1188 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Rebuild removing window: " + win);
1189 count--;
1190 numRemoved++;
1191 continue;
1192 } else if (lastBelow == i-1) {
1193 if (w.mAttrs.type == TYPE_WALLPAPER) {
1194 lastBelow = i;
1195 }
1196 }
1197 i++;
1198 }
1199
1200 // Keep whatever windows were below the app windows still below, by skipping them.
1201 lastBelow++;
1202 i = lastBelow;
1203
1204 // First add all of the exiting app tokens... these are no longer in the main app list,
1205 // but still have windows shown. We put them in the back because now that the animation is
1206 // over we no longer will care about them.
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001207 final int numStacks = mTaskStackContainers.size();
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001208 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001209 AppTokenList exitingAppTokens = mTaskStackContainers.get(stackNdx).mExitingAppTokens;
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001210 int NT = exitingAppTokens.size();
1211 for (int j = 0; j < NT; j++) {
Wale Ogunwale360a8bc2016-10-10 13:25:26 -07001212 i = exitingAppTokens.get(j).rebuildWindowListUnchecked(i);
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001213 }
1214 }
1215
1216 // And add in the still active app tokens in Z order.
1217 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001218 i = mTaskStackContainers.get(stackNdx).rebuildWindowList(i);
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001219 }
1220
1221 i -= lastBelow;
1222 if (i != numRemoved) {
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001223 setLayoutNeeded();
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001224 Slog.w(TAG_WM, "On display=" + mDisplayId + " Rebuild removed " + numRemoved
1225 + " windows but added " + i + " rebuildAppWindowListLocked() "
1226 + " callers=" + Debug.getCallers(10));
1227 for (i = 0; i < numRemoved; i++) {
1228 WindowState ws = mRebuildTmp[i];
1229 if (ws.mRebuilding) {
1230 StringWriter sw = new StringWriter();
1231 PrintWriter pw = new FastPrintWriter(sw, false, 1024);
1232 ws.dump(pw, "", true);
1233 pw.flush();
1234 Slog.w(TAG_WM, "This window was lost: " + ws);
1235 Slog.w(TAG_WM, sw.toString());
1236 ws.mWinAnimator.destroySurfaceLocked();
1237 }
1238 }
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07001239 Slog.w(TAG_WM, "Current window hierarchy:");
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001240 dumpChildrenNames();
1241 Slog.w(TAG_WM, "Final window list:");
1242 dumpWindows();
1243 }
1244 Arrays.fill(mRebuildTmp, null);
1245 }
1246
Wale Ogunwaleec731152016-09-08 20:18:57 -07001247 /** Return the list of Windows on this display associated with the input token. */
1248 WindowList getTokenWindowsOnDisplay(WindowToken token) {
1249 final WindowList windowList = new WindowList();
1250 final int count = mWindows.size();
1251 for (int i = 0; i < count; i++) {
1252 final WindowState win = mWindows.get(i);
1253 if (win.mToken == token) {
1254 windowList.add(win);
1255 }
1256 }
1257 return windowList;
1258 }
1259
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001260 void setLayoutNeeded() {
1261 if (DEBUG_LAYOUT) Slog.w(TAG_WM, "setLayoutNeeded: callers=" + Debug.getCallers(3));
1262 mLayoutNeeded = true;
1263 }
1264
1265 void clearLayoutNeeded() {
1266 if (DEBUG_LAYOUT) Slog.w(TAG_WM, "clearLayoutNeeded: callers=" + Debug.getCallers(3));
1267 mLayoutNeeded = false;
1268 }
1269
1270 boolean isLayoutNeeded() {
1271 return mLayoutNeeded;
1272 }
1273
Wale Ogunwaleec731152016-09-08 20:18:57 -07001274 private int addAppWindowExisting(WindowState win, WindowList tokenWindowList) {
1275
1276 int tokenWindowsPos;
1277 // If this application has existing windows, we simply place the new window on top of
1278 // them... but keep the starting window on top.
1279 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
1280 // Base windows go behind everything else.
1281 final WindowState lowestWindow = tokenWindowList.get(0);
1282 addWindowToListBefore(win, lowestWindow);
1283 tokenWindowsPos = win.mToken.getWindowIndex(lowestWindow);
1284 } else {
1285 final AppWindowToken atoken = win.mAppToken;
1286 final int windowListPos = tokenWindowList.size();
1287 final WindowState lastWindow = tokenWindowList.get(windowListPos - 1);
1288 if (atoken != null && lastWindow == atoken.startingWindow) {
1289 addWindowToListBefore(win, lastWindow);
1290 tokenWindowsPos = win.mToken.getWindowIndex(lastWindow);
1291 } else {
1292 int newIdx = findIdxBasedOnAppTokens(win);
1293 // There is a window above this one associated with the same apptoken note that the
1294 // window could be a floating window that was created later or a window at the top
1295 // of the list of windows associated with this token.
1296 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1297 "not Base app: Adding window " + win + " at " + (newIdx + 1) + " of "
1298 + mWindows.size());
1299 mWindows.add(newIdx + 1, win);
1300 if (newIdx < 0) {
1301 // No window from token found on win's display.
1302 tokenWindowsPos = 0;
1303 } else {
1304 tokenWindowsPos = win.mToken.getWindowIndex(mWindows.get(newIdx)) + 1;
1305 }
1306 mService.mWindowsChanged = true;
1307 }
1308 }
1309 return tokenWindowsPos;
1310 }
1311
1312 /** Places the first input window after the second input window in the window list. */
1313 private void addWindowToListAfter(WindowState first, WindowState second) {
1314 final int i = mWindows.indexOf(second);
1315 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1316 "Adding window " + this + " at " + (i + 1) + " of " + mWindows.size()
1317 + " (after " + second + ")");
1318 mWindows.add(i + 1, first);
1319 mService.mWindowsChanged = true;
1320 }
1321
1322 /** Places the first input window before the second input window in the window list. */
1323 private void addWindowToListBefore(WindowState first, WindowState second) {
1324 int i = mWindows.indexOf(second);
1325 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1326 "Adding window " + this + " at " + i + " of " + mWindows.size()
1327 + " (before " + second + ")");
1328 if (i < 0) {
1329 Slog.w(TAG_WM, "addWindowToListBefore: Unable to find " + second + " in " + mWindows);
1330 i = 0;
1331 }
1332 mWindows.add(i, first);
1333 mService.mWindowsChanged = true;
1334 }
1335
1336 /**
1337 * This method finds out the index of a window that has the same app token as win. used for z
1338 * ordering the windows in mWindows
1339 */
1340 private int findIdxBasedOnAppTokens(WindowState win) {
1341 for(int j = mWindows.size() - 1; j >= 0; j--) {
1342 final WindowState wentry = mWindows.get(j);
1343 if(wentry.mAppToken == win.mAppToken) {
1344 return j;
1345 }
1346 }
1347 return -1;
1348 }
1349
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001350 private void dumpChildrenNames() {
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07001351 StringBuilder output = new StringBuilder();
1352 dumpChildrenNames(output, " ");
1353 Slog.v(TAG_WM, output.toString());
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001354 }
1355
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001356 private void dumpWindows() {
Wale Ogunwale10124582016-09-15 20:25:50 -07001357 Slog.v(TAG_WM, " Display #" + mDisplayId);
1358 final WindowList windows = getWindowList();
1359 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1360 Slog.v(TAG_WM, " #" + winNdx + ": " + windows.get(winNdx));
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001361 }
1362 }
1363
Wale Ogunwale02319a62016-09-26 15:21:22 -07001364 void dumpTokens(PrintWriter pw, boolean dumpAll) {
1365 if (mTokenMap.isEmpty()) {
1366 return;
1367 }
1368 pw.println(" Display #" + mDisplayId);
1369 final Iterator<WindowToken> it = mTokenMap.values().iterator();
1370 while (it.hasNext()) {
1371 final WindowToken token = it.next();
1372 pw.print(" ");
1373 pw.print(token);
1374 if (dumpAll) {
1375 pw.println(':');
1376 token.dump(pw, " ");
1377 } else {
1378 pw.println();
1379 }
1380 }
1381 }
1382
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001383 void enableSurfaceTrace(FileDescriptor fd) {
1384 for (int i = mWindows.size() - 1; i >= 0; i--) {
1385 final WindowState win = mWindows.get(i);
1386 win.mWinAnimator.enableSurfaceTrace(fd);
1387 }
1388 }
1389
1390 void disableSurfaceTrace() {
1391 for (int i = mWindows.size() - 1; i >= 0; i--) {
1392 final WindowState win = mWindows.get(i);
1393 win.mWinAnimator.disableSurfaceTrace();
1394 }
1395 }
1396
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001397 static final class GetWindowOnDisplaySearchResult {
Wale Ogunwaleec731152016-09-08 20:18:57 -07001398 boolean reachedToken;
1399 WindowState foundWindow;
1400
1401 void reset() {
1402 reachedToken = false;
1403 foundWindow = null;
1404 }
1405 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001406
1407 static final class TaskForResizePointSearchResult {
1408 boolean searchDone;
1409 Task taskForResize;
1410
1411 void reset() {
1412 searchDone = false;
1413 taskForResize = null;
1414 }
1415 }
Robert Carr3b716242016-08-16 16:02:21 -07001416
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001417 /**
1418 * Base class for any direct child window container of {@link #DisplayContent} need to inherit
1419 * from. This is mainly a pass through class that allows {@link #DisplayContent} to have
1420 * homogeneous children type which is currently required by sub-classes of
1421 * {@link WindowContainer} class.
1422 */
1423 static class DisplayChildWindowContainer<E extends WindowContainer> extends WindowContainer<E> {
1424
1425 int size() {
1426 return mChildren.size();
1427 }
1428
1429 E get(int index) {
1430 return mChildren.get(index);
1431 }
1432
1433 @Override
1434 boolean fillsParent() {
1435 return true;
1436 }
1437
1438 @Override
1439 boolean isVisible() {
1440 return true;
Robert Carr3b716242016-08-16 16:02:21 -07001441 }
1442 }
1443
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001444 /**
1445 * Window container class that contains all containers on this display relating to Apps.
1446 * I.e Activities.
1447 */
1448 private class TaskStackContainers extends DisplayChildWindowContainer<TaskStack> {
1449
1450 void attachStack(TaskStack stack, boolean onTop) {
1451 if (stack.mStackId == HOME_STACK_ID) {
1452 if (mHomeStack != null) {
1453 throw new IllegalArgumentException("attachStack: HOME_STACK_ID (0) not first.");
1454 }
1455 mHomeStack = stack;
1456 }
1457 addChild(stack, onTop);
1458 stack.onDisplayChanged(DisplayContent.this);
Robert Carr3b716242016-08-16 16:02:21 -07001459 }
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001460
1461 void moveStack(TaskStack stack, boolean toTop) {
1462 if (StackId.isAlwaysOnTop(stack.mStackId) && !toTop) {
1463 // This stack is always-on-top silly...
1464 Slog.w(TAG_WM, "Ignoring move of always-on-top stack=" + stack + " to bottom");
1465 return;
1466 }
1467
1468 if (!mChildren.contains(stack)) {
1469 Slog.wtf(TAG_WM, "moving stack that was not added: " + stack, new Throwable());
1470 }
1471 removeChild(stack);
1472 addChild(stack, toTop);
1473 }
1474
1475 private void addChild(TaskStack stack, boolean toTop) {
1476 int addIndex = toTop ? mChildren.size() : 0;
1477
1478 if (toTop
1479 && mService.isStackVisibleLocked(PINNED_STACK_ID)
1480 && stack.mStackId != PINNED_STACK_ID) {
1481 // The pinned stack is always the top most stack (always-on-top) when it is visible.
1482 // So, stack is moved just below the pinned stack.
1483 addIndex--;
1484 TaskStack topStack = mChildren.get(addIndex);
1485 if (topStack.mStackId != PINNED_STACK_ID) {
1486 throw new IllegalStateException("Pinned stack isn't top stack??? " + mChildren);
1487 }
1488 }
1489 addChild(stack, addIndex);
1490 setLayoutNeeded();
1491 }
1492
1493 }
1494
1495 /**
1496 * Window container class that contains all containers on this display that are not related to
1497 * Apps. E.g. status bar.
1498 */
1499 private static class NonAppWindowContainers extends DisplayChildWindowContainer<WindowToken> {
1500
Robert Carr3b716242016-08-16 16:02:21 -07001501 }
Craig Mautner59c00972012-07-30 12:10:24 -07001502}