blob: fab0b29b14295435d5caa5f36f1bbca91422bb06 [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;
205 int mInputMethodAnimLayerAdjustment;
206
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800207 /**
Craig Mautner2d5618c2012-10-18 13:55:47 -0700208 * @param display May not be null.
Craig Mautnerdf88d732014-01-27 09:21:32 -0800209 * @param service You know.
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700210 * @param layersController window layer controller used to assign layer to the windows on this
211 * display.
Craig Mautner2d5618c2012-10-18 13:55:47 -0700212 */
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700213 DisplayContent(Display display, WindowManagerService service,
214 WindowLayersController layersController) {
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700215 mDisplay = display;
216 mDisplayId = display.getDisplayId();
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700217 mLayersController = layersController;
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700218 display.getDisplayInfo(mDisplayInfo);
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700219 display.getMetrics(mDisplayMetrics);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700220 isDefaultDisplay = mDisplayId == DEFAULT_DISPLAY;
Craig Mautner9d808b12013-08-06 18:00:25 -0700221 mService = service;
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -0700222 initializeDisplayBaseInfo();
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800223 mDividerControllerLocked = new DockedStackDividerController(service, this);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800224 mDimLayerController = new DimLayerController(this);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700225
226 // These are the only direct children we should ever have and they are permanent.
227 super.addChild(mTaskStackContainers, null);
228 super.addChild(mNonAppWindowContainers, null);
Craig Mautner59c00972012-07-30 12:10:24 -0700229 }
230
231 int getDisplayId() {
232 return mDisplayId;
233 }
234
235 WindowList getWindowList() {
236 return mWindows;
237 }
238
Wale Ogunwale02319a62016-09-26 15:21:22 -0700239 WindowToken getWindowToken(IBinder binder) {
240 return mTokenMap.get(binder);
241 }
242
243 AppWindowToken getAppWindowToken(IBinder binder) {
244 final WindowToken token = getWindowToken(binder);
245 if (token == null) {
246 return null;
247 }
248 return token.asAppWindowToken();
249 }
250
251 void setWindowToken(IBinder binder, WindowToken token) {
252 final DisplayContent dc = mService.mRoot.getWindowTokenDisplay(token);
253 if (dc != null) {
254 // We currently don't support adding a window token to the display if the display
255 // already has the binder mapped to another token. If there is a use case for supporting
256 // this moving forward we will either need to merge the WindowTokens some how or have
257 // the binder map to a list of window tokens.
258 throw new IllegalArgumentException("Can't map token=" + token + " to display=" + this
259 + " already mapped to display=" + dc + " tokens=" + dc.mTokenMap);
260 }
261 mTokenMap.put(binder, token);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700262
263 if (token.asAppWindowToken() == null) {
264 // Add non-app token to container hierarchy on the display. App tokens are added through
265 // the parent container managing them (e.g. Tasks).
266 mNonAppWindowContainers.addChild(token, null);
267 }
Wale Ogunwale02319a62016-09-26 15:21:22 -0700268 }
269
270 WindowToken removeWindowToken(IBinder binder) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700271 final WindowToken token = mTokenMap.remove(binder);
272 if (token != null && token.asAppWindowToken() == null) {
273 mNonAppWindowContainers.removeChild(token);
274 }
275 return token;
Wale Ogunwale02319a62016-09-26 15:21:22 -0700276 }
277
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700278 Display getDisplay() {
279 return mDisplay;
280 }
281
Craig Mautner59c00972012-07-30 12:10:24 -0700282 DisplayInfo getDisplayInfo() {
283 return mDisplayInfo;
284 }
285
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700286 DisplayMetrics getDisplayMetrics() {
287 return mDisplayMetrics;
288 }
289
Jorim Jaggi61f39a72015-10-29 16:54:18 +0100290 DockedStackDividerController getDockedDividerController() {
291 return mDividerControllerLocked;
292 }
293
Jeff Browna506a6e2013-06-04 00:02:38 -0700294 /**
295 * Returns true if the specified UID has access to this display.
296 */
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700297 boolean hasAccess(int uid) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700298 return mDisplay.hasAccess(uid);
299 }
300
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700301 boolean isPrivate() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700302 return (mDisplay.getFlags() & FLAG_PRIVATE) != 0;
keunyounga446bf02013-06-21 19:07:57 -0700303 }
304
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700305 TaskStack getHomeStack() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700306 if (mHomeStack == null && mDisplayId == DEFAULT_DISPLAY) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800307 Slog.e(TAG_WM, "getHomeStack: Returning null from this=" + this);
Craig Mautnere0a38842013-12-16 16:14:02 -0800308 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700309 return mHomeStack;
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700310 }
311
Chong Zhangd9d35bd2016-08-04 17:55:21 -0700312 TaskStack getStackById(int stackId) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700313 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
314 final TaskStack stack = mTaskStackContainers.get(i);
Chong Zhangd9d35bd2016-08-04 17:55:21 -0700315 if (stack.mStackId == stackId) {
316 return stack;
317 }
318 }
319 return null;
320 }
321
Andrii Kulian441e4492016-09-29 15:25:00 -0700322 @Override
323 void onConfigurationChanged(Configuration newParentConfig) {
324 super.onConfigurationChanged(newParentConfig);
325
Andrii Kulian3a507b52016-09-19 18:14:12 -0700326 // The display size information is heavily dependent on the resources in the current
327 // configuration, so we need to reconfigure it every time the configuration changes.
328 // See {@link PhoneWindowManager#setInitialDisplaySize}...sigh...
329 mService.reconfigureDisplayLocked(this);
330
331 getDockedDividerController().onConfigurationChanged();
Andrii Kulian441e4492016-09-29 15:25:00 -0700332 }
Andrii Kulian3a507b52016-09-19 18:14:12 -0700333
Andrii Kulian441e4492016-09-29 15:25:00 -0700334 /**
335 * Callback used to trigger bounds update after configuration change and get ids of stacks whose
336 * bounds were updated.
337 */
338 void updateStackBoundsAfterConfigChange(@NonNull List<Integer> changedStackList) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700339 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
340 final TaskStack stack = mTaskStackContainers.get(i);
Andrii Kulian441e4492016-09-29 15:25:00 -0700341 if (stack.updateBoundsAfterConfigChange()) {
Andrii Kulian3a507b52016-09-19 18:14:12 -0700342 changedStackList.add(stack.mStackId);
343 }
344 }
345 }
346
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700347 @Override
348 boolean fillsParent() {
349 return true;
350 }
351
352 @Override
353 boolean isVisible() {
354 return true;
355 }
356
357 @Override
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700358 void onAppTransitionDone() {
Wale Ogunwale10124582016-09-15 20:25:50 -0700359 super.onAppTransitionDone();
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700360 rebuildAppWindowList();
361 }
362
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700363 @Override
Wale Ogunwale51362492016-09-08 17:49:17 -0700364 int getOrientation() {
Wale Ogunwale51362492016-09-08 17:49:17 -0700365 if (mService.isStackVisibleLocked(DOCKED_STACK_ID)
366 || mService.isStackVisibleLocked(FREEFORM_WORKSPACE_STACK_ID)) {
367 // Apps and their containers are not allowed to specify an orientation while the docked
368 // or freeform stack is visible...except for the home stack/task if the docked stack is
369 // minimized and it actually set something.
Andrii Kulian8072d112016-09-16 11:11:01 -0700370 if (mHomeStack != null && mHomeStack.isVisible()
371 && mDividerControllerLocked.isMinimizedDock()) {
Wale Ogunwale51362492016-09-08 17:49:17 -0700372 final int orientation = mHomeStack.getOrientation();
373 if (orientation != SCREEN_ORIENTATION_UNSET) {
374 return orientation;
375 }
376 }
377 return SCREEN_ORIENTATION_UNSPECIFIED;
378 }
379
Wale Ogunwale10124582016-09-15 20:25:50 -0700380 final int orientation = super.getOrientation();
Wale Ogunwalea77e1462016-09-28 10:09:46 -0700381 if (orientation != SCREEN_ORIENTATION_UNSET && orientation != SCREEN_ORIENTATION_BEHIND) {
Wale Ogunwale10124582016-09-15 20:25:50 -0700382 if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
383 "App is requesting an orientation, return " + orientation);
384 return orientation;
Wale Ogunwale51362492016-09-08 17:49:17 -0700385 }
386
387 if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
388 "No app is requesting an orientation, return " + mService.mLastOrientation);
389 // The next app has not been requested to be visible, so we keep the current orientation
390 // to prevent freezing/unfreezing the display too early.
391 return mService.mLastOrientation;
392 }
393
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700394 void updateDisplayInfo() {
Craig Mautner722285e2012-09-07 13:55:58 -0700395 mDisplay.getDisplayInfo(mDisplayInfo);
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700396 mDisplay.getMetrics(mDisplayMetrics);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700397 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
398 mTaskStackContainers.get(i).updateDisplayInfo(null);
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800399 }
Craig Mautner722285e2012-09-07 13:55:58 -0700400 }
401
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -0700402 void initializeDisplayBaseInfo() {
Wale Ogunwaleb699ce02016-07-18 12:05:30 -0700403 final DisplayManagerInternal displayManagerInternal = mService.mDisplayManagerInternal;
404 if (displayManagerInternal != null) {
405 // Bootstrap the default logical display from the display manager.
406 final DisplayInfo newDisplayInfo = displayManagerInternal.getDisplayInfo(mDisplayId);
407 if (newDisplayInfo != null) {
408 mDisplayInfo.copyFrom(newDisplayInfo);
409 }
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -0700410 }
Wale Ogunwaleb699ce02016-07-18 12:05:30 -0700411
Filip Gruszczynski608797e2015-11-12 19:08:20 -0800412 mBaseDisplayWidth = mInitialDisplayWidth = mDisplayInfo.logicalWidth;
413 mBaseDisplayHeight = mInitialDisplayHeight = mDisplayInfo.logicalHeight;
414 mBaseDisplayDensity = mInitialDisplayDensity = mDisplayInfo.logicalDensityDpi;
415 mBaseDisplayRect.set(0, 0, mBaseDisplayWidth, mBaseDisplayHeight);
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -0700416 }
417
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700418 void getLogicalDisplayRect(Rect out) {
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700419 // Uses same calculation as in LogicalDisplay#configureDisplayInTransactionLocked.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800420 final int orientation = mDisplayInfo.rotation;
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700421 boolean rotated = (orientation == ROTATION_90 || orientation == ROTATION_270);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800422 final int physWidth = rotated ? mBaseDisplayHeight : mBaseDisplayWidth;
423 final int physHeight = rotated ? mBaseDisplayWidth : mBaseDisplayHeight;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700424 int width = mDisplayInfo.logicalWidth;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800425 int left = (physWidth - width) / 2;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700426 int height = mDisplayInfo.logicalHeight;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800427 int top = (physHeight - height) / 2;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700428 out.set(left, top, left + width, top + height);
429 }
430
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700431 private void getLogicalDisplayRect(Rect out, int orientation) {
432 getLogicalDisplayRect(out);
433
434 // Rotate the Rect if needed.
435 final int currentRotation = mDisplayInfo.rotation;
436 final int rotationDelta = deltaRotation(currentRotation, orientation);
437 if (rotationDelta == ROTATION_90 || rotationDelta == ROTATION_270) {
438 createRotationMatrix(rotationDelta, mBaseDisplayWidth, mBaseDisplayHeight, mTmpMatrix);
439 mTmpRectF.set(out);
440 mTmpMatrix.mapRect(mTmpRectF);
441 mTmpRectF.round(out);
442 }
443 }
444
Chong Zhangf66db432016-01-13 10:39:51 -0800445 void getContentRect(Rect out) {
446 out.set(mContentRect);
447 }
448
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700449 /** Refer to {@link WindowManagerService#attachStack(int, int, boolean)} */
450 void attachStack(TaskStack stack, boolean onTop) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700451 mTaskStackContainers.attachStack(stack, onTop);
Craig Mautnerc00204b2013-03-05 15:02:14 -0800452 }
453
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800454 void moveStack(TaskStack stack, boolean toTop) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700455 mTaskStackContainers.moveStack(stack, toTop);
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700456 }
Wale Ogunwale1e60e0c2015-10-28 13:36:10 -0700457
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700458 @Override
459 protected void addChild(DisplayChildWindowContainer child,
460 Comparator<DisplayChildWindowContainer> comparator) {
461 throw new UnsupportedOperationException("See DisplayChildWindowContainer");
462 }
Wale Ogunwale1e60e0c2015-10-28 13:36:10 -0700463
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700464 @Override
465 protected void addChild(DisplayChildWindowContainer child, int index) {
466 throw new UnsupportedOperationException("See DisplayChildWindowContainer");
467 }
468
469 @Override
470 protected void removeChild(DisplayChildWindowContainer child) {
Wale Ogunwale601a3f02016-10-17 08:39:39 -0700471 // Only allow removal of direct children from this display if the display is in the process
472 // of been removed.
473 if (mRemovingDisplay) {
474 super.removeChild(child);
475 return;
476 }
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700477 throw new UnsupportedOperationException("See DisplayChildWindowContainer");
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800478 }
479
480 /**
481 * Propagate the new bounds to all child stacks.
482 * @param contentRect The bounds to apply at the top level.
483 */
484 void resize(Rect contentRect) {
485 mContentRect.set(contentRect);
486 }
487
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700488 int taskIdFromPoint(int x, int y) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700489 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
490 final TaskStack stack = mTaskStackContainers.get(stackNdx);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700491 final int taskId = stack.taskIdFromPoint(x, y);
492 if (taskId != -1) {
493 return taskId;
Craig Mautner967212c2013-04-13 21:10:58 -0700494 }
495 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800496 return -1;
Craig Mautnercf910b02013-04-23 11:23:27 -0700497 }
498
Chong Zhang8e89b312015-09-09 15:09:30 -0700499 /**
Chong Zhangd8ceb852015-11-11 14:53:41 -0800500 * Find the task whose outside touch area (for resizing) (x, y) falls within.
Chong Zhang9184ec62015-09-24 12:32:21 -0700501 * Returns null if the touch doesn't fall into a resizing area.
Chong Zhang8e89b312015-09-09 15:09:30 -0700502 */
Wale Ogunwale15ead902016-09-02 14:30:11 -0700503 Task findTaskForResizePoint(int x, int y) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700504 final int delta = dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700505 mTmpTaskForResizePointSearchResult.reset();
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700506 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
507 final TaskStack stack = mTaskStackContainers.get(stackNdx);
Wale Ogunwale3797c222015-10-27 14:21:58 -0700508 if (!StackId.isTaskResizeAllowed(stack.mStackId)) {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700509 return null;
Chong Zhang8e89b312015-09-09 15:09:30 -0700510 }
Chong Zhang9184ec62015-09-24 12:32:21 -0700511
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700512 stack.findTaskForResizePoint(x, y, delta, mTmpTaskForResizePointSearchResult);
513 if (mTmpTaskForResizePointSearchResult.searchDone) {
514 return mTmpTaskForResizePointSearchResult.taskForResize;
Chong Zhang8e89b312015-09-09 15:09:30 -0700515 }
516 }
Chong Zhang9184ec62015-09-24 12:32:21 -0700517 return null;
Chong Zhang8e89b312015-09-09 15:09:30 -0700518 }
519
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700520 void setTouchExcludeRegion(Task focusedTask) {
Craig Mautner6601b7b2013-04-29 10:29:11 -0700521 mTouchExcludeRegion.set(mBaseDisplayRect);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700522 final int delta = dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700523 mTmpRect2.setEmpty();
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700524 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
525 final TaskStack stack = mTaskStackContainers.get(stackNdx);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700526 stack.setTouchExcludeRegion(
527 focusedTask, delta, mTouchExcludeRegion, mContentRect, mTmpRect2);
Craig Mautner6601b7b2013-04-29 10:29:11 -0700528 }
Chong Zhangd8ceb852015-11-11 14:53:41 -0800529 // If we removed the focused task above, add it back and only leave its
530 // outside touch area in the exclusion. TapDectector is not interested in
531 // any touch inside the focused task itself.
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700532 if (!mTmpRect2.isEmpty()) {
Chong Zhangd8ceb852015-11-11 14:53:41 -0800533 mTouchExcludeRegion.op(mTmpRect2, Region.Op.UNION);
534 }
Filip Gruszczynski912d9192015-12-01 16:14:04 -0800535 final WindowState inputMethod = mService.mInputMethodWindow;
536 if (inputMethod != null && inputMethod.isVisibleLw()) {
537 // If the input method is visible and the user is typing, we don't want these touch
538 // events to be intercepted and used to change focus. This would likely cause a
539 // disappearance of the input method.
540 inputMethod.getTouchableRegion(mTmpRegion);
541 mTouchExcludeRegion.op(mTmpRegion, Region.Op.UNION);
542 }
Filip Gruszczynskiecf67222015-12-11 15:16:36 -0800543 for (int i = mTapExcludedWindows.size() - 1; i >= 0; i--) {
544 WindowState win = mTapExcludedWindows.get(i);
545 win.getTouchableRegion(mTmpRegion);
546 mTouchExcludeRegion.op(mTmpRegion, Region.Op.UNION);
547 }
Jorim Jaggid47e7e12016-03-01 09:57:38 +0100548 if (getDockedStackVisibleForUserLocked() != null) {
549 mDividerControllerLocked.getTouchRegion(mTmpRect);
Jorim Jaggi7f19cb82016-03-25 19:37:44 -0700550 mTmpRegion.set(mTmpRect);
Jorim Jaggid47e7e12016-03-01 09:57:38 +0100551 mTouchExcludeRegion.op(mTmpRegion, Op.UNION);
552 }
Craig Mautner1bef3892015-02-17 15:09:47 -0800553 if (mTapDetector != null) {
Chong Zhang2e2c81a2016-07-15 11:28:17 -0700554 mTapDetector.setTouchExcludeRegion(mTouchExcludeRegion);
Craig Mautner1bef3892015-02-17 15:09:47 -0800555 }
Craig Mautner6601b7b2013-04-29 10:29:11 -0700556 }
557
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700558 void switchUser() {
Craig Mautner858d8a62013-04-23 17:08:34 -0700559 final WindowList windows = getWindowList();
560 for (int i = 0; i < windows.size(); i++) {
561 final WindowState win = windows.get(i);
562 if (win.isHiddenFromUserLocked()) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800563 if (DEBUG_VISIBILITY) Slog.w(TAG_WM, "user changing, hiding " + win
Wale Ogunwale498e8c92015-02-13 09:42:46 -0800564 + ", attrs=" + win.mAttrs.type + ", belonging to " + win.mOwnerUid);
Craig Mautner858d8a62013-04-23 17:08:34 -0700565 win.hideLw(false);
566 }
567 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700568
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700569 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
570 mTaskStackContainers.get(stackNdx).switchUser();
Craig Mautner858d8a62013-04-23 17:08:34 -0700571 }
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700572
573 rebuildAppWindowList();
Craig Mautner858d8a62013-04-23 17:08:34 -0700574 }
575
Craig Mautner05d29032013-05-03 13:40:13 -0700576 void resetAnimationBackgroundAnimator() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700577 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
578 mTaskStackContainers.get(stackNdx).resetAnimationBackgroundAnimator();
Craig Mautner05d29032013-05-03 13:40:13 -0700579 }
580 }
581
582 boolean animateDimLayers() {
Chong Zhang112eb8c2015-11-02 11:17:00 -0800583 return mDimLayerController.animateDimLayers();
Craig Mautner05d29032013-05-03 13:40:13 -0700584 }
585
586 void resetDimming() {
Chong Zhang112eb8c2015-11-02 11:17:00 -0800587 mDimLayerController.resetDimming();
Craig Mautner05d29032013-05-03 13:40:13 -0700588 }
589
590 boolean isDimming() {
Chong Zhang112eb8c2015-11-02 11:17:00 -0800591 return mDimLayerController.isDimming();
Craig Mautner05d29032013-05-03 13:40:13 -0700592 }
593
594 void stopDimmingIfNeeded() {
Chong Zhang112eb8c2015-11-02 11:17:00 -0800595 mDimLayerController.stopDimmingIfNeeded();
Craig Mautner05d29032013-05-03 13:40:13 -0700596 }
597
Wale Ogunwale10124582016-09-15 20:25:50 -0700598 @Override
599 void removeIfPossible() {
600 if (isAnimating()) {
601 mDeferredRemoval = true;
602 return;
Craig Mautner2eb15342013-08-07 13:13:35 -0700603 }
Wale Ogunwale10124582016-09-15 20:25:50 -0700604 removeImmediately();
Craig Mautner2eb15342013-08-07 13:13:35 -0700605 }
606
Wale Ogunwale10124582016-09-15 20:25:50 -0700607 @Override
608 void removeImmediately() {
Wale Ogunwale601a3f02016-10-17 08:39:39 -0700609 mRemovingDisplay = true;
610 try {
611 super.removeImmediately();
612 if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Removing display=" + this);
613 mDimLayerController.close();
614 if (mDisplayId == DEFAULT_DISPLAY) {
615 mService.unregisterPointerEventListener(mTapDetector);
616 mService.unregisterPointerEventListener(mService.mMousePositionTracker);
617 }
618 } finally {
619 mRemovingDisplay = false;
Craig Mautner95da1082014-02-24 17:54:35 -0800620 }
Craig Mautner95da1082014-02-24 17:54:35 -0800621 }
622
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700623 /** Returns true if a removal action is still being deferred. */
Wale Ogunwale10124582016-09-15 20:25:50 -0700624 @Override
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700625 boolean checkCompleteDeferredRemoval() {
Wale Ogunwale10124582016-09-15 20:25:50 -0700626 final boolean stillDeferringRemoval = super.checkCompleteDeferredRemoval();
627
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700628 if (!stillDeferringRemoval && mDeferredRemoval) {
Wale Ogunwale10124582016-09-15 20:25:50 -0700629 removeImmediately();
Craig Mautner95da1082014-02-24 17:54:35 -0800630 mService.onDisplayRemoved(mDisplayId);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700631 return false;
Craig Mautner95da1082014-02-24 17:54:35 -0800632 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700633 return true;
Craig Mautner95da1082014-02-24 17:54:35 -0800634 }
635
Wale Ogunwale10124582016-09-15 20:25:50 -0700636 boolean animateForIme(float interpolatedValue, float animationTarget,
637 float dividerAnimationTarget) {
638 boolean updated = false;
639
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700640 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
641 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale10124582016-09-15 20:25:50 -0700642 if (stack == null || !stack.isAdjustedForIme()) {
643 continue;
644 }
645
646 if (interpolatedValue >= 1f && animationTarget == 0f && dividerAnimationTarget == 0f) {
647 stack.resetAdjustedForIme(true /* adjustBoundsNow */);
648 updated = true;
649 } else {
650 mDividerControllerLocked.mLastAnimationProgress =
651 mDividerControllerLocked.getInterpolatedAnimationValue(interpolatedValue);
652 mDividerControllerLocked.mLastDividerProgress =
653 mDividerControllerLocked.getInterpolatedDividerValue(interpolatedValue);
654 updated |= stack.updateAdjustForIme(
655 mDividerControllerLocked.mLastAnimationProgress,
656 mDividerControllerLocked.mLastDividerProgress,
657 false /* force */);
658 }
659 if (interpolatedValue >= 1f) {
660 stack.endImeAdjustAnimation();
661 }
662 }
663
664 return updated;
665 }
666
667 boolean clearImeAdjustAnimation() {
668 boolean changed = false;
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700669 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
670 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale10124582016-09-15 20:25:50 -0700671 if (stack != null && stack.isAdjustedForIme()) {
672 stack.resetAdjustedForIme(true /* adjustBoundsNow */);
673 changed = true;
674 }
675 }
676 return changed;
677 }
678
679 void beginImeAdjustAnimation() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700680 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
681 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale10124582016-09-15 20:25:50 -0700682 if (stack.isVisible() && stack.isAdjustedForIme()) {
683 stack.beginImeAdjustAnimation();
684 }
685 }
686 }
687
688 void adjustForImeIfNeeded() {
689 final WindowState imeWin = mService.mInputMethodWindow;
690 final boolean imeVisible = imeWin != null && imeWin.isVisibleLw() && imeWin.isDisplayedLw()
691 && !mDividerControllerLocked.isImeHideRequested();
692 final boolean dockVisible = mService.isStackVisibleLocked(DOCKED_STACK_ID);
693 final TaskStack imeTargetStack = mService.getImeFocusStackLocked();
694 final int imeDockSide = (dockVisible && imeTargetStack != null) ?
695 imeTargetStack.getDockSide() : DOCKED_INVALID;
696 final boolean imeOnTop = (imeDockSide == DOCKED_TOP);
697 final boolean imeOnBottom = (imeDockSide == DOCKED_BOTTOM);
698 final boolean dockMinimized = mDividerControllerLocked.isMinimizedDock();
699 final int imeHeight = mService.mPolicy.getInputMethodWindowVisibleHeightLw();
700 final boolean imeHeightChanged = imeVisible &&
701 imeHeight != mDividerControllerLocked.getImeHeightAdjustedFor();
702
703 // The divider could be adjusted for IME position, or be thinner than usual,
704 // or both. There are three possible cases:
705 // - If IME is visible, and focus is on top, divider is not moved for IME but thinner.
706 // - If IME is visible, and focus is on bottom, divider is moved for IME and thinner.
707 // - If IME is not visible, divider is not moved and is normal width.
708
709 if (imeVisible && dockVisible && (imeOnTop || imeOnBottom) && !dockMinimized) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700710 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
711 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale10124582016-09-15 20:25:50 -0700712 final boolean isDockedOnBottom = stack.getDockSide() == DOCKED_BOTTOM;
713 if (stack.isVisible() && (imeOnBottom || isDockedOnBottom)) {
714 stack.setAdjustedForIme(imeWin, imeOnBottom && imeHeightChanged);
715 } else {
716 stack.resetAdjustedForIme(false);
717 }
718 }
719 mDividerControllerLocked.setAdjustedForIme(
720 imeOnBottom /*ime*/, true /*divider*/, true /*animate*/, imeWin, imeHeight);
721 } else {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700722 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
723 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale10124582016-09-15 20:25:50 -0700724 stack.resetAdjustedForIme(!dockVisible);
725 }
726 mDividerControllerLocked.setAdjustedForIme(
727 false /*ime*/, false /*divider*/, dockVisible /*animate*/, imeWin, imeHeight);
728 }
729 }
730
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700731 void setInputMethodAnimLayerAdjustment(int adj) {
732 if (DEBUG_LAYERS) Slog.v(TAG_WM, "Setting im layer adj to " + adj);
733 mInputMethodAnimLayerAdjustment = adj;
734 final WindowState imw = mService.mInputMethodWindow;
735 if (imw != null) {
736 imw.adjustAnimLayer(adj);
737 }
738 for (int i = mService.mInputMethodDialogs.size() - 1; i >= 0; i--) {
739 final WindowState dialog = mService.mInputMethodDialogs.get(i);
740 // TODO: This and other places setting mAnimLayer can probably use WS.adjustAnimLayer,
741 // but need to make sure we are not setting things twice for child windows that are
742 // already in the list.
743 dialog.mWinAnimator.mAnimLayer = dialog.mLayer + adj;
744 if (DEBUG_LAYERS) Slog.v(TAG_WM, "IM win " + imw
745 + " anim layer: " + dialog.mWinAnimator.mAnimLayer);
746 }
747 }
748
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -0700749 /**
750 * If a window that has an animation specifying a colored background and the current wallpaper
751 * is visible, then the color goes *below* the wallpaper so we don't cause the wallpaper to
752 * suddenly disappear.
753 */
754 int getLayerForAnimationBackground(WindowStateAnimator winAnimator) {
755 for (int i = mWindows.size() - 1; i >= 0; --i) {
756 final WindowState win = mWindows.get(i);
757 if (win.mIsWallpaper && win.isVisibleNow()) {
758 return win.mWinAnimator.mAnimLayer;
759 }
760 }
761 return winAnimator.mAnimLayer;
762 }
763
Wale Ogunwale10124582016-09-15 20:25:50 -0700764 void prepareFreezingTaskBounds() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700765 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
766 final TaskStack stack = mTaskStackContainers.get(stackNdx);
Wale Ogunwale10124582016-09-15 20:25:50 -0700767 stack.prepareFreezingTaskBounds();
768 }
769 }
770
Wale Ogunwale94744212015-09-21 19:01:47 -0700771 void rotateBounds(int oldRotation, int newRotation, Rect bounds) {
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700772 getLogicalDisplayRect(mTmpRect, newRotation);
773
774 // Compute a transform matrix to undo the coordinate space transformation,
775 // and present the window at the same physical position it previously occupied.
776 final int deltaRotation = deltaRotation(newRotation, oldRotation);
777 createRotationMatrix(deltaRotation, mTmpRect.width(), mTmpRect.height(), mTmpMatrix);
778
779 mTmpRectF.set(bounds);
780 mTmpMatrix.mapRect(mTmpRectF);
781 mTmpRectF.round(bounds);
Wale Ogunwale94744212015-09-21 19:01:47 -0700782 }
783
Wale Ogunwale4a02d812015-02-12 23:01:38 -0800784 static int deltaRotation(int oldRotation, int newRotation) {
785 int delta = newRotation - oldRotation;
786 if (delta < 0) delta += 4;
787 return delta;
788 }
789
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700790 private static void createRotationMatrix(int rotation, float displayWidth, float displayHeight,
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700791 Matrix outMatrix) {
792 // For rotations without Z-ordering we don't need the target rectangle's position.
793 createRotationMatrix(rotation, 0 /* rectLeft */, 0 /* rectTop */, displayWidth,
794 displayHeight, outMatrix);
795 }
796
797 static void createRotationMatrix(int rotation, float rectLeft, float rectTop,
798 float displayWidth, float displayHeight, Matrix outMatrix) {
799 switch (rotation) {
800 case ROTATION_0:
801 outMatrix.reset();
802 break;
803 case ROTATION_270:
804 outMatrix.setRotate(270, 0, 0);
805 outMatrix.postTranslate(0, displayHeight);
806 outMatrix.postTranslate(rectTop, 0);
807 break;
808 case ROTATION_180:
809 outMatrix.reset();
810 break;
811 case ROTATION_90:
812 outMatrix.setRotate(90, 0, 0);
813 outMatrix.postTranslate(displayWidth, 0);
814 outMatrix.postTranslate(-rectTop, rectLeft);
815 break;
816 }
817 }
818
Craig Mautnera91f9e22012-09-14 16:22:08 -0700819 public void dump(String prefix, PrintWriter pw) {
820 pw.print(prefix); pw.print("Display: mDisplayId="); pw.println(mDisplayId);
821 final String subPrefix = " " + prefix;
822 pw.print(subPrefix); pw.print("init="); pw.print(mInitialDisplayWidth); pw.print("x");
823 pw.print(mInitialDisplayHeight); pw.print(" "); pw.print(mInitialDisplayDensity);
824 pw.print("dpi");
825 if (mInitialDisplayWidth != mBaseDisplayWidth
826 || mInitialDisplayHeight != mBaseDisplayHeight
827 || mInitialDisplayDensity != mBaseDisplayDensity) {
828 pw.print(" base=");
829 pw.print(mBaseDisplayWidth); pw.print("x"); pw.print(mBaseDisplayHeight);
830 pw.print(" "); pw.print(mBaseDisplayDensity); pw.print("dpi");
831 }
Jeff Brownd46747a2015-04-15 19:02:36 -0700832 if (mDisplayScalingDisabled) {
833 pw.println(" noscale");
834 }
Craig Mautnera91f9e22012-09-14 16:22:08 -0700835 pw.print(" cur=");
836 pw.print(mDisplayInfo.logicalWidth);
837 pw.print("x"); pw.print(mDisplayInfo.logicalHeight);
838 pw.print(" app=");
839 pw.print(mDisplayInfo.appWidth);
840 pw.print("x"); pw.print(mDisplayInfo.appHeight);
841 pw.print(" rng="); pw.print(mDisplayInfo.smallestNominalAppWidth);
842 pw.print("x"); pw.print(mDisplayInfo.smallestNominalAppHeight);
843 pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth);
844 pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight);
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700845 pw.println(subPrefix + "deferred=" + mDeferredRemoval
846 + " mLayoutNeeded=" + mLayoutNeeded);
Wale Ogunwaleb429e682016-01-06 12:36:34 -0800847
Craig Mautnerdc548482014-02-05 13:35:24 -0800848 pw.println();
Craig Mautnere8b85fd2014-10-22 09:23:25 -0700849 pw.println(" Application tokens in top down Z order:");
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700850 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
851 final TaskStack stack = mTaskStackContainers.get(stackNdx);
Wale Ogunwaleb429e682016-01-06 12:36:34 -0800852 stack.dump(prefix + " ", pw);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700853 }
Wale Ogunwaleb429e682016-01-06 12:36:34 -0800854
Craig Mautnerdc548482014-02-05 13:35:24 -0800855 pw.println();
856 if (!mExitingTokens.isEmpty()) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700857 pw.println();
858 pw.println(" Exiting tokens:");
Wale Ogunwaleb429e682016-01-06 12:36:34 -0800859 for (int i = mExitingTokens.size() - 1; i >= 0; i--) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700860 final WindowToken token = mExitingTokens.get(i);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700861 pw.print(" Exiting #"); pw.print(i);
862 pw.print(' '); pw.print(token);
863 pw.println(':');
864 token.dump(pw, " ");
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800865 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700866 }
Craig Mautner59c00972012-07-30 12:10:24 -0700867 pw.println();
Chong Zhang112eb8c2015-11-02 11:17:00 -0800868 mDimLayerController.dump(prefix + " ", pw);
Jorim Jaggi31f71702016-05-04 16:43:04 -0700869 pw.println();
870 mDividerControllerLocked.dump(prefix + " ", pw);
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700871
872 if (mInputMethodAnimLayerAdjustment != 0) {
873 pw.println(subPrefix
874 + "mInputMethodAnimLayerAdjustment=" + mInputMethodAnimLayerAdjustment);
875 }
Craig Mautner59c00972012-07-30 12:10:24 -0700876 }
Craig Mautnere0a38842013-12-16 16:14:02 -0800877
878 @Override
879 public String toString() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700880 return "Display " + mDisplayId + " info=" + mDisplayInfo + " stacks=" + mChildren;
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700881 }
882
883 String getName() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700884 return "Display " + mDisplayId + " name=\"" + mDisplayInfo.name + "\"";
Craig Mautnere0a38842013-12-16 16:14:02 -0800885 }
Filip Gruszczynski466f3212015-09-21 17:57:57 -0700886
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800887 /**
888 * @return The docked stack, but only if it is visible, and {@code null} otherwise.
889 */
Filip Gruszczynski3ddc5d62015-09-23 15:01:30 -0700890 TaskStack getDockedStackLocked() {
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700891 final TaskStack stack = mService.mStackIdToStack.get(DOCKED_STACK_ID);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700892 return (stack != null && stack.isVisible()) ? stack : null;
Filip Gruszczynski466f3212015-09-21 17:57:57 -0700893 }
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -0800894
895 /**
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800896 * Like {@link #getDockedStackLocked}, but also returns the docked stack if it's currently not
897 * visible, as long as it's not hidden because the current user doesn't have any tasks there.
898 */
899 TaskStack getDockedStackVisibleForUserLocked() {
900 final TaskStack stack = mService.mStackIdToStack.get(DOCKED_STACK_ID);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700901 return (stack != null && stack.isVisible(true /* ignoreKeyguard */)) ? stack : null;
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800902 }
903
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700904 /** Find the visible, touch-deliverable window under the given point */
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -0800905 WindowState getTouchableWinAtPointLocked(float xf, float yf) {
906 WindowState touchedWin = null;
907 final int x = (int) xf;
908 final int y = (int) yf;
909
910 for (int i = mWindows.size() - 1; i >= 0; i--) {
911 WindowState window = mWindows.get(i);
912 final int flags = window.mAttrs.flags;
913 if (!window.isVisibleLw()) {
914 continue;
915 }
916 if ((flags & FLAG_NOT_TOUCHABLE) != 0) {
917 continue;
918 }
919
920 window.getVisibleBounds(mTmpRect);
921 if (!mTmpRect.contains(x, y)) {
922 continue;
923 }
924
925 window.getTouchableRegion(mTmpRegion);
926
927 final int touchFlags = flags & (FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL);
928 if (mTmpRegion.contains(x, y) || touchFlags == 0) {
929 touchedWin = window;
930 break;
931 }
932 }
933
934 return touchedWin;
935 }
Jorim Jaggi6626f542016-08-22 13:08:44 -0700936
Svetoslav Ganovaa076532016-08-01 19:16:43 -0700937 boolean canAddToastWindowForUid(int uid) {
938 // We allow one toast window per UID being shown at a time.
939 WindowList windows = getWindowList();
940 final int windowCount = windows.size();
941 for (int i = 0; i < windowCount; i++) {
942 WindowState window = windows.get(i);
943 if (window.mAttrs.type == TYPE_TOAST && window.mOwnerUid == uid
Svet Ganov62a40f82016-09-29 00:43:51 -0700944 && !window.mPermanentlyHidden && !window.mAnimatingExit
945 && !window.mRemoveOnExit) {
Svetoslav Ganovaa076532016-08-01 19:16:43 -0700946 return false;
947 }
948 }
949 return true;
950 }
951
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700952 void scheduleToastWindowsTimeoutIfNeededLocked(WindowState oldFocus, WindowState newFocus) {
Svetoslav Ganovaa076532016-08-01 19:16:43 -0700953 if (oldFocus == null || (newFocus != null && newFocus.mOwnerUid == oldFocus.mOwnerUid)) {
954 return;
955 }
956 final int lostFocusUid = oldFocus.mOwnerUid;
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700957 final WindowList windows = getWindowList();
Svetoslav Ganovaa076532016-08-01 19:16:43 -0700958 final int windowCount = windows.size();
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700959 final Handler handler = mService.mH;
Svetoslav Ganovaa076532016-08-01 19:16:43 -0700960 for (int i = 0; i < windowCount; i++) {
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700961 final WindowState window = windows.get(i);
Svetoslav Ganovaa076532016-08-01 19:16:43 -0700962 if (window.mAttrs.type == TYPE_TOAST && window.mOwnerUid == lostFocusUid) {
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700963 if (!handler.hasMessages(WINDOW_HIDE_TIMEOUT, window)) {
964 handler.sendMessageDelayed(handler.obtainMessage(WINDOW_HIDE_TIMEOUT, window),
Svetoslav Ganovaa076532016-08-01 19:16:43 -0700965 window.mAttrs.hideTimeoutMilliseconds);
966 }
967 }
968 }
969 }
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -0700970
971 WindowState findFocusedWindow() {
972 final AppWindowToken focusedApp = mService.mFocusedApp;
973
974 for (int i = mWindows.size() - 1; i >= 0; i--) {
975 final WindowState win = mWindows.get(i);
976
977 if (DEBUG_FOCUS) Slog.v(TAG_WM, "Looking for focus: " + i + " = " + win
978 + ", flags=" + win.mAttrs.flags + ", canReceive=" + win.canReceiveKeys());
979
980 if (!win.canReceiveKeys()) {
981 continue;
982 }
983
984 final AppWindowToken wtoken = win.mAppToken;
985
986 // If this window's application has been removed, just skip it.
987 if (wtoken != null && (wtoken.removed || wtoken.sendingToBottom)) {
988 if (DEBUG_FOCUS) Slog.v(TAG_WM, "Skipping " + wtoken + " because "
989 + (wtoken.removed ? "removed" : "sendingToBottom"));
990 continue;
991 }
992
993 if (focusedApp == null) {
994 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp=null"
995 + " using new focus @ " + i + " = " + win);
996 return win;
997 }
998
999 if (!focusedApp.windowsAreFocusable()) {
1000 // Current focused app windows aren't focusable...
1001 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp windows not"
1002 + " focusable using new focus @ " + i + " = " + win);
1003 return win;
1004 }
1005
1006 // Descend through all of the app tokens and find the first that either matches
1007 // win.mAppToken (return win) or mFocusedApp (return null).
1008 if (wtoken != null && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
Wale Ogunwale10124582016-09-15 20:25:50 -07001009 if (focusedApp.compareTo(wtoken) > 0) {
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -07001010 // App stack below focused app stack. No focus for you!!!
1011 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM,
1012 "findFocusedWindow: Reached focused app=" + focusedApp);
1013 return null;
1014 }
1015 }
1016
1017 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: Found new focus @ "
1018 + i + " = " + win);
1019 return win;
1020 }
1021
1022 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: No focusable windows.");
1023 return null;
1024 }
Wale Ogunwaleec731152016-09-08 20:18:57 -07001025
1026 int addAppWindowToWindowList(final WindowState win) {
1027 final IWindow client = win.mClient;
1028
1029 WindowList tokenWindowList = getTokenWindowsOnDisplay(win.mToken);
1030 if (!tokenWindowList.isEmpty()) {
1031 return addAppWindowExisting(win, tokenWindowList);
1032 }
1033
1034 // No windows from this token on this display
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001035 if (localLOGV) Slog.v(TAG_WM, "Figuring out where to add app window "
Wale Ogunwaleec731152016-09-08 20:18:57 -07001036 + client.asBinder() + " (token=" + this + ")");
1037
1038 final WindowToken wToken = win.mToken;
1039
1040 // Figure out where the window should go, based on the order of applications.
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001041 mTmpGetWindowOnDisplaySearchResult.reset();
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001042 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
1043 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001044 stack.getWindowOnDisplayBeforeToken(this, wToken, mTmpGetWindowOnDisplaySearchResult);
1045 if (mTmpGetWindowOnDisplaySearchResult.reachedToken) {
Wale Ogunwaleec731152016-09-08 20:18:57 -07001046 // We have reach the token we are interested in. End search.
1047 break;
1048 }
1049 }
1050
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001051 WindowState pos = mTmpGetWindowOnDisplaySearchResult.foundWindow;
Wale Ogunwaleec731152016-09-08 20:18:57 -07001052
1053 // We now know the index into the apps. If we found an app window above, that gives us the
1054 // position; else we need to look some more.
1055 if (pos != null) {
1056 // Move behind any windows attached to this one.
Wale Ogunwale02319a62016-09-26 15:21:22 -07001057 final WindowToken atoken = getWindowToken(pos.mClient.asBinder());
Wale Ogunwaleec731152016-09-08 20:18:57 -07001058 if (atoken != null) {
1059 tokenWindowList = getTokenWindowsOnDisplay(atoken);
1060 final int NC = tokenWindowList.size();
1061 if (NC > 0) {
1062 WindowState bottom = tokenWindowList.get(0);
1063 if (bottom.mSubLayer < 0) {
1064 pos = bottom;
1065 }
1066 }
1067 }
1068 addWindowToListBefore(win, pos);
1069 return 0;
1070 }
1071
1072 // Continue looking down until we find the first token that has windows on this display.
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001073 mTmpGetWindowOnDisplaySearchResult.reset();
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001074 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
1075 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001076 stack.getWindowOnDisplayAfterToken(this, wToken, mTmpGetWindowOnDisplaySearchResult);
1077 if (mTmpGetWindowOnDisplaySearchResult.foundWindow != null) {
Wale Ogunwaleec731152016-09-08 20:18:57 -07001078 // We have found a window after the token. End search.
1079 break;
1080 }
1081 }
1082
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001083 pos = mTmpGetWindowOnDisplaySearchResult.foundWindow;
Wale Ogunwaleec731152016-09-08 20:18:57 -07001084
1085 if (pos != null) {
1086 // Move in front of any windows attached to this one.
Wale Ogunwale02319a62016-09-26 15:21:22 -07001087 final WindowToken atoken = getWindowToken(pos.mClient.asBinder());
Wale Ogunwaleec731152016-09-08 20:18:57 -07001088 if (atoken != null) {
1089 final WindowState top = atoken.getTopWindow();
1090 if (top != null && top.mSubLayer >= 0) {
1091 pos = top;
1092 }
1093 }
1094 addWindowToListAfter(win, pos);
1095 return 0;
1096 }
1097
1098 // Just search for the start of this layer.
1099 final int myLayer = win.mBaseLayer;
1100 int i;
1101 for (i = mWindows.size() - 1; i >= 0; --i) {
1102 final WindowState w = mWindows.get(i);
1103 // Dock divider shares the base layer with application windows, but we want to always
1104 // keep it above the application windows. The sharing of the base layer is intended
1105 // for window animations, which need to be above the dock divider for the duration
1106 // of the animation.
1107 if (w.mBaseLayer <= myLayer && w.mAttrs.type != TYPE_DOCK_DIVIDER) {
1108 break;
1109 }
1110 }
1111 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1112 "Based on layer: Adding window " + win + " at " + (i + 1) + " of "
1113 + mWindows.size());
1114 mWindows.add(i + 1, win);
1115 mService.mWindowsChanged = true;
1116 return 0;
1117 }
1118
1119 /** Adds this non-app window to the window list. */
1120 void addNonAppWindowToWindowList(WindowState win) {
1121 // Figure out where window should go, based on layer.
1122 int i;
1123 for (i = mWindows.size() - 1; i >= 0; i--) {
1124 final WindowState otherWin = mWindows.get(i);
1125 if (otherWin.getBaseType() != TYPE_WALLPAPER && otherWin.mBaseLayer <= win.mBaseLayer) {
1126 // Wallpaper wanders through the window list, for example to position itself
1127 // directly behind keyguard. Because of this it will break the ordering based on
1128 // WindowState.mBaseLayer. There might windows with higher mBaseLayer behind it and
1129 // we don't want the new window to appear above them. An example of this is adding
1130 // of the docked stack divider. Consider a scenario with the following ordering (top
1131 // to bottom): keyguard, wallpaper, assist preview, apps. We want the dock divider
1132 // to land below the assist preview, so the dock divider must ignore the wallpaper,
1133 // with which it shares the base layer.
1134 break;
1135 }
1136 }
1137
1138 i++;
1139 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1140 "Free window: Adding window " + this + " at " + i + " of " + mWindows.size());
1141 mWindows.add(i, win);
1142 mService.mWindowsChanged = true;
1143 }
1144
Wale Ogunwaleb9a07c32016-10-12 14:55:56 -07001145 void addToWindowList(WindowState win, int index) {
1146 mWindows.add(index, win);
1147 }
1148
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07001149 boolean removeFromWindowList(WindowState win) {
1150 return mWindows.remove(win);
1151 }
1152
1153 private int removeWindowAndChildrenFromWindowList(WindowState win, int interestingPos) {
1154 final WindowList windows = getWindowList();
1155 int wpos = windows.indexOf(win);
1156 if (wpos < 0) {
1157 return interestingPos;
1158 }
1159
1160 if (wpos < interestingPos) interestingPos--;
1161 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Temp removing at " + wpos + ": " + this);
1162 windows.remove(wpos);
1163 mService.mWindowsChanged = true;
1164 int childWinCount = win.mChildren.size();
1165 while (childWinCount > 0) {
1166 childWinCount--;
1167 final WindowState cw = win.mChildren.get(childWinCount);
1168 int cpos = windows.indexOf(cw);
1169 if (cpos >= 0) {
1170 if (cpos < interestingPos) interestingPos--;
1171 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM,
1172 "Temp removing child at " + cpos + ": " + cw);
1173 windows.remove(cpos);
1174 }
1175 }
1176 return interestingPos;
1177 }
1178
Wale Ogunwaleec731152016-09-08 20:18:57 -07001179 void addChildWindowToWindowList(WindowState win) {
1180 final WindowState parentWindow = win.getParentWindow();
1181
1182 WindowList windowsOnSameDisplay = getTokenWindowsOnDisplay(win.mToken);
1183
1184 // Figure out this window's ordering relative to the parent window.
1185 final int wCount = windowsOnSameDisplay.size();
1186 final int sublayer = win.mSubLayer;
1187 int largestSublayer = Integer.MIN_VALUE;
1188 WindowState windowWithLargestSublayer = null;
1189 int i;
1190 for (i = 0; i < wCount; i++) {
1191 WindowState w = windowsOnSameDisplay.get(i);
1192 final int wSublayer = w.mSubLayer;
1193 if (wSublayer >= largestSublayer) {
1194 largestSublayer = wSublayer;
1195 windowWithLargestSublayer = w;
1196 }
1197 if (sublayer < 0) {
1198 // For negative sublayers, we go below all windows in the same sublayer.
1199 if (wSublayer >= sublayer) {
1200 addWindowToListBefore(win, wSublayer >= 0 ? parentWindow : w);
1201 break;
1202 }
1203 } else {
1204 // For positive sublayers, we go above all windows in the same sublayer.
1205 if (wSublayer > sublayer) {
1206 addWindowToListBefore(win, w);
1207 break;
1208 }
1209 }
1210 }
1211 if (i >= wCount) {
1212 if (sublayer < 0) {
1213 addWindowToListBefore(win, parentWindow);
1214 } else {
1215 addWindowToListAfter(win,
1216 largestSublayer >= 0 ? windowWithLargestSublayer : parentWindow);
1217 }
1218 }
1219 }
1220
Wale Ogunwalec69694a2016-10-18 13:51:15 -07001221 /** Updates the layer assignment of windows on this display. */
1222 void assignWindowLayers(boolean setLayoutNeeded) {
1223 mLayersController.assignWindowLayers(mWindows);
1224 if (setLayoutNeeded) {
1225 setLayoutNeeded();
1226 }
1227 }
1228
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001229 /**
1230 * Z-orders the display window list so that:
1231 * <ul>
1232 * <li>Any windows that are currently below the wallpaper window stay below the wallpaper
1233 * window.
1234 * <li>Exiting application windows are at the bottom, but above the wallpaper window.
1235 * <li>All other application windows are above the exiting application windows and ordered based
1236 * on the ordering of their stacks and tasks on the display.
1237 * <li>Non-application windows are at the very top.
1238 * </ul>
1239 * <p>
1240 * NOTE: This isn't a complete picture of what the user see. Further manipulation of the window
1241 * surface layering is done in {@link WindowLayersController}.
1242 */
1243 void rebuildAppWindowList() {
1244 int count = mWindows.size();
1245 int i;
1246 int lastBelow = -1;
1247 int numRemoved = 0;
1248
1249 if (mRebuildTmp.length < count) {
1250 mRebuildTmp = new WindowState[count + 10];
1251 }
1252
1253 // First remove all existing app windows.
1254 i = 0;
1255 while (i < count) {
1256 final WindowState w = mWindows.get(i);
1257 if (w.mAppToken != null) {
1258 final WindowState win = mWindows.remove(i);
1259 win.mRebuilding = true;
1260 mRebuildTmp[numRemoved] = win;
1261 mService.mWindowsChanged = true;
1262 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Rebuild removing window: " + win);
1263 count--;
1264 numRemoved++;
1265 continue;
1266 } else if (lastBelow == i-1) {
1267 if (w.mAttrs.type == TYPE_WALLPAPER) {
1268 lastBelow = i;
1269 }
1270 }
1271 i++;
1272 }
1273
1274 // Keep whatever windows were below the app windows still below, by skipping them.
1275 lastBelow++;
1276 i = lastBelow;
1277
1278 // First add all of the exiting app tokens... these are no longer in the main app list,
1279 // but still have windows shown. We put them in the back because now that the animation is
1280 // over we no longer will care about them.
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001281 final int numStacks = mTaskStackContainers.size();
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001282 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001283 AppTokenList exitingAppTokens = mTaskStackContainers.get(stackNdx).mExitingAppTokens;
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001284 int NT = exitingAppTokens.size();
1285 for (int j = 0; j < NT; j++) {
Wale Ogunwale360a8bc2016-10-10 13:25:26 -07001286 i = exitingAppTokens.get(j).rebuildWindowListUnchecked(i);
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001287 }
1288 }
1289
1290 // And add in the still active app tokens in Z order.
1291 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001292 i = mTaskStackContainers.get(stackNdx).rebuildWindowList(i);
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001293 }
1294
1295 i -= lastBelow;
1296 if (i != numRemoved) {
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001297 setLayoutNeeded();
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001298 Slog.w(TAG_WM, "On display=" + mDisplayId + " Rebuild removed " + numRemoved
1299 + " windows but added " + i + " rebuildAppWindowListLocked() "
1300 + " callers=" + Debug.getCallers(10));
1301 for (i = 0; i < numRemoved; i++) {
1302 WindowState ws = mRebuildTmp[i];
1303 if (ws.mRebuilding) {
1304 StringWriter sw = new StringWriter();
1305 PrintWriter pw = new FastPrintWriter(sw, false, 1024);
1306 ws.dump(pw, "", true);
1307 pw.flush();
1308 Slog.w(TAG_WM, "This window was lost: " + ws);
1309 Slog.w(TAG_WM, sw.toString());
1310 ws.mWinAnimator.destroySurfaceLocked();
1311 }
1312 }
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07001313 Slog.w(TAG_WM, "Current window hierarchy:");
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001314 dumpChildrenNames();
1315 Slog.w(TAG_WM, "Final window list:");
1316 dumpWindows();
1317 }
1318 Arrays.fill(mRebuildTmp, null);
1319 }
1320
Wale Ogunwaleec731152016-09-08 20:18:57 -07001321 /** Return the list of Windows on this display associated with the input token. */
1322 WindowList getTokenWindowsOnDisplay(WindowToken token) {
1323 final WindowList windowList = new WindowList();
1324 final int count = mWindows.size();
1325 for (int i = 0; i < count; i++) {
1326 final WindowState win = mWindows.get(i);
1327 if (win.mToken == token) {
1328 windowList.add(win);
1329 }
1330 }
1331 return windowList;
1332 }
1333
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07001334 private void reAddToWindowList(WindowState win) {
1335 win.mToken.addWindow(win);
1336 // This is a hack to get all of the child windows added as well at the right position. Child
1337 // windows should be rare and this case should be rare, so it shouldn't be that big a deal.
1338 int wpos = mWindows.indexOf(win);
1339 if (wpos >= 0) {
1340 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "ReAdd removing from " + wpos + ": " + win);
1341 mWindows.remove(wpos);
1342 mService.mWindowsChanged = true;
1343 win.reAddWindow(wpos);
1344 }
1345 }
1346
1347 void moveInputMethodDialogs(int pos) {
1348 ArrayList<WindowState> dialogs = mService.mInputMethodDialogs;
1349
1350 final int N = dialogs.size();
1351 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Removing " + N + " dialogs w/pos=" + pos);
1352 for (int i = 0; i < N; i++) {
1353 pos = removeWindowAndChildrenFromWindowList(dialogs.get(i), pos);
1354 }
1355 if (DEBUG_INPUT_METHOD) {
1356 Slog.v(TAG_WM, "Window list w/pos=" + pos);
1357 logWindowList(mWindows, " ");
1358 }
1359
1360 WindowState ime = mService.mInputMethodWindow;
1361 if (pos >= 0) {
1362 // Skip windows owned by the input method.
1363 if (ime != null) {
1364 while (pos < mWindows.size()) {
1365 WindowState wp = mWindows.get(pos);
1366 if (wp == ime || wp.getParentWindow() == ime) {
1367 pos++;
1368 continue;
1369 }
1370 break;
1371 }
1372 }
1373 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Adding " + N + " dialogs at pos=" + pos);
1374 for (int i=0; i<N; i++) {
1375 WindowState win = dialogs.get(i);
1376 pos = win.reAddWindow(pos);
1377 }
1378 if (DEBUG_INPUT_METHOD) {
1379 Slog.v(TAG_WM, "Final window list:");
1380 logWindowList(mWindows, " ");
1381 }
1382 return;
1383 }
1384 for (int i=0; i<N; i++) {
1385 WindowState win = dialogs.get(i);
1386 reAddToWindowList(win);
1387 if (DEBUG_INPUT_METHOD) {
1388 Slog.v(TAG_WM, "No IM target, final list:");
1389 logWindowList(mWindows, " ");
1390 }
1391 }
1392 }
1393
1394 boolean moveInputMethodWindowsIfNeeded(boolean needAssignLayers) {
1395 final WindowState imWin = mService.mInputMethodWindow;
1396 final int DN = mService.mInputMethodDialogs.size();
1397 if (imWin == null && DN == 0) {
1398 return false;
1399 }
1400
1401 // TODO(multidisplay): IMEs are only supported on the default display.
1402 WindowList windows = mWindows;
1403
1404 int imPos = findDesiredInputMethodWindowIndex(true);
1405 if (imPos >= 0) {
1406 // In this case, the input method windows are to be placed
1407 // immediately above the window they are targeting.
1408
1409 // First check to see if the input method windows are already
1410 // located here, and contiguous.
1411 final int N = windows.size();
1412 final WindowState firstImWin = imPos < N ? windows.get(imPos) : null;
1413
1414 // Figure out the actual input method window that should be
1415 // at the bottom of their stack.
1416 WindowState baseImWin = imWin != null ? imWin : mService.mInputMethodDialogs.get(0);
1417 final WindowState cw = baseImWin.getBottomChild();
1418 if (cw != null && cw.mSubLayer < 0) {
1419 baseImWin = cw;
1420 }
1421
1422 if (firstImWin == baseImWin) {
1423 // The windows haven't moved... but are they still contiguous?
1424 // First find the top IM window.
1425 int pos = imPos+1;
1426 while (pos < N) {
1427 if (!(windows.get(pos)).mIsImWindow) {
1428 break;
1429 }
1430 pos++;
1431 }
1432 pos++;
1433 // Now there should be no more input method windows above.
1434 while (pos < N) {
1435 if ((windows.get(pos)).mIsImWindow) {
1436 break;
1437 }
1438 pos++;
1439 }
1440 if (pos >= N) {
1441 return false;
1442 }
1443 }
1444
1445 if (imWin != null) {
1446 if (DEBUG_INPUT_METHOD) {
1447 Slog.v(TAG_WM, "Moving IM from " + imPos);
1448 logWindowList(windows, " ");
1449 }
1450 imPos = removeWindowAndChildrenFromWindowList(imWin, imPos);
1451 if (DEBUG_INPUT_METHOD) {
1452 Slog.v(TAG_WM, "List after removing with new pos " + imPos + ":");
1453 logWindowList(windows, " ");
1454 }
1455 imWin.reAddWindow(imPos);
1456 if (DEBUG_INPUT_METHOD) {
1457 Slog.v(TAG_WM, "List after moving IM to " + imPos + ":");
1458 logWindowList(windows, " ");
1459 }
1460 if (DN > 0) moveInputMethodDialogs(imPos+1);
1461 } else {
1462 moveInputMethodDialogs(imPos);
1463 }
1464
1465 } else {
1466 // In this case, the input method windows go in a fixed layer,
1467 // because they aren't currently associated with a focus window.
1468
1469 if (imWin != null) {
1470 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Moving IM from " + imPos);
1471 removeWindowAndChildrenFromWindowList(imWin, 0);
1472 reAddToWindowList(imWin);
1473 if (DEBUG_INPUT_METHOD) {
1474 Slog.v(TAG_WM, "List with no IM target:");
1475 logWindowList(windows, " ");
1476 }
1477 if (DN > 0) moveInputMethodDialogs(-1);
1478 } else {
1479 moveInputMethodDialogs(-1);
1480 }
1481
1482 }
1483
1484 if (needAssignLayers) {
1485 assignWindowLayers(false /* setLayoutNeeded */);
1486 }
1487
1488 return true;
1489 }
1490
1491 /**
1492 * Dig through the WindowStates and find the one that the Input Method will target.
1493 * @param willMove
1494 * @return The index+1 in mWindows of the discovered target.
1495 */
1496 int findDesiredInputMethodWindowIndex(boolean willMove) {
1497 // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the
1498 // same display. Or even when the current IME/target are not on the same screen as the next
1499 // IME/target. For now only look for input windows on the main screen.
1500 final WindowList windows = getWindowList();
1501 WindowState w = null;
1502 int i;
1503 for (i = windows.size() - 1; i >= 0; --i) {
1504 WindowState win = windows.get(i);
1505
1506 if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG_WM, "Checking window @" + i
1507 + " " + win + " fl=0x" + Integer.toHexString(win.mAttrs.flags));
1508 if (canBeImeTarget(win)) {
1509 w = win;
1510 //Slog.i(TAG_WM, "Putting input method here!");
1511
1512 // Yet more tricksyness! If this window is a "starting" window, we do actually want
1513 // to be on top of it, but it is not -really- where input will go. So if the caller
1514 // is not actually looking to move the IME, look down below for a real window to
1515 // target...
1516 if (!willMove && w.mAttrs.type == TYPE_APPLICATION_STARTING && i > 0) {
1517 WindowState wb = windows.get(i-1);
1518 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
1519 i--;
1520 w = wb;
1521 }
1522 }
1523 break;
1524 }
1525 }
1526
1527 // Now w is either mWindows[0] or an IME (or null if mWindows is empty).
1528
1529 if (DEBUG_INPUT_METHOD && willMove) Slog.v(TAG_WM, "Proposed new IME target: " + w);
1530
1531 // Now, a special case -- if the last target's window is in the process of exiting, and is
1532 // above the new target, keep on the last target to avoid flicker. Consider for example a
1533 // Dialog with the IME shown: when the Dialog is dismissed, we want to keep the IME above it
1534 // until it is completely gone so it doesn't drop behind the dialog or its full-screen
1535 // scrim.
1536 final WindowState curTarget = mService.mInputMethodTarget;
1537 if (curTarget != null
1538 && curTarget.isDisplayedLw()
1539 && curTarget.isClosing()
1540 && (w == null || curTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer)) {
1541 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Current target higher, not changing");
1542 return windows.indexOf(curTarget) + 1;
1543 }
1544
1545 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Desired input method target="
1546 + w + " willMove=" + willMove);
1547
1548 if (willMove && w != null) {
1549 AppWindowToken token = curTarget == null ? null : curTarget.mAppToken;
1550 if (token != null) {
1551
1552 // Now some fun for dealing with window animations that modify the Z order. We need
1553 // to look at all windows below the current target that are in this app, finding the
1554 // highest visible one in layering.
1555 WindowState highestTarget = null;
1556 int highestPos = 0;
1557 if (token.mAppAnimator.animating || token.mAppAnimator.animation != null) {
1558 WindowList curWindows = token.getDisplayContent().getWindowList();
1559 int pos = curWindows.indexOf(curTarget);
1560 while (pos >= 0) {
1561 WindowState win = curWindows.get(pos);
1562 if (win.mAppToken != token) {
1563 break;
1564 }
1565 if (!win.mRemoved) {
1566 if (highestTarget == null || win.mWinAnimator.mAnimLayer >
1567 highestTarget.mWinAnimator.mAnimLayer) {
1568 highestTarget = win;
1569 highestPos = pos;
1570 }
1571 }
1572 pos--;
1573 }
1574 }
1575
1576 if (highestTarget != null) {
1577 final AppTransition appTransition = mService.mAppTransition;
1578 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, appTransition + " " + highestTarget
1579 + " animating=" + highestTarget.mWinAnimator.isAnimationSet()
1580 + " layer=" + highestTarget.mWinAnimator.mAnimLayer
1581 + " new layer=" + w.mWinAnimator.mAnimLayer);
1582
1583 if (appTransition.isTransitionSet()) {
1584 // If we are currently setting up for an animation, hold everything until we
1585 // can find out what will happen.
1586 mService.mInputMethodTargetWaitingAnim = true;
1587 mService.mInputMethodTarget = highestTarget;
1588 return highestPos + 1;
1589 } else if (highestTarget.mWinAnimator.isAnimationSet() &&
1590 highestTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
1591 // If the window we are currently targeting is involved with an animation,
1592 // and it is on top of the next target we will be over, then hold off on
1593 // moving until that is done.
1594 mService.mInputMethodTargetWaitingAnim = true;
1595 mService.mInputMethodTarget = highestTarget;
1596 return highestPos + 1;
1597 }
1598 }
1599 }
1600 }
1601
1602 //Slog.i(TAG_WM, "Placing input method @" + (i+1));
1603 if (w != null) {
1604 if (willMove) {
1605 if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to "
1606 + w + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : ""));
1607 mService.mInputMethodTarget = w;
1608 mService.mInputMethodTargetWaitingAnim = false;
1609 if (w.mAppToken != null) {
1610 setInputMethodAnimLayerAdjustment(
1611 w.mAppToken.mAppAnimator.animLayerAdjustment);
1612 } else {
1613 setInputMethodAnimLayerAdjustment(0);
1614 }
1615 }
1616
1617 // If the docked divider is visible, we still need to go through this whole excercise to
1618 // find the appropriate input method target (used for animations and dialog
1619 // adjustments), but for purposes of Z ordering we simply wish to place it above the
1620 // docked divider. Unless it is already above the divider.
1621 final WindowState dockedDivider = mDividerControllerLocked.getWindow();
1622 if (dockedDivider != null && dockedDivider.isVisibleLw()) {
1623 int dividerIndex = windows.indexOf(dockedDivider);
1624 if (dividerIndex > 0 && dividerIndex > i) {
1625 return dividerIndex + 1;
1626 }
1627 }
1628 return i+1;
1629 }
1630 if (willMove) {
1631 if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget
1632 + " to null." + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : ""));
1633 mService.mInputMethodTarget = null;
1634 setInputMethodAnimLayerAdjustment(0);
1635 }
1636 return -1;
1637 }
1638
1639 private static boolean canBeImeTarget(WindowState w) {
1640 final int fl = w.mAttrs.flags & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
1641 final int type = w.mAttrs.type;
1642
1643 if (fl != 0 && fl != (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM)
1644 && type != TYPE_APPLICATION_STARTING) {
1645 return false;
1646 }
1647
1648 if (DEBUG_INPUT_METHOD) {
1649 Slog.i(TAG_WM, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
1650 if (!w.isVisibleOrAdding()) {
1651 Slog.i(TAG_WM, " mSurfaceController=" + w.mWinAnimator.mSurfaceController
1652 + " relayoutCalled=" + w.mRelayoutCalled
1653 + " viewVis=" + w.mViewVisibility
1654 + " policyVis=" + w.mPolicyVisibility
1655 + " policyVisAfterAnim=" + w.mPolicyVisibilityAfterAnim
1656 + " parentHidden=" + w.isParentWindowHidden()
1657 + " exiting=" + w.mAnimatingExit + " destroying=" + w.mDestroying);
1658 if (w.mAppToken != null) {
1659 Slog.i(TAG_WM, " mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested);
1660 }
1661 }
1662 }
1663 return w.isVisibleOrAdding();
1664 }
1665
1666 private void logWindowList(final WindowList windows, String prefix) {
1667 int N = windows.size();
1668 while (N > 0) {
1669 N--;
1670 Slog.v(TAG_WM, prefix + "#" + N + ": " + windows.get(N));
1671 }
1672 }
1673
1674 boolean getNeedsMenu(WindowState win, WindowManagerPolicy.WindowState bottom) {
1675 int index = -1;
1676 WindowList windows = getWindowList();
1677 while (true) {
1678 if (win.mAttrs.needsMenuKey != NEEDS_MENU_UNSET) {
1679 return win.mAttrs.needsMenuKey == NEEDS_MENU_SET_TRUE;
1680 }
1681 // If we reached the bottom of the range of windows we are considering,
1682 // assume no menu is needed.
1683 if (win == bottom) {
1684 return false;
1685 }
1686 // The current window hasn't specified whether menu key is needed; look behind it.
1687 // First, we may need to determine the starting position.
1688 if (index < 0) {
1689 index = windows.indexOf(win);
1690 }
1691 index--;
1692 if (index < 0) {
1693 return false;
1694 }
1695 win = windows.get(index);
1696 }
1697 }
1698
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001699 void setLayoutNeeded() {
1700 if (DEBUG_LAYOUT) Slog.w(TAG_WM, "setLayoutNeeded: callers=" + Debug.getCallers(3));
1701 mLayoutNeeded = true;
1702 }
1703
1704 void clearLayoutNeeded() {
1705 if (DEBUG_LAYOUT) Slog.w(TAG_WM, "clearLayoutNeeded: callers=" + Debug.getCallers(3));
1706 mLayoutNeeded = false;
1707 }
1708
1709 boolean isLayoutNeeded() {
1710 return mLayoutNeeded;
1711 }
1712
Wale Ogunwaleec731152016-09-08 20:18:57 -07001713 private int addAppWindowExisting(WindowState win, WindowList tokenWindowList) {
1714
1715 int tokenWindowsPos;
1716 // If this application has existing windows, we simply place the new window on top of
1717 // them... but keep the starting window on top.
1718 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
1719 // Base windows go behind everything else.
1720 final WindowState lowestWindow = tokenWindowList.get(0);
1721 addWindowToListBefore(win, lowestWindow);
1722 tokenWindowsPos = win.mToken.getWindowIndex(lowestWindow);
1723 } else {
1724 final AppWindowToken atoken = win.mAppToken;
1725 final int windowListPos = tokenWindowList.size();
1726 final WindowState lastWindow = tokenWindowList.get(windowListPos - 1);
1727 if (atoken != null && lastWindow == atoken.startingWindow) {
1728 addWindowToListBefore(win, lastWindow);
1729 tokenWindowsPos = win.mToken.getWindowIndex(lastWindow);
1730 } else {
1731 int newIdx = findIdxBasedOnAppTokens(win);
1732 // There is a window above this one associated with the same apptoken note that the
1733 // window could be a floating window that was created later or a window at the top
1734 // of the list of windows associated with this token.
1735 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1736 "not Base app: Adding window " + win + " at " + (newIdx + 1) + " of "
1737 + mWindows.size());
1738 mWindows.add(newIdx + 1, win);
1739 if (newIdx < 0) {
1740 // No window from token found on win's display.
1741 tokenWindowsPos = 0;
1742 } else {
1743 tokenWindowsPos = win.mToken.getWindowIndex(mWindows.get(newIdx)) + 1;
1744 }
1745 mService.mWindowsChanged = true;
1746 }
1747 }
1748 return tokenWindowsPos;
1749 }
1750
1751 /** Places the first input window after the second input window in the window list. */
1752 private void addWindowToListAfter(WindowState first, WindowState second) {
1753 final int i = mWindows.indexOf(second);
1754 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1755 "Adding window " + this + " at " + (i + 1) + " of " + mWindows.size()
1756 + " (after " + second + ")");
1757 mWindows.add(i + 1, first);
1758 mService.mWindowsChanged = true;
1759 }
1760
1761 /** Places the first input window before the second input window in the window list. */
1762 private void addWindowToListBefore(WindowState first, WindowState second) {
1763 int i = mWindows.indexOf(second);
1764 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1765 "Adding window " + this + " at " + i + " of " + mWindows.size()
1766 + " (before " + second + ")");
1767 if (i < 0) {
1768 Slog.w(TAG_WM, "addWindowToListBefore: Unable to find " + second + " in " + mWindows);
1769 i = 0;
1770 }
1771 mWindows.add(i, first);
1772 mService.mWindowsChanged = true;
1773 }
1774
1775 /**
1776 * This method finds out the index of a window that has the same app token as win. used for z
1777 * ordering the windows in mWindows
1778 */
1779 private int findIdxBasedOnAppTokens(WindowState win) {
1780 for(int j = mWindows.size() - 1; j >= 0; j--) {
1781 final WindowState wentry = mWindows.get(j);
1782 if(wentry.mAppToken == win.mAppToken) {
1783 return j;
1784 }
1785 }
1786 return -1;
1787 }
1788
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001789 private void dumpChildrenNames() {
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07001790 StringBuilder output = new StringBuilder();
1791 dumpChildrenNames(output, " ");
1792 Slog.v(TAG_WM, output.toString());
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001793 }
1794
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001795 private void dumpWindows() {
Wale Ogunwale10124582016-09-15 20:25:50 -07001796 Slog.v(TAG_WM, " Display #" + mDisplayId);
1797 final WindowList windows = getWindowList();
1798 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1799 Slog.v(TAG_WM, " #" + winNdx + ": " + windows.get(winNdx));
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001800 }
1801 }
1802
Wale Ogunwale02319a62016-09-26 15:21:22 -07001803 void dumpTokens(PrintWriter pw, boolean dumpAll) {
1804 if (mTokenMap.isEmpty()) {
1805 return;
1806 }
1807 pw.println(" Display #" + mDisplayId);
1808 final Iterator<WindowToken> it = mTokenMap.values().iterator();
1809 while (it.hasNext()) {
1810 final WindowToken token = it.next();
1811 pw.print(" ");
1812 pw.print(token);
1813 if (dumpAll) {
1814 pw.println(':');
1815 token.dump(pw, " ");
1816 } else {
1817 pw.println();
1818 }
1819 }
1820 }
1821
Wale Ogunwale824ab5c2016-10-20 09:31:56 -07001822 void dumpWindowAnimators(PrintWriter pw, String subPrefix) {
1823 final int count = mWindows.size();
1824 for (int j = 0; j < count; j++) {
1825 final WindowStateAnimator wAnim = mWindows.get(j).mWinAnimator;
1826 pw.println(subPrefix + "Window #" + j + ": " + wAnim);
1827 }
1828 }
1829
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001830 void enableSurfaceTrace(FileDescriptor fd) {
1831 for (int i = mWindows.size() - 1; i >= 0; i--) {
1832 final WindowState win = mWindows.get(i);
1833 win.mWinAnimator.enableSurfaceTrace(fd);
1834 }
1835 }
1836
1837 void disableSurfaceTrace() {
1838 for (int i = mWindows.size() - 1; i >= 0; i--) {
1839 final WindowState win = mWindows.get(i);
1840 win.mWinAnimator.disableSurfaceTrace();
1841 }
1842 }
1843
Wale Ogunwale824ab5c2016-10-20 09:31:56 -07001844 void updateWindowsForAnimator(WindowAnimator animator) {
1845 final WindowManagerPolicy policy = animator.mPolicy;
1846 final int keyguardGoingAwayFlags = animator.mKeyguardGoingAwayFlags;
1847 final boolean keyguardGoingAwayToShade =
1848 (keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_TO_SHADE) != 0;
1849 final boolean keyguardGoingAwayNoAnimation =
1850 (keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS) != 0;
1851 final boolean keyguardGoingAwayWithWallpaper =
1852 (keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER) != 0;
1853
1854 if (animator.mKeyguardGoingAway) {
1855 for (int i = mWindows.size() - 1; i >= 0; i--) {
1856 WindowState win = mWindows.get(i);
1857 if (!policy.isKeyguardHostWindow(win.mAttrs)) {
1858 continue;
1859 }
1860 final WindowStateAnimator winAnimator = win.mWinAnimator;
1861 if (policy.isKeyguardShowingAndNotOccluded()) {
1862 if (!winAnimator.mAnimating) {
1863 if (DEBUG_KEYGUARD) Slog.d(TAG,
1864 "updateWindowsForAnimator: creating delay animation");
1865
1866 // Create a new animation to delay until keyguard is gone on its own.
1867 winAnimator.mAnimation = new AlphaAnimation(1.0f, 1.0f);
1868 winAnimator.mAnimation.setDuration(KEYGUARD_ANIM_TIMEOUT_MS);
1869 winAnimator.mAnimationIsEntrance = false;
1870 winAnimator.mAnimationStartTime = -1;
1871 winAnimator.mKeyguardGoingAwayAnimation = true;
1872 winAnimator.mKeyguardGoingAwayWithWallpaper
1873 = keyguardGoingAwayWithWallpaper;
1874 }
1875 } else {
1876 if (DEBUG_KEYGUARD) Slog.d(TAG,
1877 "updateWindowsForAnimator: StatusBar is no longer keyguard");
1878 animator.mKeyguardGoingAway = false;
1879 winAnimator.clearAnimation();
1880 }
1881 break;
1882 }
1883 }
1884
1885 animator.mForceHiding = KEYGUARD_NOT_SHOWN;
1886
1887 boolean wallpaperInUnForceHiding = false;
1888 boolean startingInUnForceHiding = false;
1889 ArrayList<WindowStateAnimator> unForceHiding = null;
1890 WindowState wallpaper = null;
1891 final WallpaperController wallpaperController = mService.mWallpaperControllerLocked;
1892 for (int i = mWindows.size() - 1; i >= 0; i--) {
1893 WindowState win = mWindows.get(i);
1894 WindowStateAnimator winAnimator = win.mWinAnimator;
1895 final int flags = win.mAttrs.flags;
1896 boolean canBeForceHidden = policy.canBeForceHidden(win, win.mAttrs);
1897 boolean shouldBeForceHidden = animator.shouldForceHide(win);
1898 if (winAnimator.hasSurface()) {
1899 final boolean wasAnimating = winAnimator.mWasAnimating;
1900 final boolean nowAnimating = winAnimator.stepAnimationLocked(animator.mCurrentTime);
1901 winAnimator.mWasAnimating = nowAnimating;
1902 animator.orAnimating(nowAnimating);
1903
1904 if (DEBUG_WALLPAPER) Slog.v(TAG,
1905 win + ": wasAnimating=" + wasAnimating + ", nowAnimating=" + nowAnimating);
1906
1907 if (wasAnimating && !winAnimator.mAnimating
1908 && wallpaperController.isWallpaperTarget(win)) {
1909 animator.mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
1910 pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
1911 if (DEBUG_LAYOUT_REPEATS) {
1912 mService.mWindowPlacerLocked.debugLayoutRepeats(
1913 "updateWindowsAndWallpaperLocked 2", pendingLayoutChanges);
1914 }
1915 }
1916
1917 if (policy.isForceHiding(win.mAttrs)) {
1918 if (!wasAnimating && nowAnimating) {
1919 if (DEBUG_KEYGUARD || DEBUG_ANIM || DEBUG_VISIBILITY) Slog.v(TAG,
1920 "Animation started that could impact force hide: " + win);
1921 animator.mBulkUpdateParams |= SET_FORCE_HIDING_CHANGED;
1922 pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
1923 if (DEBUG_LAYOUT_REPEATS) {
1924 mService.mWindowPlacerLocked.debugLayoutRepeats(
1925 "updateWindowsAndWallpaperLocked 3", pendingLayoutChanges);
1926 }
1927 mService.mFocusMayChange = true;
1928 } else if (animator.mKeyguardGoingAway && !nowAnimating) {
1929 // Timeout!!
1930 Slog.e(TAG, "Timeout waiting for animation to startup");
1931 policy.startKeyguardExitAnimation(0, 0);
1932 animator.mKeyguardGoingAway = false;
1933 }
1934 if (win.isReadyForDisplay()) {
1935 if (nowAnimating && win.mWinAnimator.mKeyguardGoingAwayAnimation) {
1936 animator.mForceHiding = KEYGUARD_ANIMATING_OUT;
1937 } else {
1938 animator.mForceHiding = win.isDrawnLw()
1939 ? KEYGUARD_SHOWN : KEYGUARD_NOT_SHOWN;
1940 }
1941 }
1942 if (DEBUG_KEYGUARD || DEBUG_VISIBILITY) Slog.v(TAG,
1943 "Force hide " + animator.forceHidingToString()
1944 + " hasSurface=" + win.mHasSurface
1945 + " policyVis=" + win.mPolicyVisibility
1946 + " destroying=" + win.mDestroying
1947 + " parentHidden=" + win.isParentWindowHidden()
1948 + " vis=" + win.mViewVisibility
1949 + " hidden=" + win.mToken.hidden
1950 + " anim=" + win.mWinAnimator.mAnimation);
1951 } else if (canBeForceHidden) {
1952 if (shouldBeForceHidden) {
1953 if (!win.hideLw(false, false)) {
1954 // Was already hidden
1955 continue;
1956 }
1957 if (DEBUG_KEYGUARD || DEBUG_VISIBILITY) Slog.v(TAG,
1958 "Now policy hidden: " + win);
1959 } else {
1960 final Animation postKeyguardExitAnimation =
1961 animator.mPostKeyguardExitAnimation;
1962 boolean applyExistingExitAnimation = postKeyguardExitAnimation != null
1963 && !postKeyguardExitAnimation.hasEnded()
1964 && !winAnimator.mKeyguardGoingAwayAnimation
1965 && win.hasDrawnLw()
1966 && !win.isChildWindow()
1967 && !win.mIsImWindow
1968 && isDefaultDisplay;
1969
1970 // If the window is already showing and we don't need to apply an existing
1971 // Keyguard exit animation, skip.
1972 if (!win.showLw(false, false) && !applyExistingExitAnimation) {
1973 continue;
1974 }
1975 final boolean visibleNow = win.isVisibleNow();
1976 if (!visibleNow) {
1977 // Couldn't really show, must showLw() again when win becomes visible.
1978 win.hideLw(false, false);
1979 continue;
1980 }
1981 if (DEBUG_KEYGUARD || DEBUG_VISIBILITY) Slog.v(TAG,
1982 "Now policy shown: " + win);
1983 if ((animator.mBulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0
1984 && !win.isChildWindow()) {
1985 if (unForceHiding == null) {
1986 unForceHiding = new ArrayList<>();
1987 }
1988 unForceHiding.add(winAnimator);
1989 if ((flags & FLAG_SHOW_WALLPAPER) != 0) {
1990 wallpaperInUnForceHiding = true;
1991 }
1992 if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
1993 startingInUnForceHiding = true;
1994 }
1995 } else if (applyExistingExitAnimation) {
1996 // We're already in the middle of an animation. Use the existing
1997 // animation to bring in this window.
1998 if (DEBUG_KEYGUARD) Slog.v(TAG,
1999 "Applying existing Keyguard exit animation to new window: win="
2000 + win);
2001
2002 final Animation a = policy.createForceHideEnterAnimation(false,
2003 keyguardGoingAwayToShade);
2004 winAnimator.setAnimation(a, postKeyguardExitAnimation.getStartTime(),
2005 STACK_CLIP_BEFORE_ANIM);
2006 winAnimator.mKeyguardGoingAwayAnimation = true;
2007 winAnimator.mKeyguardGoingAwayWithWallpaper
2008 = keyguardGoingAwayWithWallpaper;
2009 }
2010 final WindowState currentFocus = mService.mCurrentFocus;
2011 if (currentFocus == null || currentFocus.mLayer < win.mLayer) {
2012 // We are showing on top of the current
2013 // focus, so re-evaluate focus to make
2014 // sure it is correct.
2015 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG,
2016 "updateWindowsForAnimator: setting mFocusMayChange true");
2017 mService.mFocusMayChange = true;
2018 }
2019 }
2020 if ((flags & FLAG_SHOW_WALLPAPER) != 0) {
2021 animator.mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
2022 pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
2023 if (DEBUG_LAYOUT_REPEATS) {
2024 mService.mWindowPlacerLocked.debugLayoutRepeats(
2025 "updateWindowsAndWallpaperLocked 4", pendingLayoutChanges);
2026 }
2027 }
2028 }
2029 }
2030
2031 // If the window doesn't have a surface, the only thing we care about is the correct
2032 // policy visibility.
2033 else if (canBeForceHidden) {
2034 if (shouldBeForceHidden) {
2035 win.hideLw(false, false);
2036 } else {
2037 win.showLw(false, false);
2038 }
2039 }
2040
2041 final AppWindowToken atoken = win.mAppToken;
2042 if (winAnimator.mDrawState == READY_TO_SHOW) {
2043 if (atoken == null || atoken.allDrawn) {
2044 if (win.performShowLocked()) {
2045 pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
2046 if (DEBUG_LAYOUT_REPEATS) {
2047 mService.mWindowPlacerLocked.debugLayoutRepeats(
2048 "updateWindowsAndWallpaperLocked 5", pendingLayoutChanges);
2049 }
2050 }
2051 }
2052 }
2053 final AppWindowAnimator appAnimator = winAnimator.mAppAnimator;
2054 if (appAnimator != null && appAnimator.thumbnail != null) {
2055 if (appAnimator.thumbnailTransactionSeq != animator.mAnimTransactionSequence) {
2056 appAnimator.thumbnailTransactionSeq = animator.mAnimTransactionSequence;
2057 appAnimator.thumbnailLayer = 0;
2058 }
2059 if (appAnimator.thumbnailLayer < winAnimator.mAnimLayer) {
2060 appAnimator.thumbnailLayer = winAnimator.mAnimLayer;
2061 }
2062 }
2063 if (win.mIsWallpaper) {
2064 wallpaper = win;
2065 }
2066 } // end forall windows
2067
2068 // If we have windows that are being shown due to them no longer being force-hidden, apply
2069 // the appropriate animation to them if animations are not disabled.
2070 if (unForceHiding != null) {
2071 if (!keyguardGoingAwayNoAnimation) {
2072 boolean first = true;
2073 for (int i=unForceHiding.size()-1; i>=0; i--) {
2074 final WindowStateAnimator winAnimator = unForceHiding.get(i);
2075 final Animation a = policy.createForceHideEnterAnimation(
2076 wallpaperInUnForceHiding && !startingInUnForceHiding,
2077 keyguardGoingAwayToShade);
2078 if (a != null) {
2079 if (DEBUG_KEYGUARD) Slog.v(TAG,
2080 "Starting keyguard exit animation on window " + winAnimator.mWin);
2081 winAnimator.setAnimation(a, STACK_CLIP_BEFORE_ANIM);
2082 winAnimator.mKeyguardGoingAwayAnimation = true;
2083 winAnimator.mKeyguardGoingAwayWithWallpaper
2084 = keyguardGoingAwayWithWallpaper;
2085 if (first) {
2086 animator.mPostKeyguardExitAnimation = a;
2087 animator.mPostKeyguardExitAnimation.setStartTime(animator.mCurrentTime);
2088 first = false;
2089 }
2090 }
2091 }
2092 } else if (animator.mKeyguardGoingAway) {
2093 policy.startKeyguardExitAnimation(animator.mCurrentTime, 0 /* duration */);
2094 animator.mKeyguardGoingAway = false;
2095 }
2096
2097
2098 // Wallpaper is going away in un-force-hide motion, animate it as well.
2099 if (!wallpaperInUnForceHiding && wallpaper != null && !keyguardGoingAwayNoAnimation) {
2100 if (DEBUG_KEYGUARD) Slog.d(TAG,
2101 "updateWindowsForAnimator: wallpaper animating away");
2102 final Animation a = policy.createForceHideWallpaperExitAnimation(
2103 keyguardGoingAwayToShade);
2104 if (a != null) {
2105 wallpaper.mWinAnimator.setAnimation(a);
2106 }
2107 }
2108 }
2109
2110 if (animator.mPostKeyguardExitAnimation != null) {
2111 // We're in the midst of a keyguard exit animation.
2112 if (animator.mKeyguardGoingAway) {
2113 policy.startKeyguardExitAnimation(animator.mCurrentTime +
2114 animator.mPostKeyguardExitAnimation.getStartOffset(),
2115 animator.mPostKeyguardExitAnimation.getDuration());
2116 animator.mKeyguardGoingAway = false;
2117 }
2118 // mPostKeyguardExitAnimation might either be ended normally, cancelled, or "orphaned",
2119 // meaning that the window it was running on was removed. We check for hasEnded() for
2120 // ended normally and cancelled case, and check the time for the "orphaned" case.
2121 else if (animator.mPostKeyguardExitAnimation.hasEnded()
2122 || animator.mCurrentTime - animator.mPostKeyguardExitAnimation.getStartTime()
2123 > animator.mPostKeyguardExitAnimation.getDuration()) {
2124 // Done with the animation, reset.
2125 if (DEBUG_KEYGUARD) Slog.v(TAG, "Done with Keyguard exit animations.");
2126 animator.mPostKeyguardExitAnimation = null;
2127 }
2128 }
2129
2130 final WindowState winShowWhenLocked = (WindowState) policy.getWinShowWhenLockedLw();
2131 if (winShowWhenLocked != null) {
2132 animator.mLastShowWinWhenLocked = winShowWhenLocked;
2133 }
2134 }
2135
2136 void updateWallpaperForAnimator(WindowAnimator animator) {
2137 final WindowList windows = mWindows;
2138 WindowState detachedWallpaper = null;
2139
2140 for (int i = windows.size() - 1; i >= 0; i--) {
2141 final WindowState win = windows.get(i);
2142 final WindowStateAnimator winAnimator = win.mWinAnimator;
2143 if (winAnimator.mSurfaceController == null || !winAnimator.hasSurface()) {
2144 continue;
2145 }
2146
2147 final int flags = win.mAttrs.flags;
2148
2149 // If this window is animating, make a note that we have an animating window and take
2150 // care of a request to run a detached wallpaper animation.
2151 if (winAnimator.mAnimating) {
2152 if (winAnimator.mAnimation != null) {
2153 if ((flags & FLAG_SHOW_WALLPAPER) != 0
2154 && winAnimator.mAnimation.getDetachWallpaper()) {
2155 detachedWallpaper = win;
2156 }
2157 final int color = winAnimator.mAnimation.getBackgroundColor();
2158 if (color != 0) {
2159 final TaskStack stack = win.getStack();
2160 if (stack != null) {
2161 stack.setAnimationBackground(winAnimator, color);
2162 }
2163 }
2164 }
2165 animator.setAnimating(true);
2166 }
2167
2168 // If this window's app token is running a detached wallpaper animation, make a note so
2169 // we can ensure the wallpaper is displayed behind it.
2170 final AppWindowAnimator appAnimator = winAnimator.mAppAnimator;
2171 if (appAnimator != null && appAnimator.animation != null
2172 && appAnimator.animating) {
2173 if ((flags & FLAG_SHOW_WALLPAPER) != 0
2174 && appAnimator.animation.getDetachWallpaper()) {
2175 detachedWallpaper = win;
2176 }
2177
2178 final int color = appAnimator.animation.getBackgroundColor();
2179 if (color != 0) {
2180 final TaskStack stack = win.getStack();
2181 if (stack != null) {
2182 stack.setAnimationBackground(winAnimator, color);
2183 }
2184 }
2185 }
2186 } // end forall windows
2187
2188 if (animator.mWindowDetachedWallpaper != detachedWallpaper) {
2189 if (DEBUG_WALLPAPER) Slog.v(TAG, "Detached wallpaper changed from "
2190 + animator.mWindowDetachedWallpaper + " to " + detachedWallpaper);
2191 animator.mWindowDetachedWallpaper = detachedWallpaper;
2192 animator.mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
2193 }
2194 }
2195
2196 void prepareWindowSurfaces() {
2197 final int count = mWindows.size();
2198 for (int j = 0; j < count; j++) {
2199 mWindows.get(j).mWinAnimator.prepareSurfaceLocked(true);
2200 }
2201 }
2202
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07002203 static final class GetWindowOnDisplaySearchResult {
Wale Ogunwaleec731152016-09-08 20:18:57 -07002204 boolean reachedToken;
2205 WindowState foundWindow;
2206
2207 void reset() {
2208 reachedToken = false;
2209 foundWindow = null;
2210 }
2211 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07002212
2213 static final class TaskForResizePointSearchResult {
2214 boolean searchDone;
2215 Task taskForResize;
2216
2217 void reset() {
2218 searchDone = false;
2219 taskForResize = null;
2220 }
2221 }
Robert Carr3b716242016-08-16 16:02:21 -07002222
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002223 /**
2224 * Base class for any direct child window container of {@link #DisplayContent} need to inherit
2225 * from. This is mainly a pass through class that allows {@link #DisplayContent} to have
2226 * homogeneous children type which is currently required by sub-classes of
2227 * {@link WindowContainer} class.
2228 */
2229 static class DisplayChildWindowContainer<E extends WindowContainer> extends WindowContainer<E> {
2230
2231 int size() {
2232 return mChildren.size();
2233 }
2234
2235 E get(int index) {
2236 return mChildren.get(index);
2237 }
2238
2239 @Override
2240 boolean fillsParent() {
2241 return true;
2242 }
2243
2244 @Override
2245 boolean isVisible() {
2246 return true;
Robert Carr3b716242016-08-16 16:02:21 -07002247 }
2248 }
2249
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002250 /**
2251 * Window container class that contains all containers on this display relating to Apps.
2252 * I.e Activities.
2253 */
2254 private class TaskStackContainers extends DisplayChildWindowContainer<TaskStack> {
2255
2256 void attachStack(TaskStack stack, boolean onTop) {
2257 if (stack.mStackId == HOME_STACK_ID) {
2258 if (mHomeStack != null) {
2259 throw new IllegalArgumentException("attachStack: HOME_STACK_ID (0) not first.");
2260 }
2261 mHomeStack = stack;
2262 }
2263 addChild(stack, onTop);
2264 stack.onDisplayChanged(DisplayContent.this);
Robert Carr3b716242016-08-16 16:02:21 -07002265 }
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002266
2267 void moveStack(TaskStack stack, boolean toTop) {
2268 if (StackId.isAlwaysOnTop(stack.mStackId) && !toTop) {
2269 // This stack is always-on-top silly...
2270 Slog.w(TAG_WM, "Ignoring move of always-on-top stack=" + stack + " to bottom");
2271 return;
2272 }
2273
2274 if (!mChildren.contains(stack)) {
2275 Slog.wtf(TAG_WM, "moving stack that was not added: " + stack, new Throwable());
2276 }
2277 removeChild(stack);
2278 addChild(stack, toTop);
2279 }
2280
2281 private void addChild(TaskStack stack, boolean toTop) {
2282 int addIndex = toTop ? mChildren.size() : 0;
2283
2284 if (toTop
2285 && mService.isStackVisibleLocked(PINNED_STACK_ID)
2286 && stack.mStackId != PINNED_STACK_ID) {
2287 // The pinned stack is always the top most stack (always-on-top) when it is visible.
2288 // So, stack is moved just below the pinned stack.
2289 addIndex--;
2290 TaskStack topStack = mChildren.get(addIndex);
2291 if (topStack.mStackId != PINNED_STACK_ID) {
2292 throw new IllegalStateException("Pinned stack isn't top stack??? " + mChildren);
2293 }
2294 }
2295 addChild(stack, addIndex);
2296 setLayoutNeeded();
2297 }
2298
2299 }
2300
2301 /**
2302 * Window container class that contains all containers on this display that are not related to
2303 * Apps. E.g. status bar.
2304 */
2305 private static class NonAppWindowContainers extends DisplayChildWindowContainer<WindowToken> {
2306
Robert Carr3b716242016-08-16 16:02:21 -07002307 }
Craig Mautner59c00972012-07-30 12:10:24 -07002308}