blob: a99bad26f62a0f3f0d5af4edc788e5fc46cf4cc0 [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;
Winson Chung655332c2016-10-31 13:14:28 -0700199 final PinnedStackController mPinnedStackControllerLocked;
Filip Gruszczynski466f3212015-09-21 17:57:57 -0700200
Chong Zhang112eb8c2015-11-02 11:17:00 -0800201 final DimLayerController mDimLayerController;
Filip Gruszczynski0689ae92015-10-01 12:30:31 -0700202
Filip Gruszczynskiecf67222015-12-11 15:16:36 -0800203 final ArrayList<WindowState> mTapExcludedWindows = new ArrayList<>();
204
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700205 /** Used when rebuilding window list to keep track of windows that have been removed. */
206 private WindowState[] mRebuildTmp = new WindowState[20];
207
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700208 private final TaskForResizePointSearchResult mTmpTaskForResizePointSearchResult =
209 new TaskForResizePointSearchResult();
210 private final GetWindowOnDisplaySearchResult mTmpGetWindowOnDisplaySearchResult =
211 new GetWindowOnDisplaySearchResult();
212
Wale Ogunwale601a3f02016-10-17 08:39:39 -0700213 // True if this display is in the process of being removed. Used to determine if the removal of
214 // the display's direct children should be allowed.
215 private boolean mRemovingDisplay = false;
216
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700217 private final WindowLayersController mLayersController;
Wale Ogunwale0303c572016-10-20 10:16:29 -0700218 final WallpaperController mWallpaperController;
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700219 int mInputMethodAnimLayerAdjustment;
220
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800221 /**
Craig Mautner2d5618c2012-10-18 13:55:47 -0700222 * @param display May not be null.
Craig Mautnerdf88d732014-01-27 09:21:32 -0800223 * @param service You know.
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700224 * @param layersController window layer controller used to assign layer to the windows on this
225 * display.
Wale Ogunwale0303c572016-10-20 10:16:29 -0700226 * @param wallpaperController wallpaper windows controller used to adjust the positioning of the
227 * wallpaper windows in the window list.
Craig Mautner2d5618c2012-10-18 13:55:47 -0700228 */
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700229 DisplayContent(Display display, WindowManagerService service,
Wale Ogunwale0303c572016-10-20 10:16:29 -0700230 WindowLayersController layersController, WallpaperController wallpaperController) {
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700231 mDisplay = display;
232 mDisplayId = display.getDisplayId();
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700233 mLayersController = layersController;
Wale Ogunwale0303c572016-10-20 10:16:29 -0700234 mWallpaperController = wallpaperController;
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700235 display.getDisplayInfo(mDisplayInfo);
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700236 display.getMetrics(mDisplayMetrics);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700237 isDefaultDisplay = mDisplayId == DEFAULT_DISPLAY;
Craig Mautner9d808b12013-08-06 18:00:25 -0700238 mService = service;
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -0700239 initializeDisplayBaseInfo();
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800240 mDividerControllerLocked = new DockedStackDividerController(service, this);
Winson Chung655332c2016-10-31 13:14:28 -0700241 mPinnedStackControllerLocked = new PinnedStackController(service, this);
Chong Zhang112eb8c2015-11-02 11:17:00 -0800242 mDimLayerController = new DimLayerController(this);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700243
244 // These are the only direct children we should ever have and they are permanent.
245 super.addChild(mTaskStackContainers, null);
246 super.addChild(mNonAppWindowContainers, null);
Craig Mautner59c00972012-07-30 12:10:24 -0700247 }
248
249 int getDisplayId() {
250 return mDisplayId;
251 }
252
253 WindowList getWindowList() {
254 return mWindows;
255 }
256
Wale Ogunwale02319a62016-09-26 15:21:22 -0700257 WindowToken getWindowToken(IBinder binder) {
258 return mTokenMap.get(binder);
259 }
260
261 AppWindowToken getAppWindowToken(IBinder binder) {
262 final WindowToken token = getWindowToken(binder);
263 if (token == null) {
264 return null;
265 }
266 return token.asAppWindowToken();
267 }
268
269 void setWindowToken(IBinder binder, WindowToken token) {
270 final DisplayContent dc = mService.mRoot.getWindowTokenDisplay(token);
271 if (dc != null) {
272 // We currently don't support adding a window token to the display if the display
273 // already has the binder mapped to another token. If there is a use case for supporting
274 // this moving forward we will either need to merge the WindowTokens some how or have
275 // the binder map to a list of window tokens.
276 throw new IllegalArgumentException("Can't map token=" + token + " to display=" + this
277 + " already mapped to display=" + dc + " tokens=" + dc.mTokenMap);
278 }
279 mTokenMap.put(binder, token);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700280
281 if (token.asAppWindowToken() == null) {
282 // Add non-app token to container hierarchy on the display. App tokens are added through
283 // the parent container managing them (e.g. Tasks).
284 mNonAppWindowContainers.addChild(token, null);
285 }
Wale Ogunwale02319a62016-09-26 15:21:22 -0700286 }
287
288 WindowToken removeWindowToken(IBinder binder) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700289 final WindowToken token = mTokenMap.remove(binder);
290 if (token != null && token.asAppWindowToken() == null) {
291 mNonAppWindowContainers.removeChild(token);
292 }
293 return token;
Wale Ogunwale02319a62016-09-26 15:21:22 -0700294 }
295
Craig Mautnerb47bbc32012-08-22 17:41:48 -0700296 Display getDisplay() {
297 return mDisplay;
298 }
299
Craig Mautner59c00972012-07-30 12:10:24 -0700300 DisplayInfo getDisplayInfo() {
301 return mDisplayInfo;
302 }
303
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700304 DisplayMetrics getDisplayMetrics() {
305 return mDisplayMetrics;
306 }
307
Jorim Jaggi61f39a72015-10-29 16:54:18 +0100308 DockedStackDividerController getDockedDividerController() {
309 return mDividerControllerLocked;
310 }
311
Winson Chung655332c2016-10-31 13:14:28 -0700312 PinnedStackController getPinnedStackController() {
313 return mPinnedStackControllerLocked;
314 }
315
Jeff Browna506a6e2013-06-04 00:02:38 -0700316 /**
317 * Returns true if the specified UID has access to this display.
318 */
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700319 boolean hasAccess(int uid) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700320 return mDisplay.hasAccess(uid);
321 }
322
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700323 boolean isPrivate() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700324 return (mDisplay.getFlags() & FLAG_PRIVATE) != 0;
keunyounga446bf02013-06-21 19:07:57 -0700325 }
326
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700327 TaskStack getHomeStack() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700328 if (mHomeStack == null && mDisplayId == DEFAULT_DISPLAY) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800329 Slog.e(TAG_WM, "getHomeStack: Returning null from this=" + this);
Craig Mautnere0a38842013-12-16 16:14:02 -0800330 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700331 return mHomeStack;
Craig Mautnerd5d5d0f2013-04-03 15:08:21 -0700332 }
333
Chong Zhangd9d35bd2016-08-04 17:55:21 -0700334 TaskStack getStackById(int stackId) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700335 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
336 final TaskStack stack = mTaskStackContainers.get(i);
Chong Zhangd9d35bd2016-08-04 17:55:21 -0700337 if (stack.mStackId == stackId) {
338 return stack;
339 }
340 }
341 return null;
342 }
343
Andrii Kulian441e4492016-09-29 15:25:00 -0700344 @Override
345 void onConfigurationChanged(Configuration newParentConfig) {
346 super.onConfigurationChanged(newParentConfig);
347
Andrii Kulian3a507b52016-09-19 18:14:12 -0700348 // The display size information is heavily dependent on the resources in the current
349 // configuration, so we need to reconfigure it every time the configuration changes.
350 // See {@link PhoneWindowManager#setInitialDisplaySize}...sigh...
351 mService.reconfigureDisplayLocked(this);
352
353 getDockedDividerController().onConfigurationChanged();
Winson Chung655332c2016-10-31 13:14:28 -0700354 getPinnedStackController().onConfigurationChanged();
Andrii Kulian441e4492016-09-29 15:25:00 -0700355 }
Andrii Kulian3a507b52016-09-19 18:14:12 -0700356
Andrii Kulian441e4492016-09-29 15:25:00 -0700357 /**
358 * Callback used to trigger bounds update after configuration change and get ids of stacks whose
359 * bounds were updated.
360 */
361 void updateStackBoundsAfterConfigChange(@NonNull List<Integer> changedStackList) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700362 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
363 final TaskStack stack = mTaskStackContainers.get(i);
Andrii Kulian441e4492016-09-29 15:25:00 -0700364 if (stack.updateBoundsAfterConfigChange()) {
Andrii Kulian3a507b52016-09-19 18:14:12 -0700365 changedStackList.add(stack.mStackId);
366 }
367 }
368 }
369
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700370 @Override
371 boolean fillsParent() {
372 return true;
373 }
374
375 @Override
376 boolean isVisible() {
377 return true;
378 }
379
380 @Override
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700381 void onAppTransitionDone() {
Wale Ogunwale10124582016-09-15 20:25:50 -0700382 super.onAppTransitionDone();
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700383 rebuildAppWindowList();
384 }
385
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700386 @Override
Wale Ogunwale51362492016-09-08 17:49:17 -0700387 int getOrientation() {
Wale Ogunwalee6f806e2016-10-20 15:29:42 -0700388 final WindowManagerPolicy policy = mService.mPolicy;
389
390 // TODO: All the logic before the last return statement in this method should really go in
391 // #NonAppWindowContainer.getOrientation() since it is trying to decide orientation based
392 // on non-app windows. But, we can not do that until the window list is always correct in
393 // terms of z-ordering based on layers.
394 if (mService.mDisplayFrozen) {
395 if (mService.mLastWindowForcedOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
396 if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
397 "Display is frozen, return " + mService.mLastWindowForcedOrientation);
398 // If the display is frozen, some activities may be in the middle of restarting, and
399 // thus have removed their old window. If the window has the flag to hide the lock
400 // screen, then the lock screen can re-appear and inflict its own orientation on us.
401 // Keep the orientation stable until this all settles down.
402 return mService.mLastWindowForcedOrientation;
403 } else if (policy.isKeyguardLocked()) {
404 // Use the last orientation the while the display is frozen with the keyguard
405 // locked. This could be the keyguard forced orientation or from a SHOW_WHEN_LOCKED
406 // window. We don't want to check the show when locked window directly though as
407 // things aren't stable while the display is frozen, for example the window could be
408 // momentarily unavailable due to activity relaunch.
409 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display is frozen while keyguard locked, "
410 + "return " + mService.mLastOrientation);
411 return mService.mLastOrientation;
Wale Ogunwale51362492016-09-08 17:49:17 -0700412 }
Wale Ogunwalee6f806e2016-10-20 15:29:42 -0700413 } else {
414 for (int pos = mWindows.size() - 1; pos >= 0; --pos) {
415 final WindowState win = mWindows.get(pos);
416 if (win.mAppToken != null) {
417 // We hit an application window. so the orientation will be determined by the
418 // app window. No point in continuing further.
419 break;
420 }
421 if (!win.isVisibleLw() || !win.mPolicyVisibilityAfterAnim) {
422 continue;
423 }
424 int req = win.mAttrs.screenOrientation;
425 if(req == SCREEN_ORIENTATION_UNSPECIFIED || req == SCREEN_ORIENTATION_BEHIND) {
426 continue;
427 }
428
429 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, win + " forcing orientation to " + req);
430 if (policy.isKeyguardHostWindow(win.mAttrs)) {
431 mService.mLastKeyguardForcedOrientation = req;
432 }
433 return (mService.mLastWindowForcedOrientation = req);
434 }
435 mService.mLastWindowForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
436
437 if (policy.isKeyguardLocked()) {
438 // The screen is locked and no top system window is requesting an orientation.
439 // Return either the orientation of the show-when-locked app (if there is any) or
440 // the orientation of the keyguard. No point in searching from the rest of apps.
441 WindowState winShowWhenLocked = (WindowState) policy.getWinShowWhenLockedLw();
442 AppWindowToken appShowWhenLocked = winShowWhenLocked == null
443 ? null : winShowWhenLocked.mAppToken;
444 if (appShowWhenLocked != null) {
445 int req = appShowWhenLocked.getOrientation();
446 if (req == SCREEN_ORIENTATION_BEHIND) {
447 req = mService.mLastKeyguardForcedOrientation;
448 }
449 if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Done at " + appShowWhenLocked
450 + " -- show when locked, return " + req);
451 return req;
452 }
453 if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
454 "No one is requesting an orientation when the screen is locked");
455 return mService.mLastKeyguardForcedOrientation;
456 }
Wale Ogunwale51362492016-09-08 17:49:17 -0700457 }
458
Wale Ogunwalee6f806e2016-10-20 15:29:42 -0700459 // Top system windows are not requesting an orientation. Start searching from apps.
460 return mTaskStackContainers.getOrientation();
Wale Ogunwale51362492016-09-08 17:49:17 -0700461 }
462
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700463 void updateDisplayInfo() {
Craig Mautner722285e2012-09-07 13:55:58 -0700464 mDisplay.getDisplayInfo(mDisplayInfo);
Wale Ogunwale231b06e2015-09-16 12:03:09 -0700465 mDisplay.getMetrics(mDisplayMetrics);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700466 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
467 mTaskStackContainers.get(i).updateDisplayInfo(null);
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800468 }
Craig Mautner722285e2012-09-07 13:55:58 -0700469 }
470
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -0700471 void initializeDisplayBaseInfo() {
Wale Ogunwaleb699ce02016-07-18 12:05:30 -0700472 final DisplayManagerInternal displayManagerInternal = mService.mDisplayManagerInternal;
473 if (displayManagerInternal != null) {
474 // Bootstrap the default logical display from the display manager.
475 final DisplayInfo newDisplayInfo = displayManagerInternal.getDisplayInfo(mDisplayId);
476 if (newDisplayInfo != null) {
477 mDisplayInfo.copyFrom(newDisplayInfo);
478 }
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -0700479 }
Wale Ogunwaleb699ce02016-07-18 12:05:30 -0700480
Filip Gruszczynski608797e2015-11-12 19:08:20 -0800481 mBaseDisplayWidth = mInitialDisplayWidth = mDisplayInfo.logicalWidth;
482 mBaseDisplayHeight = mInitialDisplayHeight = mDisplayInfo.logicalHeight;
483 mBaseDisplayDensity = mInitialDisplayDensity = mDisplayInfo.logicalDensityDpi;
484 mBaseDisplayRect.set(0, 0, mBaseDisplayWidth, mBaseDisplayHeight);
Wale Ogunwalefd04d8c2015-09-30 10:09:39 -0700485 }
486
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700487 void getLogicalDisplayRect(Rect out) {
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700488 // Uses same calculation as in LogicalDisplay#configureDisplayInTransactionLocked.
Craig Mautner4a1cb222013-12-04 16:14:06 -0800489 final int orientation = mDisplayInfo.rotation;
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700490 boolean rotated = (orientation == ROTATION_90 || orientation == ROTATION_270);
Craig Mautner4a1cb222013-12-04 16:14:06 -0800491 final int physWidth = rotated ? mBaseDisplayHeight : mBaseDisplayWidth;
492 final int physHeight = rotated ? mBaseDisplayWidth : mBaseDisplayHeight;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700493 int width = mDisplayInfo.logicalWidth;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800494 int left = (physWidth - width) / 2;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700495 int height = mDisplayInfo.logicalHeight;
Craig Mautner4a1cb222013-12-04 16:14:06 -0800496 int top = (physHeight - height) / 2;
Craig Mautner46ac6fa2013-08-01 10:06:34 -0700497 out.set(left, top, left + width, top + height);
498 }
499
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700500 private void getLogicalDisplayRect(Rect out, int orientation) {
501 getLogicalDisplayRect(out);
502
503 // Rotate the Rect if needed.
504 final int currentRotation = mDisplayInfo.rotation;
505 final int rotationDelta = deltaRotation(currentRotation, orientation);
506 if (rotationDelta == ROTATION_90 || rotationDelta == ROTATION_270) {
507 createRotationMatrix(rotationDelta, mBaseDisplayWidth, mBaseDisplayHeight, mTmpMatrix);
508 mTmpRectF.set(out);
509 mTmpMatrix.mapRect(mTmpRectF);
510 mTmpRectF.round(out);
511 }
512 }
513
Chong Zhangf66db432016-01-13 10:39:51 -0800514 void getContentRect(Rect out) {
515 out.set(mContentRect);
516 }
517
Wale Ogunwaleddc1cb22015-07-25 19:23:04 -0700518 /** Refer to {@link WindowManagerService#attachStack(int, int, boolean)} */
519 void attachStack(TaskStack stack, boolean onTop) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700520 mTaskStackContainers.attachStack(stack, onTop);
Craig Mautnerc00204b2013-03-05 15:02:14 -0800521 }
522
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800523 void moveStack(TaskStack stack, boolean toTop) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700524 mTaskStackContainers.moveStack(stack, toTop);
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700525 }
Wale Ogunwale1e60e0c2015-10-28 13:36:10 -0700526
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700527 @Override
528 protected void addChild(DisplayChildWindowContainer child,
529 Comparator<DisplayChildWindowContainer> comparator) {
530 throw new UnsupportedOperationException("See DisplayChildWindowContainer");
531 }
Wale Ogunwale1e60e0c2015-10-28 13:36:10 -0700532
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700533 @Override
534 protected void addChild(DisplayChildWindowContainer child, int index) {
535 throw new UnsupportedOperationException("See DisplayChildWindowContainer");
536 }
537
538 @Override
539 protected void removeChild(DisplayChildWindowContainer child) {
Wale Ogunwale601a3f02016-10-17 08:39:39 -0700540 // Only allow removal of direct children from this display if the display is in the process
541 // of been removed.
542 if (mRemovingDisplay) {
543 super.removeChild(child);
544 return;
545 }
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700546 throw new UnsupportedOperationException("See DisplayChildWindowContainer");
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800547 }
548
549 /**
550 * Propagate the new bounds to all child stacks.
551 * @param contentRect The bounds to apply at the top level.
552 */
553 void resize(Rect contentRect) {
554 mContentRect.set(contentRect);
555 }
556
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700557 int taskIdFromPoint(int x, int y) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700558 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
559 final TaskStack stack = mTaskStackContainers.get(stackNdx);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700560 final int taskId = stack.taskIdFromPoint(x, y);
561 if (taskId != -1) {
562 return taskId;
Craig Mautner967212c2013-04-13 21:10:58 -0700563 }
564 }
Craig Mautnerbdc748af2013-12-02 14:08:25 -0800565 return -1;
Craig Mautnercf910b02013-04-23 11:23:27 -0700566 }
567
Chong Zhang8e89b312015-09-09 15:09:30 -0700568 /**
Chong Zhangd8ceb852015-11-11 14:53:41 -0800569 * Find the task whose outside touch area (for resizing) (x, y) falls within.
Chong Zhang9184ec62015-09-24 12:32:21 -0700570 * Returns null if the touch doesn't fall into a resizing area.
Chong Zhang8e89b312015-09-09 15:09:30 -0700571 */
Wale Ogunwale15ead902016-09-02 14:30:11 -0700572 Task findTaskForResizePoint(int x, int y) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700573 final int delta = dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700574 mTmpTaskForResizePointSearchResult.reset();
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700575 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
576 final TaskStack stack = mTaskStackContainers.get(stackNdx);
Wale Ogunwale3797c222015-10-27 14:21:58 -0700577 if (!StackId.isTaskResizeAllowed(stack.mStackId)) {
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700578 return null;
Chong Zhang8e89b312015-09-09 15:09:30 -0700579 }
Chong Zhang9184ec62015-09-24 12:32:21 -0700580
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700581 stack.findTaskForResizePoint(x, y, delta, mTmpTaskForResizePointSearchResult);
582 if (mTmpTaskForResizePointSearchResult.searchDone) {
583 return mTmpTaskForResizePointSearchResult.taskForResize;
Chong Zhang8e89b312015-09-09 15:09:30 -0700584 }
585 }
Chong Zhang9184ec62015-09-24 12:32:21 -0700586 return null;
Chong Zhang8e89b312015-09-09 15:09:30 -0700587 }
588
Wale Ogunwalee4a0c572015-06-30 08:40:31 -0700589 void setTouchExcludeRegion(Task focusedTask) {
Craig Mautner6601b7b2013-04-29 10:29:11 -0700590 mTouchExcludeRegion.set(mBaseDisplayRect);
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700591 final int delta = dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700592 mTmpRect2.setEmpty();
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700593 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
594 final TaskStack stack = mTaskStackContainers.get(stackNdx);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700595 stack.setTouchExcludeRegion(
596 focusedTask, delta, mTouchExcludeRegion, mContentRect, mTmpRect2);
Craig Mautner6601b7b2013-04-29 10:29:11 -0700597 }
Chong Zhangd8ceb852015-11-11 14:53:41 -0800598 // If we removed the focused task above, add it back and only leave its
599 // outside touch area in the exclusion. TapDectector is not interested in
600 // any touch inside the focused task itself.
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700601 if (!mTmpRect2.isEmpty()) {
Chong Zhangd8ceb852015-11-11 14:53:41 -0800602 mTouchExcludeRegion.op(mTmpRect2, Region.Op.UNION);
603 }
Filip Gruszczynski912d9192015-12-01 16:14:04 -0800604 final WindowState inputMethod = mService.mInputMethodWindow;
605 if (inputMethod != null && inputMethod.isVisibleLw()) {
606 // If the input method is visible and the user is typing, we don't want these touch
607 // events to be intercepted and used to change focus. This would likely cause a
608 // disappearance of the input method.
609 inputMethod.getTouchableRegion(mTmpRegion);
610 mTouchExcludeRegion.op(mTmpRegion, Region.Op.UNION);
611 }
Filip Gruszczynskiecf67222015-12-11 15:16:36 -0800612 for (int i = mTapExcludedWindows.size() - 1; i >= 0; i--) {
613 WindowState win = mTapExcludedWindows.get(i);
614 win.getTouchableRegion(mTmpRegion);
615 mTouchExcludeRegion.op(mTmpRegion, Region.Op.UNION);
616 }
Jorim Jaggid47e7e12016-03-01 09:57:38 +0100617 if (getDockedStackVisibleForUserLocked() != null) {
618 mDividerControllerLocked.getTouchRegion(mTmpRect);
Jorim Jaggi7f19cb82016-03-25 19:37:44 -0700619 mTmpRegion.set(mTmpRect);
Jorim Jaggid47e7e12016-03-01 09:57:38 +0100620 mTouchExcludeRegion.op(mTmpRegion, Op.UNION);
621 }
Craig Mautner1bef3892015-02-17 15:09:47 -0800622 if (mTapDetector != null) {
Chong Zhang2e2c81a2016-07-15 11:28:17 -0700623 mTapDetector.setTouchExcludeRegion(mTouchExcludeRegion);
Craig Mautner1bef3892015-02-17 15:09:47 -0800624 }
Craig Mautner6601b7b2013-04-29 10:29:11 -0700625 }
626
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700627 void switchUser() {
Craig Mautner858d8a62013-04-23 17:08:34 -0700628 final WindowList windows = getWindowList();
629 for (int i = 0; i < windows.size(); i++) {
630 final WindowState win = windows.get(i);
631 if (win.isHiddenFromUserLocked()) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800632 if (DEBUG_VISIBILITY) Slog.w(TAG_WM, "user changing, hiding " + win
Wale Ogunwale498e8c92015-02-13 09:42:46 -0800633 + ", attrs=" + win.mAttrs.type + ", belonging to " + win.mOwnerUid);
Craig Mautner858d8a62013-04-23 17:08:34 -0700634 win.hideLw(false);
635 }
636 }
Craig Mautnerac6f8432013-07-17 13:24:59 -0700637
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700638 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
639 mTaskStackContainers.get(stackNdx).switchUser();
Craig Mautner858d8a62013-04-23 17:08:34 -0700640 }
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700641
642 rebuildAppWindowList();
Craig Mautner858d8a62013-04-23 17:08:34 -0700643 }
644
Craig Mautner05d29032013-05-03 13:40:13 -0700645 void resetAnimationBackgroundAnimator() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700646 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
647 mTaskStackContainers.get(stackNdx).resetAnimationBackgroundAnimator();
Craig Mautner05d29032013-05-03 13:40:13 -0700648 }
649 }
650
651 boolean animateDimLayers() {
Chong Zhang112eb8c2015-11-02 11:17:00 -0800652 return mDimLayerController.animateDimLayers();
Craig Mautner05d29032013-05-03 13:40:13 -0700653 }
654
655 void resetDimming() {
Chong Zhang112eb8c2015-11-02 11:17:00 -0800656 mDimLayerController.resetDimming();
Craig Mautner05d29032013-05-03 13:40:13 -0700657 }
658
659 boolean isDimming() {
Chong Zhang112eb8c2015-11-02 11:17:00 -0800660 return mDimLayerController.isDimming();
Craig Mautner05d29032013-05-03 13:40:13 -0700661 }
662
663 void stopDimmingIfNeeded() {
Chong Zhang112eb8c2015-11-02 11:17:00 -0800664 mDimLayerController.stopDimmingIfNeeded();
Craig Mautner05d29032013-05-03 13:40:13 -0700665 }
666
Wale Ogunwale10124582016-09-15 20:25:50 -0700667 @Override
668 void removeIfPossible() {
669 if (isAnimating()) {
670 mDeferredRemoval = true;
671 return;
Craig Mautner2eb15342013-08-07 13:13:35 -0700672 }
Wale Ogunwale10124582016-09-15 20:25:50 -0700673 removeImmediately();
Craig Mautner2eb15342013-08-07 13:13:35 -0700674 }
675
Wale Ogunwale10124582016-09-15 20:25:50 -0700676 @Override
677 void removeImmediately() {
Wale Ogunwale601a3f02016-10-17 08:39:39 -0700678 mRemovingDisplay = true;
679 try {
680 super.removeImmediately();
681 if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Removing display=" + this);
682 mDimLayerController.close();
683 if (mDisplayId == DEFAULT_DISPLAY) {
684 mService.unregisterPointerEventListener(mTapDetector);
685 mService.unregisterPointerEventListener(mService.mMousePositionTracker);
686 }
687 } finally {
688 mRemovingDisplay = false;
Craig Mautner95da1082014-02-24 17:54:35 -0800689 }
Craig Mautner95da1082014-02-24 17:54:35 -0800690 }
691
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700692 /** Returns true if a removal action is still being deferred. */
Wale Ogunwale10124582016-09-15 20:25:50 -0700693 @Override
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700694 boolean checkCompleteDeferredRemoval() {
Wale Ogunwale10124582016-09-15 20:25:50 -0700695 final boolean stillDeferringRemoval = super.checkCompleteDeferredRemoval();
696
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700697 if (!stillDeferringRemoval && mDeferredRemoval) {
Wale Ogunwale10124582016-09-15 20:25:50 -0700698 removeImmediately();
Craig Mautner95da1082014-02-24 17:54:35 -0800699 mService.onDisplayRemoved(mDisplayId);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700700 return false;
Craig Mautner95da1082014-02-24 17:54:35 -0800701 }
Wale Ogunwale3f4433d2016-08-18 20:42:42 -0700702 return true;
Craig Mautner95da1082014-02-24 17:54:35 -0800703 }
704
Wale Ogunwale10124582016-09-15 20:25:50 -0700705 boolean animateForIme(float interpolatedValue, float animationTarget,
706 float dividerAnimationTarget) {
707 boolean updated = false;
708
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700709 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
710 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale10124582016-09-15 20:25:50 -0700711 if (stack == null || !stack.isAdjustedForIme()) {
712 continue;
713 }
714
715 if (interpolatedValue >= 1f && animationTarget == 0f && dividerAnimationTarget == 0f) {
716 stack.resetAdjustedForIme(true /* adjustBoundsNow */);
717 updated = true;
718 } else {
719 mDividerControllerLocked.mLastAnimationProgress =
720 mDividerControllerLocked.getInterpolatedAnimationValue(interpolatedValue);
721 mDividerControllerLocked.mLastDividerProgress =
722 mDividerControllerLocked.getInterpolatedDividerValue(interpolatedValue);
723 updated |= stack.updateAdjustForIme(
724 mDividerControllerLocked.mLastAnimationProgress,
725 mDividerControllerLocked.mLastDividerProgress,
726 false /* force */);
727 }
728 if (interpolatedValue >= 1f) {
729 stack.endImeAdjustAnimation();
730 }
731 }
732
733 return updated;
734 }
735
736 boolean clearImeAdjustAnimation() {
737 boolean changed = false;
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700738 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
739 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale10124582016-09-15 20:25:50 -0700740 if (stack != null && stack.isAdjustedForIme()) {
741 stack.resetAdjustedForIme(true /* adjustBoundsNow */);
742 changed = true;
743 }
744 }
745 return changed;
746 }
747
748 void beginImeAdjustAnimation() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700749 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
750 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale10124582016-09-15 20:25:50 -0700751 if (stack.isVisible() && stack.isAdjustedForIme()) {
752 stack.beginImeAdjustAnimation();
753 }
754 }
755 }
756
757 void adjustForImeIfNeeded() {
758 final WindowState imeWin = mService.mInputMethodWindow;
759 final boolean imeVisible = imeWin != null && imeWin.isVisibleLw() && imeWin.isDisplayedLw()
760 && !mDividerControllerLocked.isImeHideRequested();
761 final boolean dockVisible = mService.isStackVisibleLocked(DOCKED_STACK_ID);
762 final TaskStack imeTargetStack = mService.getImeFocusStackLocked();
763 final int imeDockSide = (dockVisible && imeTargetStack != null) ?
764 imeTargetStack.getDockSide() : DOCKED_INVALID;
765 final boolean imeOnTop = (imeDockSide == DOCKED_TOP);
766 final boolean imeOnBottom = (imeDockSide == DOCKED_BOTTOM);
767 final boolean dockMinimized = mDividerControllerLocked.isMinimizedDock();
768 final int imeHeight = mService.mPolicy.getInputMethodWindowVisibleHeightLw();
769 final boolean imeHeightChanged = imeVisible &&
770 imeHeight != mDividerControllerLocked.getImeHeightAdjustedFor();
771
772 // The divider could be adjusted for IME position, or be thinner than usual,
773 // or both. There are three possible cases:
774 // - If IME is visible, and focus is on top, divider is not moved for IME but thinner.
775 // - If IME is visible, and focus is on bottom, divider is moved for IME and thinner.
776 // - If IME is not visible, divider is not moved and is normal width.
777
778 if (imeVisible && dockVisible && (imeOnTop || imeOnBottom) && !dockMinimized) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700779 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
780 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale10124582016-09-15 20:25:50 -0700781 final boolean isDockedOnBottom = stack.getDockSide() == DOCKED_BOTTOM;
782 if (stack.isVisible() && (imeOnBottom || isDockedOnBottom)) {
783 stack.setAdjustedForIme(imeWin, imeOnBottom && imeHeightChanged);
784 } else {
785 stack.resetAdjustedForIme(false);
786 }
787 }
788 mDividerControllerLocked.setAdjustedForIme(
789 imeOnBottom /*ime*/, true /*divider*/, true /*animate*/, imeWin, imeHeight);
790 } else {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700791 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
792 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale10124582016-09-15 20:25:50 -0700793 stack.resetAdjustedForIme(!dockVisible);
794 }
795 mDividerControllerLocked.setAdjustedForIme(
796 false /*ime*/, false /*divider*/, dockVisible /*animate*/, imeWin, imeHeight);
797 }
Winson Chung655332c2016-10-31 13:14:28 -0700798 mPinnedStackControllerLocked.setAdjustedForIme(imeVisible, imeHeight);
Wale Ogunwale10124582016-09-15 20:25:50 -0700799 }
800
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700801 void setInputMethodAnimLayerAdjustment(int adj) {
802 if (DEBUG_LAYERS) Slog.v(TAG_WM, "Setting im layer adj to " + adj);
803 mInputMethodAnimLayerAdjustment = adj;
804 final WindowState imw = mService.mInputMethodWindow;
805 if (imw != null) {
806 imw.adjustAnimLayer(adj);
807 }
808 for (int i = mService.mInputMethodDialogs.size() - 1; i >= 0; i--) {
809 final WindowState dialog = mService.mInputMethodDialogs.get(i);
810 // TODO: This and other places setting mAnimLayer can probably use WS.adjustAnimLayer,
811 // but need to make sure we are not setting things twice for child windows that are
812 // already in the list.
813 dialog.mWinAnimator.mAnimLayer = dialog.mLayer + adj;
814 if (DEBUG_LAYERS) Slog.v(TAG_WM, "IM win " + imw
815 + " anim layer: " + dialog.mWinAnimator.mAnimLayer);
816 }
817 }
818
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -0700819 /**
820 * If a window that has an animation specifying a colored background and the current wallpaper
821 * is visible, then the color goes *below* the wallpaper so we don't cause the wallpaper to
822 * suddenly disappear.
823 */
824 int getLayerForAnimationBackground(WindowStateAnimator winAnimator) {
825 for (int i = mWindows.size() - 1; i >= 0; --i) {
826 final WindowState win = mWindows.get(i);
827 if (win.mIsWallpaper && win.isVisibleNow()) {
828 return win.mWinAnimator.mAnimLayer;
829 }
830 }
831 return winAnimator.mAnimLayer;
832 }
833
Wale Ogunwale10124582016-09-15 20:25:50 -0700834 void prepareFreezingTaskBounds() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700835 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
836 final TaskStack stack = mTaskStackContainers.get(stackNdx);
Wale Ogunwale10124582016-09-15 20:25:50 -0700837 stack.prepareFreezingTaskBounds();
838 }
839 }
840
Wale Ogunwale94744212015-09-21 19:01:47 -0700841 void rotateBounds(int oldRotation, int newRotation, Rect bounds) {
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700842 getLogicalDisplayRect(mTmpRect, newRotation);
843
844 // Compute a transform matrix to undo the coordinate space transformation,
845 // and present the window at the same physical position it previously occupied.
846 final int deltaRotation = deltaRotation(newRotation, oldRotation);
847 createRotationMatrix(deltaRotation, mTmpRect.width(), mTmpRect.height(), mTmpMatrix);
848
849 mTmpRectF.set(bounds);
850 mTmpMatrix.mapRect(mTmpRectF);
851 mTmpRectF.round(bounds);
Wale Ogunwale94744212015-09-21 19:01:47 -0700852 }
853
Wale Ogunwale4a02d812015-02-12 23:01:38 -0800854 static int deltaRotation(int oldRotation, int newRotation) {
855 int delta = newRotation - oldRotation;
856 if (delta < 0) delta += 4;
857 return delta;
858 }
859
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700860 private static void createRotationMatrix(int rotation, float displayWidth, float displayHeight,
Andrii Kulian4dfb9c42016-10-11 20:06:27 -0700861 Matrix outMatrix) {
862 // For rotations without Z-ordering we don't need the target rectangle's position.
863 createRotationMatrix(rotation, 0 /* rectLeft */, 0 /* rectTop */, displayWidth,
864 displayHeight, outMatrix);
865 }
866
867 static void createRotationMatrix(int rotation, float rectLeft, float rectTop,
868 float displayWidth, float displayHeight, Matrix outMatrix) {
869 switch (rotation) {
870 case ROTATION_0:
871 outMatrix.reset();
872 break;
873 case ROTATION_270:
874 outMatrix.setRotate(270, 0, 0);
875 outMatrix.postTranslate(0, displayHeight);
876 outMatrix.postTranslate(rectTop, 0);
877 break;
878 case ROTATION_180:
879 outMatrix.reset();
880 break;
881 case ROTATION_90:
882 outMatrix.setRotate(90, 0, 0);
883 outMatrix.postTranslate(displayWidth, 0);
884 outMatrix.postTranslate(-rectTop, rectLeft);
885 break;
886 }
887 }
888
Craig Mautnera91f9e22012-09-14 16:22:08 -0700889 public void dump(String prefix, PrintWriter pw) {
890 pw.print(prefix); pw.print("Display: mDisplayId="); pw.println(mDisplayId);
891 final String subPrefix = " " + prefix;
892 pw.print(subPrefix); pw.print("init="); pw.print(mInitialDisplayWidth); pw.print("x");
893 pw.print(mInitialDisplayHeight); pw.print(" "); pw.print(mInitialDisplayDensity);
894 pw.print("dpi");
895 if (mInitialDisplayWidth != mBaseDisplayWidth
896 || mInitialDisplayHeight != mBaseDisplayHeight
897 || mInitialDisplayDensity != mBaseDisplayDensity) {
898 pw.print(" base=");
899 pw.print(mBaseDisplayWidth); pw.print("x"); pw.print(mBaseDisplayHeight);
900 pw.print(" "); pw.print(mBaseDisplayDensity); pw.print("dpi");
901 }
Jeff Brownd46747a2015-04-15 19:02:36 -0700902 if (mDisplayScalingDisabled) {
903 pw.println(" noscale");
904 }
Craig Mautnera91f9e22012-09-14 16:22:08 -0700905 pw.print(" cur=");
906 pw.print(mDisplayInfo.logicalWidth);
907 pw.print("x"); pw.print(mDisplayInfo.logicalHeight);
908 pw.print(" app=");
909 pw.print(mDisplayInfo.appWidth);
910 pw.print("x"); pw.print(mDisplayInfo.appHeight);
911 pw.print(" rng="); pw.print(mDisplayInfo.smallestNominalAppWidth);
912 pw.print("x"); pw.print(mDisplayInfo.smallestNominalAppHeight);
913 pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth);
914 pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight);
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700915 pw.println(subPrefix + "deferred=" + mDeferredRemoval
916 + " mLayoutNeeded=" + mLayoutNeeded);
Wale Ogunwaleb429e682016-01-06 12:36:34 -0800917
Craig Mautnerdc548482014-02-05 13:35:24 -0800918 pw.println();
Craig Mautnere8b85fd2014-10-22 09:23:25 -0700919 pw.println(" Application tokens in top down Z order:");
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700920 for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
921 final TaskStack stack = mTaskStackContainers.get(stackNdx);
Wale Ogunwaleb429e682016-01-06 12:36:34 -0800922 stack.dump(prefix + " ", pw);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700923 }
Wale Ogunwaleb429e682016-01-06 12:36:34 -0800924
Craig Mautnerdc548482014-02-05 13:35:24 -0800925 pw.println();
926 if (!mExitingTokens.isEmpty()) {
Craig Mautnerde4ef022013-04-07 19:01:33 -0700927 pw.println();
928 pw.println(" Exiting tokens:");
Wale Ogunwaleb429e682016-01-06 12:36:34 -0800929 for (int i = mExitingTokens.size() - 1; i >= 0; i--) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700930 final WindowToken token = mExitingTokens.get(i);
Craig Mautnerde4ef022013-04-07 19:01:33 -0700931 pw.print(" Exiting #"); pw.print(i);
932 pw.print(' '); pw.print(token);
933 pw.println(':');
934 token.dump(pw, " ");
Craig Mautnerb1fd65c02013-02-05 13:34:57 -0800935 }
Craig Mautnerde4ef022013-04-07 19:01:33 -0700936 }
Craig Mautner59c00972012-07-30 12:10:24 -0700937 pw.println();
Chong Zhang112eb8c2015-11-02 11:17:00 -0800938 mDimLayerController.dump(prefix + " ", pw);
Jorim Jaggi31f71702016-05-04 16:43:04 -0700939 pw.println();
940 mDividerControllerLocked.dump(prefix + " ", pw);
Winson Chung655332c2016-10-31 13:14:28 -0700941 pw.println();
942 mPinnedStackControllerLocked.dump(prefix + " ", pw);
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700943
944 if (mInputMethodAnimLayerAdjustment != 0) {
945 pw.println(subPrefix
946 + "mInputMethodAnimLayerAdjustment=" + mInputMethodAnimLayerAdjustment);
947 }
Craig Mautner59c00972012-07-30 12:10:24 -0700948 }
Craig Mautnere0a38842013-12-16 16:14:02 -0800949
950 @Override
951 public String toString() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700952 return "Display " + mDisplayId + " info=" + mDisplayInfo + " stacks=" + mChildren;
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700953 }
954
955 String getName() {
Wale Ogunwale19e452e2016-10-12 12:36:29 -0700956 return "Display " + mDisplayId + " name=\"" + mDisplayInfo.name + "\"";
Craig Mautnere0a38842013-12-16 16:14:02 -0800957 }
Filip Gruszczynski466f3212015-09-21 17:57:57 -0700958
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800959 /**
960 * @return The docked stack, but only if it is visible, and {@code null} otherwise.
961 */
Filip Gruszczynski3ddc5d62015-09-23 15:01:30 -0700962 TaskStack getDockedStackLocked() {
Wale Ogunwalee45899a2015-10-01 11:30:34 -0700963 final TaskStack stack = mService.mStackIdToStack.get(DOCKED_STACK_ID);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700964 return (stack != null && stack.isVisible()) ? stack : null;
Filip Gruszczynski466f3212015-09-21 17:57:57 -0700965 }
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -0800966
967 /**
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800968 * Like {@link #getDockedStackLocked}, but also returns the docked stack if it's currently not
969 * visible, as long as it's not hidden because the current user doesn't have any tasks there.
970 */
971 TaskStack getDockedStackVisibleForUserLocked() {
972 final TaskStack stack = mService.mStackIdToStack.get(DOCKED_STACK_ID);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700973 return (stack != null && stack.isVisible(true /* ignoreKeyguard */)) ? stack : null;
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800974 }
975
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700976 /** Find the visible, touch-deliverable window under the given point */
Vladislav Kaznacheev5d6bdeb2016-02-12 17:07:20 -0800977 WindowState getTouchableWinAtPointLocked(float xf, float yf) {
978 WindowState touchedWin = null;
979 final int x = (int) xf;
980 final int y = (int) yf;
981
982 for (int i = mWindows.size() - 1; i >= 0; i--) {
983 WindowState window = mWindows.get(i);
984 final int flags = window.mAttrs.flags;
985 if (!window.isVisibleLw()) {
986 continue;
987 }
988 if ((flags & FLAG_NOT_TOUCHABLE) != 0) {
989 continue;
990 }
991
992 window.getVisibleBounds(mTmpRect);
993 if (!mTmpRect.contains(x, y)) {
994 continue;
995 }
996
997 window.getTouchableRegion(mTmpRegion);
998
999 final int touchFlags = flags & (FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL);
1000 if (mTmpRegion.contains(x, y) || touchFlags == 0) {
1001 touchedWin = window;
1002 break;
1003 }
1004 }
1005
1006 return touchedWin;
1007 }
Jorim Jaggi6626f542016-08-22 13:08:44 -07001008
Svetoslav Ganovaa076532016-08-01 19:16:43 -07001009 boolean canAddToastWindowForUid(int uid) {
1010 // We allow one toast window per UID being shown at a time.
1011 WindowList windows = getWindowList();
1012 final int windowCount = windows.size();
1013 for (int i = 0; i < windowCount; i++) {
1014 WindowState window = windows.get(i);
1015 if (window.mAttrs.type == TYPE_TOAST && window.mOwnerUid == uid
Svet Ganov62a40f82016-09-29 00:43:51 -07001016 && !window.mPermanentlyHidden && !window.mAnimatingExit
1017 && !window.mRemoveOnExit) {
Svetoslav Ganovaa076532016-08-01 19:16:43 -07001018 return false;
1019 }
1020 }
1021 return true;
1022 }
1023
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001024 void scheduleToastWindowsTimeoutIfNeededLocked(WindowState oldFocus, WindowState newFocus) {
Svetoslav Ganovaa076532016-08-01 19:16:43 -07001025 if (oldFocus == null || (newFocus != null && newFocus.mOwnerUid == oldFocus.mOwnerUid)) {
1026 return;
1027 }
1028 final int lostFocusUid = oldFocus.mOwnerUid;
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001029 final WindowList windows = getWindowList();
Svetoslav Ganovaa076532016-08-01 19:16:43 -07001030 final int windowCount = windows.size();
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001031 final Handler handler = mService.mH;
Svetoslav Ganovaa076532016-08-01 19:16:43 -07001032 for (int i = 0; i < windowCount; i++) {
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001033 final WindowState window = windows.get(i);
Svetoslav Ganovaa076532016-08-01 19:16:43 -07001034 if (window.mAttrs.type == TYPE_TOAST && window.mOwnerUid == lostFocusUid) {
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -07001035 if (!handler.hasMessages(WINDOW_HIDE_TIMEOUT, window)) {
1036 handler.sendMessageDelayed(handler.obtainMessage(WINDOW_HIDE_TIMEOUT, window),
Svetoslav Ganovaa076532016-08-01 19:16:43 -07001037 window.mAttrs.hideTimeoutMilliseconds);
1038 }
1039 }
1040 }
1041 }
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -07001042
1043 WindowState findFocusedWindow() {
1044 final AppWindowToken focusedApp = mService.mFocusedApp;
1045
1046 for (int i = mWindows.size() - 1; i >= 0; i--) {
1047 final WindowState win = mWindows.get(i);
1048
1049 if (DEBUG_FOCUS) Slog.v(TAG_WM, "Looking for focus: " + i + " = " + win
1050 + ", flags=" + win.mAttrs.flags + ", canReceive=" + win.canReceiveKeys());
1051
1052 if (!win.canReceiveKeys()) {
1053 continue;
1054 }
1055
1056 final AppWindowToken wtoken = win.mAppToken;
1057
1058 // If this window's application has been removed, just skip it.
1059 if (wtoken != null && (wtoken.removed || wtoken.sendingToBottom)) {
1060 if (DEBUG_FOCUS) Slog.v(TAG_WM, "Skipping " + wtoken + " because "
1061 + (wtoken.removed ? "removed" : "sendingToBottom"));
1062 continue;
1063 }
1064
1065 if (focusedApp == null) {
1066 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp=null"
1067 + " using new focus @ " + i + " = " + win);
1068 return win;
1069 }
1070
1071 if (!focusedApp.windowsAreFocusable()) {
1072 // Current focused app windows aren't focusable...
1073 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp windows not"
1074 + " focusable using new focus @ " + i + " = " + win);
1075 return win;
1076 }
1077
1078 // Descend through all of the app tokens and find the first that either matches
1079 // win.mAppToken (return win) or mFocusedApp (return null).
1080 if (wtoken != null && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
Wale Ogunwale10124582016-09-15 20:25:50 -07001081 if (focusedApp.compareTo(wtoken) > 0) {
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -07001082 // App stack below focused app stack. No focus for you!!!
1083 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM,
1084 "findFocusedWindow: Reached focused app=" + focusedApp);
1085 return null;
1086 }
1087 }
1088
1089 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: Found new focus @ "
1090 + i + " = " + win);
1091 return win;
1092 }
1093
1094 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: No focusable windows.");
1095 return null;
1096 }
Wale Ogunwaleec731152016-09-08 20:18:57 -07001097
Wale Ogunwale07bcab72016-10-14 15:30:09 -07001098 void addAppWindowToWindowList(final WindowState win) {
Wale Ogunwaleec731152016-09-08 20:18:57 -07001099 final IWindow client = win.mClient;
1100
1101 WindowList tokenWindowList = getTokenWindowsOnDisplay(win.mToken);
1102 if (!tokenWindowList.isEmpty()) {
Wale Ogunwale07bcab72016-10-14 15:30:09 -07001103 addAppWindowExisting(win, tokenWindowList);
1104 return;
Wale Ogunwaleec731152016-09-08 20:18:57 -07001105 }
1106
1107 // No windows from this token on this display
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001108 if (localLOGV) Slog.v(TAG_WM, "Figuring out where to add app window "
Wale Ogunwaleec731152016-09-08 20:18:57 -07001109 + client.asBinder() + " (token=" + this + ")");
1110
1111 final WindowToken wToken = win.mToken;
1112
1113 // Figure out where the window should go, based on the order of applications.
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001114 mTmpGetWindowOnDisplaySearchResult.reset();
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001115 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
1116 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001117 stack.getWindowOnDisplayBeforeToken(this, wToken, mTmpGetWindowOnDisplaySearchResult);
1118 if (mTmpGetWindowOnDisplaySearchResult.reachedToken) {
Wale Ogunwaleec731152016-09-08 20:18:57 -07001119 // We have reach the token we are interested in. End search.
1120 break;
1121 }
1122 }
1123
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001124 WindowState pos = mTmpGetWindowOnDisplaySearchResult.foundWindow;
Wale Ogunwaleec731152016-09-08 20:18:57 -07001125
1126 // We now know the index into the apps. If we found an app window above, that gives us the
1127 // position; else we need to look some more.
1128 if (pos != null) {
1129 // Move behind any windows attached to this one.
Wale Ogunwale02319a62016-09-26 15:21:22 -07001130 final WindowToken atoken = getWindowToken(pos.mClient.asBinder());
Wale Ogunwaleec731152016-09-08 20:18:57 -07001131 if (atoken != null) {
1132 tokenWindowList = getTokenWindowsOnDisplay(atoken);
1133 final int NC = tokenWindowList.size();
1134 if (NC > 0) {
1135 WindowState bottom = tokenWindowList.get(0);
1136 if (bottom.mSubLayer < 0) {
1137 pos = bottom;
1138 }
1139 }
1140 }
1141 addWindowToListBefore(win, pos);
Wale Ogunwale07bcab72016-10-14 15:30:09 -07001142 return;
Wale Ogunwaleec731152016-09-08 20:18:57 -07001143 }
1144
1145 // Continue looking down until we find the first token that has windows on this display.
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001146 mTmpGetWindowOnDisplaySearchResult.reset();
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001147 for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
1148 final TaskStack stack = mTaskStackContainers.get(i);
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001149 stack.getWindowOnDisplayAfterToken(this, wToken, mTmpGetWindowOnDisplaySearchResult);
1150 if (mTmpGetWindowOnDisplaySearchResult.foundWindow != null) {
Wale Ogunwaleec731152016-09-08 20:18:57 -07001151 // We have found a window after the token. End search.
1152 break;
1153 }
1154 }
1155
Wale Ogunwale3f4433d2016-08-18 20:42:42 -07001156 pos = mTmpGetWindowOnDisplaySearchResult.foundWindow;
Wale Ogunwaleec731152016-09-08 20:18:57 -07001157
1158 if (pos != null) {
1159 // Move in front of any windows attached to this one.
Wale Ogunwale02319a62016-09-26 15:21:22 -07001160 final WindowToken atoken = getWindowToken(pos.mClient.asBinder());
Wale Ogunwaleec731152016-09-08 20:18:57 -07001161 if (atoken != null) {
1162 final WindowState top = atoken.getTopWindow();
1163 if (top != null && top.mSubLayer >= 0) {
1164 pos = top;
1165 }
1166 }
1167 addWindowToListAfter(win, pos);
Wale Ogunwale07bcab72016-10-14 15:30:09 -07001168 return;
Wale Ogunwaleec731152016-09-08 20:18:57 -07001169 }
1170
1171 // Just search for the start of this layer.
1172 final int myLayer = win.mBaseLayer;
1173 int i;
1174 for (i = mWindows.size() - 1; i >= 0; --i) {
1175 final WindowState w = mWindows.get(i);
1176 // Dock divider shares the base layer with application windows, but we want to always
1177 // keep it above the application windows. The sharing of the base layer is intended
1178 // for window animations, which need to be above the dock divider for the duration
1179 // of the animation.
1180 if (w.mBaseLayer <= myLayer && w.mAttrs.type != TYPE_DOCK_DIVIDER) {
1181 break;
1182 }
1183 }
1184 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1185 "Based on layer: Adding window " + win + " at " + (i + 1) + " of "
1186 + mWindows.size());
1187 mWindows.add(i + 1, win);
1188 mService.mWindowsChanged = true;
Wale Ogunwaleec731152016-09-08 20:18:57 -07001189 }
1190
1191 /** Adds this non-app window to the window list. */
1192 void addNonAppWindowToWindowList(WindowState win) {
1193 // Figure out where window should go, based on layer.
1194 int i;
1195 for (i = mWindows.size() - 1; i >= 0; i--) {
1196 final WindowState otherWin = mWindows.get(i);
1197 if (otherWin.getBaseType() != TYPE_WALLPAPER && otherWin.mBaseLayer <= win.mBaseLayer) {
1198 // Wallpaper wanders through the window list, for example to position itself
1199 // directly behind keyguard. Because of this it will break the ordering based on
1200 // WindowState.mBaseLayer. There might windows with higher mBaseLayer behind it and
1201 // we don't want the new window to appear above them. An example of this is adding
1202 // of the docked stack divider. Consider a scenario with the following ordering (top
1203 // to bottom): keyguard, wallpaper, assist preview, apps. We want the dock divider
1204 // to land below the assist preview, so the dock divider must ignore the wallpaper,
1205 // with which it shares the base layer.
1206 break;
1207 }
1208 }
1209
1210 i++;
1211 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1212 "Free window: Adding window " + this + " at " + i + " of " + mWindows.size());
1213 mWindows.add(i, win);
1214 mService.mWindowsChanged = true;
1215 }
1216
Wale Ogunwaleb9a07c32016-10-12 14:55:56 -07001217 void addToWindowList(WindowState win, int index) {
1218 mWindows.add(index, win);
1219 }
1220
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07001221 boolean removeFromWindowList(WindowState win) {
1222 return mWindows.remove(win);
1223 }
1224
1225 private int removeWindowAndChildrenFromWindowList(WindowState win, int interestingPos) {
1226 final WindowList windows = getWindowList();
1227 int wpos = windows.indexOf(win);
1228 if (wpos < 0) {
1229 return interestingPos;
1230 }
1231
1232 if (wpos < interestingPos) interestingPos--;
1233 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Temp removing at " + wpos + ": " + this);
1234 windows.remove(wpos);
1235 mService.mWindowsChanged = true;
1236 int childWinCount = win.mChildren.size();
1237 while (childWinCount > 0) {
1238 childWinCount--;
1239 final WindowState cw = win.mChildren.get(childWinCount);
1240 int cpos = windows.indexOf(cw);
1241 if (cpos >= 0) {
1242 if (cpos < interestingPos) interestingPos--;
1243 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM,
1244 "Temp removing child at " + cpos + ": " + cw);
1245 windows.remove(cpos);
1246 }
1247 }
1248 return interestingPos;
1249 }
1250
Wale Ogunwaleec731152016-09-08 20:18:57 -07001251 void addChildWindowToWindowList(WindowState win) {
1252 final WindowState parentWindow = win.getParentWindow();
1253
1254 WindowList windowsOnSameDisplay = getTokenWindowsOnDisplay(win.mToken);
1255
1256 // Figure out this window's ordering relative to the parent window.
1257 final int wCount = windowsOnSameDisplay.size();
1258 final int sublayer = win.mSubLayer;
1259 int largestSublayer = Integer.MIN_VALUE;
1260 WindowState windowWithLargestSublayer = null;
1261 int i;
1262 for (i = 0; i < wCount; i++) {
1263 WindowState w = windowsOnSameDisplay.get(i);
1264 final int wSublayer = w.mSubLayer;
1265 if (wSublayer >= largestSublayer) {
1266 largestSublayer = wSublayer;
1267 windowWithLargestSublayer = w;
1268 }
1269 if (sublayer < 0) {
1270 // For negative sublayers, we go below all windows in the same sublayer.
1271 if (wSublayer >= sublayer) {
1272 addWindowToListBefore(win, wSublayer >= 0 ? parentWindow : w);
1273 break;
1274 }
1275 } else {
1276 // For positive sublayers, we go above all windows in the same sublayer.
1277 if (wSublayer > sublayer) {
1278 addWindowToListBefore(win, w);
1279 break;
1280 }
1281 }
1282 }
1283 if (i >= wCount) {
1284 if (sublayer < 0) {
1285 addWindowToListBefore(win, parentWindow);
1286 } else {
1287 addWindowToListAfter(win,
1288 largestSublayer >= 0 ? windowWithLargestSublayer : parentWindow);
1289 }
1290 }
1291 }
1292
Wale Ogunwalec69694a2016-10-18 13:51:15 -07001293 /** Updates the layer assignment of windows on this display. */
1294 void assignWindowLayers(boolean setLayoutNeeded) {
1295 mLayersController.assignWindowLayers(mWindows);
1296 if (setLayoutNeeded) {
1297 setLayoutNeeded();
1298 }
1299 }
1300
Wale Ogunwale0303c572016-10-20 10:16:29 -07001301 void adjustWallpaperWindows() {
1302 if (mWallpaperController.adjustWallpaperWindows(mWindows)) {
1303 assignWindowLayers(true /*setLayoutNeeded*/);
1304 }
1305 }
1306
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001307 /**
1308 * Z-orders the display window list so that:
1309 * <ul>
1310 * <li>Any windows that are currently below the wallpaper window stay below the wallpaper
1311 * window.
1312 * <li>Exiting application windows are at the bottom, but above the wallpaper window.
1313 * <li>All other application windows are above the exiting application windows and ordered based
1314 * on the ordering of their stacks and tasks on the display.
1315 * <li>Non-application windows are at the very top.
1316 * </ul>
1317 * <p>
1318 * NOTE: This isn't a complete picture of what the user see. Further manipulation of the window
1319 * surface layering is done in {@link WindowLayersController}.
1320 */
1321 void rebuildAppWindowList() {
1322 int count = mWindows.size();
1323 int i;
1324 int lastBelow = -1;
1325 int numRemoved = 0;
1326
1327 if (mRebuildTmp.length < count) {
1328 mRebuildTmp = new WindowState[count + 10];
1329 }
1330
1331 // First remove all existing app windows.
1332 i = 0;
1333 while (i < count) {
1334 final WindowState w = mWindows.get(i);
1335 if (w.mAppToken != null) {
1336 final WindowState win = mWindows.remove(i);
1337 win.mRebuilding = true;
1338 mRebuildTmp[numRemoved] = win;
1339 mService.mWindowsChanged = true;
1340 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Rebuild removing window: " + win);
1341 count--;
1342 numRemoved++;
1343 continue;
1344 } else if (lastBelow == i-1) {
1345 if (w.mAttrs.type == TYPE_WALLPAPER) {
1346 lastBelow = i;
1347 }
1348 }
1349 i++;
1350 }
1351
1352 // Keep whatever windows were below the app windows still below, by skipping them.
1353 lastBelow++;
1354 i = lastBelow;
1355
1356 // First add all of the exiting app tokens... these are no longer in the main app list,
1357 // but still have windows shown. We put them in the back because now that the animation is
1358 // over we no longer will care about them.
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001359 final int numStacks = mTaskStackContainers.size();
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001360 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001361 AppTokenList exitingAppTokens = mTaskStackContainers.get(stackNdx).mExitingAppTokens;
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001362 int NT = exitingAppTokens.size();
1363 for (int j = 0; j < NT; j++) {
Wale Ogunwale360a8bc2016-10-10 13:25:26 -07001364 i = exitingAppTokens.get(j).rebuildWindowListUnchecked(i);
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001365 }
1366 }
1367
1368 // And add in the still active app tokens in Z order.
1369 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001370 i = mTaskStackContainers.get(stackNdx).rebuildWindowList(i);
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001371 }
1372
1373 i -= lastBelow;
1374 if (i != numRemoved) {
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001375 setLayoutNeeded();
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001376 Slog.w(TAG_WM, "On display=" + mDisplayId + " Rebuild removed " + numRemoved
1377 + " windows but added " + i + " rebuildAppWindowListLocked() "
1378 + " callers=" + Debug.getCallers(10));
1379 for (i = 0; i < numRemoved; i++) {
1380 WindowState ws = mRebuildTmp[i];
1381 if (ws.mRebuilding) {
1382 StringWriter sw = new StringWriter();
1383 PrintWriter pw = new FastPrintWriter(sw, false, 1024);
1384 ws.dump(pw, "", true);
1385 pw.flush();
1386 Slog.w(TAG_WM, "This window was lost: " + ws);
1387 Slog.w(TAG_WM, sw.toString());
1388 ws.mWinAnimator.destroySurfaceLocked();
1389 }
1390 }
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07001391 Slog.w(TAG_WM, "Current window hierarchy:");
Wale Ogunwale9adfe572016-09-08 20:43:58 -07001392 dumpChildrenNames();
1393 Slog.w(TAG_WM, "Final window list:");
1394 dumpWindows();
1395 }
1396 Arrays.fill(mRebuildTmp, null);
1397 }
1398
Wale Ogunwaleec731152016-09-08 20:18:57 -07001399 /** Return the list of Windows on this display associated with the input token. */
1400 WindowList getTokenWindowsOnDisplay(WindowToken token) {
1401 final WindowList windowList = new WindowList();
1402 final int count = mWindows.size();
1403 for (int i = 0; i < count; i++) {
1404 final WindowState win = mWindows.get(i);
1405 if (win.mToken == token) {
1406 windowList.add(win);
1407 }
1408 }
1409 return windowList;
1410 }
1411
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -07001412 private void reAddToWindowList(WindowState win) {
1413 win.mToken.addWindow(win);
1414 // This is a hack to get all of the child windows added as well at the right position. Child
1415 // windows should be rare and this case should be rare, so it shouldn't be that big a deal.
1416 int wpos = mWindows.indexOf(win);
1417 if (wpos >= 0) {
1418 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "ReAdd removing from " + wpos + ": " + win);
1419 mWindows.remove(wpos);
1420 mService.mWindowsChanged = true;
1421 win.reAddWindow(wpos);
1422 }
1423 }
1424
1425 void moveInputMethodDialogs(int pos) {
1426 ArrayList<WindowState> dialogs = mService.mInputMethodDialogs;
1427
1428 final int N = dialogs.size();
1429 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Removing " + N + " dialogs w/pos=" + pos);
1430 for (int i = 0; i < N; i++) {
1431 pos = removeWindowAndChildrenFromWindowList(dialogs.get(i), pos);
1432 }
1433 if (DEBUG_INPUT_METHOD) {
1434 Slog.v(TAG_WM, "Window list w/pos=" + pos);
1435 logWindowList(mWindows, " ");
1436 }
1437
1438 WindowState ime = mService.mInputMethodWindow;
1439 if (pos >= 0) {
1440 // Skip windows owned by the input method.
1441 if (ime != null) {
1442 while (pos < mWindows.size()) {
1443 WindowState wp = mWindows.get(pos);
1444 if (wp == ime || wp.getParentWindow() == ime) {
1445 pos++;
1446 continue;
1447 }
1448 break;
1449 }
1450 }
1451 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Adding " + N + " dialogs at pos=" + pos);
1452 for (int i=0; i<N; i++) {
1453 WindowState win = dialogs.get(i);
1454 pos = win.reAddWindow(pos);
1455 }
1456 if (DEBUG_INPUT_METHOD) {
1457 Slog.v(TAG_WM, "Final window list:");
1458 logWindowList(mWindows, " ");
1459 }
1460 return;
1461 }
1462 for (int i=0; i<N; i++) {
1463 WindowState win = dialogs.get(i);
1464 reAddToWindowList(win);
1465 if (DEBUG_INPUT_METHOD) {
1466 Slog.v(TAG_WM, "No IM target, final list:");
1467 logWindowList(mWindows, " ");
1468 }
1469 }
1470 }
1471
1472 boolean moveInputMethodWindowsIfNeeded(boolean needAssignLayers) {
1473 final WindowState imWin = mService.mInputMethodWindow;
1474 final int DN = mService.mInputMethodDialogs.size();
1475 if (imWin == null && DN == 0) {
1476 return false;
1477 }
1478
1479 // TODO(multidisplay): IMEs are only supported on the default display.
1480 WindowList windows = mWindows;
1481
1482 int imPos = findDesiredInputMethodWindowIndex(true);
1483 if (imPos >= 0) {
1484 // In this case, the input method windows are to be placed
1485 // immediately above the window they are targeting.
1486
1487 // First check to see if the input method windows are already
1488 // located here, and contiguous.
1489 final int N = windows.size();
1490 final WindowState firstImWin = imPos < N ? windows.get(imPos) : null;
1491
1492 // Figure out the actual input method window that should be
1493 // at the bottom of their stack.
1494 WindowState baseImWin = imWin != null ? imWin : mService.mInputMethodDialogs.get(0);
1495 final WindowState cw = baseImWin.getBottomChild();
1496 if (cw != null && cw.mSubLayer < 0) {
1497 baseImWin = cw;
1498 }
1499
1500 if (firstImWin == baseImWin) {
1501 // The windows haven't moved... but are they still contiguous?
1502 // First find the top IM window.
1503 int pos = imPos+1;
1504 while (pos < N) {
1505 if (!(windows.get(pos)).mIsImWindow) {
1506 break;
1507 }
1508 pos++;
1509 }
1510 pos++;
1511 // Now there should be no more input method windows above.
1512 while (pos < N) {
1513 if ((windows.get(pos)).mIsImWindow) {
1514 break;
1515 }
1516 pos++;
1517 }
1518 if (pos >= N) {
1519 return false;
1520 }
1521 }
1522
1523 if (imWin != null) {
1524 if (DEBUG_INPUT_METHOD) {
1525 Slog.v(TAG_WM, "Moving IM from " + imPos);
1526 logWindowList(windows, " ");
1527 }
1528 imPos = removeWindowAndChildrenFromWindowList(imWin, imPos);
1529 if (DEBUG_INPUT_METHOD) {
1530 Slog.v(TAG_WM, "List after removing with new pos " + imPos + ":");
1531 logWindowList(windows, " ");
1532 }
1533 imWin.reAddWindow(imPos);
1534 if (DEBUG_INPUT_METHOD) {
1535 Slog.v(TAG_WM, "List after moving IM to " + imPos + ":");
1536 logWindowList(windows, " ");
1537 }
1538 if (DN > 0) moveInputMethodDialogs(imPos+1);
1539 } else {
1540 moveInputMethodDialogs(imPos);
1541 }
1542
1543 } else {
1544 // In this case, the input method windows go in a fixed layer,
1545 // because they aren't currently associated with a focus window.
1546
1547 if (imWin != null) {
1548 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Moving IM from " + imPos);
1549 removeWindowAndChildrenFromWindowList(imWin, 0);
1550 reAddToWindowList(imWin);
1551 if (DEBUG_INPUT_METHOD) {
1552 Slog.v(TAG_WM, "List with no IM target:");
1553 logWindowList(windows, " ");
1554 }
1555 if (DN > 0) moveInputMethodDialogs(-1);
1556 } else {
1557 moveInputMethodDialogs(-1);
1558 }
1559
1560 }
1561
1562 if (needAssignLayers) {
1563 assignWindowLayers(false /* setLayoutNeeded */);
1564 }
1565
1566 return true;
1567 }
1568
1569 /**
1570 * Dig through the WindowStates and find the one that the Input Method will target.
1571 * @param willMove
1572 * @return The index+1 in mWindows of the discovered target.
1573 */
1574 int findDesiredInputMethodWindowIndex(boolean willMove) {
1575 // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the
1576 // same display. Or even when the current IME/target are not on the same screen as the next
1577 // IME/target. For now only look for input windows on the main screen.
1578 final WindowList windows = getWindowList();
1579 WindowState w = null;
1580 int i;
1581 for (i = windows.size() - 1; i >= 0; --i) {
1582 WindowState win = windows.get(i);
1583
1584 if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG_WM, "Checking window @" + i
1585 + " " + win + " fl=0x" + Integer.toHexString(win.mAttrs.flags));
1586 if (canBeImeTarget(win)) {
1587 w = win;
1588 //Slog.i(TAG_WM, "Putting input method here!");
1589
1590 // Yet more tricksyness! If this window is a "starting" window, we do actually want
1591 // to be on top of it, but it is not -really- where input will go. So if the caller
1592 // is not actually looking to move the IME, look down below for a real window to
1593 // target...
1594 if (!willMove && w.mAttrs.type == TYPE_APPLICATION_STARTING && i > 0) {
1595 WindowState wb = windows.get(i-1);
1596 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
1597 i--;
1598 w = wb;
1599 }
1600 }
1601 break;
1602 }
1603 }
1604
1605 // Now w is either mWindows[0] or an IME (or null if mWindows is empty).
1606
1607 if (DEBUG_INPUT_METHOD && willMove) Slog.v(TAG_WM, "Proposed new IME target: " + w);
1608
1609 // Now, a special case -- if the last target's window is in the process of exiting, and is
1610 // above the new target, keep on the last target to avoid flicker. Consider for example a
1611 // Dialog with the IME shown: when the Dialog is dismissed, we want to keep the IME above it
1612 // until it is completely gone so it doesn't drop behind the dialog or its full-screen
1613 // scrim.
1614 final WindowState curTarget = mService.mInputMethodTarget;
1615 if (curTarget != null
1616 && curTarget.isDisplayedLw()
1617 && curTarget.isClosing()
1618 && (w == null || curTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer)) {
1619 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Current target higher, not changing");
1620 return windows.indexOf(curTarget) + 1;
1621 }
1622
1623 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Desired input method target="
1624 + w + " willMove=" + willMove);
1625
1626 if (willMove && w != null) {
1627 AppWindowToken token = curTarget == null ? null : curTarget.mAppToken;
1628 if (token != null) {
1629
1630 // Now some fun for dealing with window animations that modify the Z order. We need
1631 // to look at all windows below the current target that are in this app, finding the
1632 // highest visible one in layering.
1633 WindowState highestTarget = null;
1634 int highestPos = 0;
1635 if (token.mAppAnimator.animating || token.mAppAnimator.animation != null) {
1636 WindowList curWindows = token.getDisplayContent().getWindowList();
1637 int pos = curWindows.indexOf(curTarget);
1638 while (pos >= 0) {
1639 WindowState win = curWindows.get(pos);
1640 if (win.mAppToken != token) {
1641 break;
1642 }
1643 if (!win.mRemoved) {
1644 if (highestTarget == null || win.mWinAnimator.mAnimLayer >
1645 highestTarget.mWinAnimator.mAnimLayer) {
1646 highestTarget = win;
1647 highestPos = pos;
1648 }
1649 }
1650 pos--;
1651 }
1652 }
1653
1654 if (highestTarget != null) {
1655 final AppTransition appTransition = mService.mAppTransition;
1656 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, appTransition + " " + highestTarget
1657 + " animating=" + highestTarget.mWinAnimator.isAnimationSet()
1658 + " layer=" + highestTarget.mWinAnimator.mAnimLayer
1659 + " new layer=" + w.mWinAnimator.mAnimLayer);
1660
1661 if (appTransition.isTransitionSet()) {
1662 // If we are currently setting up for an animation, hold everything until we
1663 // can find out what will happen.
1664 mService.mInputMethodTargetWaitingAnim = true;
1665 mService.mInputMethodTarget = highestTarget;
1666 return highestPos + 1;
1667 } else if (highestTarget.mWinAnimator.isAnimationSet() &&
1668 highestTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
1669 // If the window we are currently targeting is involved with an animation,
1670 // and it is on top of the next target we will be over, then hold off on
1671 // moving until that is done.
1672 mService.mInputMethodTargetWaitingAnim = true;
1673 mService.mInputMethodTarget = highestTarget;
1674 return highestPos + 1;
1675 }
1676 }
1677 }
1678 }
1679
1680 //Slog.i(TAG_WM, "Placing input method @" + (i+1));
1681 if (w != null) {
1682 if (willMove) {
1683 if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to "
1684 + w + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : ""));
1685 mService.mInputMethodTarget = w;
1686 mService.mInputMethodTargetWaitingAnim = false;
1687 if (w.mAppToken != null) {
1688 setInputMethodAnimLayerAdjustment(
1689 w.mAppToken.mAppAnimator.animLayerAdjustment);
1690 } else {
1691 setInputMethodAnimLayerAdjustment(0);
1692 }
1693 }
1694
1695 // If the docked divider is visible, we still need to go through this whole excercise to
1696 // find the appropriate input method target (used for animations and dialog
1697 // adjustments), but for purposes of Z ordering we simply wish to place it above the
1698 // docked divider. Unless it is already above the divider.
1699 final WindowState dockedDivider = mDividerControllerLocked.getWindow();
1700 if (dockedDivider != null && dockedDivider.isVisibleLw()) {
1701 int dividerIndex = windows.indexOf(dockedDivider);
1702 if (dividerIndex > 0 && dividerIndex > i) {
1703 return dividerIndex + 1;
1704 }
1705 }
1706 return i+1;
1707 }
1708 if (willMove) {
1709 if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget
1710 + " to null." + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : ""));
1711 mService.mInputMethodTarget = null;
1712 setInputMethodAnimLayerAdjustment(0);
1713 }
1714 return -1;
1715 }
1716
1717 private static boolean canBeImeTarget(WindowState w) {
1718 final int fl = w.mAttrs.flags & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
1719 final int type = w.mAttrs.type;
1720
1721 if (fl != 0 && fl != (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM)
1722 && type != TYPE_APPLICATION_STARTING) {
1723 return false;
1724 }
1725
1726 if (DEBUG_INPUT_METHOD) {
1727 Slog.i(TAG_WM, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
1728 if (!w.isVisibleOrAdding()) {
1729 Slog.i(TAG_WM, " mSurfaceController=" + w.mWinAnimator.mSurfaceController
1730 + " relayoutCalled=" + w.mRelayoutCalled
1731 + " viewVis=" + w.mViewVisibility
1732 + " policyVis=" + w.mPolicyVisibility
1733 + " policyVisAfterAnim=" + w.mPolicyVisibilityAfterAnim
1734 + " parentHidden=" + w.isParentWindowHidden()
1735 + " exiting=" + w.mAnimatingExit + " destroying=" + w.mDestroying);
1736 if (w.mAppToken != null) {
1737 Slog.i(TAG_WM, " mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested);
1738 }
1739 }
1740 }
1741 return w.isVisibleOrAdding();
1742 }
1743
1744 private void logWindowList(final WindowList windows, String prefix) {
1745 int N = windows.size();
1746 while (N > 0) {
1747 N--;
1748 Slog.v(TAG_WM, prefix + "#" + N + ": " + windows.get(N));
1749 }
1750 }
1751
1752 boolean getNeedsMenu(WindowState win, WindowManagerPolicy.WindowState bottom) {
1753 int index = -1;
1754 WindowList windows = getWindowList();
1755 while (true) {
1756 if (win.mAttrs.needsMenuKey != NEEDS_MENU_UNSET) {
1757 return win.mAttrs.needsMenuKey == NEEDS_MENU_SET_TRUE;
1758 }
1759 // If we reached the bottom of the range of windows we are considering,
1760 // assume no menu is needed.
1761 if (win == bottom) {
1762 return false;
1763 }
1764 // The current window hasn't specified whether menu key is needed; look behind it.
1765 // First, we may need to determine the starting position.
1766 if (index < 0) {
1767 index = windows.indexOf(win);
1768 }
1769 index--;
1770 if (index < 0) {
1771 return false;
1772 }
1773 win = windows.get(index);
1774 }
1775 }
1776
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001777 void setLayoutNeeded() {
1778 if (DEBUG_LAYOUT) Slog.w(TAG_WM, "setLayoutNeeded: callers=" + Debug.getCallers(3));
1779 mLayoutNeeded = true;
1780 }
1781
1782 void clearLayoutNeeded() {
1783 if (DEBUG_LAYOUT) Slog.w(TAG_WM, "clearLayoutNeeded: callers=" + Debug.getCallers(3));
1784 mLayoutNeeded = false;
1785 }
1786
1787 boolean isLayoutNeeded() {
1788 return mLayoutNeeded;
1789 }
1790
Wale Ogunwale07bcab72016-10-14 15:30:09 -07001791 private void addAppWindowExisting(WindowState win, WindowList tokenWindowList) {
Wale Ogunwaleec731152016-09-08 20:18:57 -07001792
Wale Ogunwaleec731152016-09-08 20:18:57 -07001793 // If this application has existing windows, we simply place the new window on top of
1794 // them... but keep the starting window on top.
1795 if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
1796 // Base windows go behind everything else.
1797 final WindowState lowestWindow = tokenWindowList.get(0);
1798 addWindowToListBefore(win, lowestWindow);
Wale Ogunwaleec731152016-09-08 20:18:57 -07001799 } else {
1800 final AppWindowToken atoken = win.mAppToken;
1801 final int windowListPos = tokenWindowList.size();
1802 final WindowState lastWindow = tokenWindowList.get(windowListPos - 1);
1803 if (atoken != null && lastWindow == atoken.startingWindow) {
1804 addWindowToListBefore(win, lastWindow);
Wale Ogunwaleec731152016-09-08 20:18:57 -07001805 } else {
1806 int newIdx = findIdxBasedOnAppTokens(win);
1807 // There is a window above this one associated with the same apptoken note that the
1808 // window could be a floating window that was created later or a window at the top
1809 // of the list of windows associated with this token.
1810 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
1811 "not Base app: Adding window " + win + " at " + (newIdx + 1) + " of "
1812 + mWindows.size());
1813 mWindows.add(newIdx + 1, win);
Wale Ogunwaleec731152016-09-08 20:18:57 -07001814 mService.mWindowsChanged = true;
1815 }
1816 }
Wale Ogunwaleec731152016-09-08 20:18:57 -07001817 }
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}