blob: 0e4ab53e5c56646b6ceb6655396e9f8d1efdbe2a [file] [log] [blame]
Dianne Hackbornf56e1022011-02-22 10:47:13 -08001/*
2 * Copyright (C) 2010 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.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080015 */
Dianne Hackbornf56e1022011-02-22 10:47:13 -080016
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080017package com.android.server.wm;
18
Wale Ogunwale6213caa2016-12-02 16:47:15 +000019import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION;
Winson41275482016-10-10 15:17:45 -070020import static android.view.WindowManager.INPUT_CONSUMER_PIP;
Winson Chunga89ffed2018-01-25 17:46:11 +000021import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
Winson41275482016-10-10 15:17:45 -070022import static android.view.WindowManager.INPUT_CONSUMER_WALLPAPER;
Wale Ogunwalef7cab102016-10-25 15:25:14 -070023import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
Wale Ogunwale6213caa2016-12-02 16:47:15 +000024import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS;
25import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
26import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
Winson Chung6463c362017-09-25 16:23:26 -070027
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080028import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
29import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
30import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT;
31import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING;
32import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Filip Gruszczynski9cac3b42015-10-30 14:20:37 -070033
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080034import android.graphics.Rect;
Winson Chung6463c362017-09-25 16:23:26 -070035import android.os.IBinder;
Winson41275482016-10-10 15:17:45 -070036import android.os.Looper;
Winson Chung6463c362017-09-25 16:23:26 -070037import android.os.Process;
Jorim Jaggi60640512018-06-29 01:14:31 +020038import android.os.Trace;
Winson Chung6463c362017-09-25 16:23:26 -070039import android.os.UserHandle;
Winson41275482016-10-10 15:17:45 -070040import android.util.ArrayMap;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080041import android.util.Log;
42import android.util.Slog;
Jeff Browncc4f7db2011-08-30 20:34:48 -070043import android.view.InputChannel;
Winson41275482016-10-10 15:17:45 -070044import android.view.InputEventReceiver;
Wale Ogunwale1e129a42016-11-21 13:03:47 -080045
Selim Cinekf83e8242015-05-19 18:08:14 -070046import com.android.server.input.InputApplicationHandle;
Selim Cinekf83e8242015-05-19 18:08:14 -070047import com.android.server.input.InputWindowHandle;
Adrian Roose99bc052017-11-20 17:55:31 +010048import com.android.server.policy.WindowManagerPolicy;
Selim Cinekf83e8242015-05-19 18:08:14 -070049
Wale Ogunwalee89eeac2016-03-12 11:07:58 -080050import java.io.PrintWriter;
Jeff Brown9302c872011-07-13 22:51:29 -070051import java.util.Arrays;
Winson Chung853c99a2017-03-21 22:16:42 -070052import java.util.Set;
Wale Ogunwale1e129a42016-11-21 13:03:47 -080053import java.util.function.Consumer;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080054
Arthur Hung95b38a92018-07-20 18:56:12 +080055final class InputMonitor {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080056 private final WindowManagerService mService;
Selim Cinekf83e8242015-05-19 18:08:14 -070057
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080058 // Current window with input focus for keys and other non-touch events. May be null.
59 private WindowState mInputFocus;
Selim Cinekf83e8242015-05-19 18:08:14 -070060
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080061 // When true, need to call updateInputWindowsLw().
62 private boolean mUpdateInputWindowsNeeded = true;
63
Jeff Brown9302c872011-07-13 22:51:29 -070064 // Array of window handles to provide to the input dispatcher.
65 private InputWindowHandle[] mInputWindowHandles;
66 private int mInputWindowHandleCount;
Vladislav Kaznacheev3787de12016-12-21 10:36:35 -080067
Wale Ogunwale6213caa2016-12-02 16:47:15 +000068 private boolean mDisableWallpaperTouchEvents;
Wale Ogunwale1e129a42016-11-21 13:03:47 -080069 private final Rect mTmpRect = new Rect();
70 private final UpdateInputForAllWindowsConsumer mUpdateInputForAllWindowsConsumer =
71 new UpdateInputForAllWindowsConsumer();
Jeff Brown9302c872011-07-13 22:51:29 -070072
Arthur Hung95b38a92018-07-20 18:56:12 +080073 private int mDisplayId;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080074
Winson41275482016-10-10 15:17:45 -070075 /**
76 * The set of input consumer added to the window manager by name, which consumes input events
77 * for the windows below it.
78 */
79 private final ArrayMap<String, InputConsumerImpl> mInputConsumers = new ArrayMap();
80
81 private static final class EventReceiverInputConsumer extends InputConsumerImpl
82 implements WindowManagerPolicy.InputConsumer {
83 private InputMonitor mInputMonitor;
84 private final InputEventReceiver mInputEventReceiver;
85
86 EventReceiverInputConsumer(WindowManagerService service, InputMonitor monitor,
87 Looper looper, String name,
Winson Chung6463c362017-09-25 16:23:26 -070088 InputEventReceiver.Factory inputEventReceiverFactory,
Arthur Hung95b38a92018-07-20 18:56:12 +080089 int clientPid, UserHandle clientUser, int displayId) {
90 super(service, null /* token */, name, null /* inputChannel */, clientPid, clientUser,
91 displayId);
Winson41275482016-10-10 15:17:45 -070092 mInputMonitor = monitor;
93 mInputEventReceiver = inputEventReceiverFactory.createInputEventReceiver(
94 mClientChannel, looper);
95 }
96
97 @Override
98 public void dismiss() {
Wale Ogunwaledb485de2018-10-29 09:47:07 -070099 synchronized (mService.mGlobalLock) {
Winson41275482016-10-10 15:17:45 -0700100 if (mInputMonitor.destroyInputConsumer(mWindowHandle.name)) {
101 mInputEventReceiver.dispose();
102 }
103 }
104 }
105 }
106
Arthur Hung95b38a92018-07-20 18:56:12 +0800107 public InputMonitor(WindowManagerService service, int displayId) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800108 mService = service;
Arthur Hung95b38a92018-07-20 18:56:12 +0800109 mDisplayId = displayId;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800110 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700111
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700112 private void addInputConsumer(String name, InputConsumerImpl consumer) {
Winson41275482016-10-10 15:17:45 -0700113 mInputConsumers.put(name, consumer);
Winson Chung6463c362017-09-25 16:23:26 -0700114 consumer.linkToDeathRecipient();
Winson41275482016-10-10 15:17:45 -0700115 updateInputWindowsLw(true /* force */);
116 }
117
118 boolean destroyInputConsumer(String name) {
119 if (disposeInputConsumer(mInputConsumers.remove(name))) {
120 updateInputWindowsLw(true /* force */);
121 return true;
122 }
123 return false;
124 }
125
126 private boolean disposeInputConsumer(InputConsumerImpl consumer) {
127 if (consumer != null) {
128 consumer.disposeChannelsLw();
129 return true;
130 }
131 return false;
132 }
133
Arthur Hung95b38a92018-07-20 18:56:12 +0800134 InputConsumerImpl getInputConsumer(String name) {
135 return mInputConsumers.get(name);
Winson41275482016-10-10 15:17:45 -0700136 }
137
138 void layoutInputConsumers(int dw, int dh) {
139 for (int i = mInputConsumers.size() - 1; i >= 0; i--) {
140 mInputConsumers.valueAt(i).layout(dw, dh);
141 }
142 }
143
144 WindowManagerPolicy.InputConsumer createInputConsumer(Looper looper, String name,
145 InputEventReceiver.Factory inputEventReceiverFactory) {
146 if (mInputConsumers.containsKey(name)) {
Arthur Hung95b38a92018-07-20 18:56:12 +0800147 throw new IllegalStateException("Existing input consumer found with name: " + name
148 + ", display: " + mDisplayId);
Winson41275482016-10-10 15:17:45 -0700149 }
Winson41275482016-10-10 15:17:45 -0700150 final EventReceiverInputConsumer consumer = new EventReceiverInputConsumer(mService,
Winson Chung6463c362017-09-25 16:23:26 -0700151 this, looper, name, inputEventReceiverFactory, Process.myPid(),
Arthur Hung95b38a92018-07-20 18:56:12 +0800152 UserHandle.SYSTEM, mDisplayId);
Winson41275482016-10-10 15:17:45 -0700153 addInputConsumer(name, consumer);
154 return consumer;
155 }
156
Winson Chung6463c362017-09-25 16:23:26 -0700157 void createInputConsumer(IBinder token, String name, InputChannel inputChannel, int clientPid,
158 UserHandle clientUser) {
Winson41275482016-10-10 15:17:45 -0700159 if (mInputConsumers.containsKey(name)) {
Arthur Hung95b38a92018-07-20 18:56:12 +0800160 throw new IllegalStateException("Existing input consumer found with name: " + name
161 + ", display: " + mDisplayId);
Winson41275482016-10-10 15:17:45 -0700162 }
163
Winson Chung6463c362017-09-25 16:23:26 -0700164 final InputConsumerImpl consumer = new InputConsumerImpl(mService, token, name,
Arthur Hung95b38a92018-07-20 18:56:12 +0800165 inputChannel, clientPid, clientUser, mDisplayId);
Winson41275482016-10-10 15:17:45 -0700166 switch (name) {
167 case INPUT_CONSUMER_WALLPAPER:
168 consumer.mWindowHandle.hasWallpaper = true;
169 break;
170 case INPUT_CONSUMER_PIP:
171 // The touchable region of the Pip input window is cropped to the bounds of the
172 // stack, and we need FLAG_NOT_TOUCH_MODAL to ensure other events fall through
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700173 consumer.mWindowHandle.layoutParamsFlags |= FLAG_NOT_TOUCH_MODAL;
Winson41275482016-10-10 15:17:45 -0700174 break;
175 }
176 addInputConsumer(name, consumer);
177 }
178
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800179
Wale Ogunwale7402ddf2017-03-29 12:58:24 -0700180 private void addInputWindowHandle(final InputWindowHandle windowHandle) {
Jeff Brown9302c872011-07-13 22:51:29 -0700181 if (mInputWindowHandles == null) {
182 mInputWindowHandles = new InputWindowHandle[16];
183 }
184 if (mInputWindowHandleCount >= mInputWindowHandles.length) {
185 mInputWindowHandles = Arrays.copyOf(mInputWindowHandles,
186 mInputWindowHandleCount * 2);
187 }
188 mInputWindowHandles[mInputWindowHandleCount++] = windowHandle;
189 }
190
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700191 void addInputWindowHandle(final InputWindowHandle inputWindowHandle,
Craig Mautnerc08eab82014-11-11 09:03:59 -0800192 final WindowState child, int flags, final int type, final boolean isVisible,
Wale Ogunwale053c8e42015-11-16 14:27:21 -0800193 final boolean hasFocus, final boolean hasWallpaper) {
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700194 // Add a window to our list of input windows.
195 inputWindowHandle.name = child.toString();
Wale Ogunwale053c8e42015-11-16 14:27:21 -0800196 flags = child.getTouchableRegion(inputWindowHandle.touchableRegion, flags);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700197 inputWindowHandle.layoutParamsFlags = flags;
198 inputWindowHandle.layoutParamsType = type;
199 inputWindowHandle.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
200 inputWindowHandle.visible = isVisible;
201 inputWindowHandle.canReceiveKeys = child.canReceiveKeys();
202 inputWindowHandle.hasFocus = hasFocus;
203 inputWindowHandle.hasWallpaper = hasWallpaper;
204 inputWindowHandle.paused = child.mAppToken != null ? child.mAppToken.paused : false;
205 inputWindowHandle.layer = child.mLayer;
206 inputWindowHandle.ownerPid = child.mSession.mPid;
207 inputWindowHandle.ownerUid = child.mSession.mUid;
208 inputWindowHandle.inputFeatures = child.mAttrs.inputFeatures;
Arthur Hung95b38a92018-07-20 18:56:12 +0800209 inputWindowHandle.displayId = child.getDisplayId();
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700210
chaviw492139a2018-07-16 16:07:35 -0700211 final Rect frame = child.getFrameLw();
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700212 inputWindowHandle.frameLeft = frame.left;
213 inputWindowHandle.frameTop = frame.top;
214 inputWindowHandle.frameRight = frame.right;
215 inputWindowHandle.frameBottom = frame.bottom;
216
217 if (child.mGlobalScale != 1) {
218 // If we are scaling the window, input coordinates need
219 // to be inversely scaled to map from what is on screen
220 // to what is actually being touched in the UI.
221 inputWindowHandle.scaleFactor = 1.0f/child.mGlobalScale;
222 } else {
223 inputWindowHandle.scaleFactor = 1;
224 }
225
Filip Gruszczynskif8a2a632015-10-28 11:18:02 -0700226 if (DEBUG_INPUT) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800227 Slog.d(TAG_WM, "addInputWindowHandle: "
Chong Zhangb15758a2015-11-17 12:12:03 -0800228 + child + ", " + inputWindowHandle);
Filip Gruszczynskif8a2a632015-10-28 11:18:02 -0700229 }
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700230 addInputWindowHandle(inputWindowHandle);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700231 }
232
Jeff Brown9302c872011-07-13 22:51:29 -0700233 private void clearInputWindowHandlesLw() {
234 while (mInputWindowHandleCount != 0) {
235 mInputWindowHandles[--mInputWindowHandleCount] = null;
236 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800237 }
238
Wale Ogunwale6213caa2016-12-02 16:47:15 +0000239 void setUpdateInputWindowsNeededLw() {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800240 mUpdateInputWindowsNeeded = true;
241 }
242
243 /* Updates the cached window information provided to the input dispatcher. */
Wale Ogunwale6213caa2016-12-02 16:47:15 +0000244 void updateInputWindowsLw(boolean force) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800245 if (!force && !mUpdateInputWindowsNeeded) {
246 return;
247 }
248 mUpdateInputWindowsNeeded = false;
249
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800250 if (false) Slog.d(TAG_WM, ">>>>>> ENTERED updateInputWindowsLw");
Jeff Brown9302c872011-07-13 22:51:29 -0700251
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800252 // Populate the input window list with information about all of the windows that
253 // could potentially receive input.
254 // As an optimization, we could try to prune the list of windows but this turns
255 // out to be difficult because only the native code knows for sure which window
256 // currently has touch focus.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800257
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700258 // If there's a drag in flight, provide a pseudo-window to catch drag input
Daichi Hirono76a26aa2017-09-11 15:13:38 +0900259 final boolean inDrag = mService.mDragDropController.dragDropActiveLocked();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800260 if (inDrag) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800261 if (DEBUG_DRAG) {
262 Log.d(TAG_WM, "Inserting drag window");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800263 }
Daichi Hirono76a26aa2017-09-11 15:13:38 +0900264 final InputWindowHandle dragWindowHandle =
Daichi Hirono768012e2017-10-30 10:05:37 +0900265 mService.mDragDropController.getInputWindowHandleLocked();
Garfield Tan07544cd2018-09-12 16:16:54 -0700266 if (dragWindowHandle == null) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800267 Slog.w(TAG_WM, "Drag is in progress but there is no "
Jeff Browncc4f7db2011-08-30 20:34:48 -0700268 + "drag window handle.");
Garfield Tan07544cd2018-09-12 16:16:54 -0700269 } else if (dragWindowHandle.displayId == mDisplayId) {
270 addInputWindowHandle(dragWindowHandle);
Jeff Browncc4f7db2011-08-30 20:34:48 -0700271 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800272 }
273
Daichi Hirono34fb7312017-12-04 10:00:24 +0900274 final boolean inPositioning = mService.mTaskPositioningController.isPositioningLocked();
Chong Zhang8e89b312015-09-09 15:09:30 -0700275 if (inPositioning) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800276 if (DEBUG_TASK_POSITIONING) {
277 Log.d(TAG_WM, "Inserting window handle for repositioning");
Chong Zhang8e89b312015-09-09 15:09:30 -0700278 }
Daichi Hirono34fb7312017-12-04 10:00:24 +0900279 final InputWindowHandle dragWindowHandle =
280 mService.mTaskPositioningController.getDragWindowHandleLocked();
Garfield Tan07544cd2018-09-12 16:16:54 -0700281 if (dragWindowHandle == null) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800282 Slog.e(TAG_WM,
Chong Zhang8e89b312015-09-09 15:09:30 -0700283 "Repositioning is in progress but there is no drag window handle.");
Garfield Tan07544cd2018-09-12 16:16:54 -0700284 } else if (dragWindowHandle.displayId == mDisplayId) {
285 addInputWindowHandle(dragWindowHandle);
Chong Zhang8e89b312015-09-09 15:09:30 -0700286 }
287 }
288
Jeff Brown83d616a2012-09-09 20:33:43 -0700289 // Add all windows on the default display.
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800290 mUpdateInputForAllWindowsConsumer.updateInputWindows(inDrag);
Wale Ogunwale6213caa2016-12-02 16:47:15 +0000291
292 if (false) Slog.d(TAG_WM, "<<<<<<< EXITED updateInputWindowsLw");
293 }
294
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800295 /* Called when the current input focus changes.
296 * Layer assignment is assumed to be complete by the time this is called.
297 */
298 public void setInputFocusLw(WindowState newWindow, boolean updateInputWindows) {
Filip Gruszczynskif8a2a632015-10-28 11:18:02 -0700299 if (DEBUG_FOCUS_LIGHT || DEBUG_INPUT) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800300 Slog.d(TAG_WM, "Input focus has changed to " + newWindow);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800301 }
302
303 if (newWindow != mInputFocus) {
304 if (newWindow != null && newWindow.canReceiveKeys()) {
305 // Displaying a window implicitly causes dispatching to be unpaused.
306 // This is to protect against bugs if someone pauses dispatching but
307 // forgets to resume.
308 newWindow.mToken.paused = false;
309 }
310
311 mInputFocus = newWindow;
312 setUpdateInputWindowsNeededLw();
313
314 if (updateInputWindows) {
315 updateInputWindowsLw(false /*force*/);
316 }
317 }
318 }
Craig Mautner58458122013-09-14 14:59:50 -0700319
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800320 public void setFocusedAppLw(AppWindowToken newApp) {
321 // Focused app has changed.
322 if (newApp == null) {
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800323 mService.mInputManager.setFocusedApplication(mDisplayId, null);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800324 } else {
Jeff Brown9302c872011-07-13 22:51:29 -0700325 final InputApplicationHandle handle = newApp.mInputApplicationHandle;
326 handle.name = newApp.toString();
Wale Ogunwale72919d22016-12-08 18:58:50 -0800327 handle.dispatchingTimeoutNanos = newApp.mInputDispatchingTimeoutNanos;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800328
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800329 mService.mInputManager.setFocusedApplication(mDisplayId, handle);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800330 }
331 }
Craig Mautner58458122013-09-14 14:59:50 -0700332
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800333 public void pauseDispatchingLw(WindowToken window) {
334 if (! window.paused) {
Filip Gruszczynskif8a2a632015-10-28 11:18:02 -0700335 if (DEBUG_INPUT) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800336 Slog.v(TAG_WM, "Pausing WindowToken " + window);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800337 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700338
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800339 window.paused = true;
340 updateInputWindowsLw(true /*force*/);
341 }
342 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700343
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800344 public void resumeDispatchingLw(WindowToken window) {
345 if (window.paused) {
Filip Gruszczynskif8a2a632015-10-28 11:18:02 -0700346 if (DEBUG_INPUT) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800347 Slog.v(TAG_WM, "Resuming WindowToken " + window);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800348 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700349
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800350 window.paused = false;
351 updateInputWindowsLw(true /*force*/);
352 }
353 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700354
Wale Ogunwalee89eeac2016-03-12 11:07:58 -0800355 void dump(PrintWriter pw, String prefix) {
Winson Chung853c99a2017-03-21 22:16:42 -0700356 final Set<String> inputConsumerKeys = mInputConsumers.keySet();
357 if (!inputConsumerKeys.isEmpty()) {
358 pw.println(prefix + "InputConsumers:");
359 for (String key : inputConsumerKeys) {
Winson Chung6463c362017-09-25 16:23:26 -0700360 mInputConsumers.get(key).dump(pw, key, prefix);
Winson Chung853c99a2017-03-21 22:16:42 -0700361 }
362 }
Wale Ogunwalee89eeac2016-03-12 11:07:58 -0800363 }
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800364
Arthur Hung39134b22018-08-14 11:58:28 +0800365 void onRemoved() {
366 // If DisplayContent removed, we need find a way to remove window handles of this display
367 // from InputDispatcher, so pass an empty InputWindowHandles to remove them.
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800368 mService.mInputManager.setInputWindows(mInputWindowHandles, mDisplayId);
Arthur Hung39134b22018-08-14 11:58:28 +0800369 }
370
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800371 private final class UpdateInputForAllWindowsConsumer implements Consumer<WindowState> {
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800372 InputConsumerImpl navInputConsumer;
373 InputConsumerImpl pipInputConsumer;
374 InputConsumerImpl wallpaperInputConsumer;
Winson Chunga89ffed2018-01-25 17:46:11 +0000375 InputConsumerImpl recentsAnimationInputConsumer;
Arthur Hung95b38a92018-07-20 18:56:12 +0800376
377 private boolean mAddInputConsumerHandle;
378 private boolean mAddPipInputConsumerHandle;
379 private boolean mAddWallpaperInputConsumerHandle;
380 private boolean mAddRecentsAnimationInputConsumerHandle;
381
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800382 boolean inDrag;
383 WallpaperController wallpaperController;
384
385 private void updateInputWindows(boolean inDrag) {
Jorim Jaggi60640512018-06-29 01:14:31 +0200386 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "updateInputWindows");
387
Arthur Hung95b38a92018-07-20 18:56:12 +0800388 navInputConsumer = getInputConsumer(INPUT_CONSUMER_NAVIGATION);
389 pipInputConsumer = getInputConsumer(INPUT_CONSUMER_PIP);
390 wallpaperInputConsumer = getInputConsumer(INPUT_CONSUMER_WALLPAPER);
391 recentsAnimationInputConsumer = getInputConsumer(INPUT_CONSUMER_RECENTS_ANIMATION);
392
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800393 mAddInputConsumerHandle = navInputConsumer != null;
394 mAddPipInputConsumerHandle = pipInputConsumer != null;
395 mAddWallpaperInputConsumerHandle = wallpaperInputConsumer != null;
Winson Chunga89ffed2018-01-25 17:46:11 +0000396 mAddRecentsAnimationInputConsumerHandle = recentsAnimationInputConsumer != null;
Arthur Hung95b38a92018-07-20 18:56:12 +0800397
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800398 mTmpRect.setEmpty();
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800399 mDisableWallpaperTouchEvents = false;
400 this.inDrag = inDrag;
401 wallpaperController = mService.mRoot.mWallpaperController;
402
Arthur Hung39134b22018-08-14 11:58:28 +0800403 mService.mRoot.getDisplayContent(mDisplayId).forAllWindows(this,
Arthur Hung95b38a92018-07-20 18:56:12 +0800404 true /* traverseTopToBottom */);
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800405 if (mAddWallpaperInputConsumerHandle) {
406 // No visible wallpaper found, add the wallpaper input consumer at the end.
407 addInputWindowHandle(wallpaperInputConsumer.mWindowHandle);
408 }
409
410 // Send windows to native code.
Tiger Huang1e5b10a2018-07-30 20:19:51 +0800411 mService.mInputManager.setInputWindows(mInputWindowHandles, mDisplayId);
Vladislav Kaznacheev2e96c632016-12-13 14:31:24 -0800412
413 clearInputWindowHandlesLw();
Jorim Jaggi60640512018-06-29 01:14:31 +0200414
415 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800416 }
417
418 @Override
419 public void accept(WindowState w) {
420 final InputChannel inputChannel = w.mInputChannel;
421 final InputWindowHandle inputWindowHandle = w.mInputWindowHandle;
422 if (inputChannel == null || inputWindowHandle == null || w.mRemoved
Matthew Nge15352e2016-12-20 15:36:29 -0800423 || w.canReceiveTouchInput()) {
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800424 // Skip this window because it cannot possibly receive input.
425 return;
426 }
427
Winson Chung61ecc1b2017-02-17 10:46:17 -0800428 final int flags = w.mAttrs.flags;
429 final int privateFlags = w.mAttrs.privateFlags;
430 final int type = w.mAttrs.type;
Arthur Hung39134b22018-08-14 11:58:28 +0800431 final boolean hasFocus = w.isFocused();
Winson Chung61ecc1b2017-02-17 10:46:17 -0800432 final boolean isVisible = w.isVisibleLw();
433
Winson Chunga89ffed2018-01-25 17:46:11 +0000434 if (mAddRecentsAnimationInputConsumerHandle) {
435 final RecentsAnimationController recentsAnimationController =
436 mService.getRecentsAnimationController();
437 if (recentsAnimationController != null
Winson Chungdb111ee2018-10-03 14:25:34 -0700438 && recentsAnimationController.shouldApplyInputConsumer(w.mAppToken)) {
Winson Chunga89ffed2018-01-25 17:46:11 +0000439 if (recentsAnimationController.updateInputConsumerForApp(
Arthur Hung95b38a92018-07-20 18:56:12 +0800440 recentsAnimationInputConsumer.mWindowHandle, hasFocus)) {
Winson Chunga89ffed2018-01-25 17:46:11 +0000441 addInputWindowHandle(recentsAnimationInputConsumer.mWindowHandle);
442 mAddRecentsAnimationInputConsumerHandle = false;
443 }
Winson Chungdb111ee2018-10-03 14:25:34 -0700444 // If the target app window does not yet exist, then we don't add the input
445 // consumer window, but also don't add the app window below.
Winson Chunga89ffed2018-01-25 17:46:11 +0000446 return;
447 }
448 }
449
Wale Ogunwale44f036f2017-09-29 05:09:09 -0700450 if (w.inPinnedWindowingMode()) {
Winson Chung61ecc1b2017-02-17 10:46:17 -0800451 if (mAddPipInputConsumerHandle
452 && (inputWindowHandle.layer <= pipInputConsumer.mWindowHandle.layer)) {
Bryce Leef3c6a472017-11-14 14:53:06 -0800453 // Update the bounds of the Pip input consumer to match the window bounds.
Winson Chunga89ffed2018-01-25 17:46:11 +0000454 w.getBounds(mTmpRect);
455 pipInputConsumer.mWindowHandle.touchableRegion.set(mTmpRect);
Winson Chung61ecc1b2017-02-17 10:46:17 -0800456 addInputWindowHandle(pipInputConsumer.mWindowHandle);
457 mAddPipInputConsumerHandle = false;
458 }
459 // TODO: Fix w.canReceiveTouchInput() to handle this case
460 if (!hasFocus) {
461 // Skip this pinned stack window if it does not have focus
462 return;
463 }
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800464 }
465
466 if (mAddInputConsumerHandle
467 && inputWindowHandle.layer <= navInputConsumer.mWindowHandle.layer) {
468 addInputWindowHandle(navInputConsumer.mWindowHandle);
469 mAddInputConsumerHandle = false;
470 }
471
472 if (mAddWallpaperInputConsumerHandle) {
473 if (w.mAttrs.type == TYPE_WALLPAPER && w.isVisibleLw()) {
474 // Add the wallpaper input consumer above the first visible wallpaper.
475 addInputWindowHandle(wallpaperInputConsumer.mWindowHandle);
476 mAddWallpaperInputConsumerHandle = false;
477 }
478 }
479
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800480 if ((privateFlags & PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS) != 0) {
481 mDisableWallpaperTouchEvents = true;
482 }
483 final boolean hasWallpaper = wallpaperController.isWallpaperTarget(w)
484 && (privateFlags & PRIVATE_FLAG_KEYGUARD) == 0
485 && !mDisableWallpaperTouchEvents;
486
487 // If there's a drag in progress and 'child' is a potential drop target,
488 // make sure it's been told about the drag
489 if (inDrag && isVisible && w.getDisplayContent().isDefaultDisplay) {
Daichi Hirono768012e2017-10-30 10:05:37 +0900490 mService.mDragDropController.sendDragStartedIfNeededLocked(w);
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800491 }
492
493 addInputWindowHandle(
494 inputWindowHandle, w, flags, type, isVisible, hasFocus, hasWallpaper);
495 }
496 }
Jeff Brownea426552011-07-18 16:53:48 -0700497}