blob: 12c72e9e07959fd86c4f1fc706871186bfc86cad [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
Andrii Kulian5406e7a2016-10-21 11:55:23 -070019import static android.view.Display.DEFAULT_DISPLAY;
Winson41275482016-10-10 15:17:45 -070020import static android.view.WindowManager.INPUT_CONSUMER_PIP;
21import static android.view.WindowManager.INPUT_CONSUMER_WALLPAPER;
Wale Ogunwalef7cab102016-10-25 15:25:14 -070022import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080023import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
24import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
25import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT;
26import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING;
27import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Filip Gruszczynski9cac3b42015-10-30 14:20:37 -070028
Sudheer Shankadc589ac2016-11-10 15:30:17 -080029import android.app.ActivityManager;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080030import android.graphics.Rect;
Wale Ogunwalee89eeac2016-03-12 11:07:58 -080031import android.os.Debug;
Winson41275482016-10-10 15:17:45 -070032import android.os.Looper;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080033import android.os.RemoteException;
Winson41275482016-10-10 15:17:45 -070034import android.util.ArrayMap;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080035import android.util.Log;
36import android.util.Slog;
Jeff Browncc4f7db2011-08-30 20:34:48 -070037import android.view.InputChannel;
Winson41275482016-10-10 15:17:45 -070038import android.view.InputEventReceiver;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080039import android.view.KeyEvent;
40import android.view.WindowManager;
41
Winson41275482016-10-10 15:17:45 -070042import android.view.WindowManagerPolicy;
Selim Cinekf83e8242015-05-19 18:08:14 -070043import com.android.server.input.InputApplicationHandle;
44import com.android.server.input.InputManagerService;
45import com.android.server.input.InputWindowHandle;
46
Wale Ogunwalee89eeac2016-03-12 11:07:58 -080047import java.io.PrintWriter;
Jeff Brown9302c872011-07-13 22:51:29 -070048import java.util.Arrays;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080049
Jeff Browna9d131c2012-09-20 16:48:17 -070050final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080051 private final WindowManagerService mService;
Selim Cinekf83e8242015-05-19 18:08:14 -070052
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080053 // Current window with input focus for keys and other non-touch events. May be null.
54 private WindowState mInputFocus;
Selim Cinekf83e8242015-05-19 18:08:14 -070055
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080056 // When true, prevents input dispatch from proceeding until set to false again.
57 private boolean mInputDispatchFrozen;
Selim Cinekf83e8242015-05-19 18:08:14 -070058
Wale Ogunwalee89eeac2016-03-12 11:07:58 -080059 // The reason the input is currently frozen or null if the input isn't frozen.
60 private String mInputFreezeReason = null;
61
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080062 // When true, input dispatch proceeds normally. Otherwise all events are dropped.
Jeff Brownc042ee22012-05-08 13:03:42 -070063 // Initially false, so that input does not get dispatched until boot is finished at
64 // which point the ActivityManager will enable dispatching.
65 private boolean mInputDispatchEnabled;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080066
67 // When true, need to call updateInputWindowsLw().
68 private boolean mUpdateInputWindowsNeeded = true;
69
Jeff Brown9302c872011-07-13 22:51:29 -070070 // Array of window handles to provide to the input dispatcher.
71 private InputWindowHandle[] mInputWindowHandles;
72 private int mInputWindowHandleCount;
73
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080074 // Set to true when the first input device configuration change notification
75 // is received to indicate that the input devices are ready.
76 private final Object mInputDevicesReadyMonitor = new Object();
77 private boolean mInputDevicesReady;
78
Winson41275482016-10-10 15:17:45 -070079 /**
80 * The set of input consumer added to the window manager by name, which consumes input events
81 * for the windows below it.
82 */
83 private final ArrayMap<String, InputConsumerImpl> mInputConsumers = new ArrayMap();
84
85 private static final class EventReceiverInputConsumer extends InputConsumerImpl
86 implements WindowManagerPolicy.InputConsumer {
87 private InputMonitor mInputMonitor;
88 private final InputEventReceiver mInputEventReceiver;
89
90 EventReceiverInputConsumer(WindowManagerService service, InputMonitor monitor,
91 Looper looper, String name,
92 InputEventReceiver.Factory inputEventReceiverFactory) {
93 super(service, name, null);
94 mInputMonitor = monitor;
95 mInputEventReceiver = inputEventReceiverFactory.createInputEventReceiver(
96 mClientChannel, looper);
97 }
98
99 @Override
100 public void dismiss() {
101 synchronized (mService.mWindowMap) {
102 if (mInputMonitor.destroyInputConsumer(mWindowHandle.name)) {
103 mInputEventReceiver.dispose();
104 }
105 }
106 }
107 }
108
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800109 public InputMonitor(WindowManagerService service) {
110 mService = service;
111 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700112
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700113 private void addInputConsumer(String name, InputConsumerImpl consumer) {
Winson41275482016-10-10 15:17:45 -0700114 mInputConsumers.put(name, consumer);
115 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
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700134 InputConsumerImpl getInputConsumer(String name, int displayId) {
135 // TODO(multi-display): Allow input consumers on non-default displays?
136 return (displayId == DEFAULT_DISPLAY) ? mInputConsumers.get(name) : null;
Winson41275482016-10-10 15:17:45 -0700137 }
138
139 void layoutInputConsumers(int dw, int dh) {
140 for (int i = mInputConsumers.size() - 1; i >= 0; i--) {
141 mInputConsumers.valueAt(i).layout(dw, dh);
142 }
143 }
144
145 WindowManagerPolicy.InputConsumer createInputConsumer(Looper looper, String name,
146 InputEventReceiver.Factory inputEventReceiverFactory) {
147 if (mInputConsumers.containsKey(name)) {
148 throw new IllegalStateException("Existing input consumer found with name: " + name);
149 }
150
151 final EventReceiverInputConsumer consumer = new EventReceiverInputConsumer(mService,
152 this, looper, name, inputEventReceiverFactory);
153 addInputConsumer(name, consumer);
154 return consumer;
155 }
156
157 void createInputConsumer(String name, InputChannel inputChannel) {
158 if (mInputConsumers.containsKey(name)) {
159 throw new IllegalStateException("Existing input consumer found with name: " + name);
160 }
161
162 final InputConsumerImpl consumer = new InputConsumerImpl(mService, name, inputChannel);
163 switch (name) {
164 case INPUT_CONSUMER_WALLPAPER:
165 consumer.mWindowHandle.hasWallpaper = true;
166 break;
167 case INPUT_CONSUMER_PIP:
168 // The touchable region of the Pip input window is cropped to the bounds of the
169 // stack, and we need FLAG_NOT_TOUCH_MODAL to ensure other events fall through
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700170 consumer.mWindowHandle.layoutParamsFlags |= FLAG_NOT_TOUCH_MODAL;
Winson41275482016-10-10 15:17:45 -0700171 break;
172 }
173 addInputConsumer(name, consumer);
174 }
175
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800176 /* Notifies the window manager about a broken input channel.
Chong Zhang8e89b312015-09-09 15:09:30 -0700177 *
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800178 * Called by the InputManager.
179 */
Craig Mautner4cd0c13f2013-04-16 15:55:52 -0700180 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800181 public void notifyInputChannelBroken(InputWindowHandle inputWindowHandle) {
182 if (inputWindowHandle == null) {
183 return;
184 }
185
186 synchronized (mService.mWindowMap) {
187 WindowState windowState = (WindowState) inputWindowHandle.windowState;
Jeff Brown9302c872011-07-13 22:51:29 -0700188 if (windowState != null) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800189 Slog.i(TAG_WM, "WINDOW DIED " + windowState);
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700190 windowState.removeIfPossible();
Jeff Brown9302c872011-07-13 22:51:29 -0700191 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800192 }
193 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700194
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800195 /* Notifies the window manager about an application that is not responding.
196 * Returns a new timeout to continue waiting in nanoseconds, or 0 to abort dispatch.
Chong Zhang8e89b312015-09-09 15:09:30 -0700197 *
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800198 * Called by the InputManager.
199 */
Craig Mautner4cd0c13f2013-04-16 15:55:52 -0700200 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800201 public long notifyANR(InputApplicationHandle inputApplicationHandle,
Jeff Brownbd181bb2013-09-10 16:44:24 -0700202 InputWindowHandle inputWindowHandle, String reason) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800203 AppWindowToken appWindowToken = null;
Dianne Hackborn5fe7e2a2012-10-04 11:58:16 -0700204 WindowState windowState = null;
205 boolean aboveSystem = false;
Jeff Brownee172412012-06-18 12:58:03 -0700206 synchronized (mService.mWindowMap) {
Jeff Brownee172412012-06-18 12:58:03 -0700207 if (inputWindowHandle != null) {
208 windowState = (WindowState) inputWindowHandle.windowState;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800209 if (windowState != null) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800210 appWindowToken = windowState.mAppToken;
211 }
212 }
Jeff Brownee172412012-06-18 12:58:03 -0700213 if (appWindowToken == null && inputApplicationHandle != null) {
214 appWindowToken = (AppWindowToken)inputApplicationHandle.appWindowToken;
Jeff Brown9302c872011-07-13 22:51:29 -0700215 }
Jeff Brownee172412012-06-18 12:58:03 -0700216
217 if (windowState != null) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800218 Slog.i(TAG_WM, "Input event dispatching timed out "
Jeff Brownbd181bb2013-09-10 16:44:24 -0700219 + "sending to " + windowState.mAttrs.getTitle()
220 + ". Reason: " + reason);
Dianne Hackborn5fe7e2a2012-10-04 11:58:16 -0700221 // Figure out whether this window is layered above system windows.
222 // We need to do this here to help the activity manager know how to
223 // layer its ANR dialog.
224 int systemAlertLayer = mService.mPolicy.windowTypeToLayerLw(
225 WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
226 aboveSystem = windowState.mBaseLayer > systemAlertLayer;
Jeff Brownee172412012-06-18 12:58:03 -0700227 } else if (appWindowToken != null) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800228 Slog.i(TAG_WM, "Input event dispatching timed out "
Jeff Brownbd181bb2013-09-10 16:44:24 -0700229 + "sending to application " + appWindowToken.stringName
230 + ". Reason: " + reason);
Jeff Brownee172412012-06-18 12:58:03 -0700231 } else {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800232 Slog.i(TAG_WM, "Input event dispatching timed out "
Jeff Brownbd181bb2013-09-10 16:44:24 -0700233 + ". Reason: " + reason);
Jeff Brownee172412012-06-18 12:58:03 -0700234 }
235
Jeff Brownbd181bb2013-09-10 16:44:24 -0700236 mService.saveANRStateLocked(appWindowToken, windowState, reason);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800237 }
238
239 if (appWindowToken != null && appWindowToken.appToken != null) {
240 try {
241 // Notify the activity manager about the timeout and let it decide whether
242 // to abort dispatching or keep waiting.
Jeff Brownbd181bb2013-09-10 16:44:24 -0700243 boolean abort = appWindowToken.appToken.keyDispatchingTimedOut(reason);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800244 if (! abort) {
245 // The activity manager declined to abort dispatching.
246 // Wait a bit longer and timeout again later.
247 return appWindowToken.inputDispatchingTimeoutNanos;
248 }
249 } catch (RemoteException ex) {
250 }
Dianne Hackborn5fe7e2a2012-10-04 11:58:16 -0700251 } else if (windowState != null) {
252 try {
253 // Notify the activity manager about the timeout and let it decide whether
254 // to abort dispatching or keep waiting.
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800255 long timeout = ActivityManager.getService().inputDispatchingTimedOut(
Jeff Brownbd181bb2013-09-10 16:44:24 -0700256 windowState.mSession.mPid, aboveSystem, reason);
Dianne Hackborn5fe7e2a2012-10-04 11:58:16 -0700257 if (timeout >= 0) {
258 // The activity manager declined to abort dispatching.
259 // Wait a bit longer and timeout again later.
baik.handef340d2015-04-15 10:21:05 +0900260 return timeout * 1000000L; // nanoseconds
Dianne Hackborn5fe7e2a2012-10-04 11:58:16 -0700261 }
262 } catch (RemoteException ex) {
263 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800264 }
265 return 0; // abort dispatching
266 }
267
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700268 void addInputWindowHandle(final InputWindowHandle windowHandle) {
Jeff Brown9302c872011-07-13 22:51:29 -0700269 if (mInputWindowHandles == null) {
270 mInputWindowHandles = new InputWindowHandle[16];
271 }
272 if (mInputWindowHandleCount >= mInputWindowHandles.length) {
273 mInputWindowHandles = Arrays.copyOf(mInputWindowHandles,
274 mInputWindowHandleCount * 2);
275 }
276 mInputWindowHandles[mInputWindowHandleCount++] = windowHandle;
277 }
278
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700279 void addInputWindowHandle(final InputWindowHandle inputWindowHandle,
Craig Mautnerc08eab82014-11-11 09:03:59 -0800280 final WindowState child, int flags, final int type, final boolean isVisible,
Wale Ogunwale053c8e42015-11-16 14:27:21 -0800281 final boolean hasFocus, final boolean hasWallpaper) {
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700282 // Add a window to our list of input windows.
283 inputWindowHandle.name = child.toString();
Wale Ogunwale053c8e42015-11-16 14:27:21 -0800284 flags = child.getTouchableRegion(inputWindowHandle.touchableRegion, flags);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700285 inputWindowHandle.layoutParamsFlags = flags;
286 inputWindowHandle.layoutParamsType = type;
287 inputWindowHandle.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
288 inputWindowHandle.visible = isVisible;
289 inputWindowHandle.canReceiveKeys = child.canReceiveKeys();
290 inputWindowHandle.hasFocus = hasFocus;
291 inputWindowHandle.hasWallpaper = hasWallpaper;
292 inputWindowHandle.paused = child.mAppToken != null ? child.mAppToken.paused : false;
293 inputWindowHandle.layer = child.mLayer;
294 inputWindowHandle.ownerPid = child.mSession.mPid;
295 inputWindowHandle.ownerUid = child.mSession.mUid;
296 inputWindowHandle.inputFeatures = child.mAttrs.inputFeatures;
297
298 final Rect frame = child.mFrame;
299 inputWindowHandle.frameLeft = frame.left;
300 inputWindowHandle.frameTop = frame.top;
301 inputWindowHandle.frameRight = frame.right;
302 inputWindowHandle.frameBottom = frame.bottom;
303
304 if (child.mGlobalScale != 1) {
305 // If we are scaling the window, input coordinates need
306 // to be inversely scaled to map from what is on screen
307 // to what is actually being touched in the UI.
308 inputWindowHandle.scaleFactor = 1.0f/child.mGlobalScale;
309 } else {
310 inputWindowHandle.scaleFactor = 1;
311 }
312
Filip Gruszczynskif8a2a632015-10-28 11:18:02 -0700313 if (DEBUG_INPUT) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800314 Slog.d(TAG_WM, "addInputWindowHandle: "
Chong Zhangb15758a2015-11-17 12:12:03 -0800315 + child + ", " + inputWindowHandle);
Filip Gruszczynskif8a2a632015-10-28 11:18:02 -0700316 }
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700317 addInputWindowHandle(inputWindowHandle);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700318 }
319
Jeff Brown9302c872011-07-13 22:51:29 -0700320 private void clearInputWindowHandlesLw() {
321 while (mInputWindowHandleCount != 0) {
322 mInputWindowHandles[--mInputWindowHandleCount] = null;
323 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800324 }
325
326 public void setUpdateInputWindowsNeededLw() {
327 mUpdateInputWindowsNeeded = true;
328 }
329
330 /* Updates the cached window information provided to the input dispatcher. */
331 public void updateInputWindowsLw(boolean force) {
332 if (!force && !mUpdateInputWindowsNeeded) {
333 return;
334 }
335 mUpdateInputWindowsNeeded = false;
336
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800337 if (false) Slog.d(TAG_WM, ">>>>>> ENTERED updateInputWindowsLw");
Jeff Brown9302c872011-07-13 22:51:29 -0700338
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800339 // Populate the input window list with information about all of the windows that
340 // could potentially receive input.
341 // As an optimization, we could try to prune the list of windows but this turns
342 // out to be difficult because only the native code knows for sure which window
343 // currently has touch focus.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800344
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700345 // If there's a drag in flight, provide a pseudo-window to catch drag input
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800346 final boolean inDrag = (mService.mDragState != null);
347 if (inDrag) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800348 if (DEBUG_DRAG) {
349 Log.d(TAG_WM, "Inserting drag window");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800350 }
Vladislav Kaznacheev64b103a2016-08-10 11:49:08 -0700351 final InputWindowHandle dragWindowHandle = mService.mDragState.getInputWindowHandle();
Jeff Browncc4f7db2011-08-30 20:34:48 -0700352 if (dragWindowHandle != null) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700353 addInputWindowHandle(dragWindowHandle);
Jeff Browncc4f7db2011-08-30 20:34:48 -0700354 } else {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800355 Slog.w(TAG_WM, "Drag is in progress but there is no "
Jeff Browncc4f7db2011-08-30 20:34:48 -0700356 + "drag window handle.");
357 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800358 }
359
Chong Zhang8e89b312015-09-09 15:09:30 -0700360 final boolean inPositioning = (mService.mTaskPositioner != null);
361 if (inPositioning) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800362 if (DEBUG_TASK_POSITIONING) {
363 Log.d(TAG_WM, "Inserting window handle for repositioning");
Chong Zhang8e89b312015-09-09 15:09:30 -0700364 }
365 final InputWindowHandle dragWindowHandle = mService.mTaskPositioner.mDragWindowHandle;
366 if (dragWindowHandle != null) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700367 addInputWindowHandle(dragWindowHandle);
Chong Zhang8e89b312015-09-09 15:09:30 -0700368 } else {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800369 Slog.e(TAG_WM,
Chong Zhang8e89b312015-09-09 15:09:30 -0700370 "Repositioning is in progress but there is no drag window handle.");
371 }
372 }
373
Jeff Brown83d616a2012-09-09 20:33:43 -0700374 // Add all windows on the default display.
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700375 mService.mRoot.updateInputWindows(this, mInputFocus, inDrag);
Vladislav Kaznacheev0d50d862016-03-29 15:43:28 -0700376
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800377 // Send windows to native code.
Jeff Brown9302c872011-07-13 22:51:29 -0700378 mService.mInputManager.setInputWindows(mInputWindowHandles);
379
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800380 // Clear the list in preparation for the next round.
Jeff Brown9302c872011-07-13 22:51:29 -0700381 clearInputWindowHandlesLw();
382
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800383 if (false) Slog.d(TAG_WM, "<<<<<<< EXITED updateInputWindowsLw");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800384 }
385
386 /* Notifies that the input device configuration has changed. */
Jeff Brown0b31d812013-08-22 19:41:29 -0700387 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800388 public void notifyConfigurationChanged() {
Andrii Kulian5406e7a2016-10-21 11:55:23 -0700389 // TODO(multi-display): Notify proper displays that are associated with this input device.
390 mService.sendNewConfiguration(DEFAULT_DISPLAY);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800391
392 synchronized (mInputDevicesReadyMonitor) {
393 if (!mInputDevicesReady) {
394 mInputDevicesReady = true;
395 mInputDevicesReadyMonitor.notifyAll();
396 }
397 }
398 }
399
400 /* Waits until the built-in input devices have been configured. */
401 public boolean waitForInputDevicesReady(long timeoutMillis) {
402 synchronized (mInputDevicesReadyMonitor) {
403 if (!mInputDevicesReady) {
404 try {
405 mInputDevicesReadyMonitor.wait(timeoutMillis);
406 } catch (InterruptedException ex) {
407 }
408 }
409 return mInputDevicesReady;
410 }
411 }
412
413 /* Notifies that the lid switch changed state. */
Jeff Brown0b31d812013-08-22 19:41:29 -0700414 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800415 public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
416 mService.mPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);
417 }
Craig Mautner58458122013-09-14 14:59:50 -0700418
Michael Wright3818c922014-09-02 13:59:07 -0700419 /* Notifies that the camera lens cover state has changed. */
420 @Override
421 public void notifyCameraLensCoverSwitchChanged(long whenNanos, boolean lensCovered) {
422 mService.mPolicy.notifyCameraLensCoverSwitchChanged(whenNanos, lensCovered);
423 }
424
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800425 /* Provides an opportunity for the window manager policy to intercept early key
426 * processing as soon as the key has been read from the device. */
Jeff Brown0b31d812013-08-22 19:41:29 -0700427 @Override
Jeff Brown037c33e2014-04-09 00:31:55 -0700428 public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
429 return mService.mPolicy.interceptKeyBeforeQueueing(event, policyFlags);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800430 }
Jeff Brown56194eb2011-03-02 19:23:13 -0800431
Michael Wright70af00a2014-09-03 19:30:20 -0700432 /* Provides an opportunity for the window manager policy to intercept early motion event
433 * processing when the device is in a non-interactive state since these events are normally
Jeff Brown56194eb2011-03-02 19:23:13 -0800434 * dropped. */
Jeff Brown0b31d812013-08-22 19:41:29 -0700435 @Override
Michael Wright70af00a2014-09-03 19:30:20 -0700436 public int interceptMotionBeforeQueueingNonInteractive(long whenNanos, int policyFlags) {
437 return mService.mPolicy.interceptMotionBeforeQueueingNonInteractive(
438 whenNanos, policyFlags);
Jeff Brown56194eb2011-03-02 19:23:13 -0800439 }
440
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800441 /* Provides an opportunity for the window manager policy to process a key before
442 * ordinary dispatch. */
Jeff Brown0b31d812013-08-22 19:41:29 -0700443 @Override
Jeff Brown905805a2011-10-12 13:57:59 -0700444 public long interceptKeyBeforeDispatching(
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800445 InputWindowHandle focus, KeyEvent event, int policyFlags) {
446 WindowState windowState = focus != null ? (WindowState) focus.windowState : null;
447 return mService.mPolicy.interceptKeyBeforeDispatching(windowState, event, policyFlags);
448 }
Craig Mautner58458122013-09-14 14:59:50 -0700449
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800450 /* Provides an opportunity for the window manager policy to process a key that
451 * the application did not handle. */
Jeff Brown0b31d812013-08-22 19:41:29 -0700452 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800453 public KeyEvent dispatchUnhandledKey(
454 InputWindowHandle focus, KeyEvent event, int policyFlags) {
455 WindowState windowState = focus != null ? (WindowState) focus.windowState : null;
456 return mService.mPolicy.dispatchUnhandledKey(windowState, event, policyFlags);
457 }
Jeff Brown4532e612012-04-05 14:27:12 -0700458
459 /* Callback to get pointer layer. */
Jeff Brown0b31d812013-08-22 19:41:29 -0700460 @Override
Jeff Brown4532e612012-04-05 14:27:12 -0700461 public int getPointerLayer() {
462 return mService.mPolicy.windowTypeToLayerLw(WindowManager.LayoutParams.TYPE_POINTER)
463 * WindowManagerService.TYPE_LAYER_MULTIPLIER
464 + WindowManagerService.TYPE_LAYER_OFFSET;
465 }
466
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800467 /* Called when the current input focus changes.
468 * Layer assignment is assumed to be complete by the time this is called.
469 */
470 public void setInputFocusLw(WindowState newWindow, boolean updateInputWindows) {
Filip Gruszczynskif8a2a632015-10-28 11:18:02 -0700471 if (DEBUG_FOCUS_LIGHT || DEBUG_INPUT) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800472 Slog.d(TAG_WM, "Input focus has changed to " + newWindow);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800473 }
474
475 if (newWindow != mInputFocus) {
476 if (newWindow != null && newWindow.canReceiveKeys()) {
477 // Displaying a window implicitly causes dispatching to be unpaused.
478 // This is to protect against bugs if someone pauses dispatching but
479 // forgets to resume.
480 newWindow.mToken.paused = false;
481 }
482
483 mInputFocus = newWindow;
484 setUpdateInputWindowsNeededLw();
485
486 if (updateInputWindows) {
487 updateInputWindowsLw(false /*force*/);
488 }
489 }
490 }
Craig Mautner58458122013-09-14 14:59:50 -0700491
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800492 public void setFocusedAppLw(AppWindowToken newApp) {
493 // Focused app has changed.
494 if (newApp == null) {
495 mService.mInputManager.setFocusedApplication(null);
496 } else {
Jeff Brown9302c872011-07-13 22:51:29 -0700497 final InputApplicationHandle handle = newApp.mInputApplicationHandle;
498 handle.name = newApp.toString();
499 handle.dispatchingTimeoutNanos = newApp.inputDispatchingTimeoutNanos;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800500
Jeff Brown9302c872011-07-13 22:51:29 -0700501 mService.mInputManager.setFocusedApplication(handle);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800502 }
503 }
Craig Mautner58458122013-09-14 14:59:50 -0700504
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800505 public void pauseDispatchingLw(WindowToken window) {
506 if (! window.paused) {
Filip Gruszczynskif8a2a632015-10-28 11:18:02 -0700507 if (DEBUG_INPUT) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800508 Slog.v(TAG_WM, "Pausing WindowToken " + window);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800509 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700510
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800511 window.paused = true;
512 updateInputWindowsLw(true /*force*/);
513 }
514 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700515
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800516 public void resumeDispatchingLw(WindowToken window) {
517 if (window.paused) {
Filip Gruszczynskif8a2a632015-10-28 11:18:02 -0700518 if (DEBUG_INPUT) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800519 Slog.v(TAG_WM, "Resuming WindowToken " + window);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800520 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700521
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800522 window.paused = false;
523 updateInputWindowsLw(true /*force*/);
524 }
525 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700526
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800527 public void freezeInputDispatchingLw() {
Wale Ogunwalee89eeac2016-03-12 11:07:58 -0800528 if (!mInputDispatchFrozen) {
Filip Gruszczynskif8a2a632015-10-28 11:18:02 -0700529 if (DEBUG_INPUT) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800530 Slog.v(TAG_WM, "Freezing input dispatching");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800531 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700532
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800533 mInputDispatchFrozen = true;
Wale Ogunwalee89eeac2016-03-12 11:07:58 -0800534
535 if (DEBUG_INPUT || true) {
536 mInputFreezeReason = Debug.getCallers(6);
537 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800538 updateInputDispatchModeLw();
539 }
540 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700541
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800542 public void thawInputDispatchingLw() {
543 if (mInputDispatchFrozen) {
Filip Gruszczynskif8a2a632015-10-28 11:18:02 -0700544 if (DEBUG_INPUT) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800545 Slog.v(TAG_WM, "Thawing input dispatching");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800546 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700547
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800548 mInputDispatchFrozen = false;
Wale Ogunwalee89eeac2016-03-12 11:07:58 -0800549 mInputFreezeReason = null;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800550 updateInputDispatchModeLw();
551 }
552 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700553
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800554 public void setEventDispatchingLw(boolean enabled) {
555 if (mInputDispatchEnabled != enabled) {
Filip Gruszczynskif8a2a632015-10-28 11:18:02 -0700556 if (DEBUG_INPUT) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800557 Slog.v(TAG_WM, "Setting event dispatching to " + enabled);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800558 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700559
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800560 mInputDispatchEnabled = enabled;
561 updateInputDispatchModeLw();
562 }
563 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700564
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800565 private void updateInputDispatchModeLw() {
566 mService.mInputManager.setInputDispatchMode(mInputDispatchEnabled, mInputDispatchFrozen);
567 }
Wale Ogunwalee89eeac2016-03-12 11:07:58 -0800568
569 void dump(PrintWriter pw, String prefix) {
570 if (mInputFreezeReason != null) {
571 pw.println(prefix + "mInputFreezeReason=" + mInputFreezeReason);
572 }
573 }
Jeff Brownea426552011-07-18 16:53:48 -0700574}