blob: 057f4931dec1b093903ae15f4becc43b06298ce4 [file] [log] [blame]
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001/*
2 * Copyright (C) 2011 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 Ogunwale0c4a40ef2016-10-07 07:06:40 -070019import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
Robert Carr683e05d2018-04-18 15:11:04 -070020import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
Louis Chang7501e332018-08-20 13:08:39 +080021
Adrian Roosb125e0b2019-10-02 14:55:14 +020022import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
23import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS;
24import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_WINDOW_MOVEMENT;
lumark9bca6b42019-10-17 18:35:22 +080025import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
26import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
27import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
Wale Ogunwalee4da0c12016-07-29 12:47:02 -070028import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
29import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
30import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070031import static com.android.server.wm.WindowTokenProto.HASH_CODE;
Issei Suzuki7b9e2572019-11-14 16:19:54 +010032import static com.android.server.wm.WindowTokenProto.HIDDEN;
Yi Jin6c6e9ca2018-03-20 16:53:35 -070033import static com.android.server.wm.WindowTokenProto.PAUSED;
34import static com.android.server.wm.WindowTokenProto.WAITING_TO_SHOW;
35import static com.android.server.wm.WindowTokenProto.WINDOWS;
36import static com.android.server.wm.WindowTokenProto.WINDOW_CONTAINER;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080037
Vishnu Nair04ab4392018-01-10 11:00:06 -080038import android.annotation.CallSuper;
Jorim Jaggife762342016-10-13 14:33:27 +020039import android.os.Debug;
40import android.os.IBinder;
Vishnu Nair04ab4392018-01-10 11:00:06 -080041import android.util.proto.ProtoOutputStream;
Jorim Jaggife762342016-10-13 14:33:27 +020042
Adrian Roosb125e0b2019-10-02 14:55:14 +020043import com.android.server.protolog.common.ProtoLog;
44
Jorim Jaggife762342016-10-13 14:33:27 +020045import java.io.PrintWriter;
Vishnu Nair04ab4392018-01-10 11:00:06 -080046import java.util.Comparator;
Jorim Jaggife762342016-10-13 14:33:27 +020047
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080048/**
Wale Ogunwaled1c37912016-08-16 03:19:39 -070049 * Container of a set of related windows in the window manager. Often this is an AppWindowToken,
50 * which is the handle for an Activity that it uses to display windows. For nested windows, there is
51 * a WindowToken created for the parent window to manage its children.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080052 */
Wale Ogunwaled90546a2016-09-09 23:28:03 -070053class WindowToken extends WindowContainer<WindowState> {
Wale Ogunwalee4da0c12016-07-29 12:47:02 -070054 private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowToken" : TAG_WM;
55
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080056 // The actual token.
57 final IBinder token;
58
59 // The type of window this token is for, as per WindowManager.LayoutParams.
60 final int windowType;
61
Adrian Roos4bef62e2018-03-21 19:52:09 +010062 /** {@code true} if this holds the rounded corner overlay */
63 final boolean mRoundedCornerOverlay;
64
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080065 // Set if this token was explicitly added by a client, so should
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -080066 // persist (not be removed) when all windows are removed.
67 boolean mPersistOnEmpty;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080068
69 // For printing.
70 String stringName;
71
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080072 // Is key dispatching paused for this token?
73 boolean paused = false;
74
Issei Suzuki7b9e2572019-11-14 16:19:54 +010075 // Should this token's windows be hidden?
76 private boolean mHidden;
77
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080078 // Temporary for finding which tokens no longer have visible windows.
79 boolean hasVisible;
80
81 // Set to true when this token is in a pending transaction where it
82 // will be shown.
83 boolean waitingToShow;
84
Wale Ogunwale5cd907d2017-01-26 14:14:08 -080085 /** The owner has {@link android.Manifest.permission#MANAGE_APP_TOKENS} */
86 final boolean mOwnerCanManageAppTokens;
87
Wale Ogunwale07bcab72016-10-14 15:30:09 -070088 /**
89 * Compares two child window of this token and returns -1 if the first is lesser than the
90 * second in terms of z-order and 1 otherwise.
91 */
92 private final Comparator<WindowState> mWindowComparator =
93 (WindowState newWindow, WindowState existingWindow) -> {
94 final WindowToken token = WindowToken.this;
95 if (newWindow.mToken != token) {
96 throw new IllegalArgumentException("newWindow=" + newWindow
97 + " is not a child of token=" + token);
98 }
99
100 if (existingWindow.mToken != token) {
101 throw new IllegalArgumentException("existingWindow=" + existingWindow
102 + " is not a child of token=" + token);
103 }
104
105 return isFirstChildWindowGreaterThanSecond(newWindow, existingWindow) ? 1 : -1;
106 };
107
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -0800108 WindowToken(WindowManagerService service, IBinder _token, int type, boolean persistOnEmpty,
Wale Ogunwale5cd907d2017-01-26 14:14:08 -0800109 DisplayContent dc, boolean ownerCanManageAppTokens) {
Adrian Roos4bef62e2018-03-21 19:52:09 +0100110 this(service, _token, type, persistOnEmpty, dc, ownerCanManageAppTokens,
111 false /* roundedCornersOverlay */);
112 }
113
114 WindowToken(WindowManagerService service, IBinder _token, int type, boolean persistOnEmpty,
115 DisplayContent dc, boolean ownerCanManageAppTokens, boolean roundedCornerOverlay) {
Jorim Jaggiffe128d2017-11-30 13:54:36 +0100116 super(service);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800117 token = _token;
118 windowType = type;
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -0800119 mPersistOnEmpty = persistOnEmpty;
Wale Ogunwale5cd907d2017-01-26 14:14:08 -0800120 mOwnerCanManageAppTokens = ownerCanManageAppTokens;
Adrian Roos4bef62e2018-03-21 19:52:09 +0100121 mRoundedCornerOverlay = roundedCornerOverlay;
Wale Ogunwaleda8b8272018-11-29 19:37:37 -0800122 if (dc != null) {
123 onDisplayChanged(dc);
124 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800125 }
126
Issei Suzuki7b9e2572019-11-14 16:19:54 +0100127 void setHidden(boolean hidden) {
128 if (hidden != mHidden) {
129 mHidden = hidden;
130 }
131 }
132
133 boolean isHidden() {
134 return mHidden;
135 }
136
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -0800137 void removeAllWindowsIfPossible() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700138 for (int i = mChildren.size() - 1; i >= 0; --i) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700139 final WindowState win = mChildren.get(i);
Adrian Roosb125e0b2019-10-02 14:55:14 +0200140 ProtoLog.w(WM_DEBUG_WINDOW_MOVEMENT,
141 "removeAllWindowsIfPossible: removing win=%s", win);
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700142 win.removeIfPossible();
Svetoslav3a5c7212014-10-14 09:54:26 -0700143 }
144 }
145
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700146 void setExiting() {
chaviwaec55ff52017-12-04 18:39:34 -0800147 if (mChildren.size() == 0) {
148 super.removeImmediately();
149 return;
150 }
151
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -0800152 // This token is exiting, so allow it to be removed when it no longer contains any windows.
153 mPersistOnEmpty = false;
154
Issei Suzuki7b9e2572019-11-14 16:19:54 +0100155 if (mHidden) {
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700156 return;
157 }
158
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700159 final int count = mChildren.size();
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700160 boolean changed = false;
lumark9bca6b42019-10-17 18:35:22 +0800161 final boolean delayed = isAnimating(TRANSITION | PARENTS | CHILDREN);
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700162
163 for (int i = 0; i < count; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700164 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700165 changed |= win.onSetAppExiting();
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700166 }
167
Issei Suzuki7b9e2572019-11-14 16:19:54 +0100168 setHidden(true);
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700169
170 if (changed) {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800171 mWmService.mWindowPlacerLocked.performSurfacePlacement();
172 mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, false /*updateInputWindows*/);
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700173 }
174
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700175 if (delayed) {
176 mDisplayContent.mExitingTokens.add(this);
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700177 }
178 }
179
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700180 /**
Riddle Hsub398da32019-01-21 21:48:16 +0800181 * @return The scale for applications running in compatibility mode. Multiply the size in the
182 * application by this scale will be the size in the screen.
183 */
184 float getSizeCompatScale() {
185 return mDisplayContent.mCompatibleScreenScale;
186 }
187
188 /**
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700189 * Returns true if the new window is considered greater than the existing window in terms of
190 * z-order.
191 */
192 protected boolean isFirstChildWindowGreaterThanSecond(WindowState newWindow,
193 WindowState existingWindow) {
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700194 // New window is considered greater if it has a higher or equal base layer.
195 return newWindow.mBaseLayer >= existingWindow.mBaseLayer;
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700196 }
197
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700198 void addWindow(final WindowState win) {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200199 ProtoLog.d(WM_DEBUG_FOCUS,
200 "addWindow: win=%s Callers=%s", win, Debug.getCallers(5));
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700201
Wale Ogunwale6213caa2016-12-02 16:47:15 +0000202 if (win.isChildWindow()) {
203 // Child windows are added to their parent windows.
Wale Ogunwaleb9a07c32016-10-12 14:55:56 -0700204 return;
205 }
Wale Ogunwaleb9a07c32016-10-12 14:55:56 -0700206 if (!mChildren.contains(win)) {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200207 ProtoLog.v(WM_DEBUG_ADD_REMOVE, "Adding %s to %s", win, this);
Wale Ogunwale6213caa2016-12-02 16:47:15 +0000208 addChild(win, mWindowComparator);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800209 mWmService.mWindowsChanged = true;
Wale Ogunwale6213caa2016-12-02 16:47:15 +0000210 // TODO: Should we also be setting layout needed here and other places?
Wale Ogunwaleb9a07c32016-10-12 14:55:56 -0700211 }
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700212 }
213
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700214 /** Returns true if the token windows list is empty. */
215 boolean isEmpty() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700216 return mChildren.isEmpty();
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700217 }
218
219 WindowState getReplacingWindow() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700220 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700221 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700222 final WindowState replacing = win.getReplacingWindow();
223 if (replacing != null) {
224 return replacing;
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700225 }
226 }
227 return null;
228 }
229
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700230 /** Return true if this token has a window that wants the wallpaper displayed behind it. */
231 boolean windowsCanBeWallpaperTarget() {
232 for (int j = mChildren.size() - 1; j >= 0; j--) {
233 final WindowState w = mChildren.get(j);
234 if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
235 return true;
236 }
237 }
238
239 return false;
240 }
241
Garfield Tane8d84ab2019-10-11 09:49:40 -0700242 ActivityRecord asActivityRecord() {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700243 // TODO: Not sure if this is the best way to handle this vs. using instanceof and casting.
244 // I am not an app window token!
245 return null;
246 }
247
Wale Ogunwale02319a62016-09-26 15:21:22 -0700248 @Override
249 void removeImmediately() {
Wale Ogunwale02319a62016-09-26 15:21:22 -0700250 if (mDisplayContent != null) {
251 mDisplayContent.removeWindowToken(token);
Wale Ogunwale02319a62016-09-26 15:21:22 -0700252 }
Wale Ogunwalecfca2582016-10-19 09:53:25 -0700253 // Needs to occur after the token is removed from the display above to avoid attempt at
254 // duplicate removal of this window container from it's parent.
255 super.removeImmediately();
Wale Ogunwale02319a62016-09-26 15:21:22 -0700256 }
257
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800258 @Override
Wale Ogunwale02319a62016-09-26 15:21:22 -0700259 void onDisplayChanged(DisplayContent dc) {
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -0800260 dc.reParentWindowToken(this);
Robert Carrda61ba92017-03-29 15:52:23 -0700261
262 // TODO(b/36740756): One day this should perhaps be hooked
263 // up with goodToGo, so we don't move a window
264 // to another display before the window behind
265 // it is ready.
Robert Carrda61ba92017-03-29 15:52:23 -0700266
Wale Ogunwale02319a62016-09-26 15:21:22 -0700267 super.onDisplayChanged(dc);
268 }
269
Wale Ogunwale0d5609b2017-09-13 05:55:07 -0700270 @CallSuper
271 @Override
Nataniel Borges023ecb52019-01-16 14:15:43 -0800272 public void writeToProto(ProtoOutputStream proto, long fieldId,
273 @WindowTraceLogLevel int logLevel) {
274 if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
275 return;
276 }
277
Steven Timotiusaf03df62017-07-18 16:56:43 -0700278 final long token = proto.start(fieldId);
Nataniel Borges023ecb52019-01-16 14:15:43 -0800279 super.writeToProto(proto, WINDOW_CONTAINER, logLevel);
Steven Timotiusaf03df62017-07-18 16:56:43 -0700280 proto.write(HASH_CODE, System.identityHashCode(this));
281 for (int i = 0; i < mChildren.size(); i++) {
282 final WindowState w = mChildren.get(i);
Nataniel Borges023ecb52019-01-16 14:15:43 -0800283 w.writeToProto(proto, WINDOWS, logLevel);
Steven Timotiusaf03df62017-07-18 16:56:43 -0700284 }
Issei Suzuki7b9e2572019-11-14 16:19:54 +0100285 proto.write(HIDDEN, mHidden);
Vishnu Nair04ab4392018-01-10 11:00:06 -0800286 proto.write(WAITING_TO_SHOW, waitingToShow);
287 proto.write(PAUSED, paused);
Steven Timotiusaf03df62017-07-18 16:56:43 -0700288 proto.end(token);
289 }
290
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200291 void dump(PrintWriter pw, String prefix, boolean dumpAll) {
292 super.dump(pw, prefix, dumpAll);
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700293 pw.print(prefix); pw.print("windows="); pw.println(mChildren);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800294 pw.print(prefix); pw.print("windowType="); pw.print(windowType);
Issei Suzuki7b9e2572019-11-14 16:19:54 +0100295 pw.print(" hidden="); pw.print(mHidden);
296 pw.print(" hasVisible="); pw.println(hasVisible);
Wale Ogunwale7a8889a2019-11-16 08:23:42 -0800297 if (waitingToShow) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800298 pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800299 }
300 }
301
302 @Override
303 public String toString() {
304 if (stringName == null) {
305 StringBuilder sb = new StringBuilder();
306 sb.append("WindowToken{");
307 sb.append(Integer.toHexString(System.identityHashCode(this)));
Dianne Hackbornef03a7f2012-10-29 18:46:52 -0700308 sb.append(" "); sb.append(token); sb.append('}');
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800309 stringName = sb.toString();
310 }
311 return stringName;
312 }
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700313
314 @Override
315 String getName() {
316 return toString();
317 }
David Stevens9440dc82017-03-16 19:00:20 -0700318
Robert Carr683e05d2018-04-18 15:11:04 -0700319 /**
320 * Return whether windows from this token can layer above the
321 * system bars, or in other words extend outside of the "Decor Frame"
322 */
323 boolean canLayerAboveSystemBars() {
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800324 int layer = mWmService.mPolicy.getWindowLayerFromTypeLw(windowType,
Robert Carr683e05d2018-04-18 15:11:04 -0700325 mOwnerCanManageAppTokens);
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800326 int navLayer = mWmService.mPolicy.getWindowLayerFromTypeLw(TYPE_NAVIGATION_BAR,
Robert Carr683e05d2018-04-18 15:11:04 -0700327 mOwnerCanManageAppTokens);
328 return mOwnerCanManageAppTokens && (layer > navLayer);
329 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800330}