blob: 7cd99714c00cbe76aeb5717597fe1bca2ef17d14 [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 Ogunwale494009b82016-10-21 09:01:38 -070039import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -070040import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -070041import static android.view.WindowManager.LayoutParams.NEEDS_MENU_SET_TRUE;
42import static android.view.WindowManager.LayoutParams.NEEDS_MENU_UNSET;
Wale Ogunwale494009b82016-10-21 09:01:38 -070043import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -070044import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
Wale Ogunwaleec731152016-09-08 20:18:57 -070045import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
Wale Ogunwale494009b82016-10-21 09:01:38 -070046import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
Wale Ogunwaleec731152016-09-08 20:18:57 -070047import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
Wale Ogunwale494009b82016-10-21 09:01:38 -070048import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION;
49import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
Svetoslav Ganovaa076532016-08-01 19:16:43 -070050import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
Wale Ogunwaleec731152016-09-08 20:18:57 -070051import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -070052import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
53import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
54import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
55import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
56import static android.view.WindowManagerPolicy.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
57import static com.android.server.wm.WindowAnimator.KEYGUARD_ANIMATING_OUT;
58import static com.android.server.wm.WindowAnimator.KEYGUARD_ANIM_TIMEOUT_MS;
59import static com.android.server.wm.WindowAnimator.KEYGUARD_NOT_SHOWN;
60import static com.android.server.wm.WindowAnimator.KEYGUARD_SHOWN;
Wale Ogunwaleec731152016-09-08 20:18:57 -070061import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -070062import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
Wale Ogunwale494009b82016-10-21 09:01:38 -070063import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT;
Wale Ogunwale10124582016-09-15 20:25:50 -070064import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -070065import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
66import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -070067import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -070068import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEYGUARD;
Wale Ogunwalec69694a2016-10-18 13:51:15 -070069import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -070070import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -070071import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
Wale Ogunwale494009b82016-10-21 09:01:38 -070072import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREEN_ON;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -070073import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
Wale Ogunwaleec731152016-09-08 20:18:57 -070074import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080075import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
Wale Ogunwale51362492016-09-08 17:49:17 -070076import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -070077import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -070078import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080079import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -070080import static com.android.server.wm.WindowManagerService.H.WINDOW_HIDE_TIMEOUT;
Wale Ogunwale494009b82016-10-21 09:01:38 -070081import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_TIMEOUT;
Wale Ogunwale19e452e2016-10-12 12:36:29 -070082import static com.android.server.wm.WindowManagerService.dipToPixel;
83import static com.android.server.wm.WindowManagerService.localLOGV;
Wale Ogunwale231b06e2015-09-16 12:03:09 -070084import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP;
Wale Ogunwale494009b82016-10-21 09:01:38 -070085import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -070086import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW;
87import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
88import static com.android.server.wm.WindowSurfacePlacer.SET_FORCE_HIDING_CHANGED;
89import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_MAY_CHANGE;
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -070090
Andrii Kulian3a507b52016-09-19 18:14:12 -070091import android.annotation.NonNull;
Wale Ogunwale3797c222015-10-27 14:21:58 -070092import android.app.ActivityManager.StackId;
Andrii Kulian441e4492016-09-29 15:25:00 -070093import android.content.res.Configuration;
Andrii Kulian4dfb9c42016-10-11 20:06:27 -070094import android.graphics.Matrix;
Craig Mautnerc00204b2013-03-05 15:02:14 -080095import android.graphics.Rect;
Andrii Kulian4dfb9c42016-10-11 20:06:27 -070096import android.graphics.RectF;
Craig Mautner6601b7b2013-04-29 10:29:11 -070097import android.graphics.Region;
Jorim Jaggid47e7e12016-03-01 09:57:38 +010098import android.graphics.Region.Op;
Wale Ogunwaleb699ce02016-07-18 12:05:30 -070099import android.hardware.display.DisplayManagerInternal;
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700100import android.os.Debug;
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700101import android.os.Handler;
Wale Ogunwale02319a62016-09-26 15:21:22 -0700102import android.os.IBinder;
Wale Ogunwale494009b82016-10-21 09:01:38 -0700103import android.os.RemoteException;
104import android.os.SystemClock;
Chong Zhang8e89b312015-09-09 15:09:30 -0700105import android.util.DisplayMetrics;
Craig Mautnerde4ef022013-04-07 19:01:33 -0700106import android.util.Slog;
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700107import android.view.Display;
Craig Mautner59c00972012-07-30 12:10:24 -0700108import android.view.DisplayInfo;
Wale Ogunwaleec731152016-09-08 20:18:57 -0700109import android.view.IWindow;
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -0700110import android.view.WindowManager;
111import android.view.WindowManagerPolicy;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -0700112import android.view.animation.AlphaAnimation;
113import android.view.animation.Animation;
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700114
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700115import com.android.internal.util.FastPrintWriter;
Wale Ogunwale494009b82016-10-21 09:01:38 -0700116import com.android.internal.view.IInputMethodClient;
Craig Mautner59c00972012-07-30 12:10:24 -0700117
Robert Carr3b716242016-08-16 16:02:21 -0700118import java.io.FileDescriptor;
Craig Mautner59c00972012-07-30 12:10:24 -0700119import java.io.PrintWriter;
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700120import java.io.StringWriter;
Craig Mautner59c00972012-07-30 12:10:24 -0700121import java.util.ArrayList;
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700122import java.util.Arrays;
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700123import java.util.Comparator;
Wale Ogunwale02319a62016-09-26 15:21:22 -0700124import java.util.HashMap;
125import java.util.Iterator;
Andrii Kulian3a507b52016-09-19 18:14:12 -0700126import java.util.List;
Craig Mautner59c00972012-07-30 12:10:24 -0700127
Craig Mautner59c00972012-07-30 12:10:24 -0700128/**
129 * Utility class for keeping track of the WindowStates and other pertinent contents of a
130 * particular Display.
131 *
132 * IMPORTANT: No method from this class should ever be used without holding
133 * WindowManagerService.mWindowMap.
134 */
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700135class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowContainer> {
Wale Ogunwale824ab5c2016-10-20 09:31:56 -0700136 private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayContent" : TAG_WM;
Craig Mautner59c00972012-07-30 12:10:24 -0700137
138 /** Unique identifier of this stack. */
139 private final int mDisplayId;
140
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700141 // The display only has 2 child window containers. mTaskStackContainers which contains all
142 // window containers that are related to apps (Activities) and mNonAppWindowContainers which
143 // contains all window containers not related to apps (e.g. Status bar).
144 private final TaskStackContainers mTaskStackContainers = new TaskStackContainers();
145 private final NonAppWindowContainers mNonAppWindowContainers = new NonAppWindowContainers();
146
Craig Mautner59c00972012-07-30 12:10:24 -0700147 /** Z-ordered (bottom-most first) list of all Window objects. Assigned to an element
148 * from mDisplayWindows; */
Craig Mautnerdc548482014-02-05 13:35:24 -0800149 private final WindowList mWindows = new WindowList();
Craig Mautner59c00972012-07-30 12:10:24 -0700150
Wale Ogunwale02319a62016-09-26 15:21:22 -0700151 // Mapping from a token IBinder to a WindowToken object on this display.
152 private final HashMap<IBinder, WindowToken> mTokenMap = new HashMap();
153
Craig Mautner59c00972012-07-30 12:10:24 -0700154 int mInitialDisplayWidth = 0;
155 int mInitialDisplayHeight = 0;
Dianne Hackborndde331c2012-08-03 14:01:57 -0700156 int mInitialDisplayDensity = 0;
Craig Mautner59c00972012-07-30 12:10:24 -0700157 int mBaseDisplayWidth = 0;
158 int mBaseDisplayHeight = 0;
Dianne Hackborndde331c2012-08-03 14:01:57 -0700159 int mBaseDisplayDensity = 0;
Jeff Brownd46747a2015-04-15 19:02:36 -0700160 boolean mDisplayScalingDisabled;
Craig Mautner2d5618c2012-10-18 13:55:47 -0700161 private final DisplayInfo mDisplayInfo = new DisplayInfo();
162 private final Display mDisplay;
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700163 private final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Craig Mautner59c00972012-07-30 12:10:24 -0700164
Craig Mautner6601b7b2013-04-29 10:29:11 -0700165 Rect mBaseDisplayRect = new Rect();
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700166 private Rect mContentRect = new Rect();
Craig Mautner6601b7b2013-04-29 10:29:11 -0700167
Craig Mautner39834192012-09-02 07:47:24 -0700168 // Accessed directly by all users.
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700169 private boolean mLayoutNeeded;
Craig Mautner76a71652012-09-03 23:23:58 -0700170 int pendingLayoutChanges;
Craig Mautner69b08182012-09-05 13:07:13 -0700171 final boolean isDefaultDisplay;
Craig Mautner39834192012-09-02 07:47:24 -0700172
Craig Mautnerdc548482014-02-05 13:35:24 -0800173 /** Window tokens that are in the process of exiting, but still on screen for animations. */
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700174 final ArrayList<WindowToken> mExitingTokens = new ArrayList<>();
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800175
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800176 /** A special TaskStack with id==HOME_STACK_ID that moves to the bottom whenever any TaskStack
177 * (except a future lockscreen TaskStack) moves to the top. */
Craig Mautnerde4ef022013-04-07 19:01:33 -0700178 private TaskStack mHomeStack = null;
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700179
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700180 /** Detect user tapping outside of current focused task bounds .*/
181 TaskTapPointerEventListener mTapDetector;
Craig Mautnercf910b02013-04-23 11:23:27 -0700182
Craig Mautner6601b7b2013-04-29 10:29:11 -0700183 /** Detect user tapping outside of current focused stack bounds .*/
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700184 private Region mTouchExcludeRegion = new Region();
Craig Mautner6601b7b2013-04-29 10:29:11 -0700185
Craig Mautner6601b7b2013-04-29 10:29:11 -0700186 /** Save allocating when calculating rects */
Filip Gruszczynski912d9192015-12-01 16:14:04 -0800187 private final Rect mTmpRect = new Rect();
188 private final Rect mTmpRect2 = new Rect();
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700189 private final RectF mTmpRectF = new RectF();
190 private final Matrix mTmpMatrix = new Matrix();
Filip Gruszczynski912d9192015-12-01 16:14:04 -0800191 private final Region mTmpRegion = new Region();
Craig Mautner6601b7b2013-04-29 10:29:11 -0700192
Craig Mautner9d808b12013-08-06 18:00:25 -0700193 final WindowManagerService mService;
194
Craig Mautner95da1082014-02-24 17:54:35 -0800195 /** Remove this display when animation on it has completed. */
Wale Ogunwaled4a00a02016-10-10 11:29:17 -0700196 private boolean mDeferredRemoval;
Craig Mautner1bf2b872014-02-05 15:37:40 -0800197
Filip Gruszczynski466f3212015-09-21 17:57:57 -0700198 final DockedStackDividerController mDividerControllerLocked;
199
Chong Zhang112eb8c2015-11-02 11:17:00 -0800200 final DimLayerController mDimLayerController;
Filip Gruszczynski0689ae92015-10-01 12:30:31 -0700201
Filip Gruszczynskiecf67222015-12-11 15:16:36 -0800202 final ArrayList<WindowState> mTapExcludedWindows = new ArrayList<>();
203
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700204 /** Used when rebuilding window list to keep track of windows that have been removed. */
205 private WindowState[] mRebuildTmp = new WindowState[20];
206
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700207 private final TaskForResizePointSearchResult mTmpTaskForResizePointSearchResult =
208 new TaskForResizePointSearchResult();
209 private final GetWindowOnDisplaySearchResult mTmpGetWindowOnDisplaySearchResult =
210 new GetWindowOnDisplaySearchResult();
211
Wale Ogunwale601a3f02016-10-17 08:39:39 -0700212 // True if this display is in the process of being removed. Used to determine if the removal of
213 // the display's direct children should be allowed.
214 private boolean mRemovingDisplay = false;
215
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700216 private final WindowLayersController mLayersController;
Wale Ogunwale0303c572016-10-20 10:16:29 -0700217 final WallpaperController mWallpaperController;
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700218 int mInputMethodAnimLayerAdjustment;
219
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800220 /**
Craig Mautner2d5618c2012-10-18 13:55:47 -0700221 * @param display May not be null.
Craig Mautnerdf88d732014-01-27 09:21:32 -0800222 * @param service You know.
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700223 * @param layersController window layer controller used to assign layer to the windows on this
224 * display.
Wale Ogunwale0303c572016-10-20 10:16:29 -0700225 * @param wallpaperController wallpaper windows controller used to adjust the positioning of the
226 * wallpaper windows in the window list.
Craig Mautner2d5618c2012-10-18 13:55:47 -0700227 */
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700228 DisplayContent(Display display, WindowManagerService service,
Wale Ogunwale0303c572016-10-20 10:16:29 -0700229 WindowLayersController layersController, WallpaperController wallpaperController) {
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700230 mDisplay = display;
231 mDisplayId = display.getDisplayId();
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700232 mLayersController = layersController;
Wale Ogunwale0303c572016-10-20 10:16:29 -0700233 mWallpaperController = wallpaperController;
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700234 display.getDisplayInfo(mDisplayInfo);
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700235 display.getMetrics(mDisplayMetrics);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700236 isDefaultDisplay = mDisplayId == DEFAULT_DISPLAY;
Craig Mautner9d808b12013-08-06 18:00:25 -0700237 mService = service;
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -0700238 initializeDisplayBaseInfo();
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800239 mDividerControllerLocked = new DockedStackDividerController(service, this);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800240 mDimLayerController = new DimLayerController(this);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700241
242 // These are the only direct children we should ever have and they are permanent.
243 super.addChild(mTaskStackContainers, null);
244 super.addChild(mNonAppWindowContainers, null);
Craig Mautner59c00972012-07-30 12:10:24 -0700245 }
246
247 int getDisplayId() {
248 return mDisplayId;
249 }
250
251 WindowList getWindowList() {
252 return mWindows;
253 }
254
Wale Ogunwale02319a62016-09-26 15:21:22 -0700255 WindowToken getWindowToken(IBinder binder) {
256 return mTokenMap.get(binder);
257 }
258
259 AppWindowToken getAppWindowToken(IBinder binder) {
260 final WindowToken token = getWindowToken(binder);
261 if (token == null) {
262 return null;
263 }
264 return token.asAppWindowToken();
265 }
266
267 void setWindowToken(IBinder binder, WindowToken token) {
268 final DisplayContent dc = mService.mRoot.getWindowTokenDisplay(token);
269 if (dc != null) {
270 // We currently don't support adding a window token to the display if the display
271 // already has the binder mapped to another token. If there is a use case for supporting
272 // this moving forward we will either need to merge the WindowTokens some how or have
273 // the binder map to a list of window tokens.
274 throw new IllegalArgumentException("Can't map token=" + token + " to display=" + this
275 + " already mapped to display=" + dc + " tokens=" + dc.mTokenMap);
276 }
277 mTokenMap.put(binder, token);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700278
279 if (token.asAppWindowToken() == null) {
280 // Add non-app token to container hierarchy on the display. App tokens are added through
281 // the parent container managing them (e.g. Tasks).
282 mNonAppWindowContainers.addChild(token, null);
283 }
Wale Ogunwale02319a62016-09-26 15:21:22 -0700284 }
285
286 WindowToken removeWindowToken(IBinder binder) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700287 final WindowToken token = mTokenMap.remove(binder);
288 if (token != null && token.asAppWindowToken() == null) {
289 mNonAppWindowContainers.removeChild(token);
290 }
291 return token;
Wale Ogunwale02319a62016-09-26 15:21:22 -0700292 }
293
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700294 Display getDisplay() {
295 return mDisplay;
296 }
297
Craig Mautner59c00972012-07-30 12:10:24 -0700298 DisplayInfo getDisplayInfo() {
299 return mDisplayInfo;
300 }
301
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700302 DisplayMetrics getDisplayMetrics() {
303 return mDisplayMetrics;
304 }
305
Jorim Jaggi61f39a72015-10-29 16:54:18 +0100306 DockedStackDividerController getDockedDividerController() {
307 return mDividerControllerLocked;
308 }
309
Jeff Browna506a6e2013-06-04 00:02:38 -0700310 /**
311 * Returns true if the specified UID has access to this display.
312 */
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700313 boolean hasAccess(int uid) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700314 return mDisplay.hasAccess(uid);
315 }
316
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700317 boolean isPrivate() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700318 return (mDisplay.getFlags() & FLAG_PRIVATE) != 0;
keunyounga446bf02013-06-21 19:07:57 -0700319 }
320
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700321 TaskStack getHomeStack() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700322 if (mHomeStack == null && mDisplayId == DEFAULT_DISPLAY) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800323 Slog.e(TAG_WM, "getHomeStack: Returning null from this=" + this);
Craig Mautnere0a38842013-12-16 16:14:02 -0800324 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700325 return mHomeStack;
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700326 }
327
Chong Zhangd9d35bd2016-08-04 17:55:21 -0700328 TaskStack getStackById(int stackId) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700329 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
330 final TaskStack stack = mTaskStackContainers.get(i);
Chong Zhangd9d35bd2016-08-04 17:55:21 -0700331 if (stack.mStackId == stackId) {
332 return stack;
333 }
334 }
335 return null;
336 }
337
Andrii Kulian441e4492016-09-29 15:25:00 -0700338 @Override
339 void onConfigurationChanged(Configuration newParentConfig) {
340 super.onConfigurationChanged(newParentConfig);
341
Andrii Kulian3a507b52016-09-19 18:14:12 -0700342 // The display size information is heavily dependent on the resources in the current
343 // configuration, so we need to reconfigure it every time the configuration changes.
344 // See {@link PhoneWindowManager#setInitialDisplaySize}...sigh...
345 mService.reconfigureDisplayLocked(this);
346
347 getDockedDividerController().onConfigurationChanged();
Andrii Kulian441e4492016-09-29 15:25:00 -0700348 }
Andrii Kulian3a507b52016-09-19 18:14:12 -0700349
Andrii Kulian441e4492016-09-29 15:25:00 -0700350 /**
351 * Callback used to trigger bounds update after configuration change and get ids of stacks whose
352 * bounds were updated.
353 */
354 void updateStackBoundsAfterConfigChange(@NonNull List<Integer> changedStackList) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700355 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
356 final TaskStack stack = mTaskStackContainers.get(i);
Andrii Kulian441e4492016-09-29 15:25:00 -0700357 if (stack.updateBoundsAfterConfigChange()) {
Andrii Kulian3a507b52016-09-19 18:14:12 -0700358 changedStackList.add(stack.mStackId);
359 }
360 }
361 }
362
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700363 @Override
364 boolean fillsParent() {
365 return true;
366 }
367
368 @Override
369 boolean isVisible() {
370 return true;
371 }
372
373 @Override
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700374 void onAppTransitionDone() {
Wale Ogunwale10124582016-09-15 20:25:50 -0700375 super.onAppTransitionDone();
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700376 rebuildAppWindowList();
377 }
378
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700379 @Override
Wale Ogunwale51362492016-09-08 17:49:17 -0700380 int getOrientation() {
Wale Ogunwalee6f806e2016-10-20 15:29:42 -0700381 final WindowManagerPolicy policy = mService.mPolicy;
382
383 // TODO: All the logic before the last return statement in this method should really go in
384 // #NonAppWindowContainer.getOrientation() since it is trying to decide orientation based
385 // on non-app windows. But, we can not do that until the window list is always correct in
386 // terms of z-ordering based on layers.
387 if (mService.mDisplayFrozen) {
388 if (mService.mLastWindowForcedOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
389 if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
390 "Display is frozen, return " + mService.mLastWindowForcedOrientation);
391 // If the display is frozen, some activities may be in the middle of restarting, and
392 // thus have removed their old window. If the window has the flag to hide the lock
393 // screen, then the lock screen can re-appear and inflict its own orientation on us.
394 // Keep the orientation stable until this all settles down.
395 return mService.mLastWindowForcedOrientation;
396 } else if (policy.isKeyguardLocked()) {
397 // Use the last orientation the while the display is frozen with the keyguard
398 // locked. This could be the keyguard forced orientation or from a SHOW_WHEN_LOCKED
399 // window. We don't want to check the show when locked window directly though as
400 // things aren't stable while the display is frozen, for example the window could be
401 // momentarily unavailable due to activity relaunch.
402 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display is frozen while keyguard locked, "
403 + "return " + mService.mLastOrientation);
404 return mService.mLastOrientation;
Wale Ogunwale51362492016-09-08 17:49:17 -0700405 }
Wale Ogunwalee6f806e2016-10-20 15:29:42 -0700406 } else {
407 for (int pos = mWindows.size() - 1; pos >= 0; --pos) {
408 final WindowState win = mWindows.get(pos);
409 if (win.mAppToken != null) {
410 // We hit an application window. so the orientation will be determined by the
411 // app window. No point in continuing further.
412 break;
413 }
414 if (!win.isVisibleLw() || !win.mPolicyVisibilityAfterAnim) {
415 continue;
416 }
417 int req = win.mAttrs.screenOrientation;
418 if(req == SCREEN_ORIENTATION_UNSPECIFIED || req == SCREEN_ORIENTATION_BEHIND) {
419 continue;
420 }
421
422 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, win + " forcing orientation to " + req);
423 if (policy.isKeyguardHostWindow(win.mAttrs)) {
424 mService.mLastKeyguardForcedOrientation = req;
425 }
426 return (mService.mLastWindowForcedOrientation = req);
427 }
428 mService.mLastWindowForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
429
430 if (policy.isKeyguardLocked()) {
431 // The screen is locked and no top system window is requesting an orientation.
432 // Return either the orientation of the show-when-locked app (if there is any) or
433 // the orientation of the keyguard. No point in searching from the rest of apps.
434 WindowState winShowWhenLocked = (WindowState) policy.getWinShowWhenLockedLw();
435 AppWindowToken appShowWhenLocked = winShowWhenLocked == null
436 ? null : winShowWhenLocked.mAppToken;
437 if (appShowWhenLocked != null) {
438 int req = appShowWhenLocked.getOrientation();
439 if (req == SCREEN_ORIENTATION_BEHIND) {
440 req = mService.mLastKeyguardForcedOrientation;
441 }
442 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Done at " + appShowWhenLocked
443 + " -- show when locked, return " + req);
444 return req;
445 }
446 if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
447 "No one is requesting an orientation when the screen is locked");
448 return mService.mLastKeyguardForcedOrientation;
449 }
Wale Ogunwale51362492016-09-08 17:49:17 -0700450 }
451
Wale Ogunwalee6f806e2016-10-20 15:29:42 -0700452 // Top system windows are not requesting an orientation. Start searching from apps.
453 return mTaskStackContainers.getOrientation();
Wale Ogunwale51362492016-09-08 17:49:17 -0700454 }
455
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700456 void updateDisplayInfo() {
Craig Mautner722285e2012-09-07 13:55:58 -0700457 mDisplay.getDisplayInfo(mDisplayInfo);
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700458 mDisplay.getMetrics(mDisplayMetrics);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700459 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
460 mTaskStackContainers.get(i).updateDisplayInfo(null);
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800461 }
Craig Mautner722285e2012-09-07 13:55:58 -0700462 }
463
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -0700464 void initializeDisplayBaseInfo() {
Wale Ogunwaleb699ce02016-07-18 12:05:30 -0700465 final DisplayManagerInternal displayManagerInternal = mService.mDisplayManagerInternal;
466 if (displayManagerInternal != null) {
467 // Bootstrap the default logical display from the display manager.
468 final DisplayInfo newDisplayInfo = displayManagerInternal.getDisplayInfo(mDisplayId);
469 if (newDisplayInfo != null) {
470 mDisplayInfo.copyFrom(newDisplayInfo);
471 }
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -0700472 }
Wale Ogunwaleb699ce02016-07-18 12:05:30 -0700473
Filip Gruszczynski608797e2015-11-12 19:08:20 -0800474 mBaseDisplayWidth = mInitialDisplayWidth = mDisplayInfo.logicalWidth;
475 mBaseDisplayHeight = mInitialDisplayHeight = mDisplayInfo.logicalHeight;
476 mBaseDisplayDensity = mInitialDisplayDensity = mDisplayInfo.logicalDensityDpi;
477 mBaseDisplayRect.set(0, 0, mBaseDisplayWidth, mBaseDisplayHeight);
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -0700478 }
479
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700480 void getLogicalDisplayRect(Rect out) {
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700481 // Uses same calculation as in LogicalDisplay#configureDisplayInTransactionLocked.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800482 final int orientation = mDisplayInfo.rotation;
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700483 boolean rotated = (orientation == ROTATION_90 || orientation == ROTATION_270);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800484 final int physWidth = rotated ? mBaseDisplayHeight : mBaseDisplayWidth;
485 final int physHeight = rotated ? mBaseDisplayWidth : mBaseDisplayHeight;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700486 int width = mDisplayInfo.logicalWidth;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800487 int left = (physWidth - width) / 2;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700488 int height = mDisplayInfo.logicalHeight;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800489 int top = (physHeight - height) / 2;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700490 out.set(left, top, left + width, top + height);
491 }
492
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700493 private void getLogicalDisplayRect(Rect out, int orientation) {
494 getLogicalDisplayRect(out);
495
496 // Rotate the Rect if needed.
497 final int currentRotation = mDisplayInfo.rotation;
498 final int rotationDelta = deltaRotation(currentRotation, orientation);
499 if (rotationDelta == ROTATION_90 || rotationDelta == ROTATION_270) {
500 createRotationMatrix(rotationDelta, mBaseDisplayWidth, mBaseDisplayHeight, mTmpMatrix);
501 mTmpRectF.set(out);
502 mTmpMatrix.mapRect(mTmpRectF);
503 mTmpRectF.round(out);
504 }
505 }
506
Chong Zhangf66db432016-01-13 10:39:51 -0800507 void getContentRect(Rect out) {
508 out.set(mContentRect);
509 }
510
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700511 /** Refer to {@link WindowManagerService#attachStack(int, int, boolean)} */
512 void attachStack(TaskStack stack, boolean onTop) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700513 mTaskStackContainers.attachStack(stack, onTop);
Craig Mautnerc00204b2013-03-05 15:02:14 -0800514 }
515
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800516 void moveStack(TaskStack stack, boolean toTop) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700517 mTaskStackContainers.moveStack(stack, toTop);
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700518 }
Wale Ogunwale1e60e0c2015-10-28 13:36:10 -0700519
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700520 @Override
521 protected void addChild(DisplayChildWindowContainer child,
522 Comparator<DisplayChildWindowContainer> comparator) {
523 throw new UnsupportedOperationException("See DisplayChildWindowContainer");
524 }
Wale Ogunwale1e60e0c2015-10-28 13:36:10 -0700525
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700526 @Override
527 protected void addChild(DisplayChildWindowContainer child, int index) {
528 throw new UnsupportedOperationException("See DisplayChildWindowContainer");
529 }
530
531 @Override
532 protected void removeChild(DisplayChildWindowContainer child) {
Wale Ogunwale601a3f02016-10-17 08:39:39 -0700533 // Only allow removal of direct children from this display if the display is in the process
534 // of been removed.
535 if (mRemovingDisplay) {
536 super.removeChild(child);
537 return;
538 }
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700539 throw new UnsupportedOperationException("See DisplayChildWindowContainer");
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800540 }
541
542 /**
543 * Propagate the new bounds to all child stacks.
544 * @param contentRect The bounds to apply at the top level.
545 */
546 void resize(Rect contentRect) {
547 mContentRect.set(contentRect);
548 }
549
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700550 int taskIdFromPoint(int x, int y) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700551 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
552 final TaskStack stack = mTaskStackContainers.get(stackNdx);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700553 final int taskId = stack.taskIdFromPoint(x, y);
554 if (taskId != -1) {
555 return taskId;
Craig Mautner967212c2013-04-13 21:10:58 -0700556 }
557 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800558 return -1;
Craig Mautnercf910b02013-04-23 11:23:27 -0700559 }
560
Chong Zhang8e89b312015-09-09 15:09:30 -0700561 /**
Chong Zhangd8ceb852015-11-11 14:53:41 -0800562 * Find the task whose outside touch area (for resizing) (x, y) falls within.
Chong Zhang9184ec62015-09-24 12:32:21 -0700563 * Returns null if the touch doesn't fall into a resizing area.
Chong Zhang8e89b312015-09-09 15:09:30 -0700564 */
Wale Ogunwale15ead902016-09-02 14:30:11 -0700565 Task findTaskForResizePoint(int x, int y) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700566 final int delta = dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700567 mTmpTaskForResizePointSearchResult.reset();
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700568 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
569 final TaskStack stack = mTaskStackContainers.get(stackNdx);
Wale Ogunwale3797c222015-10-27 14:21:58 -0700570 if (!StackId.isTaskResizeAllowed(stack.mStackId)) {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700571 return null;
Chong Zhang8e89b312015-09-09 15:09:30 -0700572 }
Chong Zhang9184ec62015-09-24 12:32:21 -0700573
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700574 stack.findTaskForResizePoint(x, y, delta, mTmpTaskForResizePointSearchResult);
575 if (mTmpTaskForResizePointSearchResult.searchDone) {
576 return mTmpTaskForResizePointSearchResult.taskForResize;
Chong Zhang8e89b312015-09-09 15:09:30 -0700577 }
578 }
Chong Zhang9184ec62015-09-24 12:32:21 -0700579 return null;
Chong Zhang8e89b312015-09-09 15:09:30 -0700580 }
581
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700582 void setTouchExcludeRegion(Task focusedTask) {
Craig Mautner6601b7b2013-04-29 10:29:11 -0700583 mTouchExcludeRegion.set(mBaseDisplayRect);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700584 final int delta = dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700585 mTmpRect2.setEmpty();
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700586 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
587 final TaskStack stack = mTaskStackContainers.get(stackNdx);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700588 stack.setTouchExcludeRegion(
589 focusedTask, delta, mTouchExcludeRegion, mContentRect, mTmpRect2);
Craig Mautner6601b7b2013-04-29 10:29:11 -0700590 }
Chong Zhangd8ceb852015-11-11 14:53:41 -0800591 // If we removed the focused task above, add it back and only leave its
592 // outside touch area in the exclusion. TapDectector is not interested in
593 // any touch inside the focused task itself.
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700594 if (!mTmpRect2.isEmpty()) {
Chong Zhangd8ceb852015-11-11 14:53:41 -0800595 mTouchExcludeRegion.op(mTmpRect2, Region.Op.UNION);
596 }
Filip Gruszczynski912d9192015-12-01 16:14:04 -0800597 final WindowState inputMethod = mService.mInputMethodWindow;
598 if (inputMethod != null && inputMethod.isVisibleLw()) {
599 // If the input method is visible and the user is typing, we don't want these touch
600 // events to be intercepted and used to change focus. This would likely cause a
601 // disappearance of the input method.
602 inputMethod.getTouchableRegion(mTmpRegion);
603 mTouchExcludeRegion.op(mTmpRegion, Region.Op.UNION);
604 }
Filip Gruszczynskiecf67222015-12-11 15:16:36 -0800605 for (int i = mTapExcludedWindows.size() - 1; i >= 0; i--) {
606 WindowState win = mTapExcludedWindows.get(i);
607 win.getTouchableRegion(mTmpRegion);
608 mTouchExcludeRegion.op(mTmpRegion, Region.Op.UNION);
609 }
Jorim Jaggid47e7e12016-03-01 09:57:38 +0100610 if (getDockedStackVisibleForUserLocked() != null) {
611 mDividerControllerLocked.getTouchRegion(mTmpRect);
Jorim Jaggi7f19cb82016-03-25 19:37:44 -0700612 mTmpRegion.set(mTmpRect);
Jorim Jaggid47e7e12016-03-01 09:57:38 +0100613 mTouchExcludeRegion.op(mTmpRegion, Op.UNION);
614 }
Craig Mautner1bef3892015-02-17 15:09:47 -0800615 if (mTapDetector != null) {
Chong Zhang2e2c81a2016-07-15 11:28:17 -0700616 mTapDetector.setTouchExcludeRegion(mTouchExcludeRegion);
Craig Mautner1bef3892015-02-17 15:09:47 -0800617 }
Craig Mautner6601b7b2013-04-29 10:29:11 -0700618 }
619
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700620 void switchUser() {
Craig Mautner858d8a62013-04-23 17:08:34 -0700621 final WindowList windows = getWindowList();
622 for (int i = 0; i < windows.size(); i++) {
623 final WindowState win = windows.get(i);
624 if (win.isHiddenFromUserLocked()) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800625 if (DEBUG_VISIBILITY) Slog.w(TAG_WM, "user changing, hiding " + win
Wale Ogunwale498e8c92015-02-13 09:42:46 -0800626 + ", attrs=" + win.mAttrs.type + ", belonging to " + win.mOwnerUid);
Craig Mautner858d8a62013-04-23 17:08:34 -0700627 win.hideLw(false);
628 }
629 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700630
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700631 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
632 mTaskStackContainers.get(stackNdx).switchUser();
Craig Mautner858d8a62013-04-23 17:08:34 -0700633 }
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700634
635 rebuildAppWindowList();
Craig Mautner858d8a62013-04-23 17:08:34 -0700636 }
637
Craig Mautner05d29032013-05-03 13:40:13 -0700638 void resetAnimationBackgroundAnimator() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700639 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
640 mTaskStackContainers.get(stackNdx).resetAnimationBackgroundAnimator();
Craig Mautner05d29032013-05-03 13:40:13 -0700641 }
642 }
643
644 boolean animateDimLayers() {
Chong Zhang112eb8c2015-11-02 11:17:00 -0800645 return mDimLayerController.animateDimLayers();
Craig Mautner05d29032013-05-03 13:40:13 -0700646 }
647
648 void resetDimming() {
Chong Zhang112eb8c2015-11-02 11:17:00 -0800649 mDimLayerController.resetDimming();
Craig Mautner05d29032013-05-03 13:40:13 -0700650 }
651
652 boolean isDimming() {
Chong Zhang112eb8c2015-11-02 11:17:00 -0800653 return mDimLayerController.isDimming();
Craig Mautner05d29032013-05-03 13:40:13 -0700654 }
655
656 void stopDimmingIfNeeded() {
Chong Zhang112eb8c2015-11-02 11:17:00 -0800657 mDimLayerController.stopDimmingIfNeeded();
Craig Mautner05d29032013-05-03 13:40:13 -0700658 }
659
Wale Ogunwale10124582016-09-15 20:25:50 -0700660 @Override
661 void removeIfPossible() {
662 if (isAnimating()) {
663 mDeferredRemoval = true;
664 return;
Craig Mautner2eb15342013-08-07 13:13:35 -0700665 }
Wale Ogunwale10124582016-09-15 20:25:50 -0700666 removeImmediately();
Craig Mautner2eb15342013-08-07 13:13:35 -0700667 }
668
Wale Ogunwale10124582016-09-15 20:25:50 -0700669 @Override
670 void removeImmediately() {
Wale Ogunwale601a3f02016-10-17 08:39:39 -0700671 mRemovingDisplay = true;
672 try {
673 super.removeImmediately();
674 if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Removing display=" + this);
675 mDimLayerController.close();
676 if (mDisplayId == DEFAULT_DISPLAY) {
677 mService.unregisterPointerEventListener(mTapDetector);
678 mService.unregisterPointerEventListener(mService.mMousePositionTracker);
679 }
680 } finally {
681 mRemovingDisplay = false;
Craig Mautner95da1082014-02-24 17:54:35 -0800682 }
Craig Mautner95da1082014-02-24 17:54:35 -0800683 }
684
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700685 /** Returns true if a removal action is still being deferred. */
Wale Ogunwale10124582016-09-15 20:25:50 -0700686 @Override
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700687 boolean checkCompleteDeferredRemoval() {
Wale Ogunwale10124582016-09-15 20:25:50 -0700688 final boolean stillDeferringRemoval = super.checkCompleteDeferredRemoval();
689
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700690 if (!stillDeferringRemoval && mDeferredRemoval) {
Wale Ogunwale10124582016-09-15 20:25:50 -0700691 removeImmediately();
Craig Mautner95da1082014-02-24 17:54:35 -0800692 mService.onDisplayRemoved(mDisplayId);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700693 return false;
Craig Mautner95da1082014-02-24 17:54:35 -0800694 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700695 return true;
Craig Mautner95da1082014-02-24 17:54:35 -0800696 }
697
Wale Ogunwale10124582016-09-15 20:25:50 -0700698 boolean animateForIme(float interpolatedValue, float animationTarget,
699 float dividerAnimationTarget) {
700 boolean updated = false;
701
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700702 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
703 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale10124582016-09-15 20:25:50 -0700704 if (stack == null || !stack.isAdjustedForIme()) {
705 continue;
706 }
707
708 if (interpolatedValue >= 1f && animationTarget == 0f && dividerAnimationTarget == 0f) {
709 stack.resetAdjustedForIme(true /* adjustBoundsNow */);
710 updated = true;
711 } else {
712 mDividerControllerLocked.mLastAnimationProgress =
713 mDividerControllerLocked.getInterpolatedAnimationValue(interpolatedValue);
714 mDividerControllerLocked.mLastDividerProgress =
715 mDividerControllerLocked.getInterpolatedDividerValue(interpolatedValue);
716 updated |= stack.updateAdjustForIme(
717 mDividerControllerLocked.mLastAnimationProgress,
718 mDividerControllerLocked.mLastDividerProgress,
719 false /* force */);
720 }
721 if (interpolatedValue >= 1f) {
722 stack.endImeAdjustAnimation();
723 }
724 }
725
726 return updated;
727 }
728
729 boolean clearImeAdjustAnimation() {
730 boolean changed = false;
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700731 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
732 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale10124582016-09-15 20:25:50 -0700733 if (stack != null && stack.isAdjustedForIme()) {
734 stack.resetAdjustedForIme(true /* adjustBoundsNow */);
735 changed = true;
736 }
737 }
738 return changed;
739 }
740
741 void beginImeAdjustAnimation() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700742 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
743 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale10124582016-09-15 20:25:50 -0700744 if (stack.isVisible() && stack.isAdjustedForIme()) {
745 stack.beginImeAdjustAnimation();
746 }
747 }
748 }
749
750 void adjustForImeIfNeeded() {
751 final WindowState imeWin = mService.mInputMethodWindow;
752 final boolean imeVisible = imeWin != null && imeWin.isVisibleLw() && imeWin.isDisplayedLw()
753 && !mDividerControllerLocked.isImeHideRequested();
754 final boolean dockVisible = mService.isStackVisibleLocked(DOCKED_STACK_ID);
755 final TaskStack imeTargetStack = mService.getImeFocusStackLocked();
756 final int imeDockSide = (dockVisible && imeTargetStack != null) ?
757 imeTargetStack.getDockSide() : DOCKED_INVALID;
758 final boolean imeOnTop = (imeDockSide == DOCKED_TOP);
759 final boolean imeOnBottom = (imeDockSide == DOCKED_BOTTOM);
760 final boolean dockMinimized = mDividerControllerLocked.isMinimizedDock();
761 final int imeHeight = mService.mPolicy.getInputMethodWindowVisibleHeightLw();
762 final boolean imeHeightChanged = imeVisible &&
763 imeHeight != mDividerControllerLocked.getImeHeightAdjustedFor();
764
765 // The divider could be adjusted for IME position, or be thinner than usual,
766 // or both. There are three possible cases:
767 // - If IME is visible, and focus is on top, divider is not moved for IME but thinner.
768 // - If IME is visible, and focus is on bottom, divider is moved for IME and thinner.
769 // - If IME is not visible, divider is not moved and is normal width.
770
771 if (imeVisible && dockVisible && (imeOnTop || imeOnBottom) && !dockMinimized) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700772 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
773 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale10124582016-09-15 20:25:50 -0700774 final boolean isDockedOnBottom = stack.getDockSide() == DOCKED_BOTTOM;
775 if (stack.isVisible() && (imeOnBottom || isDockedOnBottom)) {
776 stack.setAdjustedForIme(imeWin, imeOnBottom && imeHeightChanged);
777 } else {
778 stack.resetAdjustedForIme(false);
779 }
780 }
781 mDividerControllerLocked.setAdjustedForIme(
782 imeOnBottom /*ime*/, true /*divider*/, true /*animate*/, imeWin, imeHeight);
783 } else {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700784 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
785 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale10124582016-09-15 20:25:50 -0700786 stack.resetAdjustedForIme(!dockVisible);
787 }
788 mDividerControllerLocked.setAdjustedForIme(
789 false /*ime*/, false /*divider*/, dockVisible /*animate*/, imeWin, imeHeight);
790 }
791 }
792
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700793 void setInputMethodAnimLayerAdjustment(int adj) {
794 if (DEBUG_LAYERS) Slog.v(TAG_WM, "Setting im layer adj to " + adj);
795 mInputMethodAnimLayerAdjustment = adj;
796 final WindowState imw = mService.mInputMethodWindow;
797 if (imw != null) {
798 imw.adjustAnimLayer(adj);
799 }
800 for (int i = mService.mInputMethodDialogs.size() - 1; i >= 0; i--) {
801 final WindowState dialog = mService.mInputMethodDialogs.get(i);
802 // TODO: This and other places setting mAnimLayer can probably use WS.adjustAnimLayer,
803 // but need to make sure we are not setting things twice for child windows that are
804 // already in the list.
805 dialog.mWinAnimator.mAnimLayer = dialog.mLayer + adj;
806 if (DEBUG_LAYERS) Slog.v(TAG_WM, "IM win " + imw
807 + " anim layer: " + dialog.mWinAnimator.mAnimLayer);
808 }
809 }
810
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -0700811 /**
812 * If a window that has an animation specifying a colored background and the current wallpaper
813 * is visible, then the color goes *below* the wallpaper so we don't cause the wallpaper to
814 * suddenly disappear.
815 */
816 int getLayerForAnimationBackground(WindowStateAnimator winAnimator) {
817 for (int i = mWindows.size() - 1; i >= 0; --i) {
818 final WindowState win = mWindows.get(i);
819 if (win.mIsWallpaper && win.isVisibleNow()) {
820 return win.mWinAnimator.mAnimLayer;
821 }
822 }
823 return winAnimator.mAnimLayer;
824 }
825
Wale Ogunwale10124582016-09-15 20:25:50 -0700826 void prepareFreezingTaskBounds() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700827 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
828 final TaskStack stack = mTaskStackContainers.get(stackNdx);
Wale Ogunwale10124582016-09-15 20:25:50 -0700829 stack.prepareFreezingTaskBounds();
830 }
831 }
832
Wale Ogunwale94744212015-09-21 19:01:47 -0700833 void rotateBounds(int oldRotation, int newRotation, Rect bounds) {
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700834 getLogicalDisplayRect(mTmpRect, newRotation);
835
836 // Compute a transform matrix to undo the coordinate space transformation,
837 // and present the window at the same physical position it previously occupied.
838 final int deltaRotation = deltaRotation(newRotation, oldRotation);
839 createRotationMatrix(deltaRotation, mTmpRect.width(), mTmpRect.height(), mTmpMatrix);
840
841 mTmpRectF.set(bounds);
842 mTmpMatrix.mapRect(mTmpRectF);
843 mTmpRectF.round(bounds);
Wale Ogunwale94744212015-09-21 19:01:47 -0700844 }
845
Wale Ogunwale4a02d812015-02-12 23:01:38 -0800846 static int deltaRotation(int oldRotation, int newRotation) {
847 int delta = newRotation - oldRotation;
848 if (delta < 0) delta += 4;
849 return delta;
850 }
851
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700852 private static void createRotationMatrix(int rotation, float displayWidth, float displayHeight,
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700853 Matrix outMatrix) {
854 // For rotations without Z-ordering we don't need the target rectangle's position.
855 createRotationMatrix(rotation, 0 /* rectLeft */, 0 /* rectTop */, displayWidth,
856 displayHeight, outMatrix);
857 }
858
859 static void createRotationMatrix(int rotation, float rectLeft, float rectTop,
860 float displayWidth, float displayHeight, Matrix outMatrix) {
861 switch (rotation) {
862 case ROTATION_0:
863 outMatrix.reset();
864 break;
865 case ROTATION_270:
866 outMatrix.setRotate(270, 0, 0);
867 outMatrix.postTranslate(0, displayHeight);
868 outMatrix.postTranslate(rectTop, 0);
869 break;
870 case ROTATION_180:
871 outMatrix.reset();
872 break;
873 case ROTATION_90:
874 outMatrix.setRotate(90, 0, 0);
875 outMatrix.postTranslate(displayWidth, 0);
876 outMatrix.postTranslate(-rectTop, rectLeft);
877 break;
878 }
879 }
880
Craig Mautnera91f9e22012-09-14 16:22:08 -0700881 public void dump(String prefix, PrintWriter pw) {
882 pw.print(prefix); pw.print("Display: mDisplayId="); pw.println(mDisplayId);
883 final String subPrefix = " " + prefix;
884 pw.print(subPrefix); pw.print("init="); pw.print(mInitialDisplayWidth); pw.print("x");
885 pw.print(mInitialDisplayHeight); pw.print(" "); pw.print(mInitialDisplayDensity);
886 pw.print("dpi");
887 if (mInitialDisplayWidth != mBaseDisplayWidth
888 || mInitialDisplayHeight != mBaseDisplayHeight
889 || mInitialDisplayDensity != mBaseDisplayDensity) {
890 pw.print(" base=");
891 pw.print(mBaseDisplayWidth); pw.print("x"); pw.print(mBaseDisplayHeight);
892 pw.print(" "); pw.print(mBaseDisplayDensity); pw.print("dpi");
893 }
Jeff Brownd46747a2015-04-15 19:02:36 -0700894 if (mDisplayScalingDisabled) {
895 pw.println(" noscale");
896 }
Craig Mautnera91f9e22012-09-14 16:22:08 -0700897 pw.print(" cur=");
898 pw.print(mDisplayInfo.logicalWidth);
899 pw.print("x"); pw.print(mDisplayInfo.logicalHeight);
900 pw.print(" app=");
901 pw.print(mDisplayInfo.appWidth);
902 pw.print("x"); pw.print(mDisplayInfo.appHeight);
903 pw.print(" rng="); pw.print(mDisplayInfo.smallestNominalAppWidth);
904 pw.print("x"); pw.print(mDisplayInfo.smallestNominalAppHeight);
905 pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth);
906 pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight);
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700907 pw.println(subPrefix + "deferred=" + mDeferredRemoval
908 + " mLayoutNeeded=" + mLayoutNeeded);
Wale Ogunwaleb429e682016-01-06 12:36:34 -0800909
Craig Mautnerdc548482014-02-05 13:35:24 -0800910 pw.println();
Craig Mautnere8b85fd2014-10-22 09:23:25 -0700911 pw.println(" Application tokens in top down Z order:");
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700912 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
913 final TaskStack stack = mTaskStackContainers.get(stackNdx);
Wale Ogunwaleb429e682016-01-06 12:36:34 -0800914 stack.dump(prefix + " ", pw);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700915 }
Wale Ogunwaleb429e682016-01-06 12:36:34 -0800916
Craig Mautnerdc548482014-02-05 13:35:24 -0800917 pw.println();
918 if (!mExitingTokens.isEmpty()) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700919 pw.println();
920 pw.println(" Exiting tokens:");
Wale Ogunwaleb429e682016-01-06 12:36:34 -0800921 for (int i = mExitingTokens.size() - 1; i >= 0; i--) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700922 final WindowToken token = mExitingTokens.get(i);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700923 pw.print(" Exiting #"); pw.print(i);
924 pw.print(' '); pw.print(token);
925 pw.println(':');
926 token.dump(pw, " ");
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800927 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700928 }
Craig Mautner59c00972012-07-30 12:10:24 -0700929 pw.println();
Chong Zhang112eb8c2015-11-02 11:17:00 -0800930 mDimLayerController.dump(prefix + " ", pw);
Jorim Jaggi31f71702016-05-04 16:43:04 -0700931 pw.println();
932 mDividerControllerLocked.dump(prefix + " ", pw);
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700933
934 if (mInputMethodAnimLayerAdjustment != 0) {
935 pw.println(subPrefix
936 + "mInputMethodAnimLayerAdjustment=" + mInputMethodAnimLayerAdjustment);
937 }
Craig Mautner59c00972012-07-30 12:10:24 -0700938 }
Craig Mautnere0a38842013-12-16 16:14:02 -0800939
940 @Override
941 public String toString() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700942 return "Display " + mDisplayId + " info=" + mDisplayInfo + " stacks=" + mChildren;
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700943 }
944
945 String getName() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700946 return "Display " + mDisplayId + " name=\"" + mDisplayInfo.name + "\"";
Craig Mautnere0a38842013-12-16 16:14:02 -0800947 }
Filip Gruszczynski466f3212015-09-21 17:57:57 -0700948
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800949 /**
950 * @return The docked stack, but only if it is visible, and {@code null} otherwise.
951 */
Filip Gruszczynski3ddc5d62015-09-23 15:01:30 -0700952 TaskStack getDockedStackLocked() {
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700953 final TaskStack stack = mService.mStackIdToStack.get(DOCKED_STACK_ID);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700954 return (stack != null && stack.isVisible()) ? stack : null;
Filip Gruszczynski466f3212015-09-21 17:57:57 -0700955 }
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -0800956
957 /**
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800958 * Like {@link #getDockedStackLocked}, but also returns the docked stack if it's currently not
959 * visible, as long as it's not hidden because the current user doesn't have any tasks there.
960 */
961 TaskStack getDockedStackVisibleForUserLocked() {
962 final TaskStack stack = mService.mStackIdToStack.get(DOCKED_STACK_ID);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700963 return (stack != null && stack.isVisible(true /* ignoreKeyguard */)) ? stack : null;
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800964 }
965
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700966 /** Find the visible, touch-deliverable window under the given point */
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -0800967 WindowState getTouchableWinAtPointLocked(float xf, float yf) {
968 WindowState touchedWin = null;
969 final int x = (int) xf;
970 final int y = (int) yf;
971
972 for (int i = mWindows.size() - 1; i >= 0; i--) {
973 WindowState window = mWindows.get(i);
974 final int flags = window.mAttrs.flags;
975 if (!window.isVisibleLw()) {
976 continue;
977 }
978 if ((flags & FLAG_NOT_TOUCHABLE) != 0) {
979 continue;
980 }
981
982 window.getVisibleBounds(mTmpRect);
983 if (!mTmpRect.contains(x, y)) {
984 continue;
985 }
986
987 window.getTouchableRegion(mTmpRegion);
988
989 final int touchFlags = flags & (FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL);
990 if (mTmpRegion.contains(x, y) || touchFlags == 0) {
991 touchedWin = window;
992 break;
993 }
994 }
995
996 return touchedWin;
997 }
Jorim Jaggi6626f542016-08-22 13:08:44 -0700998
Svetoslav Ganovaa076532016-08-01 19:16:43 -0700999 boolean canAddToastWindowForUid(int uid) {
1000 // We allow one toast window per UID being shown at a time.
1001 WindowList windows = getWindowList();
1002 final int windowCount = windows.size();
1003 for (int i = 0; i < windowCount; i++) {
1004 WindowState window = windows.get(i);
1005 if (window.mAttrs.type == TYPE_TOAST && window.mOwnerUid == uid
Svet Ganov62a40f82016-09-29 00:43:51 -07001006 && !window.mPermanentlyHidden && !window.mAnimatingExit
1007 && !window.mRemoveOnExit) {
Svetoslav Ganovaa076532016-08-01 19:16:43 -07001008 return false;
1009 }
1010 }
1011 return true;
1012 }
1013
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001014 void scheduleToastWindowsTimeoutIfNeededLocked(WindowState oldFocus, WindowState newFocus) {
Svetoslav Ganovaa076532016-08-01 19:16:43 -07001015 if (oldFocus == null || (newFocus != null && newFocus.mOwnerUid == oldFocus.mOwnerUid)) {
1016 return;
1017 }
1018 final int lostFocusUid = oldFocus.mOwnerUid;
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001019 final WindowList windows = getWindowList();
Svetoslav Ganovaa076532016-08-01 19:16:43 -07001020 final int windowCount = windows.size();
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001021 final Handler handler = mService.mH;
Svetoslav Ganovaa076532016-08-01 19:16:43 -07001022 for (int i = 0; i < windowCount; i++) {
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001023 final WindowState window = windows.get(i);
Svetoslav Ganovaa076532016-08-01 19:16:43 -07001024 if (window.mAttrs.type == TYPE_TOAST && window.mOwnerUid == lostFocusUid) {
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001025 if (!handler.hasMessages(WINDOW_HIDE_TIMEOUT, window)) {
1026 handler.sendMessageDelayed(handler.obtainMessage(WINDOW_HIDE_TIMEOUT, window),
Svetoslav Ganovaa076532016-08-01 19:16:43 -07001027 window.mAttrs.hideTimeoutMilliseconds);
1028 }
1029 }
1030 }
1031 }
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -07001032
1033 WindowState findFocusedWindow() {
1034 final AppWindowToken focusedApp = mService.mFocusedApp;
1035
1036 for (int i = mWindows.size() - 1; i >= 0; i--) {
1037 final WindowState win = mWindows.get(i);
1038
1039 if (DEBUG_FOCUS) Slog.v(TAG_WM, "Looking for focus: " + i + " = " + win
1040 + ", flags=" + win.mAttrs.flags + ", canReceive=" + win.canReceiveKeys());
1041
1042 if (!win.canReceiveKeys()) {
1043 continue;
1044 }
1045
1046 final AppWindowToken wtoken = win.mAppToken;
1047
1048 // If this window's application has been removed, just skip it.
1049 if (wtoken != null && (wtoken.removed || wtoken.sendingToBottom)) {
1050 if (DEBUG_FOCUS) Slog.v(TAG_WM, "Skipping " + wtoken + " because "
1051 + (wtoken.removed ? "removed" : "sendingToBottom"));
1052 continue;
1053 }
1054
1055 if (focusedApp == null) {
1056 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp=null"
1057 + " using new focus @ " + i + " = " + win);
1058 return win;
1059 }
1060
1061 if (!focusedApp.windowsAreFocusable()) {
1062 // Current focused app windows aren't focusable...
1063 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp windows not"
1064 + " focusable using new focus @ " + i + " = " + win);
1065 return win;
1066 }
1067
1068 // Descend through all of the app tokens and find the first that either matches
1069 // win.mAppToken (return win) or mFocusedApp (return null).
1070 if (wtoken != null && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
Wale Ogunwale10124582016-09-15 20:25:50 -07001071 if (focusedApp.compareTo(wtoken) > 0) {
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -07001072 // App stack below focused app stack. No focus for you!!!
1073 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM,
1074 "findFocusedWindow: Reached focused app=" + focusedApp);
1075 return null;
1076 }
1077 }
1078
1079 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: Found new focus @ "
1080 + i + " = " + win);
1081 return win;
1082 }
1083
1084 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: No focusable windows.");
1085 return null;
1086 }
Wale Ogunwaleec731152016-09-08 20:18:57 -07001087
1088 int addAppWindowToWindowList(final WindowState win) {
1089 final IWindow client = win.mClient;
1090
1091 WindowList tokenWindowList = getTokenWindowsOnDisplay(win.mToken);
1092 if (!tokenWindowList.isEmpty()) {
1093 return addAppWindowExisting(win, tokenWindowList);
1094 }
1095
1096 // No windows from this token on this display
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001097 if (localLOGV) Slog.v(TAG_WM, "Figuring out where to add app window "
Wale Ogunwaleec731152016-09-08 20:18:57 -07001098 + client.asBinder() + " (token=" + this + ")");
1099
1100 final WindowToken wToken = win.mToken;
1101
1102 // Figure out where the window should go, based on the order of applications.
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001103 mTmpGetWindowOnDisplaySearchResult.reset();
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001104 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
1105 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001106 stack.getWindowOnDisplayBeforeToken(this, wToken, mTmpGetWindowOnDisplaySearchResult);
1107 if (mTmpGetWindowOnDisplaySearchResult.reachedToken) {
Wale Ogunwaleec731152016-09-08 20:18:57 -07001108 // We have reach the token we are interested in. End search.
1109 break;
1110 }
1111 }
1112
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001113 WindowState pos = mTmpGetWindowOnDisplaySearchResult.foundWindow;
Wale Ogunwaleec731152016-09-08 20:18:57 -07001114
1115 // We now know the index into the apps. If we found an app window above, that gives us the
1116 // position; else we need to look some more.
1117 if (pos != null) {
1118 // Move behind any windows attached to this one.
Wale Ogunwale02319a62016-09-26 15:21:22 -07001119 final WindowToken atoken = getWindowToken(pos.mClient.asBinder());
Wale Ogunwaleec731152016-09-08 20:18:57 -07001120 if (atoken != null) {
1121 tokenWindowList = getTokenWindowsOnDisplay(atoken);
1122 final int NC = tokenWindowList.size();
1123 if (NC > 0) {
1124 WindowState bottom = tokenWindowList.get(0);
1125 if (bottom.mSubLayer < 0) {
1126 pos = bottom;
1127 }
1128 }
1129 }
1130 addWindowToListBefore(win, pos);
1131 return 0;
1132 }
1133
1134 // Continue looking down until we find the first token that has windows on this display.
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001135 mTmpGetWindowOnDisplaySearchResult.reset();
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001136 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
1137 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001138 stack.getWindowOnDisplayAfterToken(this, wToken, mTmpGetWindowOnDisplaySearchResult);
1139 if (mTmpGetWindowOnDisplaySearchResult.foundWindow != null) {
Wale Ogunwaleec731152016-09-08 20:18:57 -07001140 // We have found a window after the token. End search.
1141 break;
1142 }
1143 }
1144
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001145 pos = mTmpGetWindowOnDisplaySearchResult.foundWindow;
Wale Ogunwaleec731152016-09-08 20:18:57 -07001146
1147 if (pos != null) {
1148 // Move in front of any windows attached to this one.
Wale Ogunwale02319a62016-09-26 15:21:22 -07001149 final WindowToken atoken = getWindowToken(pos.mClient.asBinder());
Wale Ogunwaleec731152016-09-08 20:18:57 -07001150 if (atoken != null) {
1151 final WindowState top = atoken.getTopWindow();
1152 if (top != null && top.mSubLayer >= 0) {
1153 pos = top;
1154 }
1155 }
1156 addWindowToListAfter(win, pos);
1157 return 0;
1158 }
1159
1160 // Just search for the start of this layer.
1161 final int myLayer = win.mBaseLayer;
1162 int i;
1163 for (i = mWindows.size() - 1; i >= 0; --i) {
1164 final WindowState w = mWindows.get(i);
1165 // Dock divider shares the base layer with application windows, but we want to always
1166 // keep it above the application windows. The sharing of the base layer is intended
1167 // for window animations, which need to be above the dock divider for the duration
1168 // of the animation.
1169 if (w.mBaseLayer <= myLayer && w.mAttrs.type != TYPE_DOCK_DIVIDER) {
1170 break;
1171 }
1172 }
1173 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1174 "Based on layer: Adding window " + win + " at " + (i + 1) + " of "
1175 + mWindows.size());
1176 mWindows.add(i + 1, win);
1177 mService.mWindowsChanged = true;
1178 return 0;
1179 }
1180
1181 /** Adds this non-app window to the window list. */
1182 void addNonAppWindowToWindowList(WindowState win) {
1183 // Figure out where window should go, based on layer.
1184 int i;
1185 for (i = mWindows.size() - 1; i >= 0; i--) {
1186 final WindowState otherWin = mWindows.get(i);
1187 if (otherWin.getBaseType() != TYPE_WALLPAPER && otherWin.mBaseLayer <= win.mBaseLayer) {
1188 // Wallpaper wanders through the window list, for example to position itself
1189 // directly behind keyguard. Because of this it will break the ordering based on
1190 // WindowState.mBaseLayer. There might windows with higher mBaseLayer behind it and
1191 // we don't want the new window to appear above them. An example of this is adding
1192 // of the docked stack divider. Consider a scenario with the following ordering (top
1193 // to bottom): keyguard, wallpaper, assist preview, apps. We want the dock divider
1194 // to land below the assist preview, so the dock divider must ignore the wallpaper,
1195 // with which it shares the base layer.
1196 break;
1197 }
1198 }
1199
1200 i++;
1201 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1202 "Free window: Adding window " + this + " at " + i + " of " + mWindows.size());
1203 mWindows.add(i, win);
1204 mService.mWindowsChanged = true;
1205 }
1206
Wale Ogunwaleb9a07c32016-10-12 14:55:56 -07001207 void addToWindowList(WindowState win, int index) {
1208 mWindows.add(index, win);
1209 }
1210
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07001211 boolean removeFromWindowList(WindowState win) {
1212 return mWindows.remove(win);
1213 }
1214
1215 private int removeWindowAndChildrenFromWindowList(WindowState win, int interestingPos) {
1216 final WindowList windows = getWindowList();
1217 int wpos = windows.indexOf(win);
1218 if (wpos < 0) {
1219 return interestingPos;
1220 }
1221
1222 if (wpos < interestingPos) interestingPos--;
1223 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Temp removing at " + wpos + ": " + this);
1224 windows.remove(wpos);
1225 mService.mWindowsChanged = true;
1226 int childWinCount = win.mChildren.size();
1227 while (childWinCount > 0) {
1228 childWinCount--;
1229 final WindowState cw = win.mChildren.get(childWinCount);
1230 int cpos = windows.indexOf(cw);
1231 if (cpos >= 0) {
1232 if (cpos < interestingPos) interestingPos--;
1233 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM,
1234 "Temp removing child at " + cpos + ": " + cw);
1235 windows.remove(cpos);
1236 }
1237 }
1238 return interestingPos;
1239 }
1240
Wale Ogunwaleec731152016-09-08 20:18:57 -07001241 void addChildWindowToWindowList(WindowState win) {
1242 final WindowState parentWindow = win.getParentWindow();
1243
1244 WindowList windowsOnSameDisplay = getTokenWindowsOnDisplay(win.mToken);
1245
1246 // Figure out this window's ordering relative to the parent window.
1247 final int wCount = windowsOnSameDisplay.size();
1248 final int sublayer = win.mSubLayer;
1249 int largestSublayer = Integer.MIN_VALUE;
1250 WindowState windowWithLargestSublayer = null;
1251 int i;
1252 for (i = 0; i < wCount; i++) {
1253 WindowState w = windowsOnSameDisplay.get(i);
1254 final int wSublayer = w.mSubLayer;
1255 if (wSublayer >= largestSublayer) {
1256 largestSublayer = wSublayer;
1257 windowWithLargestSublayer = w;
1258 }
1259 if (sublayer < 0) {
1260 // For negative sublayers, we go below all windows in the same sublayer.
1261 if (wSublayer >= sublayer) {
1262 addWindowToListBefore(win, wSublayer >= 0 ? parentWindow : w);
1263 break;
1264 }
1265 } else {
1266 // For positive sublayers, we go above all windows in the same sublayer.
1267 if (wSublayer > sublayer) {
1268 addWindowToListBefore(win, w);
1269 break;
1270 }
1271 }
1272 }
1273 if (i >= wCount) {
1274 if (sublayer < 0) {
1275 addWindowToListBefore(win, parentWindow);
1276 } else {
1277 addWindowToListAfter(win,
1278 largestSublayer >= 0 ? windowWithLargestSublayer : parentWindow);
1279 }
1280 }
1281 }
1282
Wale Ogunwalec69694a2016-10-18 13:51:15 -07001283 /** Updates the layer assignment of windows on this display. */
1284 void assignWindowLayers(boolean setLayoutNeeded) {
1285 mLayersController.assignWindowLayers(mWindows);
1286 if (setLayoutNeeded) {
1287 setLayoutNeeded();
1288 }
1289 }
1290
Wale Ogunwale0303c572016-10-20 10:16:29 -07001291 void adjustWallpaperWindows() {
1292 if (mWallpaperController.adjustWallpaperWindows(mWindows)) {
1293 assignWindowLayers(true /*setLayoutNeeded*/);
1294 }
1295 }
1296
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001297 /**
1298 * Z-orders the display window list so that:
1299 * <ul>
1300 * <li>Any windows that are currently below the wallpaper window stay below the wallpaper
1301 * window.
1302 * <li>Exiting application windows are at the bottom, but above the wallpaper window.
1303 * <li>All other application windows are above the exiting application windows and ordered based
1304 * on the ordering of their stacks and tasks on the display.
1305 * <li>Non-application windows are at the very top.
1306 * </ul>
1307 * <p>
1308 * NOTE: This isn't a complete picture of what the user see. Further manipulation of the window
1309 * surface layering is done in {@link WindowLayersController}.
1310 */
1311 void rebuildAppWindowList() {
1312 int count = mWindows.size();
1313 int i;
1314 int lastBelow = -1;
1315 int numRemoved = 0;
1316
1317 if (mRebuildTmp.length < count) {
1318 mRebuildTmp = new WindowState[count + 10];
1319 }
1320
1321 // First remove all existing app windows.
1322 i = 0;
1323 while (i < count) {
1324 final WindowState w = mWindows.get(i);
1325 if (w.mAppToken != null) {
1326 final WindowState win = mWindows.remove(i);
1327 win.mRebuilding = true;
1328 mRebuildTmp[numRemoved] = win;
1329 mService.mWindowsChanged = true;
1330 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Rebuild removing window: " + win);
1331 count--;
1332 numRemoved++;
1333 continue;
1334 } else if (lastBelow == i-1) {
1335 if (w.mAttrs.type == TYPE_WALLPAPER) {
1336 lastBelow = i;
1337 }
1338 }
1339 i++;
1340 }
1341
1342 // Keep whatever windows were below the app windows still below, by skipping them.
1343 lastBelow++;
1344 i = lastBelow;
1345
1346 // First add all of the exiting app tokens... these are no longer in the main app list,
1347 // but still have windows shown. We put them in the back because now that the animation is
1348 // over we no longer will care about them.
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001349 final int numStacks = mTaskStackContainers.size();
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001350 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001351 AppTokenList exitingAppTokens = mTaskStackContainers.get(stackNdx).mExitingAppTokens;
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001352 int NT = exitingAppTokens.size();
1353 for (int j = 0; j < NT; j++) {
Wale Ogunwale360a8bc2016-10-10 13:25:26 -07001354 i = exitingAppTokens.get(j).rebuildWindowListUnchecked(i);
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001355 }
1356 }
1357
1358 // And add in the still active app tokens in Z order.
1359 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001360 i = mTaskStackContainers.get(stackNdx).rebuildWindowList(i);
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001361 }
1362
1363 i -= lastBelow;
1364 if (i != numRemoved) {
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001365 setLayoutNeeded();
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001366 Slog.w(TAG_WM, "On display=" + mDisplayId + " Rebuild removed " + numRemoved
1367 + " windows but added " + i + " rebuildAppWindowListLocked() "
1368 + " callers=" + Debug.getCallers(10));
1369 for (i = 0; i < numRemoved; i++) {
1370 WindowState ws = mRebuildTmp[i];
1371 if (ws.mRebuilding) {
1372 StringWriter sw = new StringWriter();
1373 PrintWriter pw = new FastPrintWriter(sw, false, 1024);
1374 ws.dump(pw, "", true);
1375 pw.flush();
1376 Slog.w(TAG_WM, "This window was lost: " + ws);
1377 Slog.w(TAG_WM, sw.toString());
1378 ws.mWinAnimator.destroySurfaceLocked();
1379 }
1380 }
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07001381 Slog.w(TAG_WM, "Current window hierarchy:");
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001382 dumpChildrenNames();
1383 Slog.w(TAG_WM, "Final window list:");
1384 dumpWindows();
1385 }
1386 Arrays.fill(mRebuildTmp, null);
1387 }
1388
Wale Ogunwaleec731152016-09-08 20:18:57 -07001389 /** Return the list of Windows on this display associated with the input token. */
1390 WindowList getTokenWindowsOnDisplay(WindowToken token) {
1391 final WindowList windowList = new WindowList();
1392 final int count = mWindows.size();
1393 for (int i = 0; i < count; i++) {
1394 final WindowState win = mWindows.get(i);
1395 if (win.mToken == token) {
1396 windowList.add(win);
1397 }
1398 }
1399 return windowList;
1400 }
1401
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07001402 private void reAddToWindowList(WindowState win) {
1403 win.mToken.addWindow(win);
1404 // This is a hack to get all of the child windows added as well at the right position. Child
1405 // windows should be rare and this case should be rare, so it shouldn't be that big a deal.
1406 int wpos = mWindows.indexOf(win);
1407 if (wpos >= 0) {
1408 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "ReAdd removing from " + wpos + ": " + win);
1409 mWindows.remove(wpos);
1410 mService.mWindowsChanged = true;
1411 win.reAddWindow(wpos);
1412 }
1413 }
1414
1415 void moveInputMethodDialogs(int pos) {
1416 ArrayList<WindowState> dialogs = mService.mInputMethodDialogs;
1417
1418 final int N = dialogs.size();
1419 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Removing " + N + " dialogs w/pos=" + pos);
1420 for (int i = 0; i < N; i++) {
1421 pos = removeWindowAndChildrenFromWindowList(dialogs.get(i), pos);
1422 }
1423 if (DEBUG_INPUT_METHOD) {
1424 Slog.v(TAG_WM, "Window list w/pos=" + pos);
1425 logWindowList(mWindows, " ");
1426 }
1427
1428 WindowState ime = mService.mInputMethodWindow;
1429 if (pos >= 0) {
1430 // Skip windows owned by the input method.
1431 if (ime != null) {
1432 while (pos < mWindows.size()) {
1433 WindowState wp = mWindows.get(pos);
1434 if (wp == ime || wp.getParentWindow() == ime) {
1435 pos++;
1436 continue;
1437 }
1438 break;
1439 }
1440 }
1441 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Adding " + N + " dialogs at pos=" + pos);
1442 for (int i=0; i<N; i++) {
1443 WindowState win = dialogs.get(i);
1444 pos = win.reAddWindow(pos);
1445 }
1446 if (DEBUG_INPUT_METHOD) {
1447 Slog.v(TAG_WM, "Final window list:");
1448 logWindowList(mWindows, " ");
1449 }
1450 return;
1451 }
1452 for (int i=0; i<N; i++) {
1453 WindowState win = dialogs.get(i);
1454 reAddToWindowList(win);
1455 if (DEBUG_INPUT_METHOD) {
1456 Slog.v(TAG_WM, "No IM target, final list:");
1457 logWindowList(mWindows, " ");
1458 }
1459 }
1460 }
1461
1462 boolean moveInputMethodWindowsIfNeeded(boolean needAssignLayers) {
1463 final WindowState imWin = mService.mInputMethodWindow;
1464 final int DN = mService.mInputMethodDialogs.size();
1465 if (imWin == null && DN == 0) {
1466 return false;
1467 }
1468
1469 // TODO(multidisplay): IMEs are only supported on the default display.
1470 WindowList windows = mWindows;
1471
1472 int imPos = findDesiredInputMethodWindowIndex(true);
1473 if (imPos >= 0) {
1474 // In this case, the input method windows are to be placed
1475 // immediately above the window they are targeting.
1476
1477 // First check to see if the input method windows are already
1478 // located here, and contiguous.
1479 final int N = windows.size();
1480 final WindowState firstImWin = imPos < N ? windows.get(imPos) : null;
1481
1482 // Figure out the actual input method window that should be
1483 // at the bottom of their stack.
1484 WindowState baseImWin = imWin != null ? imWin : mService.mInputMethodDialogs.get(0);
1485 final WindowState cw = baseImWin.getBottomChild();
1486 if (cw != null && cw.mSubLayer < 0) {
1487 baseImWin = cw;
1488 }
1489
1490 if (firstImWin == baseImWin) {
1491 // The windows haven't moved... but are they still contiguous?
1492 // First find the top IM window.
1493 int pos = imPos+1;
1494 while (pos < N) {
1495 if (!(windows.get(pos)).mIsImWindow) {
1496 break;
1497 }
1498 pos++;
1499 }
1500 pos++;
1501 // Now there should be no more input method windows above.
1502 while (pos < N) {
1503 if ((windows.get(pos)).mIsImWindow) {
1504 break;
1505 }
1506 pos++;
1507 }
1508 if (pos >= N) {
1509 return false;
1510 }
1511 }
1512
1513 if (imWin != null) {
1514 if (DEBUG_INPUT_METHOD) {
1515 Slog.v(TAG_WM, "Moving IM from " + imPos);
1516 logWindowList(windows, " ");
1517 }
1518 imPos = removeWindowAndChildrenFromWindowList(imWin, imPos);
1519 if (DEBUG_INPUT_METHOD) {
1520 Slog.v(TAG_WM, "List after removing with new pos " + imPos + ":");
1521 logWindowList(windows, " ");
1522 }
1523 imWin.reAddWindow(imPos);
1524 if (DEBUG_INPUT_METHOD) {
1525 Slog.v(TAG_WM, "List after moving IM to " + imPos + ":");
1526 logWindowList(windows, " ");
1527 }
1528 if (DN > 0) moveInputMethodDialogs(imPos+1);
1529 } else {
1530 moveInputMethodDialogs(imPos);
1531 }
1532
1533 } else {
1534 // In this case, the input method windows go in a fixed layer,
1535 // because they aren't currently associated with a focus window.
1536
1537 if (imWin != null) {
1538 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Moving IM from " + imPos);
1539 removeWindowAndChildrenFromWindowList(imWin, 0);
1540 reAddToWindowList(imWin);
1541 if (DEBUG_INPUT_METHOD) {
1542 Slog.v(TAG_WM, "List with no IM target:");
1543 logWindowList(windows, " ");
1544 }
1545 if (DN > 0) moveInputMethodDialogs(-1);
1546 } else {
1547 moveInputMethodDialogs(-1);
1548 }
1549
1550 }
1551
1552 if (needAssignLayers) {
1553 assignWindowLayers(false /* setLayoutNeeded */);
1554 }
1555
1556 return true;
1557 }
1558
1559 /**
1560 * Dig through the WindowStates and find the one that the Input Method will target.
1561 * @param willMove
1562 * @return The index+1 in mWindows of the discovered target.
1563 */
1564 int findDesiredInputMethodWindowIndex(boolean willMove) {
1565 // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the
1566 // same display. Or even when the current IME/target are not on the same screen as the next
1567 // IME/target. For now only look for input windows on the main screen.
1568 final WindowList windows = getWindowList();
1569 WindowState w = null;
1570 int i;
1571 for (i = windows.size() - 1; i >= 0; --i) {
1572 WindowState win = windows.get(i);
1573
1574 if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG_WM, "Checking window @" + i
1575 + " " + win + " fl=0x" + Integer.toHexString(win.mAttrs.flags));
1576 if (canBeImeTarget(win)) {
1577 w = win;
1578 //Slog.i(TAG_WM, "Putting input method here!");
1579
1580 // Yet more tricksyness! If this window is a "starting" window, we do actually want
1581 // to be on top of it, but it is not -really- where input will go. So if the caller
1582 // is not actually looking to move the IME, look down below for a real window to
1583 // target...
1584 if (!willMove && w.mAttrs.type == TYPE_APPLICATION_STARTING && i > 0) {
1585 WindowState wb = windows.get(i-1);
1586 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
1587 i--;
1588 w = wb;
1589 }
1590 }
1591 break;
1592 }
1593 }
1594
1595 // Now w is either mWindows[0] or an IME (or null if mWindows is empty).
1596
1597 if (DEBUG_INPUT_METHOD && willMove) Slog.v(TAG_WM, "Proposed new IME target: " + w);
1598
1599 // Now, a special case -- if the last target's window is in the process of exiting, and is
1600 // above the new target, keep on the last target to avoid flicker. Consider for example a
1601 // Dialog with the IME shown: when the Dialog is dismissed, we want to keep the IME above it
1602 // until it is completely gone so it doesn't drop behind the dialog or its full-screen
1603 // scrim.
1604 final WindowState curTarget = mService.mInputMethodTarget;
1605 if (curTarget != null
1606 && curTarget.isDisplayedLw()
1607 && curTarget.isClosing()
1608 && (w == null || curTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer)) {
1609 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Current target higher, not changing");
1610 return windows.indexOf(curTarget) + 1;
1611 }
1612
1613 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Desired input method target="
1614 + w + " willMove=" + willMove);
1615
1616 if (willMove && w != null) {
1617 AppWindowToken token = curTarget == null ? null : curTarget.mAppToken;
1618 if (token != null) {
1619
1620 // Now some fun for dealing with window animations that modify the Z order. We need
1621 // to look at all windows below the current target that are in this app, finding the
1622 // highest visible one in layering.
1623 WindowState highestTarget = null;
1624 int highestPos = 0;
1625 if (token.mAppAnimator.animating || token.mAppAnimator.animation != null) {
1626 WindowList curWindows = token.getDisplayContent().getWindowList();
1627 int pos = curWindows.indexOf(curTarget);
1628 while (pos >= 0) {
1629 WindowState win = curWindows.get(pos);
1630 if (win.mAppToken != token) {
1631 break;
1632 }
1633 if (!win.mRemoved) {
1634 if (highestTarget == null || win.mWinAnimator.mAnimLayer >
1635 highestTarget.mWinAnimator.mAnimLayer) {
1636 highestTarget = win;
1637 highestPos = pos;
1638 }
1639 }
1640 pos--;
1641 }
1642 }
1643
1644 if (highestTarget != null) {
1645 final AppTransition appTransition = mService.mAppTransition;
1646 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, appTransition + " " + highestTarget
1647 + " animating=" + highestTarget.mWinAnimator.isAnimationSet()
1648 + " layer=" + highestTarget.mWinAnimator.mAnimLayer
1649 + " new layer=" + w.mWinAnimator.mAnimLayer);
1650
1651 if (appTransition.isTransitionSet()) {
1652 // If we are currently setting up for an animation, hold everything until we
1653 // can find out what will happen.
1654 mService.mInputMethodTargetWaitingAnim = true;
1655 mService.mInputMethodTarget = highestTarget;
1656 return highestPos + 1;
1657 } else if (highestTarget.mWinAnimator.isAnimationSet() &&
1658 highestTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
1659 // If the window we are currently targeting is involved with an animation,
1660 // and it is on top of the next target we will be over, then hold off on
1661 // moving until that is done.
1662 mService.mInputMethodTargetWaitingAnim = true;
1663 mService.mInputMethodTarget = highestTarget;
1664 return highestPos + 1;
1665 }
1666 }
1667 }
1668 }
1669
1670 //Slog.i(TAG_WM, "Placing input method @" + (i+1));
1671 if (w != null) {
1672 if (willMove) {
1673 if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to "
1674 + w + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : ""));
1675 mService.mInputMethodTarget = w;
1676 mService.mInputMethodTargetWaitingAnim = false;
1677 if (w.mAppToken != null) {
1678 setInputMethodAnimLayerAdjustment(
1679 w.mAppToken.mAppAnimator.animLayerAdjustment);
1680 } else {
1681 setInputMethodAnimLayerAdjustment(0);
1682 }
1683 }
1684
1685 // If the docked divider is visible, we still need to go through this whole excercise to
1686 // find the appropriate input method target (used for animations and dialog
1687 // adjustments), but for purposes of Z ordering we simply wish to place it above the
1688 // docked divider. Unless it is already above the divider.
1689 final WindowState dockedDivider = mDividerControllerLocked.getWindow();
1690 if (dockedDivider != null && dockedDivider.isVisibleLw()) {
1691 int dividerIndex = windows.indexOf(dockedDivider);
1692 if (dividerIndex > 0 && dividerIndex > i) {
1693 return dividerIndex + 1;
1694 }
1695 }
1696 return i+1;
1697 }
1698 if (willMove) {
1699 if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget
1700 + " to null." + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : ""));
1701 mService.mInputMethodTarget = null;
1702 setInputMethodAnimLayerAdjustment(0);
1703 }
1704 return -1;
1705 }
1706
1707 private static boolean canBeImeTarget(WindowState w) {
1708 final int fl = w.mAttrs.flags & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
1709 final int type = w.mAttrs.type;
1710
1711 if (fl != 0 && fl != (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM)
1712 && type != TYPE_APPLICATION_STARTING) {
1713 return false;
1714 }
1715
1716 if (DEBUG_INPUT_METHOD) {
1717 Slog.i(TAG_WM, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
1718 if (!w.isVisibleOrAdding()) {
1719 Slog.i(TAG_WM, " mSurfaceController=" + w.mWinAnimator.mSurfaceController
1720 + " relayoutCalled=" + w.mRelayoutCalled
1721 + " viewVis=" + w.mViewVisibility
1722 + " policyVis=" + w.mPolicyVisibility
1723 + " policyVisAfterAnim=" + w.mPolicyVisibilityAfterAnim
1724 + " parentHidden=" + w.isParentWindowHidden()
1725 + " exiting=" + w.mAnimatingExit + " destroying=" + w.mDestroying);
1726 if (w.mAppToken != null) {
1727 Slog.i(TAG_WM, " mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested);
1728 }
1729 }
1730 }
1731 return w.isVisibleOrAdding();
1732 }
1733
1734 private void logWindowList(final WindowList windows, String prefix) {
1735 int N = windows.size();
1736 while (N > 0) {
1737 N--;
1738 Slog.v(TAG_WM, prefix + "#" + N + ": " + windows.get(N));
1739 }
1740 }
1741
1742 boolean getNeedsMenu(WindowState win, WindowManagerPolicy.WindowState bottom) {
1743 int index = -1;
1744 WindowList windows = getWindowList();
1745 while (true) {
1746 if (win.mAttrs.needsMenuKey != NEEDS_MENU_UNSET) {
1747 return win.mAttrs.needsMenuKey == NEEDS_MENU_SET_TRUE;
1748 }
1749 // If we reached the bottom of the range of windows we are considering,
1750 // assume no menu is needed.
1751 if (win == bottom) {
1752 return false;
1753 }
1754 // The current window hasn't specified whether menu key is needed; look behind it.
1755 // First, we may need to determine the starting position.
1756 if (index < 0) {
1757 index = windows.indexOf(win);
1758 }
1759 index--;
1760 if (index < 0) {
1761 return false;
1762 }
1763 win = windows.get(index);
1764 }
1765 }
1766
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001767 void setLayoutNeeded() {
1768 if (DEBUG_LAYOUT) Slog.w(TAG_WM, "setLayoutNeeded: callers=" + Debug.getCallers(3));
1769 mLayoutNeeded = true;
1770 }
1771
1772 void clearLayoutNeeded() {
1773 if (DEBUG_LAYOUT) Slog.w(TAG_WM, "clearLayoutNeeded: callers=" + Debug.getCallers(3));
1774 mLayoutNeeded = false;
1775 }
1776
1777 boolean isLayoutNeeded() {
1778 return mLayoutNeeded;
1779 }
1780
Wale Ogunwaleec731152016-09-08 20:18:57 -07001781 private int addAppWindowExisting(WindowState win, WindowList tokenWindowList) {
1782
1783 int tokenWindowsPos;
1784 // If this application has existing windows, we simply place the new window on top of
1785 // them... but keep the starting window on top.
1786 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
1787 // Base windows go behind everything else.
1788 final WindowState lowestWindow = tokenWindowList.get(0);
1789 addWindowToListBefore(win, lowestWindow);
1790 tokenWindowsPos = win.mToken.getWindowIndex(lowestWindow);
1791 } else {
1792 final AppWindowToken atoken = win.mAppToken;
1793 final int windowListPos = tokenWindowList.size();
1794 final WindowState lastWindow = tokenWindowList.get(windowListPos - 1);
1795 if (atoken != null && lastWindow == atoken.startingWindow) {
1796 addWindowToListBefore(win, lastWindow);
1797 tokenWindowsPos = win.mToken.getWindowIndex(lastWindow);
1798 } else {
1799 int newIdx = findIdxBasedOnAppTokens(win);
1800 // There is a window above this one associated with the same apptoken note that the
1801 // window could be a floating window that was created later or a window at the top
1802 // of the list of windows associated with this token.
1803 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1804 "not Base app: Adding window " + win + " at " + (newIdx + 1) + " of "
1805 + mWindows.size());
1806 mWindows.add(newIdx + 1, win);
1807 if (newIdx < 0) {
1808 // No window from token found on win's display.
1809 tokenWindowsPos = 0;
1810 } else {
1811 tokenWindowsPos = win.mToken.getWindowIndex(mWindows.get(newIdx)) + 1;
1812 }
1813 mService.mWindowsChanged = true;
1814 }
1815 }
1816 return tokenWindowsPos;
1817 }
1818
1819 /** Places the first input window after the second input window in the window list. */
1820 private void addWindowToListAfter(WindowState first, WindowState second) {
1821 final int i = mWindows.indexOf(second);
1822 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1823 "Adding window " + this + " at " + (i + 1) + " of " + mWindows.size()
1824 + " (after " + second + ")");
1825 mWindows.add(i + 1, first);
1826 mService.mWindowsChanged = true;
1827 }
1828
1829 /** Places the first input window before the second input window in the window list. */
1830 private void addWindowToListBefore(WindowState first, WindowState second) {
1831 int i = mWindows.indexOf(second);
1832 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1833 "Adding window " + this + " at " + i + " of " + mWindows.size()
1834 + " (before " + second + ")");
1835 if (i < 0) {
1836 Slog.w(TAG_WM, "addWindowToListBefore: Unable to find " + second + " in " + mWindows);
1837 i = 0;
1838 }
1839 mWindows.add(i, first);
1840 mService.mWindowsChanged = true;
1841 }
1842
1843 /**
1844 * This method finds out the index of a window that has the same app token as win. used for z
1845 * ordering the windows in mWindows
1846 */
1847 private int findIdxBasedOnAppTokens(WindowState win) {
1848 for(int j = mWindows.size() - 1; j >= 0; j--) {
1849 final WindowState wentry = mWindows.get(j);
1850 if(wentry.mAppToken == win.mAppToken) {
1851 return j;
1852 }
1853 }
1854 return -1;
1855 }
1856
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001857 private void dumpChildrenNames() {
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07001858 StringBuilder output = new StringBuilder();
1859 dumpChildrenNames(output, " ");
1860 Slog.v(TAG_WM, output.toString());
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001861 }
1862
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001863 private void dumpWindows() {
Wale Ogunwale10124582016-09-15 20:25:50 -07001864 Slog.v(TAG_WM, " Display #" + mDisplayId);
1865 final WindowList windows = getWindowList();
1866 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
1867 Slog.v(TAG_WM, " #" + winNdx + ": " + windows.get(winNdx));
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001868 }
1869 }
1870
Wale Ogunwale02319a62016-09-26 15:21:22 -07001871 void dumpTokens(PrintWriter pw, boolean dumpAll) {
1872 if (mTokenMap.isEmpty()) {
1873 return;
1874 }
1875 pw.println(" Display #" + mDisplayId);
1876 final Iterator<WindowToken> it = mTokenMap.values().iterator();
1877 while (it.hasNext()) {
1878 final WindowToken token = it.next();
1879 pw.print(" ");
1880 pw.print(token);
1881 if (dumpAll) {
1882 pw.println(':');
1883 token.dump(pw, " ");
1884 } else {
1885 pw.println();
1886 }
1887 }
1888 }
1889
Wale Ogunwale824ab5c2016-10-20 09:31:56 -07001890 void dumpWindowAnimators(PrintWriter pw, String subPrefix) {
1891 final int count = mWindows.size();
1892 for (int j = 0; j < count; j++) {
1893 final WindowStateAnimator wAnim = mWindows.get(j).mWinAnimator;
1894 pw.println(subPrefix + "Window #" + j + ": " + wAnim);
1895 }
1896 }
1897
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001898 void enableSurfaceTrace(FileDescriptor fd) {
1899 for (int i = mWindows.size() - 1; i >= 0; i--) {
1900 final WindowState win = mWindows.get(i);
1901 win.mWinAnimator.enableSurfaceTrace(fd);
1902 }
1903 }
1904
1905 void disableSurfaceTrace() {
1906 for (int i = mWindows.size() - 1; i >= 0; i--) {
1907 final WindowState win = mWindows.get(i);
1908 win.mWinAnimator.disableSurfaceTrace();
1909 }
1910 }
1911
Wale Ogunwale494009b82016-10-21 09:01:38 -07001912 boolean checkWaitingForWindows() {
1913
1914 boolean haveBootMsg = false;
1915 boolean haveApp = false;
1916 // if the wallpaper service is disabled on the device, we're never going to have
1917 // wallpaper, don't bother waiting for it
1918 boolean haveWallpaper = false;
1919 boolean wallpaperEnabled = mService.mContext.getResources().getBoolean(
1920 com.android.internal.R.bool.config_enableWallpaperService)
1921 && !mService.mOnlyCore;
1922 boolean haveKeyguard = true;
1923 final int count = mWindows.size();
1924 for (int i = 0; i < count; i++) {
1925 final WindowState w = mWindows.get(i);
1926 if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
1927 return true;
1928 }
1929 if (w.isDrawnLw()) {
1930 if (w.mAttrs.type == TYPE_BOOT_PROGRESS) {
1931 haveBootMsg = true;
1932 } else if (w.mAttrs.type == TYPE_APPLICATION
1933 || w.mAttrs.type == TYPE_DRAWN_APPLICATION) {
1934 haveApp = true;
1935 } else if (w.mAttrs.type == TYPE_WALLPAPER) {
1936 haveWallpaper = true;
1937 } else if (w.mAttrs.type == TYPE_STATUS_BAR) {
1938 haveKeyguard = mService.mPolicy.isKeyguardDrawnLw();
1939 }
1940 }
1941 }
1942
1943 if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG_WM,
1944 "******** booted=" + mService.mSystemBooted
1945 + " msg=" + mService.mShowingBootMessages
1946 + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
1947 + " haveWall=" + haveWallpaper + " wallEnabled=" + wallpaperEnabled
1948 + " haveKeyguard=" + haveKeyguard);
1949
1950 // If we are turning on the screen to show the boot message, don't do it until the boot
1951 // message is actually displayed.
1952 if (!mService.mSystemBooted && !haveBootMsg) {
1953 return true;
1954 }
1955
1956 // If we are turning on the screen after the boot is completed normally, don't do so until
1957 // we have the application and wallpaper.
1958 if (mService.mSystemBooted && ((!haveApp && !haveKeyguard) ||
1959 (wallpaperEnabled && !haveWallpaper))) {
1960 return true;
1961 }
1962
1963 return false;
1964 }
1965
Wale Ogunwale824ab5c2016-10-20 09:31:56 -07001966 void updateWindowsForAnimator(WindowAnimator animator) {
1967 final WindowManagerPolicy policy = animator.mPolicy;
1968 final int keyguardGoingAwayFlags = animator.mKeyguardGoingAwayFlags;
1969 final boolean keyguardGoingAwayToShade =
1970 (keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_TO_SHADE) != 0;
1971 final boolean keyguardGoingAwayNoAnimation =
1972 (keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS) != 0;
1973 final boolean keyguardGoingAwayWithWallpaper =
1974 (keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER) != 0;
1975
1976 if (animator.mKeyguardGoingAway) {
1977 for (int i = mWindows.size() - 1; i >= 0; i--) {
1978 WindowState win = mWindows.get(i);
1979 if (!policy.isKeyguardHostWindow(win.mAttrs)) {
1980 continue;
1981 }
1982 final WindowStateAnimator winAnimator = win.mWinAnimator;
1983 if (policy.isKeyguardShowingAndNotOccluded()) {
1984 if (!winAnimator.mAnimating) {
1985 if (DEBUG_KEYGUARD) Slog.d(TAG,
1986 "updateWindowsForAnimator: creating delay animation");
1987
1988 // Create a new animation to delay until keyguard is gone on its own.
1989 winAnimator.mAnimation = new AlphaAnimation(1.0f, 1.0f);
1990 winAnimator.mAnimation.setDuration(KEYGUARD_ANIM_TIMEOUT_MS);
1991 winAnimator.mAnimationIsEntrance = false;
1992 winAnimator.mAnimationStartTime = -1;
1993 winAnimator.mKeyguardGoingAwayAnimation = true;
1994 winAnimator.mKeyguardGoingAwayWithWallpaper
1995 = keyguardGoingAwayWithWallpaper;
1996 }
1997 } else {
1998 if (DEBUG_KEYGUARD) Slog.d(TAG,
1999 "updateWindowsForAnimator: StatusBar is no longer keyguard");
2000 animator.mKeyguardGoingAway = false;
2001 winAnimator.clearAnimation();
2002 }
2003 break;
2004 }
2005 }
2006
2007 animator.mForceHiding = KEYGUARD_NOT_SHOWN;
2008
2009 boolean wallpaperInUnForceHiding = false;
2010 boolean startingInUnForceHiding = false;
2011 ArrayList<WindowStateAnimator> unForceHiding = null;
2012 WindowState wallpaper = null;
Wale Ogunwale0303c572016-10-20 10:16:29 -07002013 final WallpaperController wallpaperController = mWallpaperController;
Wale Ogunwale824ab5c2016-10-20 09:31:56 -07002014 for (int i = mWindows.size() - 1; i >= 0; i--) {
2015 WindowState win = mWindows.get(i);
2016 WindowStateAnimator winAnimator = win.mWinAnimator;
2017 final int flags = win.mAttrs.flags;
2018 boolean canBeForceHidden = policy.canBeForceHidden(win, win.mAttrs);
2019 boolean shouldBeForceHidden = animator.shouldForceHide(win);
2020 if (winAnimator.hasSurface()) {
2021 final boolean wasAnimating = winAnimator.mWasAnimating;
2022 final boolean nowAnimating = winAnimator.stepAnimationLocked(animator.mCurrentTime);
2023 winAnimator.mWasAnimating = nowAnimating;
2024 animator.orAnimating(nowAnimating);
2025
2026 if (DEBUG_WALLPAPER) Slog.v(TAG,
2027 win + ": wasAnimating=" + wasAnimating + ", nowAnimating=" + nowAnimating);
2028
2029 if (wasAnimating && !winAnimator.mAnimating
2030 && wallpaperController.isWallpaperTarget(win)) {
2031 animator.mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
2032 pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
2033 if (DEBUG_LAYOUT_REPEATS) {
2034 mService.mWindowPlacerLocked.debugLayoutRepeats(
2035 "updateWindowsAndWallpaperLocked 2", pendingLayoutChanges);
2036 }
2037 }
2038
2039 if (policy.isForceHiding(win.mAttrs)) {
2040 if (!wasAnimating && nowAnimating) {
2041 if (DEBUG_KEYGUARD || DEBUG_ANIM || DEBUG_VISIBILITY) Slog.v(TAG,
2042 "Animation started that could impact force hide: " + win);
2043 animator.mBulkUpdateParams |= SET_FORCE_HIDING_CHANGED;
2044 pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
2045 if (DEBUG_LAYOUT_REPEATS) {
2046 mService.mWindowPlacerLocked.debugLayoutRepeats(
2047 "updateWindowsAndWallpaperLocked 3", pendingLayoutChanges);
2048 }
2049 mService.mFocusMayChange = true;
2050 } else if (animator.mKeyguardGoingAway && !nowAnimating) {
2051 // Timeout!!
2052 Slog.e(TAG, "Timeout waiting for animation to startup");
2053 policy.startKeyguardExitAnimation(0, 0);
2054 animator.mKeyguardGoingAway = false;
2055 }
2056 if (win.isReadyForDisplay()) {
2057 if (nowAnimating && win.mWinAnimator.mKeyguardGoingAwayAnimation) {
2058 animator.mForceHiding = KEYGUARD_ANIMATING_OUT;
2059 } else {
2060 animator.mForceHiding = win.isDrawnLw()
2061 ? KEYGUARD_SHOWN : KEYGUARD_NOT_SHOWN;
2062 }
2063 }
2064 if (DEBUG_KEYGUARD || DEBUG_VISIBILITY) Slog.v(TAG,
2065 "Force hide " + animator.forceHidingToString()
2066 + " hasSurface=" + win.mHasSurface
2067 + " policyVis=" + win.mPolicyVisibility
2068 + " destroying=" + win.mDestroying
2069 + " parentHidden=" + win.isParentWindowHidden()
2070 + " vis=" + win.mViewVisibility
2071 + " hidden=" + win.mToken.hidden
2072 + " anim=" + win.mWinAnimator.mAnimation);
2073 } else if (canBeForceHidden) {
2074 if (shouldBeForceHidden) {
2075 if (!win.hideLw(false, false)) {
2076 // Was already hidden
2077 continue;
2078 }
2079 if (DEBUG_KEYGUARD || DEBUG_VISIBILITY) Slog.v(TAG,
2080 "Now policy hidden: " + win);
2081 } else {
2082 final Animation postKeyguardExitAnimation =
2083 animator.mPostKeyguardExitAnimation;
2084 boolean applyExistingExitAnimation = postKeyguardExitAnimation != null
2085 && !postKeyguardExitAnimation.hasEnded()
2086 && !winAnimator.mKeyguardGoingAwayAnimation
2087 && win.hasDrawnLw()
2088 && !win.isChildWindow()
2089 && !win.mIsImWindow
2090 && isDefaultDisplay;
2091
2092 // If the window is already showing and we don't need to apply an existing
2093 // Keyguard exit animation, skip.
2094 if (!win.showLw(false, false) && !applyExistingExitAnimation) {
2095 continue;
2096 }
2097 final boolean visibleNow = win.isVisibleNow();
2098 if (!visibleNow) {
2099 // Couldn't really show, must showLw() again when win becomes visible.
2100 win.hideLw(false, false);
2101 continue;
2102 }
2103 if (DEBUG_KEYGUARD || DEBUG_VISIBILITY) Slog.v(TAG,
2104 "Now policy shown: " + win);
2105 if ((animator.mBulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0
2106 && !win.isChildWindow()) {
2107 if (unForceHiding == null) {
2108 unForceHiding = new ArrayList<>();
2109 }
2110 unForceHiding.add(winAnimator);
2111 if ((flags & FLAG_SHOW_WALLPAPER) != 0) {
2112 wallpaperInUnForceHiding = true;
2113 }
2114 if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
2115 startingInUnForceHiding = true;
2116 }
2117 } else if (applyExistingExitAnimation) {
2118 // We're already in the middle of an animation. Use the existing
2119 // animation to bring in this window.
2120 if (DEBUG_KEYGUARD) Slog.v(TAG,
2121 "Applying existing Keyguard exit animation to new window: win="
2122 + win);
2123
2124 final Animation a = policy.createForceHideEnterAnimation(false,
2125 keyguardGoingAwayToShade);
2126 winAnimator.setAnimation(a, postKeyguardExitAnimation.getStartTime(),
2127 STACK_CLIP_BEFORE_ANIM);
2128 winAnimator.mKeyguardGoingAwayAnimation = true;
2129 winAnimator.mKeyguardGoingAwayWithWallpaper
2130 = keyguardGoingAwayWithWallpaper;
2131 }
2132 final WindowState currentFocus = mService.mCurrentFocus;
2133 if (currentFocus == null || currentFocus.mLayer < win.mLayer) {
2134 // We are showing on top of the current
2135 // focus, so re-evaluate focus to make
2136 // sure it is correct.
2137 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG,
2138 "updateWindowsForAnimator: setting mFocusMayChange true");
2139 mService.mFocusMayChange = true;
2140 }
2141 }
2142 if ((flags & FLAG_SHOW_WALLPAPER) != 0) {
2143 animator.mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
2144 pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
2145 if (DEBUG_LAYOUT_REPEATS) {
2146 mService.mWindowPlacerLocked.debugLayoutRepeats(
2147 "updateWindowsAndWallpaperLocked 4", pendingLayoutChanges);
2148 }
2149 }
2150 }
2151 }
2152
2153 // If the window doesn't have a surface, the only thing we care about is the correct
2154 // policy visibility.
2155 else if (canBeForceHidden) {
2156 if (shouldBeForceHidden) {
2157 win.hideLw(false, false);
2158 } else {
2159 win.showLw(false, false);
2160 }
2161 }
2162
2163 final AppWindowToken atoken = win.mAppToken;
2164 if (winAnimator.mDrawState == READY_TO_SHOW) {
2165 if (atoken == null || atoken.allDrawn) {
2166 if (win.performShowLocked()) {
2167 pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
2168 if (DEBUG_LAYOUT_REPEATS) {
2169 mService.mWindowPlacerLocked.debugLayoutRepeats(
2170 "updateWindowsAndWallpaperLocked 5", pendingLayoutChanges);
2171 }
2172 }
2173 }
2174 }
2175 final AppWindowAnimator appAnimator = winAnimator.mAppAnimator;
2176 if (appAnimator != null && appAnimator.thumbnail != null) {
2177 if (appAnimator.thumbnailTransactionSeq != animator.mAnimTransactionSequence) {
2178 appAnimator.thumbnailTransactionSeq = animator.mAnimTransactionSequence;
2179 appAnimator.thumbnailLayer = 0;
2180 }
2181 if (appAnimator.thumbnailLayer < winAnimator.mAnimLayer) {
2182 appAnimator.thumbnailLayer = winAnimator.mAnimLayer;
2183 }
2184 }
2185 if (win.mIsWallpaper) {
2186 wallpaper = win;
2187 }
2188 } // end forall windows
2189
2190 // If we have windows that are being shown due to them no longer being force-hidden, apply
2191 // the appropriate animation to them if animations are not disabled.
2192 if (unForceHiding != null) {
2193 if (!keyguardGoingAwayNoAnimation) {
2194 boolean first = true;
2195 for (int i=unForceHiding.size()-1; i>=0; i--) {
2196 final WindowStateAnimator winAnimator = unForceHiding.get(i);
2197 final Animation a = policy.createForceHideEnterAnimation(
2198 wallpaperInUnForceHiding && !startingInUnForceHiding,
2199 keyguardGoingAwayToShade);
2200 if (a != null) {
2201 if (DEBUG_KEYGUARD) Slog.v(TAG,
2202 "Starting keyguard exit animation on window " + winAnimator.mWin);
2203 winAnimator.setAnimation(a, STACK_CLIP_BEFORE_ANIM);
2204 winAnimator.mKeyguardGoingAwayAnimation = true;
2205 winAnimator.mKeyguardGoingAwayWithWallpaper
2206 = keyguardGoingAwayWithWallpaper;
2207 if (first) {
2208 animator.mPostKeyguardExitAnimation = a;
2209 animator.mPostKeyguardExitAnimation.setStartTime(animator.mCurrentTime);
2210 first = false;
2211 }
2212 }
2213 }
2214 } else if (animator.mKeyguardGoingAway) {
2215 policy.startKeyguardExitAnimation(animator.mCurrentTime, 0 /* duration */);
2216 animator.mKeyguardGoingAway = false;
2217 }
2218
2219
2220 // Wallpaper is going away in un-force-hide motion, animate it as well.
2221 if (!wallpaperInUnForceHiding && wallpaper != null && !keyguardGoingAwayNoAnimation) {
2222 if (DEBUG_KEYGUARD) Slog.d(TAG,
2223 "updateWindowsForAnimator: wallpaper animating away");
2224 final Animation a = policy.createForceHideWallpaperExitAnimation(
2225 keyguardGoingAwayToShade);
2226 if (a != null) {
2227 wallpaper.mWinAnimator.setAnimation(a);
2228 }
2229 }
2230 }
2231
2232 if (animator.mPostKeyguardExitAnimation != null) {
2233 // We're in the midst of a keyguard exit animation.
2234 if (animator.mKeyguardGoingAway) {
2235 policy.startKeyguardExitAnimation(animator.mCurrentTime +
2236 animator.mPostKeyguardExitAnimation.getStartOffset(),
2237 animator.mPostKeyguardExitAnimation.getDuration());
2238 animator.mKeyguardGoingAway = false;
2239 }
2240 // mPostKeyguardExitAnimation might either be ended normally, cancelled, or "orphaned",
2241 // meaning that the window it was running on was removed. We check for hasEnded() for
2242 // ended normally and cancelled case, and check the time for the "orphaned" case.
2243 else if (animator.mPostKeyguardExitAnimation.hasEnded()
2244 || animator.mCurrentTime - animator.mPostKeyguardExitAnimation.getStartTime()
2245 > animator.mPostKeyguardExitAnimation.getDuration()) {
2246 // Done with the animation, reset.
2247 if (DEBUG_KEYGUARD) Slog.v(TAG, "Done with Keyguard exit animations.");
2248 animator.mPostKeyguardExitAnimation = null;
2249 }
2250 }
2251
2252 final WindowState winShowWhenLocked = (WindowState) policy.getWinShowWhenLockedLw();
2253 if (winShowWhenLocked != null) {
2254 animator.mLastShowWinWhenLocked = winShowWhenLocked;
2255 }
2256 }
2257
2258 void updateWallpaperForAnimator(WindowAnimator animator) {
Jorim Jaggi7156b652016-10-25 08:31:58 -07002259 resetAnimationBackgroundAnimator();
2260
Wale Ogunwale824ab5c2016-10-20 09:31:56 -07002261 final WindowList windows = mWindows;
2262 WindowState detachedWallpaper = null;
2263
2264 for (int i = windows.size() - 1; i >= 0; i--) {
2265 final WindowState win = windows.get(i);
2266 final WindowStateAnimator winAnimator = win.mWinAnimator;
2267 if (winAnimator.mSurfaceController == null || !winAnimator.hasSurface()) {
2268 continue;
2269 }
2270
2271 final int flags = win.mAttrs.flags;
2272
2273 // If this window is animating, make a note that we have an animating window and take
2274 // care of a request to run a detached wallpaper animation.
2275 if (winAnimator.mAnimating) {
2276 if (winAnimator.mAnimation != null) {
2277 if ((flags & FLAG_SHOW_WALLPAPER) != 0
2278 && winAnimator.mAnimation.getDetachWallpaper()) {
2279 detachedWallpaper = win;
2280 }
2281 final int color = winAnimator.mAnimation.getBackgroundColor();
2282 if (color != 0) {
2283 final TaskStack stack = win.getStack();
2284 if (stack != null) {
2285 stack.setAnimationBackground(winAnimator, color);
2286 }
2287 }
2288 }
2289 animator.setAnimating(true);
2290 }
2291
2292 // If this window's app token is running a detached wallpaper animation, make a note so
2293 // we can ensure the wallpaper is displayed behind it.
2294 final AppWindowAnimator appAnimator = winAnimator.mAppAnimator;
2295 if (appAnimator != null && appAnimator.animation != null
2296 && appAnimator.animating) {
2297 if ((flags & FLAG_SHOW_WALLPAPER) != 0
2298 && appAnimator.animation.getDetachWallpaper()) {
2299 detachedWallpaper = win;
2300 }
2301
2302 final int color = appAnimator.animation.getBackgroundColor();
2303 if (color != 0) {
2304 final TaskStack stack = win.getStack();
2305 if (stack != null) {
2306 stack.setAnimationBackground(winAnimator, color);
2307 }
2308 }
2309 }
2310 } // end forall windows
2311
2312 if (animator.mWindowDetachedWallpaper != detachedWallpaper) {
2313 if (DEBUG_WALLPAPER) Slog.v(TAG, "Detached wallpaper changed from "
2314 + animator.mWindowDetachedWallpaper + " to " + detachedWallpaper);
2315 animator.mWindowDetachedWallpaper = detachedWallpaper;
2316 animator.mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
2317 }
2318 }
2319
2320 void prepareWindowSurfaces() {
2321 final int count = mWindows.size();
2322 for (int j = 0; j < count; j++) {
2323 mWindows.get(j).mWinAnimator.prepareSurfaceLocked(true);
2324 }
2325 }
2326
Wale Ogunwale494009b82016-10-21 09:01:38 -07002327 boolean inputMethodClientHasFocus(IInputMethodClient client) {
2328 // The focus for the client is the window immediately below where we would place the input
2329 // method window.
2330 int idx = findDesiredInputMethodWindowIndex(false);
2331 if (idx <= 0) {
2332 return false;
2333 }
2334
2335 WindowState imFocus = mWindows.get(idx - 1);
2336 if (DEBUG_INPUT_METHOD) {
2337 Slog.i(TAG_WM, "Desired input method target: " + imFocus);
2338 Slog.i(TAG_WM, "Current focus: " + mService.mCurrentFocus);
2339 Slog.i(TAG_WM, "Last focus: " + mService.mLastFocus);
2340 }
2341
2342 if (imFocus == null) {
2343 return false;
2344 }
2345
2346 // This may be a starting window, in which case we still want to count it as okay.
2347 if (imFocus.mAttrs.type == TYPE_APPLICATION_STARTING && imFocus.mAppToken != null) {
2348 // The client has definitely started, so it really should have a window in this app
2349 // token. Let's look for it.
2350 final WindowState w = imFocus.mAppToken.getFirstNonStartingWindow();
2351 if (w != null) {
2352 if (DEBUG_INPUT_METHOD) Slog.i(TAG_WM, "Switching to real app window: " + w);
2353 imFocus = w;
2354 }
2355 }
2356
2357 final IInputMethodClient imeClient = imFocus.mSession.mClient;
2358
2359 if (DEBUG_INPUT_METHOD) {
2360 Slog.i(TAG_WM, "IM target client: " + imeClient);
2361 if (imeClient != null) {
2362 Slog.i(TAG_WM, "IM target client binder: " + imeClient.asBinder());
2363 Slog.i(TAG_WM, "Requesting client binder: " + client.asBinder());
2364 }
2365 }
2366
2367 return imeClient != null && imeClient.asBinder() == client.asBinder();
2368 }
2369
2370 boolean hasSecureWindowOnScreen() {
2371 for (int i = mWindows.size() - 1; i >= 0; --i) {
2372 final WindowState ws = mWindows.get(i);
2373 if (ws.isOnScreen() && (ws.mAttrs.flags & FLAG_SECURE) != 0) {
2374 return true;
2375 }
2376 }
2377 return false;
2378 }
2379
2380 void updateSystemUiVisibility(int visibility, int globalDiff) {
2381 for (int i = mWindows.size() - 1; i >= 0; --i) {
2382 final WindowState ws = mWindows.get(i);
2383 try {
2384 int curValue = ws.mSystemUiVisibility;
2385 int diff = (curValue ^ visibility) & globalDiff;
2386 int newValue = (curValue & ~diff) | (visibility & diff);
2387 if (newValue != curValue) {
2388 ws.mSeq++;
2389 ws.mSystemUiVisibility = newValue;
2390 }
2391 if (newValue != curValue || ws.mAttrs.hasSystemUiListeners) {
2392 ws.mClient.dispatchSystemUiVisibilityChanged(ws.mSeq,
2393 visibility, newValue, diff);
2394 }
2395 } catch (RemoteException e) {
2396 // so sorry
2397 }
2398 }
2399 }
2400
2401 void onWindowFreezeTimeout() {
2402 Slog.w(TAG_WM, "Window freeze timeout expired.");
2403 mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT;
2404 for (int i = mWindows.size() - 1; i >= 0; --i) {
2405 final WindowState w = mWindows.get(i);
2406 if (!w.mOrientationChanging) {
2407 continue;
2408 }
2409 w.mOrientationChanging = false;
2410 w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
2411 - mService.mDisplayFreezeTime);
2412 Slog.w(TAG_WM, "Force clearing orientation change: " + w);
2413 }
2414 mService.mWindowPlacerLocked.performSurfacePlacement();
2415 }
2416
2417 void waitForAllWindowsDrawn() {
2418 final WindowManagerPolicy policy = mService.mPolicy;
2419 for (int winNdx = mWindows.size() - 1; winNdx >= 0; --winNdx) {
2420 final WindowState win = mWindows.get(winNdx);
2421 final boolean isForceHiding = policy.isForceHiding(win.mAttrs);
2422 final boolean keyguard = policy.isKeyguardHostWindow(win.mAttrs);
2423 if (win.isVisibleLw() && (win.mAppToken != null || isForceHiding || keyguard)) {
2424 win.mWinAnimator.mDrawState = DRAW_PENDING;
2425 // Force add to mResizingWindows.
2426 win.mLastContentInsets.set(-1, -1, -1, -1);
2427 mService.mWaitingForDrawn.add(win);
2428
2429 // No need to wait for the windows below Keyguard.
2430 if (isForceHiding) {
2431 return;
2432 }
2433 }
2434 }
2435 }
2436
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07002437 static final class GetWindowOnDisplaySearchResult {
Wale Ogunwaleec731152016-09-08 20:18:57 -07002438 boolean reachedToken;
2439 WindowState foundWindow;
2440
2441 void reset() {
2442 reachedToken = false;
2443 foundWindow = null;
2444 }
2445 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07002446
2447 static final class TaskForResizePointSearchResult {
2448 boolean searchDone;
2449 Task taskForResize;
2450
2451 void reset() {
2452 searchDone = false;
2453 taskForResize = null;
2454 }
2455 }
Robert Carr3b716242016-08-16 16:02:21 -07002456
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002457 /**
2458 * Base class for any direct child window container of {@link #DisplayContent} need to inherit
2459 * from. This is mainly a pass through class that allows {@link #DisplayContent} to have
2460 * homogeneous children type which is currently required by sub-classes of
2461 * {@link WindowContainer} class.
2462 */
2463 static class DisplayChildWindowContainer<E extends WindowContainer> extends WindowContainer<E> {
2464
2465 int size() {
2466 return mChildren.size();
2467 }
2468
2469 E get(int index) {
2470 return mChildren.get(index);
2471 }
2472
2473 @Override
2474 boolean fillsParent() {
2475 return true;
2476 }
2477
2478 @Override
2479 boolean isVisible() {
2480 return true;
Robert Carr3b716242016-08-16 16:02:21 -07002481 }
2482 }
2483
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002484 /**
2485 * Window container class that contains all containers on this display relating to Apps.
2486 * I.e Activities.
2487 */
2488 private class TaskStackContainers extends DisplayChildWindowContainer<TaskStack> {
2489
2490 void attachStack(TaskStack stack, boolean onTop) {
2491 if (stack.mStackId == HOME_STACK_ID) {
2492 if (mHomeStack != null) {
2493 throw new IllegalArgumentException("attachStack: HOME_STACK_ID (0) not first.");
2494 }
2495 mHomeStack = stack;
2496 }
2497 addChild(stack, onTop);
2498 stack.onDisplayChanged(DisplayContent.this);
Robert Carr3b716242016-08-16 16:02:21 -07002499 }
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002500
2501 void moveStack(TaskStack stack, boolean toTop) {
2502 if (StackId.isAlwaysOnTop(stack.mStackId) && !toTop) {
2503 // This stack is always-on-top silly...
2504 Slog.w(TAG_WM, "Ignoring move of always-on-top stack=" + stack + " to bottom");
2505 return;
2506 }
2507
2508 if (!mChildren.contains(stack)) {
2509 Slog.wtf(TAG_WM, "moving stack that was not added: " + stack, new Throwable());
2510 }
2511 removeChild(stack);
2512 addChild(stack, toTop);
2513 }
2514
2515 private void addChild(TaskStack stack, boolean toTop) {
2516 int addIndex = toTop ? mChildren.size() : 0;
2517
2518 if (toTop
2519 && mService.isStackVisibleLocked(PINNED_STACK_ID)
2520 && stack.mStackId != PINNED_STACK_ID) {
2521 // The pinned stack is always the top most stack (always-on-top) when it is visible.
2522 // So, stack is moved just below the pinned stack.
2523 addIndex--;
2524 TaskStack topStack = mChildren.get(addIndex);
2525 if (topStack.mStackId != PINNED_STACK_ID) {
2526 throw new IllegalStateException("Pinned stack isn't top stack??? " + mChildren);
2527 }
2528 }
2529 addChild(stack, addIndex);
2530 setLayoutNeeded();
2531 }
2532
Wale Ogunwalee6f806e2016-10-20 15:29:42 -07002533 @Override
2534 int getOrientation() {
2535 if (mService.isStackVisibleLocked(DOCKED_STACK_ID)
2536 || mService.isStackVisibleLocked(FREEFORM_WORKSPACE_STACK_ID)) {
2537 // Apps and their containers are not allowed to specify an orientation while the
2538 // docked or freeform stack is visible...except for the home stack/task if the
2539 // docked stack is minimized and it actually set something.
2540 if (mHomeStack != null && mHomeStack.isVisible()
2541 && mDividerControllerLocked.isMinimizedDock()) {
2542 final int orientation = mHomeStack.getOrientation();
2543 if (orientation != SCREEN_ORIENTATION_UNSET) {
2544 return orientation;
2545 }
2546 }
2547 return SCREEN_ORIENTATION_UNSPECIFIED;
2548 }
2549
2550 final int orientation = super.getOrientation();
2551 if (orientation != SCREEN_ORIENTATION_UNSET
2552 && orientation != SCREEN_ORIENTATION_BEHIND) {
2553 if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
2554 "App is requesting an orientation, return " + orientation);
2555 return orientation;
2556 }
2557
2558 if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
2559 "No app is requesting an orientation, return " + mService.mLastOrientation);
2560 // The next app has not been requested to be visible, so we keep the current orientation
2561 // to prevent freezing/unfreezing the display too early.
2562 return mService.mLastOrientation;
2563 }
Wale Ogunwale19e452e2016-10-12 12:36:29 -07002564 }
2565
2566 /**
2567 * Window container class that contains all containers on this display that are not related to
2568 * Apps. E.g. status bar.
2569 */
2570 private static class NonAppWindowContainers extends DisplayChildWindowContainer<WindowToken> {
2571
Robert Carr3b716242016-08-16 16:02:21 -07002572 }
Craig Mautner59c00972012-07-30 12:10:24 -07002573}