blob: 065a3dca05ff51be065e1423c68ab08a620e5d18 [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
Winson41275482016-10-10 15:17:45 -070019import static android.view.WindowManager.INPUT_CONSUMER_PIP;
20import static android.view.WindowManager.INPUT_CONSUMER_WALLPAPER;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080021import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
22import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
23import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT;
24import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING;
25import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Filip Gruszczynski9cac3b42015-10-30 14:20:37 -070026
Dianne Hackborn5fe7e2a2012-10-04 11:58:16 -070027import android.app.ActivityManagerNative;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080028import android.graphics.Rect;
Wale Ogunwalee89eeac2016-03-12 11:07:58 -080029import android.os.Debug;
Winson41275482016-10-10 15:17:45 -070030import android.os.Looper;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080031import android.os.RemoteException;
Winson41275482016-10-10 15:17:45 -070032import android.util.ArrayMap;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080033import android.util.Log;
34import android.util.Slog;
Jeff Browncc4f7db2011-08-30 20:34:48 -070035import android.view.InputChannel;
Winson41275482016-10-10 15:17:45 -070036import android.view.InputEventReceiver;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080037import android.view.KeyEvent;
38import android.view.WindowManager;
39
Winson41275482016-10-10 15:17:45 -070040import android.view.WindowManagerPolicy;
Selim Cinekf83e8242015-05-19 18:08:14 -070041import com.android.server.input.InputApplicationHandle;
42import com.android.server.input.InputManagerService;
43import com.android.server.input.InputWindowHandle;
44
Wale Ogunwalee89eeac2016-03-12 11:07:58 -080045import java.io.PrintWriter;
Jeff Brown9302c872011-07-13 22:51:29 -070046import java.util.Arrays;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080047
Jeff Browna9d131c2012-09-20 16:48:17 -070048final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080049 private final WindowManagerService mService;
Selim Cinekf83e8242015-05-19 18:08:14 -070050
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080051 // Current window with input focus for keys and other non-touch events. May be null.
52 private WindowState mInputFocus;
Selim Cinekf83e8242015-05-19 18:08:14 -070053
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080054 // When true, prevents input dispatch from proceeding until set to false again.
55 private boolean mInputDispatchFrozen;
Selim Cinekf83e8242015-05-19 18:08:14 -070056
Wale Ogunwalee89eeac2016-03-12 11:07:58 -080057 // The reason the input is currently frozen or null if the input isn't frozen.
58 private String mInputFreezeReason = null;
59
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080060 // When true, input dispatch proceeds normally. Otherwise all events are dropped.
Jeff Brownc042ee22012-05-08 13:03:42 -070061 // Initially false, so that input does not get dispatched until boot is finished at
62 // which point the ActivityManager will enable dispatching.
63 private boolean mInputDispatchEnabled;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080064
65 // When true, need to call updateInputWindowsLw().
66 private boolean mUpdateInputWindowsNeeded = true;
67
Jeff Brown9302c872011-07-13 22:51:29 -070068 // Array of window handles to provide to the input dispatcher.
69 private InputWindowHandle[] mInputWindowHandles;
70 private int mInputWindowHandleCount;
71
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080072 // Set to true when the first input device configuration change notification
73 // is received to indicate that the input devices are ready.
74 private final Object mInputDevicesReadyMonitor = new Object();
75 private boolean mInputDevicesReady;
76
Winson41275482016-10-10 15:17:45 -070077 /**
78 * The set of input consumer added to the window manager by name, which consumes input events
79 * for the windows below it.
80 */
81 private final ArrayMap<String, InputConsumerImpl> mInputConsumers = new ArrayMap();
82
83 private static final class EventReceiverInputConsumer extends InputConsumerImpl
84 implements WindowManagerPolicy.InputConsumer {
85 private InputMonitor mInputMonitor;
86 private final InputEventReceiver mInputEventReceiver;
87
88 EventReceiverInputConsumer(WindowManagerService service, InputMonitor monitor,
89 Looper looper, String name,
90 InputEventReceiver.Factory inputEventReceiverFactory) {
91 super(service, name, null);
92 mInputMonitor = monitor;
93 mInputEventReceiver = inputEventReceiverFactory.createInputEventReceiver(
94 mClientChannel, looper);
95 }
96
97 @Override
98 public void dismiss() {
99 synchronized (mService.mWindowMap) {
100 if (mInputMonitor.destroyInputConsumer(mWindowHandle.name)) {
101 mInputEventReceiver.dispose();
102 }
103 }
104 }
105 }
106
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800107 public InputMonitor(WindowManagerService service) {
108 mService = service;
109 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700110
Winson41275482016-10-10 15:17:45 -0700111 void addInputConsumer(String name, InputConsumerImpl consumer) {
112 mInputConsumers.put(name, consumer);
113 updateInputWindowsLw(true /* force */);
114 }
115
116 boolean destroyInputConsumer(String name) {
117 if (disposeInputConsumer(mInputConsumers.remove(name))) {
118 updateInputWindowsLw(true /* force */);
119 return true;
120 }
121 return false;
122 }
123
124 private boolean disposeInputConsumer(InputConsumerImpl consumer) {
125 if (consumer != null) {
126 consumer.disposeChannelsLw();
127 return true;
128 }
129 return false;
130 }
131
132 InputConsumerImpl getInputConsumer(String name) {
133 return mInputConsumers.get(name);
134 }
135
136 void layoutInputConsumers(int dw, int dh) {
137 for (int i = mInputConsumers.size() - 1; i >= 0; i--) {
138 mInputConsumers.valueAt(i).layout(dw, dh);
139 }
140 }
141
142 WindowManagerPolicy.InputConsumer createInputConsumer(Looper looper, String name,
143 InputEventReceiver.Factory inputEventReceiverFactory) {
144 if (mInputConsumers.containsKey(name)) {
145 throw new IllegalStateException("Existing input consumer found with name: " + name);
146 }
147
148 final EventReceiverInputConsumer consumer = new EventReceiverInputConsumer(mService,
149 this, looper, name, inputEventReceiverFactory);
150 addInputConsumer(name, consumer);
151 return consumer;
152 }
153
154 void createInputConsumer(String name, InputChannel inputChannel) {
155 if (mInputConsumers.containsKey(name)) {
156 throw new IllegalStateException("Existing input consumer found with name: " + name);
157 }
158
159 final InputConsumerImpl consumer = new InputConsumerImpl(mService, name, inputChannel);
160 switch (name) {
161 case INPUT_CONSUMER_WALLPAPER:
162 consumer.mWindowHandle.hasWallpaper = true;
163 break;
164 case INPUT_CONSUMER_PIP:
165 // The touchable region of the Pip input window is cropped to the bounds of the
166 // stack, and we need FLAG_NOT_TOUCH_MODAL to ensure other events fall through
167 consumer.mWindowHandle.layoutParamsFlags |=
168 WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
169 break;
170 }
171 addInputConsumer(name, consumer);
172 }
173
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800174 /* Notifies the window manager about a broken input channel.
Chong Zhang8e89b312015-09-09 15:09:30 -0700175 *
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800176 * Called by the InputManager.
177 */
Craig Mautner4cd0c13f2013-04-16 15:55:52 -0700178 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800179 public void notifyInputChannelBroken(InputWindowHandle inputWindowHandle) {
180 if (inputWindowHandle == null) {
181 return;
182 }
183
184 synchronized (mService.mWindowMap) {
185 WindowState windowState = (WindowState) inputWindowHandle.windowState;
Jeff Brown9302c872011-07-13 22:51:29 -0700186 if (windowState != null) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800187 Slog.i(TAG_WM, "WINDOW DIED " + windowState);
Wale Ogunwale92fc3722016-08-05 12:19:08 -0700188 windowState.removeIfPossible();
Jeff Brown9302c872011-07-13 22:51:29 -0700189 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800190 }
191 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700192
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800193 /* Notifies the window manager about an application that is not responding.
194 * Returns a new timeout to continue waiting in nanoseconds, or 0 to abort dispatch.
Chong Zhang8e89b312015-09-09 15:09:30 -0700195 *
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800196 * Called by the InputManager.
197 */
Craig Mautner4cd0c13f2013-04-16 15:55:52 -0700198 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800199 public long notifyANR(InputApplicationHandle inputApplicationHandle,
Jeff Brownbd181bb2013-09-10 16:44:24 -0700200 InputWindowHandle inputWindowHandle, String reason) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800201 AppWindowToken appWindowToken = null;
Dianne Hackborn5fe7e2a2012-10-04 11:58:16 -0700202 WindowState windowState = null;
203 boolean aboveSystem = false;
Jeff Brownee172412012-06-18 12:58:03 -0700204 synchronized (mService.mWindowMap) {
Jeff Brownee172412012-06-18 12:58:03 -0700205 if (inputWindowHandle != null) {
206 windowState = (WindowState) inputWindowHandle.windowState;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800207 if (windowState != null) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800208 appWindowToken = windowState.mAppToken;
209 }
210 }
Jeff Brownee172412012-06-18 12:58:03 -0700211 if (appWindowToken == null && inputApplicationHandle != null) {
212 appWindowToken = (AppWindowToken)inputApplicationHandle.appWindowToken;
Jeff Brown9302c872011-07-13 22:51:29 -0700213 }
Jeff Brownee172412012-06-18 12:58:03 -0700214
215 if (windowState != null) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800216 Slog.i(TAG_WM, "Input event dispatching timed out "
Jeff Brownbd181bb2013-09-10 16:44:24 -0700217 + "sending to " + windowState.mAttrs.getTitle()
218 + ". Reason: " + reason);
Dianne Hackborn5fe7e2a2012-10-04 11:58:16 -0700219 // Figure out whether this window is layered above system windows.
220 // We need to do this here to help the activity manager know how to
221 // layer its ANR dialog.
222 int systemAlertLayer = mService.mPolicy.windowTypeToLayerLw(
223 WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
224 aboveSystem = windowState.mBaseLayer > systemAlertLayer;
Jeff Brownee172412012-06-18 12:58:03 -0700225 } else if (appWindowToken != null) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800226 Slog.i(TAG_WM, "Input event dispatching timed out "
Jeff Brownbd181bb2013-09-10 16:44:24 -0700227 + "sending to application " + appWindowToken.stringName
228 + ". Reason: " + reason);
Jeff Brownee172412012-06-18 12:58:03 -0700229 } else {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800230 Slog.i(TAG_WM, "Input event dispatching timed out "
Jeff Brownbd181bb2013-09-10 16:44:24 -0700231 + ". Reason: " + reason);
Jeff Brownee172412012-06-18 12:58:03 -0700232 }
233
Jeff Brownbd181bb2013-09-10 16:44:24 -0700234 mService.saveANRStateLocked(appWindowToken, windowState, reason);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800235 }
236
237 if (appWindowToken != null && appWindowToken.appToken != null) {
238 try {
239 // Notify the activity manager about the timeout and let it decide whether
240 // to abort dispatching or keep waiting.
Jeff Brownbd181bb2013-09-10 16:44:24 -0700241 boolean abort = appWindowToken.appToken.keyDispatchingTimedOut(reason);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800242 if (! abort) {
243 // The activity manager declined to abort dispatching.
244 // Wait a bit longer and timeout again later.
245 return appWindowToken.inputDispatchingTimeoutNanos;
246 }
247 } catch (RemoteException ex) {
248 }
Dianne Hackborn5fe7e2a2012-10-04 11:58:16 -0700249 } else if (windowState != null) {
250 try {
251 // Notify the activity manager about the timeout and let it decide whether
252 // to abort dispatching or keep waiting.
253 long timeout = ActivityManagerNative.getDefault().inputDispatchingTimedOut(
Jeff Brownbd181bb2013-09-10 16:44:24 -0700254 windowState.mSession.mPid, aboveSystem, reason);
Dianne Hackborn5fe7e2a2012-10-04 11:58:16 -0700255 if (timeout >= 0) {
256 // The activity manager declined to abort dispatching.
257 // Wait a bit longer and timeout again later.
baik.handef340d2015-04-15 10:21:05 +0900258 return timeout * 1000000L; // nanoseconds
Dianne Hackborn5fe7e2a2012-10-04 11:58:16 -0700259 }
260 } catch (RemoteException ex) {
261 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800262 }
263 return 0; // abort dispatching
264 }
265
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700266 void addInputWindowHandle(final InputWindowHandle windowHandle) {
Jeff Brown9302c872011-07-13 22:51:29 -0700267 if (mInputWindowHandles == null) {
268 mInputWindowHandles = new InputWindowHandle[16];
269 }
270 if (mInputWindowHandleCount >= mInputWindowHandles.length) {
271 mInputWindowHandles = Arrays.copyOf(mInputWindowHandles,
272 mInputWindowHandleCount * 2);
273 }
274 mInputWindowHandles[mInputWindowHandleCount++] = windowHandle;
275 }
276
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700277 void addInputWindowHandle(final InputWindowHandle inputWindowHandle,
Craig Mautnerc08eab82014-11-11 09:03:59 -0800278 final WindowState child, int flags, final int type, final boolean isVisible,
Wale Ogunwale053c8e42015-11-16 14:27:21 -0800279 final boolean hasFocus, final boolean hasWallpaper) {
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700280 // Add a window to our list of input windows.
281 inputWindowHandle.name = child.toString();
Wale Ogunwale053c8e42015-11-16 14:27:21 -0800282 flags = child.getTouchableRegion(inputWindowHandle.touchableRegion, flags);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700283 inputWindowHandle.layoutParamsFlags = flags;
284 inputWindowHandle.layoutParamsType = type;
285 inputWindowHandle.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
286 inputWindowHandle.visible = isVisible;
287 inputWindowHandle.canReceiveKeys = child.canReceiveKeys();
288 inputWindowHandle.hasFocus = hasFocus;
289 inputWindowHandle.hasWallpaper = hasWallpaper;
290 inputWindowHandle.paused = child.mAppToken != null ? child.mAppToken.paused : false;
291 inputWindowHandle.layer = child.mLayer;
292 inputWindowHandle.ownerPid = child.mSession.mPid;
293 inputWindowHandle.ownerUid = child.mSession.mUid;
294 inputWindowHandle.inputFeatures = child.mAttrs.inputFeatures;
295
296 final Rect frame = child.mFrame;
297 inputWindowHandle.frameLeft = frame.left;
298 inputWindowHandle.frameTop = frame.top;
299 inputWindowHandle.frameRight = frame.right;
300 inputWindowHandle.frameBottom = frame.bottom;
301
302 if (child.mGlobalScale != 1) {
303 // If we are scaling the window, input coordinates need
304 // to be inversely scaled to map from what is on screen
305 // to what is actually being touched in the UI.
306 inputWindowHandle.scaleFactor = 1.0f/child.mGlobalScale;
307 } else {
308 inputWindowHandle.scaleFactor = 1;
309 }
310
Filip Gruszczynskif8a2a632015-10-28 11:18:02 -0700311 if (DEBUG_INPUT) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800312 Slog.d(TAG_WM, "addInputWindowHandle: "
Chong Zhangb15758a2015-11-17 12:12:03 -0800313 + child + ", " + inputWindowHandle);
Filip Gruszczynskif8a2a632015-10-28 11:18:02 -0700314 }
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700315 addInputWindowHandle(inputWindowHandle);
Dianne Hackborna4b7f2f2012-05-21 11:28:41 -0700316 }
317
Jeff Brown9302c872011-07-13 22:51:29 -0700318 private void clearInputWindowHandlesLw() {
319 while (mInputWindowHandleCount != 0) {
320 mInputWindowHandles[--mInputWindowHandleCount] = null;
321 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800322 }
323
324 public void setUpdateInputWindowsNeededLw() {
325 mUpdateInputWindowsNeeded = true;
326 }
327
328 /* Updates the cached window information provided to the input dispatcher. */
329 public void updateInputWindowsLw(boolean force) {
330 if (!force && !mUpdateInputWindowsNeeded) {
331 return;
332 }
333 mUpdateInputWindowsNeeded = false;
334
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800335 if (false) Slog.d(TAG_WM, ">>>>>> ENTERED updateInputWindowsLw");
Jeff Brown9302c872011-07-13 22:51:29 -0700336
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800337 // Populate the input window list with information about all of the windows that
338 // could potentially receive input.
339 // As an optimization, we could try to prune the list of windows but this turns
340 // out to be difficult because only the native code knows for sure which window
341 // currently has touch focus.
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800342
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700343 // If there's a drag in flight, provide a pseudo-window to catch drag input
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800344 final boolean inDrag = (mService.mDragState != null);
345 if (inDrag) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800346 if (DEBUG_DRAG) {
347 Log.d(TAG_WM, "Inserting drag window");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800348 }
Vladislav Kaznacheev64b103a2016-08-10 11:49:08 -0700349 final InputWindowHandle dragWindowHandle = mService.mDragState.getInputWindowHandle();
Jeff Browncc4f7db2011-08-30 20:34:48 -0700350 if (dragWindowHandle != null) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700351 addInputWindowHandle(dragWindowHandle);
Jeff Browncc4f7db2011-08-30 20:34:48 -0700352 } else {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800353 Slog.w(TAG_WM, "Drag is in progress but there is no "
Jeff Browncc4f7db2011-08-30 20:34:48 -0700354 + "drag window handle.");
355 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800356 }
357
Chong Zhang8e89b312015-09-09 15:09:30 -0700358 final boolean inPositioning = (mService.mTaskPositioner != null);
359 if (inPositioning) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800360 if (DEBUG_TASK_POSITIONING) {
361 Log.d(TAG_WM, "Inserting window handle for repositioning");
Chong Zhang8e89b312015-09-09 15:09:30 -0700362 }
363 final InputWindowHandle dragWindowHandle = mService.mTaskPositioner.mDragWindowHandle;
364 if (dragWindowHandle != null) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700365 addInputWindowHandle(dragWindowHandle);
Chong Zhang8e89b312015-09-09 15:09:30 -0700366 } else {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800367 Slog.e(TAG_WM,
Chong Zhang8e89b312015-09-09 15:09:30 -0700368 "Repositioning is in progress but there is no drag window handle.");
369 }
370 }
371
Jeff Brown83d616a2012-09-09 20:33:43 -0700372 // Add all windows on the default display.
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700373 mService.mRoot.updateInputWindows(this, mInputFocus, inDrag);
Vladislav Kaznacheev0d50d862016-03-29 15:43:28 -0700374
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800375 // Send windows to native code.
Jeff Brown9302c872011-07-13 22:51:29 -0700376 mService.mInputManager.setInputWindows(mInputWindowHandles);
377
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800378 // Clear the list in preparation for the next round.
Jeff Brown9302c872011-07-13 22:51:29 -0700379 clearInputWindowHandlesLw();
380
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800381 if (false) Slog.d(TAG_WM, "<<<<<<< EXITED updateInputWindowsLw");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800382 }
383
384 /* Notifies that the input device configuration has changed. */
Jeff Brown0b31d812013-08-22 19:41:29 -0700385 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800386 public void notifyConfigurationChanged() {
387 mService.sendNewConfiguration();
388
389 synchronized (mInputDevicesReadyMonitor) {
390 if (!mInputDevicesReady) {
391 mInputDevicesReady = true;
392 mInputDevicesReadyMonitor.notifyAll();
393 }
394 }
395 }
396
397 /* Waits until the built-in input devices have been configured. */
398 public boolean waitForInputDevicesReady(long timeoutMillis) {
399 synchronized (mInputDevicesReadyMonitor) {
400 if (!mInputDevicesReady) {
401 try {
402 mInputDevicesReadyMonitor.wait(timeoutMillis);
403 } catch (InterruptedException ex) {
404 }
405 }
406 return mInputDevicesReady;
407 }
408 }
409
410 /* Notifies that the lid switch changed state. */
Jeff Brown0b31d812013-08-22 19:41:29 -0700411 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800412 public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
413 mService.mPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);
414 }
Craig Mautner58458122013-09-14 14:59:50 -0700415
Michael Wright3818c922014-09-02 13:59:07 -0700416 /* Notifies that the camera lens cover state has changed. */
417 @Override
418 public void notifyCameraLensCoverSwitchChanged(long whenNanos, boolean lensCovered) {
419 mService.mPolicy.notifyCameraLensCoverSwitchChanged(whenNanos, lensCovered);
420 }
421
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800422 /* Provides an opportunity for the window manager policy to intercept early key
423 * processing as soon as the key has been read from the device. */
Jeff Brown0b31d812013-08-22 19:41:29 -0700424 @Override
Jeff Brown037c33e2014-04-09 00:31:55 -0700425 public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
426 return mService.mPolicy.interceptKeyBeforeQueueing(event, policyFlags);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800427 }
Jeff Brown56194eb2011-03-02 19:23:13 -0800428
Michael Wright70af00a2014-09-03 19:30:20 -0700429 /* Provides an opportunity for the window manager policy to intercept early motion event
430 * processing when the device is in a non-interactive state since these events are normally
Jeff Brown56194eb2011-03-02 19:23:13 -0800431 * dropped. */
Jeff Brown0b31d812013-08-22 19:41:29 -0700432 @Override
Michael Wright70af00a2014-09-03 19:30:20 -0700433 public int interceptMotionBeforeQueueingNonInteractive(long whenNanos, int policyFlags) {
434 return mService.mPolicy.interceptMotionBeforeQueueingNonInteractive(
435 whenNanos, policyFlags);
Jeff Brown56194eb2011-03-02 19:23:13 -0800436 }
437
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800438 /* Provides an opportunity for the window manager policy to process a key before
439 * ordinary dispatch. */
Jeff Brown0b31d812013-08-22 19:41:29 -0700440 @Override
Jeff Brown905805a2011-10-12 13:57:59 -0700441 public long interceptKeyBeforeDispatching(
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800442 InputWindowHandle focus, KeyEvent event, int policyFlags) {
443 WindowState windowState = focus != null ? (WindowState) focus.windowState : null;
444 return mService.mPolicy.interceptKeyBeforeDispatching(windowState, event, policyFlags);
445 }
Craig Mautner58458122013-09-14 14:59:50 -0700446
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800447 /* Provides an opportunity for the window manager policy to process a key that
448 * the application did not handle. */
Jeff Brown0b31d812013-08-22 19:41:29 -0700449 @Override
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800450 public KeyEvent dispatchUnhandledKey(
451 InputWindowHandle focus, KeyEvent event, int policyFlags) {
452 WindowState windowState = focus != null ? (WindowState) focus.windowState : null;
453 return mService.mPolicy.dispatchUnhandledKey(windowState, event, policyFlags);
454 }
Jeff Brown4532e612012-04-05 14:27:12 -0700455
456 /* Callback to get pointer layer. */
Jeff Brown0b31d812013-08-22 19:41:29 -0700457 @Override
Jeff Brown4532e612012-04-05 14:27:12 -0700458 public int getPointerLayer() {
459 return mService.mPolicy.windowTypeToLayerLw(WindowManager.LayoutParams.TYPE_POINTER)
460 * WindowManagerService.TYPE_LAYER_MULTIPLIER
461 + WindowManagerService.TYPE_LAYER_OFFSET;
462 }
463
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800464 /* Called when the current input focus changes.
465 * Layer assignment is assumed to be complete by the time this is called.
466 */
467 public void setInputFocusLw(WindowState newWindow, boolean updateInputWindows) {
Filip Gruszczynskif8a2a632015-10-28 11:18:02 -0700468 if (DEBUG_FOCUS_LIGHT || DEBUG_INPUT) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800469 Slog.d(TAG_WM, "Input focus has changed to " + newWindow);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800470 }
471
472 if (newWindow != mInputFocus) {
473 if (newWindow != null && newWindow.canReceiveKeys()) {
474 // Displaying a window implicitly causes dispatching to be unpaused.
475 // This is to protect against bugs if someone pauses dispatching but
476 // forgets to resume.
477 newWindow.mToken.paused = false;
478 }
479
480 mInputFocus = newWindow;
481 setUpdateInputWindowsNeededLw();
482
483 if (updateInputWindows) {
484 updateInputWindowsLw(false /*force*/);
485 }
486 }
487 }
Craig Mautner58458122013-09-14 14:59:50 -0700488
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800489 public void setFocusedAppLw(AppWindowToken newApp) {
490 // Focused app has changed.
491 if (newApp == null) {
492 mService.mInputManager.setFocusedApplication(null);
493 } else {
Jeff Brown9302c872011-07-13 22:51:29 -0700494 final InputApplicationHandle handle = newApp.mInputApplicationHandle;
495 handle.name = newApp.toString();
496 handle.dispatchingTimeoutNanos = newApp.inputDispatchingTimeoutNanos;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800497
Jeff Brown9302c872011-07-13 22:51:29 -0700498 mService.mInputManager.setFocusedApplication(handle);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800499 }
500 }
Craig Mautner58458122013-09-14 14:59:50 -0700501
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800502 public void pauseDispatchingLw(WindowToken window) {
503 if (! window.paused) {
Filip Gruszczynskif8a2a632015-10-28 11:18:02 -0700504 if (DEBUG_INPUT) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800505 Slog.v(TAG_WM, "Pausing WindowToken " + window);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800506 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700507
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800508 window.paused = true;
509 updateInputWindowsLw(true /*force*/);
510 }
511 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700512
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800513 public void resumeDispatchingLw(WindowToken window) {
514 if (window.paused) {
Filip Gruszczynskif8a2a632015-10-28 11:18:02 -0700515 if (DEBUG_INPUT) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800516 Slog.v(TAG_WM, "Resuming WindowToken " + window);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800517 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700518
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800519 window.paused = false;
520 updateInputWindowsLw(true /*force*/);
521 }
522 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700523
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800524 public void freezeInputDispatchingLw() {
Wale Ogunwalee89eeac2016-03-12 11:07:58 -0800525 if (!mInputDispatchFrozen) {
Filip Gruszczynskif8a2a632015-10-28 11:18:02 -0700526 if (DEBUG_INPUT) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800527 Slog.v(TAG_WM, "Freezing input dispatching");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800528 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700529
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800530 mInputDispatchFrozen = true;
Wale Ogunwalee89eeac2016-03-12 11:07:58 -0800531
532 if (DEBUG_INPUT || true) {
533 mInputFreezeReason = Debug.getCallers(6);
534 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800535 updateInputDispatchModeLw();
536 }
537 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700538
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800539 public void thawInputDispatchingLw() {
540 if (mInputDispatchFrozen) {
Filip Gruszczynskif8a2a632015-10-28 11:18:02 -0700541 if (DEBUG_INPUT) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800542 Slog.v(TAG_WM, "Thawing input dispatching");
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800543 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700544
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800545 mInputDispatchFrozen = false;
Wale Ogunwalee89eeac2016-03-12 11:07:58 -0800546 mInputFreezeReason = null;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800547 updateInputDispatchModeLw();
548 }
549 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700550
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800551 public void setEventDispatchingLw(boolean enabled) {
552 if (mInputDispatchEnabled != enabled) {
Filip Gruszczynskif8a2a632015-10-28 11:18:02 -0700553 if (DEBUG_INPUT) {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -0800554 Slog.v(TAG_WM, "Setting event dispatching to " + enabled);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800555 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700556
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800557 mInputDispatchEnabled = enabled;
558 updateInputDispatchModeLw();
559 }
560 }
Chong Zhang8e89b312015-09-09 15:09:30 -0700561
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800562 private void updateInputDispatchModeLw() {
563 mService.mInputManager.setInputDispatchMode(mInputDispatchEnabled, mInputDispatchFrozen);
564 }
Wale Ogunwalee89eeac2016-03-12 11:07:58 -0800565
566 void dump(PrintWriter pw, String prefix) {
567 if (mInputFreezeReason != null) {
568 pw.println(prefix + "mInputFreezeReason=" + mInputFreezeReason);
569 }
570 }
Jeff Brownea426552011-07-18 16:53:48 -0700571}