blob: 422615b10fc13a6fa651e5b7401e8283f9da6a47 [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
Steven Timotiusaf03df62017-07-18 16:56:43 -070019import android.util.proto.ProtoOutputStream;
Wale Ogunwale07bcab72016-10-14 15:30:09 -070020import java.util.Comparator;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -070021import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
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;
Steven Timotiusaf03df62017-07-18 16:56:43 -070029import static com.android.server.wm.proto.WindowTokenProto.HASH_CODE;
30import static com.android.server.wm.proto.WindowTokenProto.WINDOWS;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080031
Jorim Jaggife762342016-10-13 14:33:27 +020032import android.os.Debug;
33import android.os.IBinder;
Jorim Jaggife762342016-10-13 14:33:27 +020034import android.util.Slog;
Robert Carrda61ba92017-03-29 15:52:23 -070035import android.view.SurfaceControl;
Jorim Jaggife762342016-10-13 14:33:27 +020036
37import java.io.PrintWriter;
38
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080039/**
Wale Ogunwaled1c37912016-08-16 03:19:39 -070040 * Container of a set of related windows in the window manager. Often this is an AppWindowToken,
41 * which is the handle for an Activity that it uses to display windows. For nested windows, there is
42 * a WindowToken created for the parent window to manage its children.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080043 */
Wale Ogunwaled90546a2016-09-09 23:28:03 -070044class WindowToken extends WindowContainer<WindowState> {
Wale Ogunwalee4da0c12016-07-29 12:47:02 -070045 private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowToken" : TAG_WM;
46
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080047 // The window manager!
Wale Ogunwale2049dbf2016-08-02 21:05:23 -070048 protected final WindowManagerService mService;
Svetoslav3a5c7212014-10-14 09:54:26 -070049
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080050 // The actual token.
51 final IBinder token;
52
53 // The type of window this token is for, as per WindowManager.LayoutParams.
54 final int windowType;
55
56 // Set if this token was explicitly added by a client, so should
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -080057 // persist (not be removed) when all windows are removed.
58 boolean mPersistOnEmpty;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080059
60 // For printing.
61 String stringName;
62
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080063 // Is key dispatching paused for this token?
64 boolean paused = false;
65
66 // Should this token's windows be hidden?
67 boolean hidden;
68
69 // Temporary for finding which tokens no longer have visible windows.
70 boolean hasVisible;
71
72 // Set to true when this token is in a pending transaction where it
73 // will be shown.
74 boolean waitingToShow;
75
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080076 // Set to true when this token is in a pending transaction where its
77 // windows will be put to the bottom of the list.
78 boolean sendingToBottom;
79
Wale Ogunwale02319a62016-09-26 15:21:22 -070080 // The display this token is on.
Jorim Jaggi879ff722016-11-04 18:08:17 -070081 protected DisplayContent mDisplayContent;
Wale Ogunwale02319a62016-09-26 15:21:22 -070082
Wale Ogunwale5cd907d2017-01-26 14:14:08 -080083 /** The owner has {@link android.Manifest.permission#MANAGE_APP_TOKENS} */
84 final boolean mOwnerCanManageAppTokens;
85
Wale Ogunwale07bcab72016-10-14 15:30:09 -070086 /**
87 * Compares two child window of this token and returns -1 if the first is lesser than the
88 * second in terms of z-order and 1 otherwise.
89 */
90 private final Comparator<WindowState> mWindowComparator =
91 (WindowState newWindow, WindowState existingWindow) -> {
92 final WindowToken token = WindowToken.this;
93 if (newWindow.mToken != token) {
94 throw new IllegalArgumentException("newWindow=" + newWindow
95 + " is not a child of token=" + token);
96 }
97
98 if (existingWindow.mToken != token) {
99 throw new IllegalArgumentException("existingWindow=" + existingWindow
100 + " is not a child of token=" + token);
101 }
102
103 return isFirstChildWindowGreaterThanSecond(newWindow, existingWindow) ? 1 : -1;
104 };
105
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -0800106 WindowToken(WindowManagerService service, IBinder _token, int type, boolean persistOnEmpty,
Wale Ogunwale5cd907d2017-01-26 14:14:08 -0800107 DisplayContent dc, boolean ownerCanManageAppTokens) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700108 mService = service;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800109 token = _token;
110 windowType = type;
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -0800111 mPersistOnEmpty = persistOnEmpty;
Wale Ogunwale5cd907d2017-01-26 14:14:08 -0800112 mOwnerCanManageAppTokens = ownerCanManageAppTokens;
Wale Ogunwale02319a62016-09-26 15:21:22 -0700113 onDisplayChanged(dc);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800114 }
115
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -0800116 void removeAllWindowsIfPossible() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700117 for (int i = mChildren.size() - 1; i >= 0; --i) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700118 final WindowState win = mChildren.get(i);
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -0800119 if (DEBUG_WINDOW_MOVEMENT) Slog.w(TAG_WM,
120 "removeAllWindowsIfPossible: removing win=" + win);
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700121 win.removeIfPossible();
Svetoslav3a5c7212014-10-14 09:54:26 -0700122 }
123 }
124
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700125 void setExiting() {
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -0800126 // This token is exiting, so allow it to be removed when it no longer contains any windows.
127 mPersistOnEmpty = false;
128
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700129 if (hidden) {
130 return;
131 }
132
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700133 final int count = mChildren.size();
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700134 boolean changed = false;
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700135 boolean delayed = false;
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700136
137 for (int i = 0; i < count; i++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700138 final WindowState win = mChildren.get(i);
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700139 if (win.mWinAnimator.isAnimationSet()) {
140 delayed = true;
141 }
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700142 changed |= win.onSetAppExiting();
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700143 }
144
145 hidden = true;
146
147 if (changed) {
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700148 mService.mWindowPlacerLocked.performSurfacePlacement();
149 mService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, false /*updateInputWindows*/);
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700150 }
151
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700152 if (delayed) {
153 mDisplayContent.mExitingTokens.add(this);
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700154 }
155 }
156
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700157 /**
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700158 * Returns true if the new window is considered greater than the existing window in terms of
159 * z-order.
160 */
161 protected boolean isFirstChildWindowGreaterThanSecond(WindowState newWindow,
162 WindowState existingWindow) {
Wale Ogunwaleb783fd82016-11-04 09:51:54 -0700163 // New window is considered greater if it has a higher or equal base layer.
164 return newWindow.mBaseLayer >= existingWindow.mBaseLayer;
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700165 }
166
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700167 void addWindow(final WindowState win) {
Wale Ogunwale07bcab72016-10-14 15:30:09 -0700168 if (DEBUG_FOCUS) Slog.d(TAG_WM,
169 "addWindow: win=" + win + " Callers=" + Debug.getCallers(5));
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700170
Wale Ogunwale6213caa2016-12-02 16:47:15 +0000171 if (win.isChildWindow()) {
172 // Child windows are added to their parent windows.
Wale Ogunwaleb9a07c32016-10-12 14:55:56 -0700173 return;
174 }
Wale Ogunwaleb9a07c32016-10-12 14:55:56 -0700175 if (!mChildren.contains(win)) {
Wale Ogunwale6213caa2016-12-02 16:47:15 +0000176 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Adding " + win + " to " + this);
177 addChild(win, mWindowComparator);
178 mService.mWindowsChanged = true;
179 // TODO: Should we also be setting layout needed here and other places?
Wale Ogunwaleb9a07c32016-10-12 14:55:56 -0700180 }
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700181 }
182
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700183 /** Returns true if the token windows list is empty. */
184 boolean isEmpty() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700185 return mChildren.isEmpty();
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700186 }
187
Robert Carrdee1b3f2017-02-27 11:33:33 -0800188 // Used by AppWindowToken.
189 int getAnimLayerAdjustment() {
190 return 0;
191 }
192
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700193 WindowState getReplacingWindow() {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700194 for (int i = mChildren.size() - 1; i >= 0; i--) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700195 final WindowState win = mChildren.get(i);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700196 final WindowState replacing = win.getReplacingWindow();
197 if (replacing != null) {
198 return replacing;
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700199 }
200 }
201 return null;
202 }
203
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700204 /** Return true if this token has a window that wants the wallpaper displayed behind it. */
205 boolean windowsCanBeWallpaperTarget() {
206 for (int j = mChildren.size() - 1; j >= 0; j--) {
207 final WindowState w = mChildren.get(j);
208 if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
209 return true;
210 }
211 }
212
213 return false;
214 }
215
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700216 int getHighestAnimLayer() {
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700217 int highest = -1;
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700218 for (int j = 0; j < mChildren.size(); j++) {
Wale Ogunwaled90546a2016-09-09 23:28:03 -0700219 final WindowState w = mChildren.get(j);
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700220 final int wLayer = w.getHighestAnimLayer();
221 if (wLayer > highest) {
222 highest = wLayer;
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700223 }
224 }
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700225 return highest;
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700226 }
227
Wale Ogunwale2049dbf2016-08-02 21:05:23 -0700228 AppWindowToken asAppWindowToken() {
229 // TODO: Not sure if this is the best way to handle this vs. using instanceof and casting.
230 // I am not an app window token!
231 return null;
232 }
233
Wale Ogunwale02319a62016-09-26 15:21:22 -0700234 DisplayContent getDisplayContent() {
235 return mDisplayContent;
236 }
237
238 @Override
239 void removeImmediately() {
Wale Ogunwale02319a62016-09-26 15:21:22 -0700240 if (mDisplayContent != null) {
241 mDisplayContent.removeWindowToken(token);
Wale Ogunwale02319a62016-09-26 15:21:22 -0700242 }
Wale Ogunwalecfca2582016-10-19 09:53:25 -0700243 // Needs to occur after the token is removed from the display above to avoid attempt at
244 // duplicate removal of this window container from it's parent.
245 super.removeImmediately();
Wale Ogunwale02319a62016-09-26 15:21:22 -0700246 }
247
248 void onDisplayChanged(DisplayContent dc) {
Wale Ogunwale3d0bfd92016-12-05 11:38:02 -0800249 dc.reParentWindowToken(this);
Wale Ogunwale02319a62016-09-26 15:21:22 -0700250 mDisplayContent = dc;
Robert Carrda61ba92017-03-29 15:52:23 -0700251
252 // TODO(b/36740756): One day this should perhaps be hooked
253 // up with goodToGo, so we don't move a window
254 // to another display before the window behind
255 // it is ready.
256 SurfaceControl.openTransaction();
257 for (int i = mChildren.size() - 1; i >= 0; --i) {
258 final WindowState win = mChildren.get(i);
259 win.mWinAnimator.updateLayerStackInTransaction();
260 }
261 SurfaceControl.closeTransaction();
262
Wale Ogunwale02319a62016-09-26 15:21:22 -0700263 super.onDisplayChanged(dc);
264 }
265
Steven Timotiusaf03df62017-07-18 16:56:43 -0700266 void writeToProto(ProtoOutputStream proto, long fieldId) {
267 final long token = proto.start(fieldId);
268 proto.write(HASH_CODE, System.identityHashCode(this));
269 for (int i = 0; i < mChildren.size(); i++) {
270 final WindowState w = mChildren.get(i);
271 w.writeToProto(proto, WINDOWS);
272 }
273 proto.end(token);
274 }
275
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800276 void dump(PrintWriter pw, String prefix) {
Wale Ogunwaled1c37912016-08-16 03:19:39 -0700277 pw.print(prefix); pw.print("windows="); pw.println(mChildren);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800278 pw.print(prefix); pw.print("windowType="); pw.print(windowType);
279 pw.print(" hidden="); pw.print(hidden);
280 pw.print(" hasVisible="); pw.println(hasVisible);
Wale Ogunwale10cb5e22015-05-24 12:36:21 -0700281 if (waitingToShow || sendingToBottom) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800282 pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800283 pw.print(" sendingToBottom="); pw.print(sendingToBottom);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800284 }
285 }
286
287 @Override
288 public String toString() {
289 if (stringName == null) {
290 StringBuilder sb = new StringBuilder();
291 sb.append("WindowToken{");
292 sb.append(Integer.toHexString(System.identityHashCode(this)));
Dianne Hackbornef03a7f2012-10-29 18:46:52 -0700293 sb.append(" "); sb.append(token); sb.append('}');
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800294 stringName = sb.toString();
295 }
296 return stringName;
297 }
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700298
299 @Override
300 String getName() {
301 return toString();
302 }
David Stevens9440dc82017-03-16 19:00:20 -0700303
304 boolean okToDisplay() {
305 return mDisplayContent != null && mDisplayContent.okToDisplay();
306 }
307
308 boolean okToAnimate() {
309 return mDisplayContent != null && mDisplayContent.okToAnimate();
310 }
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800311}