blob: 48d1618c1c915cee8735e3672ec6b19a9fed5614 [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 Ogunwale07bcab72016-10-14 15:30:09 -070019import java.util.Comparator;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -070020import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
Wale Ogunwale9bc47732016-08-10 14:44:22 -070021import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
Jorim Jaggife762342016-10-13 14:33:27 +020022
Wale Ogunwalee4da0c12016-07-29 12:47:02 -070023import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
24import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
Wale Ogunwalee4da0c12016-07-29 12:47:02 -070025import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
26import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
27import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
28import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080029
Jorim Jaggife762342016-10-13 14:33:27 +020030import android.os.Debug;
31import android.os.IBinder;
Jorim Jaggife762342016-10-13 14:33:27 +020032import android.util.Slog;
Robert Carrda61ba92017-03-29 15:52:23 -070033import android.view.SurfaceControl;
Jorim Jaggife762342016-10-13 14:33:27 +020034
35import java.io.PrintWriter;
36
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080037/**
Wale Ogunwaled1c37912016-08-16 03:19:39 -070038 * Container of a set of related windows in the window manager. Often this is an AppWindowToken,
39 * which is the handle for an Activity that it uses to display windows. For nested windows, there is
40 * a WindowToken created for the parent window to manage its children.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080041 */
Wale Ogunwaled90546a2016-09-09 23:28:03 -070042class WindowToken extends WindowContainer<WindowState> {
Wale Ogunwalee4da0c12016-07-29 12:47:02 -070043 private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowToken" : TAG_WM;
44
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080045 // The window manager!
Wale Ogunwale2049dbf2016-08-02 21:05:23 -070046 protected final WindowManagerService mService;
Svetoslav3a5c7212014-10-14 09:54:26 -070047
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080048 // The actual token.
49 final IBinder token;
50
51 // The type of window this token is for, as per WindowManager.LayoutParams.
52 final int windowType;
53
54 // Set if this token was explicitly added by a client, so should
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -080055 // persist (not be removed) when all windows are removed.
56 boolean mPersistOnEmpty;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080057
58 // For printing.
59 String stringName;
60
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080061 // Is key dispatching paused for this token?
62 boolean paused = false;
63
64 // Should this token's windows be hidden?
65 boolean hidden;
66
67 // Temporary for finding which tokens no longer have visible windows.
68 boolean hasVisible;
69
70 // Set to true when this token is in a pending transaction where it
71 // will be shown.
72 boolean waitingToShow;
73
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080074 // Set to true when this token is in a pending transaction where its
75 // windows will be put to the bottom of the list.
76 boolean sendingToBottom;
77
Wale Ogunwale02319a62016-09-26 15:21:22 -070078 // The display this token is on.
Jorim Jaggi879ff722016-11-04 18:08:17 -070079 protected DisplayContent mDisplayContent;
Wale Ogunwale02319a62016-09-26 15:21:22 -070080
Wale Ogunwale5cd907d2017-01-26 14:14:08 -080081 /** The owner has {@link android.Manifest.permission#MANAGE_APP_TOKENS} */
82 final boolean mOwnerCanManageAppTokens;
83
Wale Ogunwale07bcab72016-10-14 15:30:09 -070084 /**
85 * Compares two child window of this token and returns -1 if the first is lesser than the
86 * second in terms of z-order and 1 otherwise.
87 */
88 private final Comparator<WindowState> mWindowComparator =
89 (WindowState newWindow, WindowState existingWindow) -> {
90 final WindowToken token = WindowToken.this;
91 if (newWindow.mToken != token) {
92 throw new IllegalArgumentException("newWindow=" + newWindow
93 + " is not a child of token=" + token);
94 }
95
96 if (existingWindow.mToken != token) {
97 throw new IllegalArgumentException("existingWindow=" + existingWindow
98 + " is not a child of token=" + token);
99 }
100
101 return isFirstChildWindowGreaterThanSecond(newWindow, existingWindow) ? 1 : -1;
102 };
103
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -0800104 WindowToken(WindowManagerService service, IBinder _token, int type, boolean persistOnEmpty,
Wale Ogunwale5cd907d2017-01-26 14:14:08 -0800105 DisplayContent dc, boolean ownerCanManageAppTokens) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700106 mService = service;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800107 token = _token;
108 windowType = type;
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -0800109 mPersistOnEmpty = persistOnEmpty;
Wale Ogunwale5cd907d2017-01-26 14:14:08 -0800110 mOwnerCanManageAppTokens = ownerCanManageAppTokens;
Wale Ogunwale02319a62016-09-26 15:21:22 -0700111 onDisplayChanged(dc);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800112 }
113
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -0800114 void removeAllWindowsIfPossible() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700115 for (int i = mChildren.size() - 1; i >= 0; --i) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700116 final WindowState win = mChildren.get(i);
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -0800117 if (DEBUG_WINDOW_MOVEMENT) Slog.w(TAG_WM,
118 "removeAllWindowsIfPossible: removing win=" + win);
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700119 win.removeIfPossible();
Svetoslav3a5c7212014-10-14 09:54:26 -0700120 }
121 }
122
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700123 void setExiting() {
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -0800124 // This token is exiting, so allow it to be removed when it no longer contains any windows.
125 mPersistOnEmpty = false;
126
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700127 if (hidden) {
128 return;
129 }
130
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700131 final int count = mChildren.size();
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700132 boolean changed = false;
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700133 boolean delayed = false;
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700134
135 for (int i = 0; i < count; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700136 final WindowState win = mChildren.get(i);
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700137 if (win.mWinAnimator.isAnimationSet()) {
138 delayed = true;
139 }
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700140 changed |= win.onSetAppExiting();
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700141 }
142
143 hidden = true;
144
145 if (changed) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700146 mService.mWindowPlacerLocked.performSurfacePlacement();
147 mService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, false /*updateInputWindows*/);
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700148 }
149
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700150 if (delayed) {
151 mDisplayContent.mExitingTokens.add(this);
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700152 }
153 }
154
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700155 /**
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700156 * Returns true if the new window is considered greater than the existing window in terms of
157 * z-order.
158 */
159 protected boolean isFirstChildWindowGreaterThanSecond(WindowState newWindow,
160 WindowState existingWindow) {
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700161 // New window is considered greater if it has a higher or equal base layer.
162 return newWindow.mBaseLayer >= existingWindow.mBaseLayer;
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700163 }
164
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700165 void addWindow(final WindowState win) {
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700166 if (DEBUG_FOCUS) Slog.d(TAG_WM,
167 "addWindow: win=" + win + " Callers=" + Debug.getCallers(5));
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700168
Wale Ogunwale6213caa2016-12-02 16:47:15 +0000169 if (win.isChildWindow()) {
170 // Child windows are added to their parent windows.
Wale Ogunwaleb9a07c32016-10-12 14:55:56 -0700171 return;
172 }
Wale Ogunwaleb9a07c32016-10-12 14:55:56 -0700173 if (!mChildren.contains(win)) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +0000174 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Adding " + win + " to " + this);
175 addChild(win, mWindowComparator);
176 mService.mWindowsChanged = true;
177 // TODO: Should we also be setting layout needed here and other places?
Wale Ogunwaleb9a07c32016-10-12 14:55:56 -0700178 }
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700179 }
180
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700181 /** Returns true if the token windows list is empty. */
182 boolean isEmpty() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700183 return mChildren.isEmpty();
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700184 }
185
Robert Carrdee1b3f2017-02-27 11:33:33 -0800186 // Used by AppWindowToken.
187 int getAnimLayerAdjustment() {
188 return 0;
189 }
190
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700191 WindowState getReplacingWindow() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700192 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700193 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700194 final WindowState replacing = win.getReplacingWindow();
195 if (replacing != null) {
196 return replacing;
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700197 }
198 }
199 return null;
200 }
201
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700202 /** Return true if this token has a window that wants the wallpaper displayed behind it. */
203 boolean windowsCanBeWallpaperTarget() {
204 for (int j = mChildren.size() - 1; j >= 0; j--) {
205 final WindowState w = mChildren.get(j);
206 if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
207 return true;
208 }
209 }
210
211 return false;
212 }
213
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700214 int getHighestAnimLayer() {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700215 int highest = -1;
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700216 for (int j = 0; j < mChildren.size(); j++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700217 final WindowState w = mChildren.get(j);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700218 final int wLayer = w.getHighestAnimLayer();
219 if (wLayer > highest) {
220 highest = wLayer;
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700221 }
222 }
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700223 return highest;
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700224 }
225
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700226 AppWindowToken asAppWindowToken() {
227 // TODO: Not sure if this is the best way to handle this vs. using instanceof and casting.
228 // I am not an app window token!
229 return null;
230 }
231
Wale Ogunwale02319a62016-09-26 15:21:22 -0700232 DisplayContent getDisplayContent() {
233 return mDisplayContent;
234 }
235
236 @Override
237 void removeImmediately() {
Wale Ogunwale02319a62016-09-26 15:21:22 -0700238 if (mDisplayContent != null) {
239 mDisplayContent.removeWindowToken(token);
Wale Ogunwale02319a62016-09-26 15:21:22 -0700240 }
Wale Ogunwalecfca2582016-10-19 09:53:25 -0700241 // Needs to occur after the token is removed from the display above to avoid attempt at
242 // duplicate removal of this window container from it's parent.
243 super.removeImmediately();
Wale Ogunwale02319a62016-09-26 15:21:22 -0700244 }
245
246 void onDisplayChanged(DisplayContent dc) {
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -0800247 dc.reParentWindowToken(this);
Wale Ogunwale02319a62016-09-26 15:21:22 -0700248 mDisplayContent = dc;
Robert Carrda61ba92017-03-29 15:52:23 -0700249
250 // TODO(b/36740756): One day this should perhaps be hooked
251 // up with goodToGo, so we don't move a window
252 // to another display before the window behind
253 // it is ready.
254 SurfaceControl.openTransaction();
255 for (int i = mChildren.size() - 1; i >= 0; --i) {
256 final WindowState win = mChildren.get(i);
257 win.mWinAnimator.updateLayerStackInTransaction();
258 }
259 SurfaceControl.closeTransaction();
260
Wale Ogunwale02319a62016-09-26 15:21:22 -0700261 super.onDisplayChanged(dc);
262 }
263
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800264 void dump(PrintWriter pw, String prefix) {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700265 pw.print(prefix); pw.print("windows="); pw.println(mChildren);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800266 pw.print(prefix); pw.print("windowType="); pw.print(windowType);
267 pw.print(" hidden="); pw.print(hidden);
268 pw.print(" hasVisible="); pw.println(hasVisible);
Wale Ogunwale10cb5e22015-05-24 12:36:21 -0700269 if (waitingToShow || sendingToBottom) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800270 pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800271 pw.print(" sendingToBottom="); pw.print(sendingToBottom);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800272 }
273 }
274
275 @Override
276 public String toString() {
277 if (stringName == null) {
278 StringBuilder sb = new StringBuilder();
279 sb.append("WindowToken{");
280 sb.append(Integer.toHexString(System.identityHashCode(this)));
Dianne Hackbornef03a7f2012-10-29 18:46:52 -0700281 sb.append(" "); sb.append(token); sb.append('}');
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800282 stringName = sb.toString();
283 }
284 return stringName;
285 }
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700286
287 @Override
288 String getName() {
289 return toString();
290 }
David Stevensf62360c2017-03-16 19:00:20 -0700291
292 boolean okToDisplay() {
293 return mDisplayContent != null && mDisplayContent.okToDisplay();
294 }
295
296 boolean okToAnimate() {
297 return mDisplayContent != null && mDisplayContent.okToAnimate();
298 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800299}