blob: 4a7f816226fbce8ae5540612cb0fb642675f4ee7 [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;
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -070035import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -080036import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
37import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
38import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -070039import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -070040import static android.view.WindowManager.LayoutParams.NEEDS_MENU_SET_TRUE;
41import static android.view.WindowManager.LayoutParams.NEEDS_MENU_UNSET;
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -070042import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
Wale Ogunwaleec731152016-09-08 20:18:57 -070043import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
44import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
Svetoslav Ganovaa076532016-08-01 19:16:43 -070045import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
Wale Ogunwaleec731152016-09-08 20:18:57 -070046import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -070047import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
48import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
49import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
50import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
51import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
52import static com.android.server.wm.WindowAnimator.KEYGUARD_ANIMATING_OUT;
53import static com.android.server.wm.WindowAnimator.KEYGUARD_ANIM_TIMEOUT_MS;
54import static com.android.server.wm.WindowAnimator.KEYGUARD_NOT_SHOWN;
55import static com.android.server.wm.WindowAnimator.KEYGUARD_SHOWN;
Wale Ogunwaleec731152016-09-08 20:18:57 -070056import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -070057import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
Wale Ogunwale10124582016-09-15 20:25:50 -070058import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -070059import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
60import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -070061import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -070062import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEYGUARD;
Wale Ogunwalec69694a2016-10-18 13:51:15 -070063import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -070064import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -070065import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
66import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
Wale Ogunwaleec731152016-09-08 20:18:57 -070067import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080068import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
Wale Ogunwale51362492016-09-08 17:49:17 -070069import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -070070import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -070071import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080072import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -070073import static com.android.server.wm.WindowManagerService.H.WINDOW_HIDE_TIMEOUT;
Wale Ogunwale19e452e2016-10-12 12:36:29 -070074import static com.android.server.wm.WindowManagerService.dipToPixel;
75import static com.android.server.wm.WindowManagerService.localLOGV;
Wale Ogunwale231b06e2015-09-16 12:03:09 -070076import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -070077import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW;
78import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
79import static com.android.server.wm.WindowSurfacePlacer.SET_FORCE_HIDING_CHANGED;
80import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_MAY_CHANGE;
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -070081
Andrii Kulian3a507b52016-09-19 18:14:12 -070082import android.annotation.NonNull;
Wale Ogunwale3797c222015-10-27 14:21:58 -070083import android.app.ActivityManager.StackId;
Andrii Kulian441e4492016-09-29 15:25:00 -070084import android.content.res.Configuration;
Andrii Kulian4dfb9c42016-10-11 20:06:27 -070085import android.graphics.Matrix;
Craig Mautnerc00204b2013-03-05 15:02:14 -080086import android.graphics.Rect;
Andrii Kulian4dfb9c42016-10-11 20:06:27 -070087import android.graphics.RectF;
Craig Mautner6601b7b2013-04-29 10:29:11 -070088import android.graphics.Region;
Jorim Jaggid47e7e12016-03-01 09:57:38 +010089import android.graphics.Region.Op;
Wale Ogunwaleb699ce02016-07-18 12:05:30 -070090import android.hardware.display.DisplayManagerInternal;
Wale Ogunwale9adfe572016-09-08 20:43:58 -070091import android.os.Debug;
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -070092import android.os.Handler;
Wale Ogunwale02319a62016-09-26 15:21:22 -070093import android.os.IBinder;
Chong Zhang8e89b312015-09-09 15:09:30 -070094import android.util.DisplayMetrics;
Craig Mautnerde4ef022013-04-07 19:01:33 -070095import android.util.Slog;
Craig Mautnerb47bbc32012-08-22 17:41:48 -070096import android.view.Display;
Craig Mautner59c00972012-07-30 12:10:24 -070097import android.view.DisplayInfo;
Wale Ogunwaleec731152016-09-08 20:18:57 -070098import android.view.IWindow;
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -070099import android.view.WindowManager;
100import android.view.WindowManagerPolicy;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -0700101import android.view.animation.AlphaAnimation;
102import android.view.animation.Animation;
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700103
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700104import com.android.internal.util.FastPrintWriter;
Craig Mautner59c00972012-07-30 12:10:24 -0700105
Robert Carr3b716242016-08-16 16:02:21 -0700106import java.io.FileDescriptor;
Craig Mautner59c00972012-07-30 12:10:24 -0700107import java.io.PrintWriter;
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700108import java.io.StringWriter;
Craig Mautner59c00972012-07-30 12:10:24 -0700109import java.util.ArrayList;
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700110import java.util.Arrays;
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700111import java.util.Comparator;
Wale Ogunwale02319a62016-09-26 15:21:22 -0700112import java.util.HashMap;
113import java.util.Iterator;
Andrii Kulian3a507b52016-09-19 18:14:12 -0700114import java.util.List;
Craig Mautner59c00972012-07-30 12:10:24 -0700115
Craig Mautner59c00972012-07-30 12:10:24 -0700116/**
117 * Utility class for keeping track of the WindowStates and other pertinent contents of a
118 * particular Display.
119 *
120 * IMPORTANT: No method from this class should ever be used without holding
121 * WindowManagerService.mWindowMap.
122 */
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700123class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowContainer> {
Wale Ogunwale824ab5c2016-10-20 09:31:56 -0700124 private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayContent" : TAG_WM;
Craig Mautner59c00972012-07-30 12:10:24 -0700125
126 /** Unique identifier of this stack. */
127 private final int mDisplayId;
128
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700129 // The display only has 2 child window containers. mTaskStackContainers which contains all
130 // window containers that are related to apps (Activities) and mNonAppWindowContainers which
131 // contains all window containers not related to apps (e.g. Status bar).
132 private final TaskStackContainers mTaskStackContainers = new TaskStackContainers();
133 private final NonAppWindowContainers mNonAppWindowContainers = new NonAppWindowContainers();
134
Craig Mautner59c00972012-07-30 12:10:24 -0700135 /** Z-ordered (bottom-most first) list of all Window objects. Assigned to an element
136 * from mDisplayWindows; */
Craig Mautnerdc548482014-02-05 13:35:24 -0800137 private final WindowList mWindows = new WindowList();
Craig Mautner59c00972012-07-30 12:10:24 -0700138
Wale Ogunwale02319a62016-09-26 15:21:22 -0700139 // Mapping from a token IBinder to a WindowToken object on this display.
140 private final HashMap<IBinder, WindowToken> mTokenMap = new HashMap();
141
Craig Mautner59c00972012-07-30 12:10:24 -0700142 int mInitialDisplayWidth = 0;
143 int mInitialDisplayHeight = 0;
Dianne Hackborndde331c2012-08-03 14:01:57 -0700144 int mInitialDisplayDensity = 0;
Craig Mautner59c00972012-07-30 12:10:24 -0700145 int mBaseDisplayWidth = 0;
146 int mBaseDisplayHeight = 0;
Dianne Hackborndde331c2012-08-03 14:01:57 -0700147 int mBaseDisplayDensity = 0;
Jeff Brownd46747a2015-04-15 19:02:36 -0700148 boolean mDisplayScalingDisabled;
Craig Mautner2d5618c2012-10-18 13:55:47 -0700149 private final DisplayInfo mDisplayInfo = new DisplayInfo();
150 private final Display mDisplay;
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700151 private final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Craig Mautner59c00972012-07-30 12:10:24 -0700152
Craig Mautner6601b7b2013-04-29 10:29:11 -0700153 Rect mBaseDisplayRect = new Rect();
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700154 private Rect mContentRect = new Rect();
Craig Mautner6601b7b2013-04-29 10:29:11 -0700155
Craig Mautner39834192012-09-02 07:47:24 -0700156 // Accessed directly by all users.
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700157 private boolean mLayoutNeeded;
Craig Mautner76a71652012-09-03 23:23:58 -0700158 int pendingLayoutChanges;
Craig Mautner69b08182012-09-05 13:07:13 -0700159 final boolean isDefaultDisplay;
Craig Mautner39834192012-09-02 07:47:24 -0700160
Craig Mautnerdc548482014-02-05 13:35:24 -0800161 /** Window tokens that are in the process of exiting, but still on screen for animations. */
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700162 final ArrayList<WindowToken> mExitingTokens = new ArrayList<>();
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800163
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800164 /** A special TaskStack with id==HOME_STACK_ID that moves to the bottom whenever any TaskStack
165 * (except a future lockscreen TaskStack) moves to the top. */
Craig Mautnerde4ef022013-04-07 19:01:33 -0700166 private TaskStack mHomeStack = null;
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700167
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700168 /** Detect user tapping outside of current focused task bounds .*/
169 TaskTapPointerEventListener mTapDetector;
Craig Mautnercf910b02013-04-23 11:23:27 -0700170
Craig Mautner6601b7b2013-04-29 10:29:11 -0700171 /** Detect user tapping outside of current focused stack bounds .*/
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700172 private Region mTouchExcludeRegion = new Region();
Craig Mautner6601b7b2013-04-29 10:29:11 -0700173
Craig Mautner6601b7b2013-04-29 10:29:11 -0700174 /** Save allocating when calculating rects */
Filip Gruszczynski912d9192015-12-01 16:14:04 -0800175 private final Rect mTmpRect = new Rect();
176 private final Rect mTmpRect2 = new Rect();
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700177 private final RectF mTmpRectF = new RectF();
178 private final Matrix mTmpMatrix = new Matrix();
Filip Gruszczynski912d9192015-12-01 16:14:04 -0800179 private final Region mTmpRegion = new Region();
Craig Mautner6601b7b2013-04-29 10:29:11 -0700180
Craig Mautner9d808b12013-08-06 18:00:25 -0700181 final WindowManagerService mService;
182
Craig Mautner95da1082014-02-24 17:54:35 -0800183 /** Remove this display when animation on it has completed. */
Wale Ogunwaled4a00a02016-10-10 11:29:17 -0700184 private boolean mDeferredRemoval;
Craig Mautner1bf2b872014-02-05 15:37:40 -0800185
Filip Gruszczynski466f3212015-09-21 17:57:57 -0700186 final DockedStackDividerController mDividerControllerLocked;
187
Chong Zhang112eb8c2015-11-02 11:17:00 -0800188 final DimLayerController mDimLayerController;
Filip Gruszczynski0689ae92015-10-01 12:30:31 -0700189
Filip Gruszczynskiecf67222015-12-11 15:16:36 -0800190 final ArrayList<WindowState> mTapExcludedWindows = new ArrayList<>();
191
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700192 /** Used when rebuilding window list to keep track of windows that have been removed. */
193 private WindowState[] mRebuildTmp = new WindowState[20];
194
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700195 private final TaskForResizePointSearchResult mTmpTaskForResizePointSearchResult =
196 new TaskForResizePointSearchResult();
197 private final GetWindowOnDisplaySearchResult mTmpGetWindowOnDisplaySearchResult =
198 new GetWindowOnDisplaySearchResult();
199
Wale Ogunwale601a3f02016-10-17 08:39:39 -0700200 // True if this display is in the process of being removed. Used to determine if the removal of
201 // the display's direct children should be allowed.
202 private boolean mRemovingDisplay = false;
203
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700204 private final WindowLayersController mLayersController;
Wale Ogunwale0303c572016-10-20 10:16:29 -0700205 final WallpaperController mWallpaperController;
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700206 int mInputMethodAnimLayerAdjustment;
207
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800208 /**
Craig Mautner2d5618c2012-10-18 13:55:47 -0700209 * @param display May not be null.
Craig Mautnerdf88d732014-01-27 09:21:32 -0800210 * @param service You know.
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700211 * @param layersController window layer controller used to assign layer to the windows on this
212 * display.
Wale Ogunwale0303c572016-10-20 10:16:29 -0700213 * @param wallpaperController wallpaper windows controller used to adjust the positioning of the
214 * wallpaper windows in the window list.
Craig Mautner2d5618c2012-10-18 13:55:47 -0700215 */
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700216 DisplayContent(Display display, WindowManagerService service,
Wale Ogunwale0303c572016-10-20 10:16:29 -0700217 WindowLayersController layersController, WallpaperController wallpaperController) {
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700218 mDisplay = display;
219 mDisplayId = display.getDisplayId();
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700220 mLayersController = layersController;
Wale Ogunwale0303c572016-10-20 10:16:29 -0700221 mWallpaperController = wallpaperController;
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700222 display.getDisplayInfo(mDisplayInfo);
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700223 display.getMetrics(mDisplayMetrics);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700224 isDefaultDisplay = mDisplayId == DEFAULT_DISPLAY;
Craig Mautner9d808b12013-08-06 18:00:25 -0700225 mService = service;
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -0700226 initializeDisplayBaseInfo();
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800227 mDividerControllerLocked = new DockedStackDividerController(service, this);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800228 mDimLayerController = new DimLayerController(this);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700229
230 // These are the only direct children we should ever have and they are permanent.
231 super.addChild(mTaskStackContainers, null);
232 super.addChild(mNonAppWindowContainers, null);
Craig Mautner59c00972012-07-30 12:10:24 -0700233 }
234
235 int getDisplayId() {
236 return mDisplayId;
237 }
238
239 WindowList getWindowList() {
240 return mWindows;
241 }
242
Wale Ogunwale02319a62016-09-26 15:21:22 -0700243 WindowToken getWindowToken(IBinder binder) {
244 return mTokenMap.get(binder);
245 }
246
247 AppWindowToken getAppWindowToken(IBinder binder) {
248 final WindowToken token = getWindowToken(binder);
249 if (token == null) {
250 return null;
251 }
252 return token.asAppWindowToken();
253 }
254
255 void setWindowToken(IBinder binder, WindowToken token) {
256 final DisplayContent dc = mService.mRoot.getWindowTokenDisplay(token);
257 if (dc != null) {
258 // We currently don't support adding a window token to the display if the display
259 // already has the binder mapped to another token. If there is a use case for supporting
260 // this moving forward we will either need to merge the WindowTokens some how or have
261 // the binder map to a list of window tokens.
262 throw new IllegalArgumentException("Can't map token=" + token + " to display=" + this
263 + " already mapped to display=" + dc + " tokens=" + dc.mTokenMap);
264 }
265 mTokenMap.put(binder, token);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700266
267 if (token.asAppWindowToken() == null) {
268 // Add non-app token to container hierarchy on the display. App tokens are added through
269 // the parent container managing them (e.g. Tasks).
270 mNonAppWindowContainers.addChild(token, null);
271 }
Wale Ogunwale02319a62016-09-26 15:21:22 -0700272 }
273
274 WindowToken removeWindowToken(IBinder binder) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700275 final WindowToken token = mTokenMap.remove(binder);
276 if (token != null && token.asAppWindowToken() == null) {
277 mNonAppWindowContainers.removeChild(token);
278 }
279 return token;
Wale Ogunwale02319a62016-09-26 15:21:22 -0700280 }
281
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700282 Display getDisplay() {
283 return mDisplay;
284 }
285
Craig Mautner59c00972012-07-30 12:10:24 -0700286 DisplayInfo getDisplayInfo() {
287 return mDisplayInfo;
288 }
289
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700290 DisplayMetrics getDisplayMetrics() {
291 return mDisplayMetrics;
292 }
293
Jorim Jaggi61f39a72015-10-29 16:54:18 +0100294 DockedStackDividerController getDockedDividerController() {
295 return mDividerControllerLocked;
296 }
297
Jeff Browna506a6e2013-06-04 00:02:38 -0700298 /**
299 * Returns true if the specified UID has access to this display.
300 */
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700301 boolean hasAccess(int uid) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700302 return mDisplay.hasAccess(uid);
303 }
304
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700305 boolean isPrivate() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700306 return (mDisplay.getFlags() & FLAG_PRIVATE) != 0;
keunyounga446bf02013-06-21 19:07:57 -0700307 }
308
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700309 TaskStack getHomeStack() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700310 if (mHomeStack == null && mDisplayId == DEFAULT_DISPLAY) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800311 Slog.e(TAG_WM, "getHomeStack: Returning null from this=" + this);
Craig Mautnere0a38842013-12-16 16:14:02 -0800312 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700313 return mHomeStack;
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700314 }
315
Chong Zhangd9d35bd2016-08-04 17:55:21 -0700316 TaskStack getStackById(int stackId) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700317 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
318 final TaskStack stack = mTaskStackContainers.get(i);
Chong Zhangd9d35bd2016-08-04 17:55:21 -0700319 if (stack.mStackId == stackId) {
320 return stack;
321 }
322 }
323 return null;
324 }
325
Andrii Kulian441e4492016-09-29 15:25:00 -0700326 @Override
327 void onConfigurationChanged(Configuration newParentConfig) {
328 super.onConfigurationChanged(newParentConfig);
329
Andrii Kulian3a507b52016-09-19 18:14:12 -0700330 // The display size information is heavily dependent on the resources in the current
331 // configuration, so we need to reconfigure it every time the configuration changes.
332 // See {@link PhoneWindowManager#setInitialDisplaySize}...sigh...
333 mService.reconfigureDisplayLocked(this);
334
335 getDockedDividerController().onConfigurationChanged();
Andrii Kulian441e4492016-09-29 15:25:00 -0700336 }
Andrii Kulian3a507b52016-09-19 18:14:12 -0700337
Andrii Kulian441e4492016-09-29 15:25:00 -0700338 /**
339 * Callback used to trigger bounds update after configuration change and get ids of stacks whose
340 * bounds were updated.
341 */
342 void updateStackBoundsAfterConfigChange(@NonNull List<Integer> changedStackList) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700343 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
344 final TaskStack stack = mTaskStackContainers.get(i);
Andrii Kulian441e4492016-09-29 15:25:00 -0700345 if (stack.updateBoundsAfterConfigChange()) {
Andrii Kulian3a507b52016-09-19 18:14:12 -0700346 changedStackList.add(stack.mStackId);
347 }
348 }
349 }
350
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700351 @Override
352 boolean fillsParent() {
353 return true;
354 }
355
356 @Override
357 boolean isVisible() {
358 return true;
359 }
360
361 @Override
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700362 void onAppTransitionDone() {
Wale Ogunwale10124582016-09-15 20:25:50 -0700363 super.onAppTransitionDone();
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700364 rebuildAppWindowList();
365 }
366
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700367 @Override
Wale Ogunwale51362492016-09-08 17:49:17 -0700368 int getOrientation() {
Wale Ogunwalee6f806e2016-10-20 15:29:42 -0700369 final WindowManagerPolicy policy = mService.mPolicy;
370
371 // TODO: All the logic before the last return statement in this method should really go in
372 // #NonAppWindowContainer.getOrientation() since it is trying to decide orientation based
373 // on non-app windows. But, we can not do that until the window list is always correct in
374 // terms of z-ordering based on layers.
375 if (mService.mDisplayFrozen) {
376 if (mService.mLastWindowForcedOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
377 if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
378 "Display is frozen, return " + mService.mLastWindowForcedOrientation);
379 // If the display is frozen, some activities may be in the middle of restarting, and
380 // thus have removed their old window. If the window has the flag to hide the lock
381 // screen, then the lock screen can re-appear and inflict its own orientation on us.
382 // Keep the orientation stable until this all settles down.
383 return mService.mLastWindowForcedOrientation;
384 } else if (policy.isKeyguardLocked()) {
385 // Use the last orientation the while the display is frozen with the keyguard
386 // locked. This could be the keyguard forced orientation or from a SHOW_WHEN_LOCKED
387 // window. We don't want to check the show when locked window directly though as
388 // things aren't stable while the display is frozen, for example the window could be
389 // momentarily unavailable due to activity relaunch.
390 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display is frozen while keyguard locked, "
391 + "return " + mService.mLastOrientation);
392 return mService.mLastOrientation;
Wale Ogunwale51362492016-09-08 17:49:17 -0700393 }
Wale Ogunwalee6f806e2016-10-20 15:29:42 -0700394 } else {
395 for (int pos = mWindows.size() - 1; pos >= 0; --pos) {
396 final WindowState win = mWindows.get(pos);
397 if (win.mAppToken != null) {
398 // We hit an application window. so the orientation will be determined by the
399 // app window. No point in continuing further.
400 break;
401 }
402 if (!win.isVisibleLw() || !win.mPolicyVisibilityAfterAnim) {
403 continue;
404 }
405 int req = win.mAttrs.screenOrientation;
406 if(req == SCREEN_ORIENTATION_UNSPECIFIED || req == SCREEN_ORIENTATION_BEHIND) {
407 continue;
408 }
409
410 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, win + " forcing orientation to " + req);
411 if (policy.isKeyguardHostWindow(win.mAttrs)) {
412 mService.mLastKeyguardForcedOrientation = req;
413 }
414 return (mService.mLastWindowForcedOrientation = req);
415 }
416 mService.mLastWindowForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
417
418 if (policy.isKeyguardLocked()) {
419 // The screen is locked and no top system window is requesting an orientation.
420 // Return either the orientation of the show-when-locked app (if there is any) or
421 // the orientation of the keyguard. No point in searching from the rest of apps.
422 WindowState winShowWhenLocked = (WindowState) policy.getWinShowWhenLockedLw();
423 AppWindowToken appShowWhenLocked = winShowWhenLocked == null
424 ? null : winShowWhenLocked.mAppToken;
425 if (appShowWhenLocked != null) {
426 int req = appShowWhenLocked.getOrientation();
427 if (req == SCREEN_ORIENTATION_BEHIND) {
428 req = mService.mLastKeyguardForcedOrientation;
429 }
430 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Done at " + appShowWhenLocked
431 + " -- show when locked, return " + req);
432 return req;
433 }
434 if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
435 "No one is requesting an orientation when the screen is locked");
436 return mService.mLastKeyguardForcedOrientation;
437 }
Wale Ogunwale51362492016-09-08 17:49:17 -0700438 }
439
Wale Ogunwalee6f806e2016-10-20 15:29:42 -0700440 // Top system windows are not requesting an orientation. Start searching from apps.
441 return mTaskStackContainers.getOrientation();
Wale Ogunwale51362492016-09-08 17:49:17 -0700442 }
443
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700444 void updateDisplayInfo() {
Craig Mautner722285e2012-09-07 13:55:58 -0700445 mDisplay.getDisplayInfo(mDisplayInfo);
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700446 mDisplay.getMetrics(mDisplayMetrics);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700447 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
448 mTaskStackContainers.get(i).updateDisplayInfo(null);
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800449 }
Craig Mautner722285e2012-09-07 13:55:58 -0700450 }
451
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -0700452 void initializeDisplayBaseInfo() {
Wale Ogunwaleb699ce02016-07-18 12:05:30 -0700453 final DisplayManagerInternal displayManagerInternal = mService.mDisplayManagerInternal;
454 if (displayManagerInternal != null) {
455 // Bootstrap the default logical display from the display manager.
456 final DisplayInfo newDisplayInfo = displayManagerInternal.getDisplayInfo(mDisplayId);
457 if (newDisplayInfo != null) {
458 mDisplayInfo.copyFrom(newDisplayInfo);
459 }
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -0700460 }
Wale Ogunwaleb699ce02016-07-18 12:05:30 -0700461
Filip Gruszczynski608797e2015-11-12 19:08:20 -0800462 mBaseDisplayWidth = mInitialDisplayWidth = mDisplayInfo.logicalWidth;
463 mBaseDisplayHeight = mInitialDisplayHeight = mDisplayInfo.logicalHeight;
464 mBaseDisplayDensity = mInitialDisplayDensity = mDisplayInfo.logicalDensityDpi;
465 mBaseDisplayRect.set(0, 0, mBaseDisplayWidth, mBaseDisplayHeight);
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -0700466 }
467
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700468 void getLogicalDisplayRect(Rect out) {
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700469 // Uses same calculation as in LogicalDisplay#configureDisplayInTransactionLocked.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800470 final int orientation = mDisplayInfo.rotation;
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700471 boolean rotated = (orientation == ROTATION_90 || orientation == ROTATION_270);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800472 final int physWidth = rotated ? mBaseDisplayHeight : mBaseDisplayWidth;
473 final int physHeight = rotated ? mBaseDisplayWidth : mBaseDisplayHeight;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700474 int width = mDisplayInfo.logicalWidth;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800475 int left = (physWidth - width) / 2;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700476 int height = mDisplayInfo.logicalHeight;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800477 int top = (physHeight - height) / 2;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700478 out.set(left, top, left + width, top + height);
479 }
480
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700481 private void getLogicalDisplayRect(Rect out, int orientation) {
482 getLogicalDisplayRect(out);
483
484 // Rotate the Rect if needed.
485 final int currentRotation = mDisplayInfo.rotation;
486 final int rotationDelta = deltaRotation(currentRotation, orientation);
487 if (rotationDelta == ROTATION_90 || rotationDelta == ROTATION_270) {
488 createRotationMatrix(rotationDelta, mBaseDisplayWidth, mBaseDisplayHeight, mTmpMatrix);
489 mTmpRectF.set(out);
490 mTmpMatrix.mapRect(mTmpRectF);
491 mTmpRectF.round(out);
492 }
493 }
494
Chong Zhangf66db432016-01-13 10:39:51 -0800495 void getContentRect(Rect out) {
496 out.set(mContentRect);
497 }
498
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700499 /** Refer to {@link WindowManagerService#attachStack(int, int, boolean)} */
500 void attachStack(TaskStack stack, boolean onTop) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700501 mTaskStackContainers.attachStack(stack, onTop);
Craig Mautnerc00204b2013-03-05 15:02:14 -0800502 }
503
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800504 void moveStack(TaskStack stack, boolean toTop) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700505 mTaskStackContainers.moveStack(stack, toTop);
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700506 }
Wale Ogunwale1e60e0c2015-10-28 13:36:10 -0700507
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700508 @Override
509 protected void addChild(DisplayChildWindowContainer child,
510 Comparator<DisplayChildWindowContainer> comparator) {
511 throw new UnsupportedOperationException("See DisplayChildWindowContainer");
512 }
Wale Ogunwale1e60e0c2015-10-28 13:36:10 -0700513
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700514 @Override
515 protected void addChild(DisplayChildWindowContainer child, int index) {
516 throw new UnsupportedOperationException("See DisplayChildWindowContainer");
517 }
518
519 @Override
520 protected void removeChild(DisplayChildWindowContainer child) {
Wale Ogunwale601a3f02016-10-17 08:39:39 -0700521 // Only allow removal of direct children from this display if the display is in the process
522 // of been removed.
523 if (mRemovingDisplay) {
524 super.removeChild(child);
525 return;
526 }
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700527 throw new UnsupportedOperationException("See DisplayChildWindowContainer");
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800528 }
529
530 /**
531 * Propagate the new bounds to all child stacks.
532 * @param contentRect The bounds to apply at the top level.
533 */
534 void resize(Rect contentRect) {
535 mContentRect.set(contentRect);
536 }
537
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700538 int taskIdFromPoint(int x, int y) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700539 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
540 final TaskStack stack = mTaskStackContainers.get(stackNdx);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700541 final int taskId = stack.taskIdFromPoint(x, y);
542 if (taskId != -1) {
543 return taskId;
Craig Mautner967212c2013-04-13 21:10:58 -0700544 }
545 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800546 return -1;
Craig Mautnercf910b02013-04-23 11:23:27 -0700547 }
548
Chong Zhang8e89b312015-09-09 15:09:30 -0700549 /**
Chong Zhangd8ceb852015-11-11 14:53:41 -0800550 * Find the task whose outside touch area (for resizing) (x, y) falls within.
Chong Zhang9184ec62015-09-24 12:32:21 -0700551 * Returns null if the touch doesn't fall into a resizing area.
Chong Zhang8e89b312015-09-09 15:09:30 -0700552 */
Wale Ogunwale15ead902016-09-02 14:30:11 -0700553 Task findTaskForResizePoint(int x, int y) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700554 final int delta = dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700555 mTmpTaskForResizePointSearchResult.reset();
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700556 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
557 final TaskStack stack = mTaskStackContainers.get(stackNdx);
Wale Ogunwale3797c222015-10-27 14:21:58 -0700558 if (!StackId.isTaskResizeAllowed(stack.mStackId)) {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700559 return null;
Chong Zhang8e89b312015-09-09 15:09:30 -0700560 }
Chong Zhang9184ec62015-09-24 12:32:21 -0700561
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700562 stack.findTaskForResizePoint(x, y, delta, mTmpTaskForResizePointSearchResult);
563 if (mTmpTaskForResizePointSearchResult.searchDone) {
564 return mTmpTaskForResizePointSearchResult.taskForResize;
Chong Zhang8e89b312015-09-09 15:09:30 -0700565 }
566 }
Chong Zhang9184ec62015-09-24 12:32:21 -0700567 return null;
Chong Zhang8e89b312015-09-09 15:09:30 -0700568 }
569
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700570 void setTouchExcludeRegion(Task focusedTask) {
Craig Mautner6601b7b2013-04-29 10:29:11 -0700571 mTouchExcludeRegion.set(mBaseDisplayRect);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700572 final int delta = dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700573 mTmpRect2.setEmpty();
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700574 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
575 final TaskStack stack = mTaskStackContainers.get(stackNdx);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700576 stack.setTouchExcludeRegion(
577 focusedTask, delta, mTouchExcludeRegion, mContentRect, mTmpRect2);
Craig Mautner6601b7b2013-04-29 10:29:11 -0700578 }
Chong Zhangd8ceb852015-11-11 14:53:41 -0800579 // If we removed the focused task above, add it back and only leave its
580 // outside touch area in the exclusion. TapDectector is not interested in
581 // any touch inside the focused task itself.
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700582 if (!mTmpRect2.isEmpty()) {
Chong Zhangd8ceb852015-11-11 14:53:41 -0800583 mTouchExcludeRegion.op(mTmpRect2, Region.Op.UNION);
584 }
Filip Gruszczynski912d9192015-12-01 16:14:04 -0800585 final WindowState inputMethod = mService.mInputMethodWindow;
586 if (inputMethod != null && inputMethod.isVisibleLw()) {
587 // If the input method is visible and the user is typing, we don't want these touch
588 // events to be intercepted and used to change focus. This would likely cause a
589 // disappearance of the input method.
590 inputMethod.getTouchableRegion(mTmpRegion);
591 mTouchExcludeRegion.op(mTmpRegion, Region.Op.UNION);
592 }
Filip Gruszczynskiecf67222015-12-11 15:16:36 -0800593 for (int i = mTapExcludedWindows.size() - 1; i >= 0; i--) {
594 WindowState win = mTapExcludedWindows.get(i);
595 win.getTouchableRegion(mTmpRegion);
596 mTouchExcludeRegion.op(mTmpRegion, Region.Op.UNION);
597 }
Jorim Jaggid47e7e12016-03-01 09:57:38 +0100598 if (getDockedStackVisibleForUserLocked() != null) {
599 mDividerControllerLocked.getTouchRegion(mTmpRect);
Jorim Jaggi7f19cb82016-03-25 19:37:44 -0700600 mTmpRegion.set(mTmpRect);
Jorim Jaggid47e7e12016-03-01 09:57:38 +0100601 mTouchExcludeRegion.op(mTmpRegion, Op.UNION);
602 }
Craig Mautner1bef3892015-02-17 15:09:47 -0800603 if (mTapDetector != null) {
Chong Zhang2e2c81a2016-07-15 11:28:17 -0700604 mTapDetector.setTouchExcludeRegion(mTouchExcludeRegion);
Craig Mautner1bef3892015-02-17 15:09:47 -0800605 }
Craig Mautner6601b7b2013-04-29 10:29:11 -0700606 }
607
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700608 void switchUser() {
Craig Mautner858d8a62013-04-23 17:08:34 -0700609 final WindowList windows = getWindowList();
610 for (int i = 0; i < windows.size(); i++) {
611 final WindowState win = windows.get(i);
612 if (win.isHiddenFromUserLocked()) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800613 if (DEBUG_VISIBILITY) Slog.w(TAG_WM, "user changing, hiding " + win
Wale Ogunwale498e8c92015-02-13 09:42:46 -0800614 + ", attrs=" + win.mAttrs.type + ", belonging to " + win.mOwnerUid);
Craig Mautner858d8a62013-04-23 17:08:34 -0700615 win.hideLw(false);
616 }
617 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700618
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700619 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
620 mTaskStackContainers.get(stackNdx).switchUser();
Craig Mautner858d8a62013-04-23 17:08:34 -0700621 }
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700622
623 rebuildAppWindowList();
Craig Mautner858d8a62013-04-23 17:08:34 -0700624 }
625
Craig Mautner05d29032013-05-03 13:40:13 -0700626 void resetAnimationBackgroundAnimator() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700627 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
628 mTaskStackContainers.get(stackNdx).resetAnimationBackgroundAnimator();
Craig Mautner05d29032013-05-03 13:40:13 -0700629 }
630 }
631
632 boolean animateDimLayers() {
Chong Zhang112eb8c2015-11-02 11:17:00 -0800633 return mDimLayerController.animateDimLayers();
Craig Mautner05d29032013-05-03 13:40:13 -0700634 }
635
636 void resetDimming() {
Chong Zhang112eb8c2015-11-02 11:17:00 -0800637 mDimLayerController.resetDimming();
Craig Mautner05d29032013-05-03 13:40:13 -0700638 }
639
640 boolean isDimming() {
Chong Zhang112eb8c2015-11-02 11:17:00 -0800641 return mDimLayerController.isDimming();
Craig Mautner05d29032013-05-03 13:40:13 -0700642 }
643
644 void stopDimmingIfNeeded() {
Chong Zhang112eb8c2015-11-02 11:17:00 -0800645 mDimLayerController.stopDimmingIfNeeded();
Craig Mautner05d29032013-05-03 13:40:13 -0700646 }
647
Wale Ogunwale10124582016-09-15 20:25:50 -0700648 @Override
649 void removeIfPossible() {
650 if (isAnimating()) {
651 mDeferredRemoval = true;
652 return;
Craig Mautner2eb15342013-08-07 13:13:35 -0700653 }
Wale Ogunwale10124582016-09-15 20:25:50 -0700654 removeImmediately();
Craig Mautner2eb15342013-08-07 13:13:35 -0700655 }
656
Wale Ogunwale10124582016-09-15 20:25:50 -0700657 @Override
658 void removeImmediately() {
Wale Ogunwale601a3f02016-10-17 08:39:39 -0700659 mRemovingDisplay = true;
660 try {
661 super.removeImmediately();
662 if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Removing display=" + this);
663 mDimLayerController.close();
664 if (mDisplayId == DEFAULT_DISPLAY) {
665 mService.unregisterPointerEventListener(mTapDetector);
666 mService.unregisterPointerEventListener(mService.mMousePositionTracker);
667 }
668 } finally {
669 mRemovingDisplay = false;
Craig Mautner95da1082014-02-24 17:54:35 -0800670 }
Craig Mautner95da1082014-02-24 17:54:35 -0800671 }
672
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700673 /** Returns true if a removal action is still being deferred. */
Wale Ogunwale10124582016-09-15 20:25:50 -0700674 @Override
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700675 boolean checkCompleteDeferredRemoval() {
Wale Ogunwale10124582016-09-15 20:25:50 -0700676 final boolean stillDeferringRemoval = super.checkCompleteDeferredRemoval();
677
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700678 if (!stillDeferringRemoval && mDeferredRemoval) {
Wale Ogunwale10124582016-09-15 20:25:50 -0700679 removeImmediately();
Craig Mautner95da1082014-02-24 17:54:35 -0800680 mService.onDisplayRemoved(mDisplayId);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700681 return false;
Craig Mautner95da1082014-02-24 17:54:35 -0800682 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700683 return true;
Craig Mautner95da1082014-02-24 17:54:35 -0800684 }
685
Wale Ogunwale10124582016-09-15 20:25:50 -0700686 boolean animateForIme(float interpolatedValue, float animationTarget,
687 float dividerAnimationTarget) {
688 boolean updated = false;
689
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700690 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
691 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale10124582016-09-15 20:25:50 -0700692 if (stack == null || !stack.isAdjustedForIme()) {
693 continue;
694 }
695
696 if (interpolatedValue >= 1f && animationTarget == 0f && dividerAnimationTarget == 0f) {
697 stack.resetAdjustedForIme(true /* adjustBoundsNow */);
698 updated = true;
699 } else {
700 mDividerControllerLocked.mLastAnimationProgress =
701 mDividerControllerLocked.getInterpolatedAnimationValue(interpolatedValue);
702 mDividerControllerLocked.mLastDividerProgress =
703 mDividerControllerLocked.getInterpolatedDividerValue(interpolatedValue);
704 updated |= stack.updateAdjustForIme(
705 mDividerControllerLocked.mLastAnimationProgress,
706 mDividerControllerLocked.mLastDividerProgress,
707 false /* force */);
708 }
709 if (interpolatedValue >= 1f) {
710 stack.endImeAdjustAnimation();
711 }
712 }
713
714 return updated;
715 }
716
717 boolean clearImeAdjustAnimation() {
718 boolean changed = false;
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700719 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
720 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale10124582016-09-15 20:25:50 -0700721 if (stack != null && stack.isAdjustedForIme()) {
722 stack.resetAdjustedForIme(true /* adjustBoundsNow */);
723 changed = true;
724 }
725 }
726 return changed;
727 }
728
729 void beginImeAdjustAnimation() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700730 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
731 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale10124582016-09-15 20:25:50 -0700732 if (stack.isVisible() && stack.isAdjustedForIme()) {
733 stack.beginImeAdjustAnimation();
734 }
735 }
736 }
737
738 void adjustForImeIfNeeded() {
739 final WindowState imeWin = mService.mInputMethodWindow;
740 final boolean imeVisible = imeWin != null && imeWin.isVisibleLw() && imeWin.isDisplayedLw()
741 && !mDividerControllerLocked.isImeHideRequested();
742 final boolean dockVisible = mService.isStackVisibleLocked(DOCKED_STACK_ID);
743 final TaskStack imeTargetStack = mService.getImeFocusStackLocked();
744 final int imeDockSide = (dockVisible && imeTargetStack != null) ?
745 imeTargetStack.getDockSide() : DOCKED_INVALID;
746 final boolean imeOnTop = (imeDockSide == DOCKED_TOP);
747 final boolean imeOnBottom = (imeDockSide == DOCKED_BOTTOM);
748 final boolean dockMinimized = mDividerControllerLocked.isMinimizedDock();
749 final int imeHeight = mService.mPolicy.getInputMethodWindowVisibleHeightLw();
750 final boolean imeHeightChanged = imeVisible &&
751 imeHeight != mDividerControllerLocked.getImeHeightAdjustedFor();
752
753 // The divider could be adjusted for IME position, or be thinner than usual,
754 // or both. There are three possible cases:
755 // - If IME is visible, and focus is on top, divider is not moved for IME but thinner.
756 // - If IME is visible, and focus is on bottom, divider is moved for IME and thinner.
757 // - If IME is not visible, divider is not moved and is normal width.
758
759 if (imeVisible && dockVisible && (imeOnTop || imeOnBottom) && !dockMinimized) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700760 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
761 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale10124582016-09-15 20:25:50 -0700762 final boolean isDockedOnBottom = stack.getDockSide() == DOCKED_BOTTOM;
763 if (stack.isVisible() && (imeOnBottom || isDockedOnBottom)) {
764 stack.setAdjustedForIme(imeWin, imeOnBottom && imeHeightChanged);
765 } else {
766 stack.resetAdjustedForIme(false);
767 }
768 }
769 mDividerControllerLocked.setAdjustedForIme(
770 imeOnBottom /*ime*/, true /*divider*/, true /*animate*/, imeWin, imeHeight);
771 } else {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700772 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
773 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale10124582016-09-15 20:25:50 -0700774 stack.resetAdjustedForIme(!dockVisible);
775 }
776 mDividerControllerLocked.setAdjustedForIme(
777 false /*ime*/, false /*divider*/, dockVisible /*animate*/, imeWin, imeHeight);
778 }
779 }
780
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700781 void setInputMethodAnimLayerAdjustment(int adj) {
782 if (DEBUG_LAYERS) Slog.v(TAG_WM, "Setting im layer adj to " + adj);
783 mInputMethodAnimLayerAdjustment = adj;
784 final WindowState imw = mService.mInputMethodWindow;
785 if (imw != null) {
786 imw.adjustAnimLayer(adj);
787 }
788 for (int i = mService.mInputMethodDialogs.size() - 1; i >= 0; i--) {
789 final WindowState dialog = mService.mInputMethodDialogs.get(i);
790 // TODO: This and other places setting mAnimLayer can probably use WS.adjustAnimLayer,
791 // but need to make sure we are not setting things twice for child windows that are
792 // already in the list.
793 dialog.mWinAnimator.mAnimLayer = dialog.mLayer + adj;
794 if (DEBUG_LAYERS) Slog.v(TAG_WM, "IM win " + imw
795 + " anim layer: " + dialog.mWinAnimator.mAnimLayer);
796 }
797 }
798
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -0700799 /**
800 * If a window that has an animation specifying a colored background and the current wallpaper
801 * is visible, then the color goes *below* the wallpaper so we don't cause the wallpaper to
802 * suddenly disappear.
803 */
804 int getLayerForAnimationBackground(WindowStateAnimator winAnimator) {
805 for (int i = mWindows.size() - 1; i >= 0; --i) {
806 final WindowState win = mWindows.get(i);
807 if (win.mIsWallpaper && win.isVisibleNow()) {
808 return win.mWinAnimator.mAnimLayer;
809 }
810 }
811 return winAnimator.mAnimLayer;
812 }
813
Wale Ogunwale10124582016-09-15 20:25:50 -0700814 void prepareFreezingTaskBounds() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700815 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
816 final TaskStack stack = mTaskStackContainers.get(stackNdx);
Wale Ogunwale10124582016-09-15 20:25:50 -0700817 stack.prepareFreezingTaskBounds();
818 }
819 }
820
Wale Ogunwale94744212015-09-21 19:01:47 -0700821 void rotateBounds(int oldRotation, int newRotation, Rect bounds) {
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700822 getLogicalDisplayRect(mTmpRect, newRotation);
823
824 // Compute a transform matrix to undo the coordinate space transformation,
825 // and present the window at the same physical position it previously occupied.
826 final int deltaRotation = deltaRotation(newRotation, oldRotation);
827 createRotationMatrix(deltaRotation, mTmpRect.width(), mTmpRect.height(), mTmpMatrix);
828
829 mTmpRectF.set(bounds);
830 mTmpMatrix.mapRect(mTmpRectF);
831 mTmpRectF.round(bounds);
Wale Ogunwale94744212015-09-21 19:01:47 -0700832 }
833
Wale Ogunwale4a02d812015-02-12 23:01:38 -0800834 static int deltaRotation(int oldRotation, int newRotation) {
835 int delta = newRotation - oldRotation;
836 if (delta < 0) delta += 4;
837 return delta;
838 }
839
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700840 private static void createRotationMatrix(int rotation, float displayWidth, float displayHeight,
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700841 Matrix outMatrix) {
842 // For rotations without Z-ordering we don't need the target rectangle's position.
843 createRotationMatrix(rotation, 0 /* rectLeft */, 0 /* rectTop */, displayWidth,
844 displayHeight, outMatrix);
845 }
846
847 static void createRotationMatrix(int rotation, float rectLeft, float rectTop,
848 float displayWidth, float displayHeight, Matrix outMatrix) {
849 switch (rotation) {
850 case ROTATION_0:
851 outMatrix.reset();
852 break;
853 case ROTATION_270:
854 outMatrix.setRotate(270, 0, 0);
855 outMatrix.postTranslate(0, displayHeight);
856 outMatrix.postTranslate(rectTop, 0);
857 break;
858 case ROTATION_180:
859 outMatrix.reset();
860 break;
861 case ROTATION_90:
862 outMatrix.setRotate(90, 0, 0);
863 outMatrix.postTranslate(displayWidth, 0);
864 outMatrix.postTranslate(-rectTop, rectLeft);
865 break;
866 }
867 }
868
Craig Mautnera91f9e22012-09-14 16:22:08 -0700869 public void dump(String prefix, PrintWriter pw) {
870 pw.print(prefix); pw.print("Display: mDisplayId="); pw.println(mDisplayId);
871 final String subPrefix = " " + prefix;
872 pw.print(subPrefix); pw.print("init="); pw.print(mInitialDisplayWidth); pw.print("x");
873 pw.print(mInitialDisplayHeight); pw.print(" "); pw.print(mInitialDisplayDensity);
874 pw.print("dpi");
875 if (mInitialDisplayWidth != mBaseDisplayWidth
876 || mInitialDisplayHeight != mBaseDisplayHeight
877 || mInitialDisplayDensity != mBaseDisplayDensity) {
878 pw.print(" base=");
879 pw.print(mBaseDisplayWidth); pw.print("x"); pw.print(mBaseDisplayHeight);
880 pw.print(" "); pw.print(mBaseDisplayDensity); pw.print("dpi");
881 }
Jeff Brownd46747a2015-04-15 19:02:36 -0700882 if (mDisplayScalingDisabled) {
883 pw.println(" noscale");
884 }
Craig Mautnera91f9e22012-09-14 16:22:08 -0700885 pw.print(" cur=");
886 pw.print(mDisplayInfo.logicalWidth);
887 pw.print("x"); pw.print(mDisplayInfo.logicalHeight);
888 pw.print(" app=");
889 pw.print(mDisplayInfo.appWidth);
890 pw.print("x"); pw.print(mDisplayInfo.appHeight);
891 pw.print(" rng="); pw.print(mDisplayInfo.smallestNominalAppWidth);
892 pw.print("x"); pw.print(mDisplayInfo.smallestNominalAppHeight);
893 pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth);
894 pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight);
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700895 pw.println(subPrefix + "deferred=" + mDeferredRemoval
896 + " mLayoutNeeded=" + mLayoutNeeded);
Wale Ogunwaleb429e682016-01-06 12:36:34 -0800897
Craig Mautnerdc548482014-02-05 13:35:24 -0800898 pw.println();
Craig Mautnere8b85fd2014-10-22 09:23:25 -0700899 pw.println(" Application tokens in top down Z order:");
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700900 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
901 final TaskStack stack = mTaskStackContainers.get(stackNdx);
Wale Ogunwaleb429e682016-01-06 12:36:34 -0800902 stack.dump(prefix + " ", pw);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700903 }
Wale Ogunwaleb429e682016-01-06 12:36:34 -0800904
Craig Mautnerdc548482014-02-05 13:35:24 -0800905 pw.println();
906 if (!mExitingTokens.isEmpty()) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700907 pw.println();
908 pw.println(" Exiting tokens:");
Wale Ogunwaleb429e682016-01-06 12:36:34 -0800909 for (int i = mExitingTokens.size() - 1; i >= 0; i--) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700910 final WindowToken token = mExitingTokens.get(i);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700911 pw.print(" Exiting #"); pw.print(i);
912 pw.print(' '); pw.print(token);
913 pw.println(':');
914 token.dump(pw, " ");
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800915 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700916 }
Craig Mautner59c00972012-07-30 12:10:24 -0700917 pw.println();
Chong Zhang112eb8c2015-11-02 11:17:00 -0800918 mDimLayerController.dump(prefix + " ", pw);
Jorim Jaggi31f71702016-05-04 16:43:04 -0700919 pw.println();
920 mDividerControllerLocked.dump(prefix + " ", pw);
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700921
922 if (mInputMethodAnimLayerAdjustment != 0) {
923 pw.println(subPrefix
924 + "mInputMethodAnimLayerAdjustment=" + mInputMethodAnimLayerAdjustment);
925 }
Craig Mautner59c00972012-07-30 12:10:24 -0700926 }
Craig Mautnere0a38842013-12-16 16:14:02 -0800927
928 @Override
929 public String toString() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700930 return "Display " + mDisplayId + " info=" + mDisplayInfo + " stacks=" + mChildren;
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700931 }
932
933 String getName() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700934 return "Display " + mDisplayId + " name=\"" + mDisplayInfo.name + "\"";
Craig Mautnere0a38842013-12-16 16:14:02 -0800935 }
Filip Gruszczynski466f3212015-09-21 17:57:57 -0700936
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800937 /**
938 * @return The docked stack, but only if it is visible, and {@code null} otherwise.
939 */
Filip Gruszczynski3ddc5d62015-09-23 15:01:30 -0700940 TaskStack getDockedStackLocked() {
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700941 final TaskStack stack = mService.mStackIdToStack.get(DOCKED_STACK_ID);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700942 return (stack != null && stack.isVisible()) ? stack : null;
Filip Gruszczynski466f3212015-09-21 17:57:57 -0700943 }
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -0800944
945 /**
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800946 * Like {@link #getDockedStackLocked}, but also returns the docked stack if it's currently not
947 * visible, as long as it's not hidden because the current user doesn't have any tasks there.
948 */
949 TaskStack getDockedStackVisibleForUserLocked() {
950 final TaskStack stack = mService.mStackIdToStack.get(DOCKED_STACK_ID);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700951 return (stack != null && stack.isVisible(true /* ignoreKeyguard */)) ? stack : null;
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800952 }
953
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700954 /** Find the visible, touch-deliverable window under the given point */
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -0800955 WindowState getTouchableWinAtPointLocked(float xf, float yf) {
956 WindowState touchedWin = null;
957 final int x = (int) xf;
958 final int y = (int) yf;
959
960 for (int i = mWindows.size() - 1; i >= 0; i--) {
961 WindowState window = mWindows.get(i);
962 final int flags = window.mAttrs.flags;
963 if (!window.isVisibleLw()) {
964 continue;
965 }
966 if ((flags & FLAG_NOT_TOUCHABLE) != 0) {
967 continue;
968 }
969
970 window.getVisibleBounds(mTmpRect);
971 if (!mTmpRect.contains(x, y)) {
972 continue;
973 }
974
975 window.getTouchableRegion(mTmpRegion);
976
977 final int touchFlags = flags & (FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL);
978 if (mTmpRegion.contains(x, y) || touchFlags == 0) {
979 touchedWin = window;
980 break;
981 }
982 }
983
984 return touchedWin;
985 }
Jorim Jaggi6626f542016-08-22 13:08:44 -0700986
Svetoslav Ganovaa076532016-08-01 19:16:43 -0700987 boolean canAddToastWindowForUid(int uid) {
988 // We allow one toast window per UID being shown at a time.
989 WindowList windows = getWindowList();
990 final int windowCount = windows.size();
991 for (int i = 0; i < windowCount; i++) {
992 WindowState window = windows.get(i);
993 if (window.mAttrs.type == TYPE_TOAST && window.mOwnerUid == uid
Svet Ganov62a40f82016-09-29 00:43:51 -0700994 && !window.mPermanentlyHidden && !window.mAnimatingExit
995 && !window.mRemoveOnExit) {
Svetoslav Ganovaa076532016-08-01 19:16:43 -0700996 return false;
997 }
998 }
999 return true;
1000 }
1001
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001002 void scheduleToastWindowsTimeoutIfNeededLocked(WindowState oldFocus, WindowState newFocus) {
Svetoslav Ganovaa076532016-08-01 19:16:43 -07001003 if (oldFocus == null || (newFocus != null && newFocus.mOwnerUid == oldFocus.mOwnerUid)) {
1004 return;
1005 }
1006 final int lostFocusUid = oldFocus.mOwnerUid;
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001007 final WindowList windows = getWindowList();
Svetoslav Ganovaa076532016-08-01 19:16:43 -07001008 final int windowCount = windows.size();
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001009 final Handler handler = mService.mH;
Svetoslav Ganovaa076532016-08-01 19:16:43 -07001010 for (int i = 0; i < windowCount; i++) {
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001011 final WindowState window = windows.get(i);
Svetoslav Ganovaa076532016-08-01 19:16:43 -07001012 if (window.mAttrs.type == TYPE_TOAST && window.mOwnerUid == lostFocusUid) {
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001013 if (!handler.hasMessages(WINDOW_HIDE_TIMEOUT, window)) {
1014 handler.sendMessageDelayed(handler.obtainMessage(WINDOW_HIDE_TIMEOUT, window),
Svetoslav Ganovaa076532016-08-01 19:16:43 -07001015 window.mAttrs.hideTimeoutMilliseconds);
1016 }
1017 }
1018 }
1019 }
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -07001020
1021 WindowState findFocusedWindow() {
1022 final AppWindowToken focusedApp = mService.mFocusedApp;
1023
1024 for (int i = mWindows.size() - 1; i >= 0; i--) {
1025 final WindowState win = mWindows.get(i);
1026
1027 if (DEBUG_FOCUS) Slog.v(TAG_WM, "Looking for focus: " + i + " = " + win
1028 + ", flags=" + win.mAttrs.flags + ", canReceive=" + win.canReceiveKeys());
1029
1030 if (!win.canReceiveKeys()) {
1031 continue;
1032 }
1033
1034 final AppWindowToken wtoken = win.mAppToken;
1035
1036 // If this window's application has been removed, just skip it.
1037 if (wtoken != null && (wtoken.removed || wtoken.sendingToBottom)) {
1038 if (DEBUG_FOCUS) Slog.v(TAG_WM, "Skipping " + wtoken + " because "
1039 + (wtoken.removed ? "removed" : "sendingToBottom"));
1040 continue;
1041 }
1042
1043 if (focusedApp == null) {
1044 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp=null"
1045 + " using new focus @ " + i + " = " + win);
1046 return win;
1047 }
1048
1049 if (!focusedApp.windowsAreFocusable()) {
1050 // Current focused app windows aren't focusable...
1051 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp windows not"
1052 + " focusable using new focus @ " + i + " = " + win);
1053 return win;
1054 }
1055
1056 // Descend through all of the app tokens and find the first that either matches
1057 // win.mAppToken (return win) or mFocusedApp (return null).
1058 if (wtoken != null && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
Wale Ogunwale10124582016-09-15 20:25:50 -07001059 if (focusedApp.compareTo(wtoken) > 0) {
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -07001060 // App stack below focused app stack. No focus for you!!!
1061 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM,
1062 "findFocusedWindow: Reached focused app=" + focusedApp);
1063 return null;
1064 }
1065 }
1066
1067 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: Found new focus @ "
1068 + i + " = " + win);
1069 return win;
1070 }
1071
1072 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: No focusable windows.");
1073 return null;
1074 }
Wale Ogunwaleec731152016-09-08 20:18:57 -07001075
1076 int addAppWindowToWindowList(final WindowState win) {
1077 final IWindow client = win.mClient;
1078
1079 WindowList tokenWindowList = getTokenWindowsOnDisplay(win.mToken);
1080 if (!tokenWindowList.isEmpty()) {
1081 return addAppWindowExisting(win, tokenWindowList);
1082 }
1083
1084 // No windows from this token on this display
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001085 if (localLOGV) Slog.v(TAG_WM, "Figuring out where to add app window "
Wale Ogunwaleec731152016-09-08 20:18:57 -07001086 + client.asBinder() + " (token=" + this + ")");
1087
1088 final WindowToken wToken = win.mToken;
1089
1090 // Figure out where the window should go, based on the order of applications.
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001091 mTmpGetWindowOnDisplaySearchResult.reset();
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001092 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
1093 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001094 stack.getWindowOnDisplayBeforeToken(this, wToken, mTmpGetWindowOnDisplaySearchResult);
1095 if (mTmpGetWindowOnDisplaySearchResult.reachedToken) {
Wale Ogunwaleec731152016-09-08 20:18:57 -07001096 // We have reach the token we are interested in. End search.
1097 break;
1098 }
1099 }
1100
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001101 WindowState pos = mTmpGetWindowOnDisplaySearchResult.foundWindow;
Wale Ogunwaleec731152016-09-08 20:18:57 -07001102
1103 // We now know the index into the apps. If we found an app window above, that gives us the
1104 // position; else we need to look some more.
1105 if (pos != null) {
1106 // Move behind any windows attached to this one.
Wale Ogunwale02319a62016-09-26 15:21:22 -07001107 final WindowToken atoken = getWindowToken(pos.mClient.asBinder());
Wale Ogunwaleec731152016-09-08 20:18:57 -07001108 if (atoken != null) {
1109 tokenWindowList = getTokenWindowsOnDisplay(atoken);
1110 final int NC = tokenWindowList.size();
1111 if (NC > 0) {
1112 WindowState bottom = tokenWindowList.get(0);
1113 if (bottom.mSubLayer < 0) {
1114 pos = bottom;
1115 }
1116 }
1117 }
1118 addWindowToListBefore(win, pos);
1119 return 0;
1120 }
1121
1122 // Continue looking down until we find the first token that has windows on this display.
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001123 mTmpGetWindowOnDisplaySearchResult.reset();
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001124 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
1125 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001126 stack.getWindowOnDisplayAfterToken(this, wToken, mTmpGetWindowOnDisplaySearchResult);
1127 if (mTmpGetWindowOnDisplaySearchResult.foundWindow != null) {
Wale Ogunwaleec731152016-09-08 20:18:57 -07001128 // We have found a window after the token. End search.
1129 break;
1130 }
1131 }
1132
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001133 pos = mTmpGetWindowOnDisplaySearchResult.foundWindow;
Wale Ogunwaleec731152016-09-08 20:18:57 -07001134
1135 if (pos != null) {
1136 // Move in front of any windows attached to this one.
Wale Ogunwale02319a62016-09-26 15:21:22 -07001137 final WindowToken atoken = getWindowToken(pos.mClient.asBinder());
Wale Ogunwaleec731152016-09-08 20:18:57 -07001138 if (atoken != null) {
1139 final WindowState top = atoken.getTopWindow();
1140 if (top != null && top.mSubLayer >= 0) {
1141 pos = top;
1142 }
1143 }
1144 addWindowToListAfter(win, pos);
1145 return 0;
1146 }
1147
1148 // Just search for the start of this layer.
1149 final int myLayer = win.mBaseLayer;
1150 int i;
1151 for (i = mWindows.size() - 1; i >= 0; --i) {
1152 final WindowState w = mWindows.get(i);
1153 // Dock divider shares the base layer with application windows, but we want to always
1154 // keep it above the application windows. The sharing of the base layer is intended
1155 // for window animations, which need to be above the dock divider for the duration
1156 // of the animation.
1157 if (w.mBaseLayer <= myLayer && w.mAttrs.type != TYPE_DOCK_DIVIDER) {
1158 break;
1159 }
1160 }
1161 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1162 "Based on layer: Adding window " + win + " at " + (i + 1) + " of "
1163 + mWindows.size());
1164 mWindows.add(i + 1, win);
1165 mService.mWindowsChanged = true;
1166 return 0;
1167 }
1168
1169 /** Adds this non-app window to the window list. */
1170 void addNonAppWindowToWindowList(WindowState win) {
1171 // Figure out where window should go, based on layer.
1172 int i;
1173 for (i = mWindows.size() - 1; i >= 0; i--) {
1174 final WindowState otherWin = mWindows.get(i);
1175 if (otherWin.getBaseType() != TYPE_WALLPAPER && otherWin.mBaseLayer <= win.mBaseLayer) {
1176 // Wallpaper wanders through the window list, for example to position itself
1177 // directly behind keyguard. Because of this it will break the ordering based on
1178 // WindowState.mBaseLayer. There might windows with higher mBaseLayer behind it and
1179 // we don't want the new window to appear above them. An example of this is adding
1180 // of the docked stack divider. Consider a scenario with the following ordering (top
1181 // to bottom): keyguard, wallpaper, assist preview, apps. We want the dock divider
1182 // to land below the assist preview, so the dock divider must ignore the wallpaper,
1183 // with which it shares the base layer.
1184 break;
1185 }
1186 }
1187
1188 i++;
1189 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1190 "Free window: Adding window " + this + " at " + i + " of " + mWindows.size());
1191 mWindows.add(i, win);
1192 mService.mWindowsChanged = true;
1193 }
1194
Wale Ogunwaleb9a07c32016-10-12 14:55:56 -07001195 void addToWindowList(WindowState win, int index) {
1196 mWindows.add(index, win);
1197 }
1198
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07001199 boolean removeFromWindowList(WindowState win) {
1200 return mWindows.remove(win);
1201 }
1202
1203 private int removeWindowAndChildrenFromWindowList(WindowState win, int interestingPos) {
1204 final WindowList windows = getWindowList();
1205 int wpos = windows.indexOf(win);
1206 if (wpos < 0) {
1207 return interestingPos;
1208 }
1209
1210 if (wpos < interestingPos) interestingPos--;
1211 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Temp removing at " + wpos + ": " + this);
1212 windows.remove(wpos);
1213 mService.mWindowsChanged = true;
1214 int childWinCount = win.mChildren.size();
1215 while (childWinCount > 0) {
1216 childWinCount--;
1217 final WindowState cw = win.mChildren.get(childWinCount);
1218 int cpos = windows.indexOf(cw);
1219 if (cpos >= 0) {
1220 if (cpos < interestingPos) interestingPos--;
1221 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM,
1222 "Temp removing child at " + cpos + ": " + cw);
1223 windows.remove(cpos);
1224 }
1225 }
1226 return interestingPos;
1227 }
1228
Wale Ogunwaleec731152016-09-08 20:18:57 -07001229 void addChildWindowToWindowList(WindowState win) {
1230 final WindowState parentWindow = win.getParentWindow();
1231
1232 WindowList windowsOnSameDisplay = getTokenWindowsOnDisplay(win.mToken);
1233
1234 // Figure out this window's ordering relative to the parent window.
1235 final int wCount = windowsOnSameDisplay.size();
1236 final int sublayer = win.mSubLayer;
1237 int largestSublayer = Integer.MIN_VALUE;
1238 WindowState windowWithLargestSublayer = null;
1239 int i;
1240 for (i = 0; i < wCount; i++) {
1241 WindowState w = windowsOnSameDisplay.get(i);
1242 final int wSublayer = w.mSubLayer;
1243 if (wSublayer >= largestSublayer) {
1244 largestSublayer = wSublayer;
1245 windowWithLargestSublayer = w;
1246 }
1247 if (sublayer < 0) {
1248 // For negative sublayers, we go below all windows in the same sublayer.
1249 if (wSublayer >= sublayer) {
1250 addWindowToListBefore(win, wSublayer >= 0 ? parentWindow : w);
1251 break;
1252 }
1253 } else {
1254 // For positive sublayers, we go above all windows in the same sublayer.
1255 if (wSublayer > sublayer) {
1256 addWindowToListBefore(win, w);
1257 break;
1258 }
1259 }
1260 }
1261 if (i >= wCount) {
1262 if (sublayer < 0) {
1263 addWindowToListBefore(win, parentWindow);
1264 } else {
1265 addWindowToListAfter(win,
1266 largestSublayer >= 0 ? windowWithLargestSublayer : parentWindow);
1267 }
1268 }
1269 }
1270
Wale Ogunwalec69694a2016-10-18 13:51:15 -07001271 /** Updates the layer assignment of windows on this display. */
1272 void assignWindowLayers(boolean setLayoutNeeded) {
1273 mLayersController.assignWindowLayers(mWindows);
1274 if (setLayoutNeeded) {
1275 setLayoutNeeded();
1276 }
1277 }
1278
Wale Ogunwale0303c572016-10-20 10:16:29 -07001279 void adjustWallpaperWindows() {
1280 if (mWallpaperController.adjustWallpaperWindows(mWindows)) {
1281 assignWindowLayers(true /*setLayoutNeeded*/);
1282 }
1283 }
1284
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001285 /**
1286 * Z-orders the display window list so that:
1287 * <ul>
1288 * <li>Any windows that are currently below the wallpaper window stay below the wallpaper
1289 * window.
1290 * <li>Exiting application windows are at the bottom, but above the wallpaper window.
1291 * <li>All other application windows are above the exiting application windows and ordered based
1292 * on the ordering of their stacks and tasks on the display.
1293 * <li>Non-application windows are at the very top.
1294 * </ul>
1295 * <p>
1296 * NOTE: This isn't a complete picture of what the user see. Further manipulation of the window
1297 * surface layering is done in {@link WindowLayersController}.
1298 */
1299 void rebuildAppWindowList() {
1300 int count = mWindows.size();
1301 int i;
1302 int lastBelow = -1;
1303 int numRemoved = 0;
1304
1305 if (mRebuildTmp.length < count) {
1306 mRebuildTmp = new WindowState[count + 10];
1307 }
1308
1309 // First remove all existing app windows.
1310 i = 0;
1311 while (i < count) {
1312 final WindowState w = mWindows.get(i);
1313 if (w.mAppToken != null) {
1314 final WindowState win = mWindows.remove(i);
1315 win.mRebuilding = true;
1316 mRebuildTmp[numRemoved] = win;
1317 mService.mWindowsChanged = true;
1318 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Rebuild removing window: " + win);
1319 count--;
1320 numRemoved++;
1321 continue;
1322 } else if (lastBelow == i-1) {
1323 if (w.mAttrs.type == TYPE_WALLPAPER) {
1324 lastBelow = i;
1325 }
1326 }
1327 i++;
1328 }
1329
1330 // Keep whatever windows were below the app windows still below, by skipping them.
1331 lastBelow++;
1332 i = lastBelow;
1333
1334 // First add all of the exiting app tokens... these are no longer in the main app list,
1335 // but still have windows shown. We put them in the back because now that the animation is
1336 // over we no longer will care about them.
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001337 final int numStacks = mTaskStackContainers.size();
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001338 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001339 AppTokenList exitingAppTokens = mTaskStackContainers.get(stackNdx).mExitingAppTokens;
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001340 int NT = exitingAppTokens.size();
1341 for (int j = 0; j < NT; j++) {
Wale Ogunwale360a8bc2016-10-10 13:25:26 -07001342 i = exitingAppTokens.get(j).rebuildWindowListUnchecked(i);
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001343 }
1344 }
1345
1346 // And add in the still active app tokens in Z order.
1347 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001348 i = mTaskStackContainers.get(stackNdx).rebuildWindowList(i);
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001349 }
1350
1351 i -= lastBelow;
1352 if (i != numRemoved) {
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001353 setLayoutNeeded();
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001354 Slog.w(TAG_WM, "On display=" + mDisplayId + " Rebuild removed " + numRemoved
1355 + " windows but added " + i + " rebuildAppWindowListLocked() "
1356 + " callers=" + Debug.getCallers(10));
1357 for (i = 0; i < numRemoved; i++) {
1358 WindowState ws = mRebuildTmp[i];
1359 if (ws.mRebuilding) {
1360 StringWriter sw = new StringWriter();
1361 PrintWriter pw = new FastPrintWriter(sw, false, 1024);
1362 ws.dump(pw, "", true);
1363 pw.flush();
1364 Slog.w(TAG_WM, "This window was lost: " + ws);
1365 Slog.w(TAG_WM, sw.toString());
1366 ws.mWinAnimator.destroySurfaceLocked();
1367 }
1368 }
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07001369 Slog.w(TAG_WM, "Current window hierarchy:");
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001370 dumpChildrenNames();
1371 Slog.w(TAG_WM, "Final window list:");
1372 dumpWindows();
1373 }
1374 Arrays.fill(mRebuildTmp, null);
1375 }
1376
Wale Ogunwaleec731152016-09-08 20:18:57 -07001377 /** Return the list of Windows on this display associated with the input token. */
1378 WindowList getTokenWindowsOnDisplay(WindowToken token) {
1379 final WindowList windowList = new WindowList();
1380 final int count = mWindows.size();
1381 for (int i = 0; i < count; i++) {
1382 final WindowState win = mWindows.get(i);
1383 if (win.mToken == token) {
1384 windowList.add(win);
1385 }
1386 }
1387 return windowList;
1388 }
1389
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07001390 private void reAddToWindowList(WindowState win) {
1391 win.mToken.addWindow(win);
1392 // This is a hack to get all of the child windows added as well at the right position. Child
1393 // windows should be rare and this case should be rare, so it shouldn't be that big a deal.
1394 int wpos = mWindows.indexOf(win);
1395 if (wpos >= 0) {
1396 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "ReAdd removing from " + wpos + ": " + win);
1397 mWindows.remove(wpos);
1398 mService.mWindowsChanged = true;
1399 win.reAddWindow(wpos);
1400 }
1401 }
1402
1403 void moveInputMethodDialogs(int pos) {
1404 ArrayList<WindowState> dialogs = mService.mInputMethodDialogs;
1405
1406 final int N = dialogs.size();
1407 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Removing " + N + " dialogs w/pos=" + pos);
1408 for (int i = 0; i < N; i++) {
1409 pos = removeWindowAndChildrenFromWindowList(dialogs.get(i), pos);
1410 }
1411 if (DEBUG_INPUT_METHOD) {
1412 Slog.v(TAG_WM, "Window list w/pos=" + pos);
1413 logWindowList(mWindows, " ");
1414 }
1415
1416 WindowState ime = mService.mInputMethodWindow;
1417 if (pos >= 0) {
1418 // Skip windows owned by the input method.
1419 if (ime != null) {
1420 while (pos < mWindows.size()) {
1421 WindowState wp = mWindows.get(pos);
1422 if (wp == ime || wp.getParentWindow() == ime) {
1423 pos++;
1424 continue;
1425 }
1426 break;
1427 }
1428 }
1429 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Adding " + N + " dialogs at pos=" + pos);
1430 for (int i=0; i<N; i++) {
1431 WindowState win = dialogs.get(i);
1432 pos = win.reAddWindow(pos);
1433 }
1434 if (DEBUG_INPUT_METHOD) {
1435 Slog.v(TAG_WM, "Final window list:");
1436 logWindowList(mWindows, " ");
1437 }
1438 return;
1439 }
1440 for (int i=0; i<N; i++) {
1441 WindowState win = dialogs.get(i);
1442 reAddToWindowList(win);
1443 if (DEBUG_INPUT_METHOD) {
1444 Slog.v(TAG_WM, "No IM target, final list:");
1445 logWindowList(mWindows, " ");
1446 }
1447 }
1448 }
1449
1450 boolean moveInputMethodWindowsIfNeeded(boolean needAssignLayers) {
1451 final WindowState imWin = mService.mInputMethodWindow;
1452 final int DN = mService.mInputMethodDialogs.size();
1453 if (imWin == null && DN == 0) {
1454 return false;
1455 }
1456
1457 // TODO(multidisplay): IMEs are only supported on the default display.
1458 WindowList windows = mWindows;
1459
1460 int imPos = findDesiredInputMethodWindowIndex(true);
1461 if (imPos >= 0) {
1462 // In this case, the input method windows are to be placed
1463 // immediately above the window they are targeting.
1464
1465 // First check to see if the input method windows are already
1466 // located here, and contiguous.
1467 final int N = windows.size();
1468 final WindowState firstImWin = imPos < N ? windows.get(imPos) : null;
1469
1470 // Figure out the actual input method window that should be
1471 // at the bottom of their stack.
1472 WindowState baseImWin = imWin != null ? imWin : mService.mInputMethodDialogs.get(0);
1473 final WindowState cw = baseImWin.getBottomChild();
1474 if (cw != null && cw.mSubLayer < 0) {
1475 baseImWin = cw;
1476 }
1477
1478 if (firstImWin == baseImWin) {
1479 // The windows haven't moved... but are they still contiguous?
1480 // First find the top IM window.
1481 int pos = imPos+1;
1482 while (pos < N) {
1483 if (!(windows.get(pos)).mIsImWindow) {
1484 break;
1485 }
1486 pos++;
1487 }
1488 pos++;
1489 // Now there should be no more input method windows above.
1490 while (pos < N) {
1491 if ((windows.get(pos)).mIsImWindow) {
1492 break;
1493 }
1494 pos++;
1495 }
1496 if (pos >= N) {
1497 return false;
1498 }
1499 }
1500
1501 if (imWin != null) {
1502 if (DEBUG_INPUT_METHOD) {
1503 Slog.v(TAG_WM, "Moving IM from " + imPos);
1504 logWindowList(windows, " ");
1505 }
1506 imPos = removeWindowAndChildrenFromWindowList(imWin, imPos);
1507 if (DEBUG_INPUT_METHOD) {
1508 Slog.v(TAG_WM, "List after removing with new pos " + imPos + ":");
1509 logWindowList(windows, " ");
1510 }
1511 imWin.reAddWindow(imPos);
1512 if (DEBUG_INPUT_METHOD) {
1513 Slog.v(TAG_WM, "List after moving IM to " + imPos + ":");
1514 logWindowList(windows, " ");
1515 }
1516 if (DN > 0) moveInputMethodDialogs(imPos+1);
1517 } else {
1518 moveInputMethodDialogs(imPos);
1519 }
1520
1521 } else {
1522 // In this case, the input method windows go in a fixed layer,
1523 // because they aren't currently associated with a focus window.
1524
1525 if (imWin != null) {
1526 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Moving IM from " + imPos);
1527 removeWindowAndChildrenFromWindowList(imWin, 0);
1528 reAddToWindowList(imWin);
1529 if (DEBUG_INPUT_METHOD) {
1530 Slog.v(TAG_WM, "List with no IM target:");
1531 logWindowList(windows, " ");
1532 }
1533 if (DN > 0) moveInputMethodDialogs(-1);
1534 } else {
1535 moveInputMethodDialogs(-1);
1536 }
1537
1538 }
1539
1540 if (needAssignLayers) {
1541 assignWindowLayers(false /* setLayoutNeeded */);
1542 }
1543
1544 return true;
1545 }
1546
1547 /**
1548 * Dig through the WindowStates and find the one that the Input Method will target.
1549 * @param willMove
1550 * @return The index+1 in mWindows of the discovered target.
1551 */
1552 int findDesiredInputMethodWindowIndex(boolean willMove) {
1553 // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the
1554 // same display. Or even when the current IME/target are not on the same screen as the next
1555 // IME/target. For now only look for input windows on the main screen.
1556 final WindowList windows = getWindowList();
1557 WindowState w = null;
1558 int i;
1559 for (i = windows.size() - 1; i >= 0; --i) {
1560 WindowState win = windows.get(i);
1561
1562 if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG_WM, "Checking window @" + i
1563 + " " + win + " fl=0x" + Integer.toHexString(win.mAttrs.flags));
1564 if (canBeImeTarget(win)) {
1565 w = win;
1566 //Slog.i(TAG_WM, "Putting input method here!");
1567
1568 // Yet more tricksyness! If this window is a "starting" window, we do actually want
1569 // to be on top of it, but it is not -really- where input will go. So if the caller
1570 // is not actually looking to move the IME, look down below for a real window to
1571 // target...
1572 if (!willMove && w.mAttrs.type == TYPE_APPLICATION_STARTING && i > 0) {
1573 WindowState wb = windows.get(i-1);
1574 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
1575 i--;
1576 w = wb;
1577 }
1578 }
1579 break;
1580 }
1581 }
1582
1583 // Now w is either mWindows[0] or an IME (or null if mWindows is empty).
1584
1585 if (DEBUG_INPUT_METHOD && willMove) Slog.v(TAG_WM, "Proposed new IME target: " + w);
1586
1587 // Now, a special case -- if the last target's window is in the process of exiting, and is
1588 // above the new target, keep on the last target to avoid flicker. Consider for example a
1589 // Dialog with the IME shown: when the Dialog is dismissed, we want to keep the IME above it
1590 // until it is completely gone so it doesn't drop behind the dialog or its full-screen
1591 // scrim.
1592 final WindowState curTarget = mService.mInputMethodTarget;
1593 if (curTarget != null
1594 && curTarget.isDisplayedLw()
1595 && curTarget.isClosing()
1596 && (w == null || curTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer)) {
1597 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Current target higher, not changing");
1598 return windows.indexOf(curTarget) + 1;
1599 }
1600
1601 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Desired input method target="
1602 + w + " willMove=" + willMove);
1603
1604 if (willMove && w != null) {
1605 AppWindowToken token = curTarget == null ? null : curTarget.mAppToken;
1606 if (token != null) {
1607
1608 // Now some fun for dealing with window animations that modify the Z order. We need
1609 // to look at all windows below the current target that are in this app, finding the
1610 // highest visible one in layering.
1611 WindowState highestTarget = null;
1612 int highestPos = 0;
1613 if (token.mAppAnimator.animating || token.mAppAnimator.animation != null) {
1614 WindowList curWindows = token.getDisplayContent().getWindowList();
1615 int pos = curWindows.indexOf(curTarget);
1616 while (pos >= 0) {
1617 WindowState win = curWindows.get(pos);
1618 if (win.mAppToken != token) {
1619 break;
1620 }
1621 if (!win.mRemoved) {
1622 if (highestTarget == null || win.mWinAnimator.mAnimLayer >
1623 highestTarget.mWinAnimator.mAnimLayer) {
1624 highestTarget = win;
1625 highestPos = pos;
1626 }
1627 }
1628 pos--;
1629 }
1630 }
1631
1632 if (highestTarget != null) {
1633 final AppTransition appTransition = mService.mAppTransition;
1634 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, appTransition + " " + highestTarget
1635 + " animating=" + highestTarget.mWinAnimator.isAnimationSet()
1636 + " layer=" + highestTarget.mWinAnimator.mAnimLayer
1637 + " new layer=" + w.mWinAnimator.mAnimLayer);
1638
1639 if (appTransition.isTransitionSet()) {
1640 // If we are currently setting up for an animation, hold everything until we
1641 // can find out what will happen.
1642 mService.mInputMethodTargetWaitingAnim = true;
1643 mService.mInputMethodTarget = highestTarget;
1644 return highestPos + 1;
1645 } else if (highestTarget.mWinAnimator.isAnimationSet() &&
1646 highestTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
1647 // If the window we are currently targeting is involved with an animation,
1648 // and it is on top of the next target we will be over, then hold off on
1649 // moving until that is done.
1650 mService.mInputMethodTargetWaitingAnim = true;
1651 mService.mInputMethodTarget = highestTarget;
1652 return highestPos + 1;
1653 }
1654 }
1655 }
1656 }
1657
1658 //Slog.i(TAG_WM, "Placing input method @" + (i+1));
1659 if (w != null) {
1660 if (willMove) {
1661 if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to "
1662 + w + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : ""));
1663 mService.mInputMethodTarget = w;
1664 mService.mInputMethodTargetWaitingAnim = false;
1665 if (w.mAppToken != null) {
1666 setInputMethodAnimLayerAdjustment(
1667 w.mAppToken.mAppAnimator.animLayerAdjustment);
1668 } else {
1669 setInputMethodAnimLayerAdjustment(0);
1670 }
1671 }
1672
1673 // If the docked divider is visible, we still need to go through this whole excercise to
1674 // find the appropriate input method target (used for animations and dialog
1675 // adjustments), but for purposes of Z ordering we simply wish to place it above the
1676 // docked divider. Unless it is already above the divider.
1677 final WindowState dockedDivider = mDividerControllerLocked.getWindow();
1678 if (dockedDivider != null && dockedDivider.isVisibleLw()) {
1679 int dividerIndex = windows.indexOf(dockedDivider);
1680 if (dividerIndex > 0 && dividerIndex > i) {
1681 return dividerIndex + 1;
1682 }
1683 }
1684 return i+1;
1685 }
1686 if (willMove) {
1687 if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget
1688 + " to null." + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : ""));
1689 mService.mInputMethodTarget = null;
1690 setInputMethodAnimLayerAdjustment(0);
1691 }
1692 return -1;
1693 }
1694
1695 private static boolean canBeImeTarget(WindowState w) {
1696 final int fl = w.mAttrs.flags & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
1697 final int type = w.mAttrs.type;
1698
1699 if (fl != 0 && fl != (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM)
1700 && type != TYPE_APPLICATION_STARTING) {
1701 return false;
1702 }
1703
1704 if (DEBUG_INPUT_METHOD) {
1705 Slog.i(TAG_WM, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
1706 if (!w.isVisibleOrAdding()) {
1707 Slog.i(TAG_WM, " mSurfaceController=" + w.mWinAnimator.mSurfaceController
1708 + " relayoutCalled=" + w.mRelayoutCalled
1709 + " viewVis=" + w.mViewVisibility
1710 + " policyVis=" + w.mPolicyVisibility
1711 + " policyVisAfterAnim=" + w.mPolicyVisibilityAfterAnim
1712 + " parentHidden=" + w.isParentWindowHidden()
1713 + " exiting=" + w.mAnimatingExit + " destroying=" + w.mDestroying);
1714 if (w.mAppToken != null) {
1715 Slog.i(TAG_WM, " mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested);
1716 }
1717 }
1718 }
1719 return w.isVisibleOrAdding();
1720 }
1721
1722 private void logWindowList(final WindowList windows, String prefix) {
1723 int N = windows.size();
1724 while (N > 0) {
1725 N--;
1726 Slog.v(TAG_WM, prefix + "#" + N + ": " + windows.get(N));
1727 }
1728 }
1729
1730 boolean getNeedsMenu(WindowState win, WindowManagerPolicy.WindowState bottom) {
1731 int index = -1;
1732 WindowList windows = getWindowList();
1733 while (true) {
1734 if (win.mAttrs.needsMenuKey != NEEDS_MENU_UNSET) {
1735 return win.mAttrs.needsMenuKey == NEEDS_MENU_SET_TRUE;
1736 }
1737 // If we reached the bottom of the range of windows we are considering,
1738 // assume no menu is needed.
1739 if (win == bottom) {
1740 return false;
1741 }
1742 // The current window hasn't specified whether menu key is needed; look behind it.
1743 // First, we may need to determine the starting position.
1744 if (index < 0) {
1745 index = windows.indexOf(win);
1746 }
1747 index--;
1748 if (index < 0) {
1749 return false;
1750 }
1751 win = windows.get(index);
1752 }
1753 }
1754
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001755 void setLayoutNeeded() {
1756 if (DEBUG_LAYOUT) Slog.w(TAG_WM, "setLayoutNeeded: callers=" + Debug.getCallers(3));
1757 mLayoutNeeded = true;
1758 }
1759
1760 void clearLayoutNeeded() {
1761 if (DEBUG_LAYOUT) Slog.w(TAG_WM, "clearLayoutNeeded: callers=" + Debug.getCallers(3));
1762 mLayoutNeeded = false;
1763 }
1764
1765 boolean isLayoutNeeded() {
1766 return mLayoutNeeded;
1767 }
1768
Wale Ogunwaleec731152016-09-08 20:18:57 -07001769 private int addAppWindowExisting(WindowState win, WindowList tokenWindowList) {
1770
1771 int tokenWindowsPos;
1772 // If this application has existing windows, we simply place the new window on top of
1773 // them... but keep the starting window on top.
1774 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
1775 // Base windows go behind everything else.
1776 final WindowState lowestWindow = tokenWindowList.get(0);
1777 addWindowToListBefore(win, lowestWindow);
1778 tokenWindowsPos = win.mToken.getWindowIndex(lowestWindow);
1779 } else {
1780 final AppWindowToken atoken = win.mAppToken;
1781 final int windowListPos = tokenWindowList.size();
1782 final WindowState lastWindow = tokenWindowList.get(windowListPos - 1);
1783 if (atoken != null && lastWindow == atoken.startingWindow) {
1784 addWindowToListBefore(win, lastWindow);
1785 tokenWindowsPos = win.mToken.getWindowIndex(lastWindow);
1786 } else {
1787 int newIdx = findIdxBasedOnAppTokens(win);
1788 // There is a window above this one associated with the same apptoken note that the
1789 // window could be a floating window that was created later or a window at the top
1790 // of the list of windows associated with this token.
1791 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1792 "not Base app: Adding window " + win + " at " + (newIdx + 1) + " of "
1793 + mWindows.size());
1794 mWindows.add(newIdx + 1, win);
1795 if (newIdx < 0) {
1796 // No window from token found on win's display.
1797 tokenWindowsPos = 0;
1798 } else {
1799 tokenWindowsPos = win.mToken.getWindowIndex(mWindows.get(newIdx)) + 1;
1800 }
1801 mService.mWindowsChanged = true;
1802 }
1803 }
1804 return tokenWindowsPos;
1805 }
1806
1807 /** Places the first input window after the second input window in the window list. */
1808 private void addWindowToListAfter(WindowState first, WindowState second) {
1809 final int i = mWindows.indexOf(second);
1810 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1811 "Adding window " + this + " at " + (i + 1) + " of " + mWindows.size()
1812 + " (after " + second + ")");
1813 mWindows.add(i + 1, first);
1814 mService.mWindowsChanged = true;
1815 }
1816
1817 /** Places the first input window before the second input window in the window list. */
1818 private void addWindowToListBefore(WindowState first, WindowState second) {
1819 int i = mWindows.indexOf(second);
1820 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1821 "Adding window " + this + " at " + i + " of " + mWindows.size()
1822 + " (before " + second + ")");
1823 if (i < 0) {
1824 Slog.w(TAG_WM, "addWindowToListBefore: Unable to find " + second + " in " + mWindows);
1825 i = 0;
1826 }
1827 mWindows.add(i, first);
1828 mService.mWindowsChanged = true;
1829 }
1830
1831 /**
1832 * This method finds out the index of a window that has the same app token as win. used for z
1833 * ordering the windows in mWindows
1834 */
1835 private int findIdxBasedOnAppTokens(WindowState win) {
1836 for(int j = mWindows.size() - 1; j >= 0; j--) {
1837 final WindowState wentry = mWindows.get(j);
1838 if(wentry.mAppToken == win.mAppToken) {
1839 return j;
1840 }
1841 }
1842 return -1;
1843 }
1844
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001845 private void dumpChildrenNames() {
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07001846 StringBuilder output = new StringBuilder();
1847 dumpChildrenNames(output, " ");
1848 Slog.v(TAG_WM, output.toString());
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001849 }
1850
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001851 private void dumpWindows() {
Wale Ogunwale10124582016-09-15 20:25:50 -07001852 Slog.v(TAG_WM, " Display #" + mDisplayId);
1853 final WindowList windows = getWindowList();
1854 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1855 Slog.v(TAG_WM, " #" + winNdx + ": " + windows.get(winNdx));
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001856 }
1857 }
1858
Wale Ogunwale02319a62016-09-26 15:21:22 -07001859 void dumpTokens(PrintWriter pw, boolean dumpAll) {
1860 if (mTokenMap.isEmpty()) {
1861 return;
1862 }
1863 pw.println(" Display #" + mDisplayId);
1864 final Iterator<WindowToken> it = mTokenMap.values().iterator();
1865 while (it.hasNext()) {
1866 final WindowToken token = it.next();
1867 pw.print(" ");
1868 pw.print(token);
1869 if (dumpAll) {
1870 pw.println(':');
1871 token.dump(pw, " ");
1872 } else {
1873 pw.println();
1874 }
1875 }
1876 }
1877
Wale Ogunwale824ab5c2016-10-20 09:31:56 -07001878 void dumpWindowAnimators(PrintWriter pw, String subPrefix) {
1879 final int count = mWindows.size();
1880 for (int j = 0; j < count; j++) {
1881 final WindowStateAnimator wAnim = mWindows.get(j).mWinAnimator;
1882 pw.println(subPrefix + "Window #" + j + ": " + wAnim);
1883 }
1884 }
1885
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001886 void enableSurfaceTrace(FileDescriptor fd) {
1887 for (int i = mWindows.size() - 1; i >= 0; i--) {
1888 final WindowState win = mWindows.get(i);
1889 win.mWinAnimator.enableSurfaceTrace(fd);
1890 }
1891 }
1892
1893 void disableSurfaceTrace() {
1894 for (int i = mWindows.size() - 1; i >= 0; i--) {
1895 final WindowState win = mWindows.get(i);
1896 win.mWinAnimator.disableSurfaceTrace();
1897 }
1898 }
1899
Wale Ogunwale824ab5c2016-10-20 09:31:56 -07001900 void updateWindowsForAnimator(WindowAnimator animator) {
1901 final WindowManagerPolicy policy = animator.mPolicy;
1902 final int keyguardGoingAwayFlags = animator.mKeyguardGoingAwayFlags;
1903 final boolean keyguardGoingAwayToShade =
1904 (keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_TO_SHADE) != 0;
1905 final boolean keyguardGoingAwayNoAnimation =
1906 (keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS) != 0;
1907 final boolean keyguardGoingAwayWithWallpaper =
1908 (keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER) != 0;
1909
1910 if (animator.mKeyguardGoingAway) {
1911 for (int i = mWindows.size() - 1; i >= 0; i--) {
1912 WindowState win = mWindows.get(i);
1913 if (!policy.isKeyguardHostWindow(win.mAttrs)) {
1914 continue;
1915 }
1916 final WindowStateAnimator winAnimator = win.mWinAnimator;
1917 if (policy.isKeyguardShowingAndNotOccluded()) {
1918 if (!winAnimator.mAnimating) {
1919 if (DEBUG_KEYGUARD) Slog.d(TAG,
1920 "updateWindowsForAnimator: creating delay animation");
1921
1922 // Create a new animation to delay until keyguard is gone on its own.
1923 winAnimator.mAnimation = new AlphaAnimation(1.0f, 1.0f);
1924 winAnimator.mAnimation.setDuration(KEYGUARD_ANIM_TIMEOUT_MS);
1925 winAnimator.mAnimationIsEntrance = false;
1926 winAnimator.mAnimationStartTime = -1;
1927 winAnimator.mKeyguardGoingAwayAnimation = true;
1928 winAnimator.mKeyguardGoingAwayWithWallpaper
1929 = keyguardGoingAwayWithWallpaper;
1930 }
1931 } else {
1932 if (DEBUG_KEYGUARD) Slog.d(TAG,
1933 "updateWindowsForAnimator: StatusBar is no longer keyguard");
1934 animator.mKeyguardGoingAway = false;
1935 winAnimator.clearAnimation();
1936 }
1937 break;
1938 }
1939 }
1940
1941 animator.mForceHiding = KEYGUARD_NOT_SHOWN;
1942
1943 boolean wallpaperInUnForceHiding = false;
1944 boolean startingInUnForceHiding = false;
1945 ArrayList<WindowStateAnimator> unForceHiding = null;
1946 WindowState wallpaper = null;
Wale Ogunwale0303c572016-10-20 10:16:29 -07001947 final WallpaperController wallpaperController = mWallpaperController;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -07001948 for (int i = mWindows.size() - 1; i >= 0; i--) {
1949 WindowState win = mWindows.get(i);
1950 WindowStateAnimator winAnimator = win.mWinAnimator;
1951 final int flags = win.mAttrs.flags;
1952 boolean canBeForceHidden = policy.canBeForceHidden(win, win.mAttrs);
1953 boolean shouldBeForceHidden = animator.shouldForceHide(win);
1954 if (winAnimator.hasSurface()) {
1955 final boolean wasAnimating = winAnimator.mWasAnimating;
1956 final boolean nowAnimating = winAnimator.stepAnimationLocked(animator.mCurrentTime);
1957 winAnimator.mWasAnimating = nowAnimating;
1958 animator.orAnimating(nowAnimating);
1959
1960 if (DEBUG_WALLPAPER) Slog.v(TAG,
1961 win + ": wasAnimating=" + wasAnimating + ", nowAnimating=" + nowAnimating);
1962
1963 if (wasAnimating && !winAnimator.mAnimating
1964 && wallpaperController.isWallpaperTarget(win)) {
1965 animator.mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
1966 pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
1967 if (DEBUG_LAYOUT_REPEATS) {
1968 mService.mWindowPlacerLocked.debugLayoutRepeats(
1969 "updateWindowsAndWallpaperLocked 2", pendingLayoutChanges);
1970 }
1971 }
1972
1973 if (policy.isForceHiding(win.mAttrs)) {
1974 if (!wasAnimating && nowAnimating) {
1975 if (DEBUG_KEYGUARD || DEBUG_ANIM || DEBUG_VISIBILITY) Slog.v(TAG,
1976 "Animation started that could impact force hide: " + win);
1977 animator.mBulkUpdateParams |= SET_FORCE_HIDING_CHANGED;
1978 pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
1979 if (DEBUG_LAYOUT_REPEATS) {
1980 mService.mWindowPlacerLocked.debugLayoutRepeats(
1981 "updateWindowsAndWallpaperLocked 3", pendingLayoutChanges);
1982 }
1983 mService.mFocusMayChange = true;
1984 } else if (animator.mKeyguardGoingAway && !nowAnimating) {
1985 // Timeout!!
1986 Slog.e(TAG, "Timeout waiting for animation to startup");
1987 policy.startKeyguardExitAnimation(0, 0);
1988 animator.mKeyguardGoingAway = false;
1989 }
1990 if (win.isReadyForDisplay()) {
1991 if (nowAnimating && win.mWinAnimator.mKeyguardGoingAwayAnimation) {
1992 animator.mForceHiding = KEYGUARD_ANIMATING_OUT;
1993 } else {
1994 animator.mForceHiding = win.isDrawnLw()
1995 ? KEYGUARD_SHOWN : KEYGUARD_NOT_SHOWN;
1996 }
1997 }
1998 if (DEBUG_KEYGUARD || DEBUG_VISIBILITY) Slog.v(TAG,
1999 "Force hide " + animator.forceHidingToString()
2000 + " hasSurface=" + win.mHasSurface
2001 + " policyVis=" + win.mPolicyVisibility
2002 + " destroying=" + win.mDestroying
2003 + " parentHidden=" + win.isParentWindowHidden()
2004 + " vis=" + win.mViewVisibility
2005 + " hidden=" + win.mToken.hidden
2006 + " anim=" + win.mWinAnimator.mAnimation);
2007 } else if (canBeForceHidden) {
2008 if (shouldBeForceHidden) {
2009 if (!win.hideLw(false, false)) {
2010 // Was already hidden
2011 continue;
2012 }
2013 if (DEBUG_KEYGUARD || DEBUG_VISIBILITY) Slog.v(TAG,
2014 "Now policy hidden: " + win);
2015 } else {
2016 final Animation postKeyguardExitAnimation =
2017 animator.mPostKeyguardExitAnimation;
2018 boolean applyExistingExitAnimation = postKeyguardExitAnimation != null
2019 && !postKeyguardExitAnimation.hasEnded()
2020 && !winAnimator.mKeyguardGoingAwayAnimation
2021 && win.hasDrawnLw()
2022 && !win.isChildWindow()
2023 && !win.mIsImWindow
2024 && isDefaultDisplay;
2025
2026 // If the window is already showing and we don't need to apply an existing
2027 // Keyguard exit animation, skip.
2028 if (!win.showLw(false, false) && !applyExistingExitAnimation) {
2029 continue;
2030 }
2031 final boolean visibleNow = win.isVisibleNow();
2032 if (!visibleNow) {
2033 // Couldn't really show, must showLw() again when win becomes visible.
2034 win.hideLw(false, false);
2035 continue;
2036 }
2037 if (DEBUG_KEYGUARD || DEBUG_VISIBILITY) Slog.v(TAG,
2038 "Now policy shown: " + win);
2039 if ((animator.mBulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0
2040 && !win.isChildWindow()) {
2041 if (unForceHiding == null) {
2042 unForceHiding = new ArrayList<>();
2043 }
2044 unForceHiding.add(winAnimator);
2045 if ((flags & FLAG_SHOW_WALLPAPER) != 0) {
2046 wallpaperInUnForceHiding = true;
2047 }
2048 if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
2049 startingInUnForceHiding = true;
2050 }
2051 } else if (applyExistingExitAnimation) {
2052 // We're already in the middle of an animation. Use the existing
2053 // animation to bring in this window.
2054 if (DEBUG_KEYGUARD) Slog.v(TAG,
2055 "Applying existing Keyguard exit animation to new window: win="
2056 + win);
2057
2058 final Animation a = policy.createForceHideEnterAnimation(false,
2059 keyguardGoingAwayToShade);
2060 winAnimator.setAnimation(a, postKeyguardExitAnimation.getStartTime(),
2061 STACK_CLIP_BEFORE_ANIM);
2062 winAnimator.mKeyguardGoingAwayAnimation = true;
2063 winAnimator.mKeyguardGoingAwayWithWallpaper
2064 = keyguardGoingAwayWithWallpaper;
2065 }
2066 final WindowState currentFocus = mService.mCurrentFocus;
2067 if (currentFocus == null || currentFocus.mLayer < win.mLayer) {
2068 // We are showing on top of the current
2069 // focus, so re-evaluate focus to make
2070 // sure it is correct.
2071 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG,
2072 "updateWindowsForAnimator: setting mFocusMayChange true");
2073 mService.mFocusMayChange = true;
2074 }
2075 }
2076 if ((flags & FLAG_SHOW_WALLPAPER) != 0) {
2077 animator.mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
2078 pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
2079 if (DEBUG_LAYOUT_REPEATS) {
2080 mService.mWindowPlacerLocked.debugLayoutRepeats(
2081 "updateWindowsAndWallpaperLocked 4", pendingLayoutChanges);
2082 }
2083 }
2084 }
2085 }
2086
2087 // If the window doesn't have a surface, the only thing we care about is the correct
2088 // policy visibility.
2089 else if (canBeForceHidden) {
2090 if (shouldBeForceHidden) {
2091 win.hideLw(false, false);
2092 } else {
2093 win.showLw(false, false);
2094 }
2095 }
2096
2097 final AppWindowToken atoken = win.mAppToken;
2098 if (winAnimator.mDrawState == READY_TO_SHOW) {
2099 if (atoken == null || atoken.allDrawn) {
2100 if (win.performShowLocked()) {
2101 pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
2102 if (DEBUG_LAYOUT_REPEATS) {
2103 mService.mWindowPlacerLocked.debugLayoutRepeats(
2104 "updateWindowsAndWallpaperLocked 5", pendingLayoutChanges);
2105 }
2106 }
2107 }
2108 }
2109 final AppWindowAnimator appAnimator = winAnimator.mAppAnimator;
2110 if (appAnimator != null && appAnimator.thumbnail != null) {
2111 if (appAnimator.thumbnailTransactionSeq != animator.mAnimTransactionSequence) {
2112 appAnimator.thumbnailTransactionSeq = animator.mAnimTransactionSequence;
2113 appAnimator.thumbnailLayer = 0;
2114 }
2115 if (appAnimator.thumbnailLayer < winAnimator.mAnimLayer) {
2116 appAnimator.thumbnailLayer = winAnimator.mAnimLayer;
2117 }
2118 }
2119 if (win.mIsWallpaper) {
2120 wallpaper = win;
2121 }
2122 } // end forall windows
2123
2124 // If we have windows that are being shown due to them no longer being force-hidden, apply
2125 // the appropriate animation to them if animations are not disabled.
2126 if (unForceHiding != null) {
2127 if (!keyguardGoingAwayNoAnimation) {
2128 boolean first = true;
2129 for (int i=unForceHiding.size()-1; i>=0; i--) {
2130 final WindowStateAnimator winAnimator = unForceHiding.get(i);
2131 final Animation a = policy.createForceHideEnterAnimation(
2132 wallpaperInUnForceHiding && !startingInUnForceHiding,
2133 keyguardGoingAwayToShade);
2134 if (a != null) {
2135 if (DEBUG_KEYGUARD) Slog.v(TAG,
2136 "Starting keyguard exit animation on window " + winAnimator.mWin);
2137 winAnimator.setAnimation(a, STACK_CLIP_BEFORE_ANIM);
2138 winAnimator.mKeyguardGoingAwayAnimation = true;
2139 winAnimator.mKeyguardGoingAwayWithWallpaper
2140 = keyguardGoingAwayWithWallpaper;
2141 if (first) {
2142 animator.mPostKeyguardExitAnimation = a;
2143 animator.mPostKeyguardExitAnimation.setStartTime(animator.mCurrentTime);
2144 first = false;
2145 }
2146 }
2147 }
2148 } else if (animator.mKeyguardGoingAway) {
2149 policy.startKeyguardExitAnimation(animator.mCurrentTime, 0 /* duration */);
2150 animator.mKeyguardGoingAway = false;
2151 }
2152
2153
2154 // Wallpaper is going away in un-force-hide motion, animate it as well.
2155 if (!wallpaperInUnForceHiding && wallpaper != null && !keyguardGoingAwayNoAnimation) {
2156 if (DEBUG_KEYGUARD) Slog.d(TAG,
2157 "updateWindowsForAnimator: wallpaper animating away");
2158 final Animation a = policy.createForceHideWallpaperExitAnimation(
2159 keyguardGoingAwayToShade);
2160 if (a != null) {
2161 wallpaper.mWinAnimator.setAnimation(a);
2162 }
2163 }
2164 }
2165
2166 if (animator.mPostKeyguardExitAnimation != null) {
2167 // We're in the midst of a keyguard exit animation.
2168 if (animator.mKeyguardGoingAway) {
2169 policy.startKeyguardExitAnimation(animator.mCurrentTime +
2170 animator.mPostKeyguardExitAnimation.getStartOffset(),
2171 animator.mPostKeyguardExitAnimation.getDuration());
2172 animator.mKeyguardGoingAway = false;
2173 }
2174 // mPostKeyguardExitAnimation might either be ended normally, cancelled, or "orphaned",
2175 // meaning that the window it was running on was removed. We check for hasEnded() for
2176 // ended normally and cancelled case, and check the time for the "orphaned" case.
2177 else if (animator.mPostKeyguardExitAnimation.hasEnded()
2178 || animator.mCurrentTime - animator.mPostKeyguardExitAnimation.getStartTime()
2179 > animator.mPostKeyguardExitAnimation.getDuration()) {
2180 // Done with the animation, reset.
2181 if (DEBUG_KEYGUARD) Slog.v(TAG, "Done with Keyguard exit animations.");
2182 animator.mPostKeyguardExitAnimation = null;
2183 }
2184 }
2185
2186 final WindowState winShowWhenLocked = (WindowState) policy.getWinShowWhenLockedLw();
2187 if (winShowWhenLocked != null) {
2188 animator.mLastShowWinWhenLocked = winShowWhenLocked;
2189 }
2190 }
2191
2192 void updateWallpaperForAnimator(WindowAnimator animator) {
2193 final WindowList windows = mWindows;
2194 WindowState detachedWallpaper = null;
2195
2196 for (int i = windows.size() - 1; i >= 0; i--) {
2197 final WindowState win = windows.get(i);
2198 final WindowStateAnimator winAnimator = win.mWinAnimator;
2199 if (winAnimator.mSurfaceController == null || !winAnimator.hasSurface()) {
2200 continue;
2201 }
2202
2203 final int flags = win.mAttrs.flags;
2204
2205 // If this window is animating, make a note that we have an animating window and take
2206 // care of a request to run a detached wallpaper animation.
2207 if (winAnimator.mAnimating) {
2208 if (winAnimator.mAnimation != null) {
2209 if ((flags & FLAG_SHOW_WALLPAPER) != 0
2210 && winAnimator.mAnimation.getDetachWallpaper()) {
2211 detachedWallpaper = win;
2212 }
2213 final int color = winAnimator.mAnimation.getBackgroundColor();
2214 if (color != 0) {
2215 final TaskStack stack = win.getStack();
2216 if (stack != null) {
2217 stack.setAnimationBackground(winAnimator, color);
2218 }
2219 }
2220 }
2221 animator.setAnimating(true);
2222 }
2223
2224 // If this window's app token is running a detached wallpaper animation, make a note so
2225 // we can ensure the wallpaper is displayed behind it.
2226 final AppWindowAnimator appAnimator = winAnimator.mAppAnimator;
2227 if (appAnimator != null && appAnimator.animation != null
2228 && appAnimator.animating) {
2229 if ((flags & FLAG_SHOW_WALLPAPER) != 0
2230 && appAnimator.animation.getDetachWallpaper()) {
2231 detachedWallpaper = win;
2232 }
2233
2234 final int color = appAnimator.animation.getBackgroundColor();
2235 if (color != 0) {
2236 final TaskStack stack = win.getStack();
2237 if (stack != null) {
2238 stack.setAnimationBackground(winAnimator, color);
2239 }
2240 }
2241 }
2242 } // end forall windows
2243
2244 if (animator.mWindowDetachedWallpaper != detachedWallpaper) {
2245 if (DEBUG_WALLPAPER) Slog.v(TAG, "Detached wallpaper changed from "
2246 + animator.mWindowDetachedWallpaper + " to " + detachedWallpaper);
2247 animator.mWindowDetachedWallpaper = detachedWallpaper;
2248 animator.mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
2249 }
2250 }
2251
2252 void prepareWindowSurfaces() {
2253 final int count = mWindows.size();
2254 for (int j = 0; j < count; j++) {
2255 mWindows.get(j).mWinAnimator.prepareSurfaceLocked(true);
2256 }
2257 }
2258
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07002259 static final class GetWindowOnDisplaySearchResult {
Wale Ogunwaleec731152016-09-08 20:18:57 -07002260 boolean reachedToken;
2261 WindowState foundWindow;
2262
2263 void reset() {
2264 reachedToken = false;
2265 foundWindow = null;
2266 }
2267 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07002268
2269 static final class TaskForResizePointSearchResult {
2270 boolean searchDone;
2271 Task taskForResize;
2272
2273 void reset() {
2274 searchDone = false;
2275 taskForResize = null;
2276 }
2277 }
Robert Carr3b716242016-08-16 16:02:21 -07002278
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002279 /**
2280 * Base class for any direct child window container of {@link #DisplayContent} need to inherit
2281 * from. This is mainly a pass through class that allows {@link #DisplayContent} to have
2282 * homogeneous children type which is currently required by sub-classes of
2283 * {@link WindowContainer} class.
2284 */
2285 static class DisplayChildWindowContainer<E extends WindowContainer> extends WindowContainer<E> {
2286
2287 int size() {
2288 return mChildren.size();
2289 }
2290
2291 E get(int index) {
2292 return mChildren.get(index);
2293 }
2294
2295 @Override
2296 boolean fillsParent() {
2297 return true;
2298 }
2299
2300 @Override
2301 boolean isVisible() {
2302 return true;
Robert Carr3b716242016-08-16 16:02:21 -07002303 }
2304 }
2305
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002306 /**
2307 * Window container class that contains all containers on this display relating to Apps.
2308 * I.e Activities.
2309 */
2310 private class TaskStackContainers extends DisplayChildWindowContainer<TaskStack> {
2311
2312 void attachStack(TaskStack stack, boolean onTop) {
2313 if (stack.mStackId == HOME_STACK_ID) {
2314 if (mHomeStack != null) {
2315 throw new IllegalArgumentException("attachStack: HOME_STACK_ID (0) not first.");
2316 }
2317 mHomeStack = stack;
2318 }
2319 addChild(stack, onTop);
2320 stack.onDisplayChanged(DisplayContent.this);
Robert Carr3b716242016-08-16 16:02:21 -07002321 }
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002322
2323 void moveStack(TaskStack stack, boolean toTop) {
2324 if (StackId.isAlwaysOnTop(stack.mStackId) && !toTop) {
2325 // This stack is always-on-top silly...
2326 Slog.w(TAG_WM, "Ignoring move of always-on-top stack=" + stack + " to bottom");
2327 return;
2328 }
2329
2330 if (!mChildren.contains(stack)) {
2331 Slog.wtf(TAG_WM, "moving stack that was not added: " + stack, new Throwable());
2332 }
2333 removeChild(stack);
2334 addChild(stack, toTop);
2335 }
2336
2337 private void addChild(TaskStack stack, boolean toTop) {
2338 int addIndex = toTop ? mChildren.size() : 0;
2339
2340 if (toTop
2341 && mService.isStackVisibleLocked(PINNED_STACK_ID)
2342 && stack.mStackId != PINNED_STACK_ID) {
2343 // The pinned stack is always the top most stack (always-on-top) when it is visible.
2344 // So, stack is moved just below the pinned stack.
2345 addIndex--;
2346 TaskStack topStack = mChildren.get(addIndex);
2347 if (topStack.mStackId != PINNED_STACK_ID) {
2348 throw new IllegalStateException("Pinned stack isn't top stack??? " + mChildren);
2349 }
2350 }
2351 addChild(stack, addIndex);
2352 setLayoutNeeded();
2353 }
2354
Wale Ogunwalee6f806e2016-10-20 15:29:42 -07002355 @Override
2356 int getOrientation() {
2357 if (mService.isStackVisibleLocked(DOCKED_STACK_ID)
2358 || mService.isStackVisibleLocked(FREEFORM_WORKSPACE_STACK_ID)) {
2359 // Apps and their containers are not allowed to specify an orientation while the
2360 // docked or freeform stack is visible...except for the home stack/task if the
2361 // docked stack is minimized and it actually set something.
2362 if (mHomeStack != null && mHomeStack.isVisible()
2363 && mDividerControllerLocked.isMinimizedDock()) {
2364 final int orientation = mHomeStack.getOrientation();
2365 if (orientation != SCREEN_ORIENTATION_UNSET) {
2366 return orientation;
2367 }
2368 }
2369 return SCREEN_ORIENTATION_UNSPECIFIED;
2370 }
2371
2372 final int orientation = super.getOrientation();
2373 if (orientation != SCREEN_ORIENTATION_UNSET
2374 && orientation != SCREEN_ORIENTATION_BEHIND) {
2375 if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
2376 "App is requesting an orientation, return " + orientation);
2377 return orientation;
2378 }
2379
2380 if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
2381 "No app is requesting an orientation, return " + mService.mLastOrientation);
2382 // The next app has not been requested to be visible, so we keep the current orientation
2383 // to prevent freezing/unfreezing the display too early.
2384 return mService.mLastOrientation;
2385 }
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002386 }
2387
2388 /**
2389 * Window container class that contains all containers on this display that are not related to
2390 * Apps. E.g. status bar.
2391 */
2392 private static class NonAppWindowContainers extends DisplayChildWindowContainer<WindowToken> {
2393
Robert Carr3b716242016-08-16 16:02:21 -07002394 }
Craig Mautner59c00972012-07-30 12:10:24 -07002395}