blob: b8cc65ee00943dc94dec45b94a337094900a0892 [file] [log] [blame]
Jeff Brown46b9ac02010-04-22 18:58:52 -07001/*
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.
15 */
16
Jeff Brown4532e612012-04-05 14:27:12 -070017package com.android.server.input;
Jeff Brown46b9ac02010-04-22 18:58:52 -070018
19import com.android.internal.util.XmlUtils;
Jeff Brown89ef0722011-08-10 16:25:21 -070020import com.android.server.Watchdog;
Jeff Brown4532e612012-04-05 14:27:12 -070021import com.android.server.input.InputFilter.Host;
22import com.android.server.wm.WindowManagerService;
Jeff Brown46b9ac02010-04-22 18:58:52 -070023
24import org.xmlpull.v1.XmlPullParser;
25
26import android.content.Context;
Jeff Brown349703e2010-06-22 01:27:15 -070027import android.content.pm.PackageManager;
Jeff Brown46b9ac02010-04-22 18:58:52 -070028import android.content.res.Configuration;
Jeff Brown1a84fd12011-06-02 01:26:32 -070029import android.database.ContentObserver;
Jeff Brown4532e612012-04-05 14:27:12 -070030import android.hardware.input.IInputManager;
Jeff Brownac143512012-04-05 18:57:33 -070031import android.hardware.input.InputManager;
Jeff Brown4532e612012-04-05 14:27:12 -070032import android.os.Binder;
Jeff Brown46b9ac02010-04-22 18:58:52 -070033import android.os.Environment;
Jeff Brown4532e612012-04-05 14:27:12 -070034import android.os.Handler;
Jeff Brown05dc66a2011-03-02 14:41:58 -080035import android.os.Looper;
36import android.os.MessageQueue;
Jeff Brownac143512012-04-05 18:57:33 -070037import android.os.Process;
Jeff Brownae9fc032010-08-18 15:51:08 -070038import android.os.SystemProperties;
Jeff Brown1a84fd12011-06-02 01:26:32 -070039import android.provider.Settings;
40import android.provider.Settings.SettingNotFoundException;
Jeff Brown46b9ac02010-04-22 18:58:52 -070041import android.util.Slog;
42import android.util.Xml;
43import android.view.InputChannel;
Jeff Brown8d608662010-08-30 03:02:23 -070044import android.view.InputDevice;
Jeff Brown6ec402b2010-07-28 15:48:59 -070045import android.view.InputEvent;
Jeff Brown1f245102010-11-18 20:53:46 -080046import android.view.KeyEvent;
Jeff Brown2352b972011-04-12 22:39:53 -070047import android.view.PointerIcon;
Jeff Brown46b9ac02010-04-22 18:58:52 -070048import android.view.Surface;
Jeff Browna4547672011-03-02 21:38:11 -080049import android.view.ViewConfiguration;
Jeff Brown83c09682010-12-23 17:50:18 -080050import android.view.WindowManager;
Jeff Brown0029c662011-03-30 02:25:18 -070051import android.view.WindowManagerPolicy;
Jeff Brown46b9ac02010-04-22 18:58:52 -070052
Jeff Brown46b9ac02010-04-22 18:58:52 -070053import java.io.File;
Jeff Brown4532e612012-04-05 14:27:12 -070054import java.io.FileDescriptor;
Jeff Brown46b9ac02010-04-22 18:58:52 -070055import java.io.FileNotFoundException;
56import java.io.FileReader;
57import java.io.IOException;
Jeff Brown46b9ac02010-04-22 18:58:52 -070058import java.io.PrintWriter;
59import java.util.ArrayList;
60
61/*
62 * Wraps the C++ InputManager and provides its callbacks.
Jeff Brown46b9ac02010-04-22 18:58:52 -070063 */
Jeff Brown4532e612012-04-05 14:27:12 -070064public class InputManagerService extends IInputManager.Stub implements Watchdog.Monitor {
Jeff Brown46b9ac02010-04-22 18:58:52 -070065 static final String TAG = "InputManager";
Jeff Brown4532e612012-04-05 14:27:12 -070066 static final boolean DEBUG = false;
Jeff Brownb6997262010-10-08 22:31:17 -070067
Jeff Brown4532e612012-04-05 14:27:12 -070068 private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml";
69
70 // Pointer to native input manager service object.
71 private final int mPtr;
72
Jeff Brown46b9ac02010-04-22 18:58:52 -070073 private final Context mContext;
Jeff Brown4532e612012-04-05 14:27:12 -070074 private final Callbacks mCallbacks;
75 private final Handler mHandler;
Jeff Brown1a84fd12011-06-02 01:26:32 -070076
Jeff Brown4532e612012-04-05 14:27:12 -070077 private static native int nativeInit(InputManagerService service,
78 Context context, MessageQueue messageQueue);
79 private static native void nativeStart(int ptr);
80 private static native void nativeSetDisplaySize(int ptr, int displayId,
81 int width, int height, int externalWidth, int externalHeight);
82 private static native void nativeSetDisplayOrientation(int ptr, int displayId, int rotation);
Jeff Brown46b9ac02010-04-22 18:58:52 -070083
Jeff Brown4532e612012-04-05 14:27:12 -070084 private static native int nativeGetScanCodeState(int ptr,
85 int deviceId, int sourceMask, int scanCode);
86 private static native int nativeGetKeyCodeState(int ptr,
87 int deviceId, int sourceMask, int keyCode);
88 private static native int nativeGetSwitchState(int ptr,
89 int deviceId, int sourceMask, int sw);
90 private static native boolean nativeHasKeys(int ptr,
91 int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists);
92 private static native void nativeRegisterInputChannel(int ptr, InputChannel inputChannel,
Jeff Brown928e0542011-01-10 11:17:36 -080093 InputWindowHandle inputWindowHandle, boolean monitor);
Jeff Brown4532e612012-04-05 14:27:12 -070094 private static native void nativeUnregisterInputChannel(int ptr, InputChannel inputChannel);
95 private static native void nativeSetInputFilterEnabled(int ptr, boolean enable);
96 private static native int nativeInjectInputEvent(int ptr, InputEvent event,
Jeff Brown0029c662011-03-30 02:25:18 -070097 int injectorPid, int injectorUid, int syncMode, int timeoutMillis,
98 int policyFlags);
Jeff Brown4532e612012-04-05 14:27:12 -070099 private static native void nativeSetInputWindows(int ptr, InputWindowHandle[] windowHandles);
100 private static native void nativeSetInputDispatchMode(int ptr, boolean enabled, boolean frozen);
101 private static native void nativeSetSystemUiVisibility(int ptr, int visibility);
102 private static native void nativeSetFocusedApplication(int ptr,
103 InputApplicationHandle application);
104 private static native InputDevice nativeGetInputDevice(int ptr, int deviceId);
105 private static native void nativeGetInputConfiguration(int ptr, Configuration configuration);
106 private static native int[] nativeGetInputDeviceIds(int ptr);
107 private static native boolean nativeTransferTouchFocus(int ptr,
108 InputChannel fromChannel, InputChannel toChannel);
109 private static native void nativeSetPointerSpeed(int ptr, int speed);
110 private static native void nativeSetShowTouches(int ptr, boolean enabled);
111 private static native String nativeDump(int ptr);
112 private static native void nativeMonitor(int ptr);
Jeff Brown4532e612012-04-05 14:27:12 -0700113
Jeff Brownac143512012-04-05 18:57:33 -0700114 // Input event injection constants defined in InputDispatcher.h.
115 private static final int INPUT_EVENT_INJECTION_SUCCEEDED = 0;
116 private static final int INPUT_EVENT_INJECTION_PERMISSION_DENIED = 1;
117 private static final int INPUT_EVENT_INJECTION_FAILED = 2;
118 private static final int INPUT_EVENT_INJECTION_TIMED_OUT = 3;
119
120 // Maximum number of milliseconds to wait for input event injection.
121 private static final int INJECTION_TIMEOUT_MILLIS = 30 * 1000;
122
Jeff Brown6d0fec22010-07-23 21:28:06 -0700123 // Key states (may be returned by queries about the current state of a
124 // particular key code, scan code or switch).
125
126 /** The key state is unknown or the requested key itself is not supported. */
127 public static final int KEY_STATE_UNKNOWN = -1;
128
129 /** The key is up. /*/
130 public static final int KEY_STATE_UP = 0;
131
132 /** The key is down. */
133 public static final int KEY_STATE_DOWN = 1;
134
135 /** The key is down but is a virtual key press that is being emulated by the system. */
136 public static final int KEY_STATE_VIRTUAL = 2;
137
Jeff Brown0029c662011-03-30 02:25:18 -0700138 // State for the currently installed input filter.
139 final Object mInputFilterLock = new Object();
140 InputFilter mInputFilter;
141 InputFilterHost mInputFilterHost;
142
Jeff Brown4532e612012-04-05 14:27:12 -0700143 public InputManagerService(Context context, Callbacks callbacks) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700144 this.mContext = context;
Jeff Brown4532e612012-04-05 14:27:12 -0700145 this.mCallbacks = callbacks;
146 this.mHandler = new Handler();
Jeff Brown05dc66a2011-03-02 14:41:58 -0800147
Jeff Brown46b9ac02010-04-22 18:58:52 -0700148 Slog.i(TAG, "Initializing input manager");
Jeff Brown4532e612012-04-05 14:27:12 -0700149 mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
Jeff Brown46b9ac02010-04-22 18:58:52 -0700150 }
Jeff Brown1a84fd12011-06-02 01:26:32 -0700151
Jeff Brown46b9ac02010-04-22 18:58:52 -0700152 public void start() {
153 Slog.i(TAG, "Starting input manager");
Jeff Brown4532e612012-04-05 14:27:12 -0700154 nativeStart(mPtr);
155
156 // Add ourself to the Watchdog monitors.
157 Watchdog.getInstance().addMonitor(this);
Jeff Brown1a84fd12011-06-02 01:26:32 -0700158
159 registerPointerSpeedSettingObserver();
Jeff Browndaf4a122011-08-26 17:14:14 -0700160 registerShowTouchesSettingObserver();
161
Jeff Brown1a84fd12011-06-02 01:26:32 -0700162 updatePointerSpeedFromSettings();
Jeff Browndaf4a122011-08-26 17:14:14 -0700163 updateShowTouchesFromSettings();
Jeff Brown46b9ac02010-04-22 18:58:52 -0700164 }
165
Jeff Brownbc68a592011-07-25 12:58:12 -0700166 public void setDisplaySize(int displayId, int width, int height,
167 int externalWidth, int externalHeight) {
168 if (width <= 0 || height <= 0 || externalWidth <= 0 || externalHeight <= 0) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700169 throw new IllegalArgumentException("Invalid display id or dimensions.");
170 }
171
Jeff Brownb6997262010-10-08 22:31:17 -0700172 if (DEBUG) {
Jeff Brownbc68a592011-07-25 12:58:12 -0700173 Slog.d(TAG, "Setting display #" + displayId + " size to " + width + "x" + height
174 + " external size " + externalWidth + "x" + externalHeight);
Jeff Brownb6997262010-10-08 22:31:17 -0700175 }
Jeff Brown4532e612012-04-05 14:27:12 -0700176 nativeSetDisplaySize(mPtr, displayId, width, height, externalWidth, externalHeight);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700177 }
178
179 public void setDisplayOrientation(int displayId, int rotation) {
180 if (rotation < Surface.ROTATION_0 || rotation > Surface.ROTATION_270) {
181 throw new IllegalArgumentException("Invalid rotation.");
182 }
183
Jeff Brownb6997262010-10-08 22:31:17 -0700184 if (DEBUG) {
185 Slog.d(TAG, "Setting display #" + displayId + " orientation to " + rotation);
186 }
Jeff Brown4532e612012-04-05 14:27:12 -0700187 nativeSetDisplayOrientation(mPtr, displayId, rotation);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700188 }
189
190 public void getInputConfiguration(Configuration config) {
191 if (config == null) {
192 throw new IllegalArgumentException("config must not be null.");
193 }
194
Jeff Brown4532e612012-04-05 14:27:12 -0700195 nativeGetInputConfiguration(mPtr, config);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700196 }
Jeff Brownac143512012-04-05 18:57:33 -0700197
Jeff Brown6d0fec22010-07-23 21:28:06 -0700198 /**
199 * Gets the current state of a key or button by key code.
200 * @param deviceId The input device id, or -1 to consult all devices.
201 * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to
202 * consider all input sources. An input device is consulted if at least one of its
203 * non-class input source bits matches the specified source mask.
204 * @param keyCode The key code to check.
205 * @return The key state.
206 */
207 public int getKeyCodeState(int deviceId, int sourceMask, int keyCode) {
Jeff Brown4532e612012-04-05 14:27:12 -0700208 return nativeGetKeyCodeState(mPtr, deviceId, sourceMask, keyCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700209 }
210
Jeff Brown6d0fec22010-07-23 21:28:06 -0700211 /**
212 * Gets the current state of a key or button by scan code.
213 * @param deviceId The input device id, or -1 to consult all devices.
214 * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to
215 * consider all input sources. An input device is consulted if at least one of its
216 * non-class input source bits matches the specified source mask.
217 * @param scanCode The scan code to check.
218 * @return The key state.
219 */
220 public int getScanCodeState(int deviceId, int sourceMask, int scanCode) {
Jeff Brown4532e612012-04-05 14:27:12 -0700221 return nativeGetScanCodeState(mPtr, deviceId, sourceMask, scanCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700222 }
223
Jeff Brown6d0fec22010-07-23 21:28:06 -0700224 /**
225 * Gets the current state of a switch by switch code.
226 * @param deviceId The input device id, or -1 to consult all devices.
227 * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to
228 * consider all input sources. An input device is consulted if at least one of its
229 * non-class input source bits matches the specified source mask.
230 * @param switchCode The switch code to check.
231 * @return The switch state.
232 */
233 public int getSwitchState(int deviceId, int sourceMask, int switchCode) {
Jeff Brown4532e612012-04-05 14:27:12 -0700234 return nativeGetSwitchState(mPtr, deviceId, sourceMask, switchCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700235 }
236
Jeff Brown6d0fec22010-07-23 21:28:06 -0700237 /**
238 * Determines whether the specified key codes are supported by a particular device.
239 * @param deviceId The input device id, or -1 to consult all devices.
240 * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to
241 * consider all input sources. An input device is consulted if at least one of its
242 * non-class input source bits matches the specified source mask.
243 * @param keyCodes The array of key codes to check.
244 * @param keyExists An array at least as large as keyCodes whose entries will be set
245 * to true or false based on the presence or absence of support for the corresponding
246 * key codes.
247 * @return True if the lookup was successful, false otherwise.
248 */
Jeff Brownac143512012-04-05 18:57:33 -0700249 @Override
Jeff Brown6d0fec22010-07-23 21:28:06 -0700250 public boolean hasKeys(int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700251 if (keyCodes == null) {
252 throw new IllegalArgumentException("keyCodes must not be null.");
253 }
Jeff Brown6d0fec22010-07-23 21:28:06 -0700254 if (keyExists == null || keyExists.length < keyCodes.length) {
255 throw new IllegalArgumentException("keyExists must not be null and must be at "
256 + "least as large as keyCodes.");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700257 }
258
Jeff Brown4532e612012-04-05 14:27:12 -0700259 return nativeHasKeys(mPtr, deviceId, sourceMask, keyCodes, keyExists);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700260 }
261
Jeff Browna41ca772010-08-11 14:46:32 -0700262 /**
263 * Creates an input channel that will receive all input from the input dispatcher.
264 * @param inputChannelName The input channel name.
265 * @return The input channel.
266 */
267 public InputChannel monitorInput(String inputChannelName) {
268 if (inputChannelName == null) {
269 throw new IllegalArgumentException("inputChannelName must not be null.");
270 }
271
272 InputChannel[] inputChannels = InputChannel.openInputChannelPair(inputChannelName);
Jeff Brown4532e612012-04-05 14:27:12 -0700273 nativeRegisterInputChannel(mPtr, inputChannels[0], null, true);
Jeff Browna41ca772010-08-11 14:46:32 -0700274 inputChannels[0].dispose(); // don't need to retain the Java object reference
275 return inputChannels[1];
276 }
277
278 /**
279 * Registers an input channel so that it can be used as an input event target.
280 * @param inputChannel The input channel to register.
Jeff Brown928e0542011-01-10 11:17:36 -0800281 * @param inputWindowHandle The handle of the input window associated with the
282 * input channel, or null if none.
Jeff Browna41ca772010-08-11 14:46:32 -0700283 */
Jeff Brown928e0542011-01-10 11:17:36 -0800284 public void registerInputChannel(InputChannel inputChannel,
285 InputWindowHandle inputWindowHandle) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700286 if (inputChannel == null) {
287 throw new IllegalArgumentException("inputChannel must not be null.");
288 }
289
Jeff Brown4532e612012-04-05 14:27:12 -0700290 nativeRegisterInputChannel(mPtr, inputChannel, inputWindowHandle, false);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700291 }
292
Jeff Browna41ca772010-08-11 14:46:32 -0700293 /**
294 * Unregisters an input channel.
295 * @param inputChannel The input channel to unregister.
296 */
Jeff Brown46b9ac02010-04-22 18:58:52 -0700297 public void unregisterInputChannel(InputChannel inputChannel) {
298 if (inputChannel == null) {
299 throw new IllegalArgumentException("inputChannel must not be null.");
300 }
301
Jeff Brown4532e612012-04-05 14:27:12 -0700302 nativeUnregisterInputChannel(mPtr, inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700303 }
Jeff Brown0029c662011-03-30 02:25:18 -0700304
305 /**
306 * Sets an input filter that will receive all input events before they are dispatched.
307 * The input filter may then reinterpret input events or inject new ones.
308 *
309 * To ensure consistency, the input dispatcher automatically drops all events
310 * in progress whenever an input filter is installed or uninstalled. After an input
311 * filter is uninstalled, it can no longer send input events unless it is reinstalled.
312 * Any events it attempts to send after it has been uninstalled will be dropped.
313 *
314 * @param filter The input filter, or null to remove the current filter.
315 */
316 public void setInputFilter(InputFilter filter) {
317 synchronized (mInputFilterLock) {
318 final InputFilter oldFilter = mInputFilter;
319 if (oldFilter == filter) {
320 return; // nothing to do
321 }
322
323 if (oldFilter != null) {
324 mInputFilter = null;
325 mInputFilterHost.disconnectLocked();
326 mInputFilterHost = null;
327 oldFilter.uninstall();
328 }
329
330 if (filter != null) {
331 mInputFilter = filter;
332 mInputFilterHost = new InputFilterHost();
333 filter.install(mInputFilterHost);
334 }
335
Jeff Brown4532e612012-04-05 14:27:12 -0700336 nativeSetInputFilterEnabled(mPtr, filter != null);
Jeff Brown0029c662011-03-30 02:25:18 -0700337 }
338 }
339
Jeff Brownac143512012-04-05 18:57:33 -0700340 @Override
341 public boolean injectInputEvent(InputEvent event, int mode) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700342 if (event == null) {
343 throw new IllegalArgumentException("event must not be null");
344 }
Jeff Brownac143512012-04-05 18:57:33 -0700345 if (mode != InputManager.INJECT_INPUT_EVENT_MODE_ASYNC
346 && mode != InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH
347 && mode != InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT) {
348 throw new IllegalArgumentException("mode is invalid");
Jeff Brown7fbdc842010-06-17 20:52:56 -0700349 }
Jeff Brown6ec402b2010-07-28 15:48:59 -0700350
Jeff Brownac143512012-04-05 18:57:33 -0700351 final int pid = Binder.getCallingPid();
352 final int uid = Binder.getCallingUid();
353 final long ident = Binder.clearCallingIdentity();
354 final int result;
355 try {
356 result = nativeInjectInputEvent(mPtr, event, pid, uid, mode,
357 INJECTION_TIMEOUT_MILLIS, WindowManagerPolicy.FLAG_DISABLE_KEY_REPEAT);
358 } finally {
359 Binder.restoreCallingIdentity(ident);
360 }
361 switch (result) {
362 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
363 Slog.w(TAG, "Input event injection from pid " + pid + " permission denied.");
364 throw new SecurityException(
365 "Injecting to another application requires INJECT_EVENTS permission");
366 case INPUT_EVENT_INJECTION_SUCCEEDED:
367 return true;
368 case INPUT_EVENT_INJECTION_TIMED_OUT:
369 Slog.w(TAG, "Input event injection from pid " + pid + " timed out.");
370 return false;
371 case INPUT_EVENT_INJECTION_FAILED:
372 default:
373 Slog.w(TAG, "Input event injection from pid " + pid + " failed.");
374 return false;
375 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700376 }
Jeff Brown0029c662011-03-30 02:25:18 -0700377
Jeff Brown8d608662010-08-30 03:02:23 -0700378 /**
379 * Gets information about the input device with the specified id.
380 * @param id The device id.
381 * @return The input device or null if not found.
382 */
Jeff Brownac143512012-04-05 18:57:33 -0700383 @Override
Jeff Brown8d608662010-08-30 03:02:23 -0700384 public InputDevice getInputDevice(int deviceId) {
Jeff Brown4532e612012-04-05 14:27:12 -0700385 return nativeGetInputDevice(mPtr, deviceId);
Jeff Brown8d608662010-08-30 03:02:23 -0700386 }
387
388 /**
389 * Gets the ids of all input devices in the system.
390 * @return The input device ids.
391 */
Jeff Brownac143512012-04-05 18:57:33 -0700392 @Override
Jeff Brown8d608662010-08-30 03:02:23 -0700393 public int[] getInputDeviceIds() {
Jeff Brown4532e612012-04-05 14:27:12 -0700394 return nativeGetInputDeviceIds(mPtr);
Jeff Brown8d608662010-08-30 03:02:23 -0700395 }
396
Jeff Brown9302c872011-07-13 22:51:29 -0700397 public void setInputWindows(InputWindowHandle[] windowHandles) {
Jeff Brown4532e612012-04-05 14:27:12 -0700398 nativeSetInputWindows(mPtr, windowHandles);
Jeff Brown349703e2010-06-22 01:27:15 -0700399 }
400
Jeff Brown9302c872011-07-13 22:51:29 -0700401 public void setFocusedApplication(InputApplicationHandle application) {
Jeff Brown4532e612012-04-05 14:27:12 -0700402 nativeSetFocusedApplication(mPtr, application);
Jeff Brown349703e2010-06-22 01:27:15 -0700403 }
404
Jeff Brown349703e2010-06-22 01:27:15 -0700405 public void setInputDispatchMode(boolean enabled, boolean frozen) {
Jeff Brown4532e612012-04-05 14:27:12 -0700406 nativeSetInputDispatchMode(mPtr, enabled, frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700407 }
Jeff Brown05dc66a2011-03-02 14:41:58 -0800408
409 public void setSystemUiVisibility(int visibility) {
Jeff Brown4532e612012-04-05 14:27:12 -0700410 nativeSetSystemUiVisibility(mPtr, visibility);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800411 }
412
Jeff Browne6504122010-09-27 14:52:15 -0700413 /**
414 * Atomically transfers touch focus from one window to another as identified by
415 * their input channels. It is possible for multiple windows to have
416 * touch focus if they support split touch dispatch
417 * {@link android.view.WindowManager.LayoutParams#FLAG_SPLIT_TOUCH} but this
418 * method only transfers touch focus of the specified window without affecting
419 * other windows that may also have touch focus at the same time.
420 * @param fromChannel The channel of a window that currently has touch focus.
421 * @param toChannel The channel of the window that should receive touch focus in
422 * place of the first.
423 * @return True if the transfer was successful. False if the window with the
424 * specified channel did not actually have touch focus at the time of the request.
425 */
426 public boolean transferTouchFocus(InputChannel fromChannel, InputChannel toChannel) {
427 if (fromChannel == null) {
428 throw new IllegalArgumentException("fromChannel must not be null.");
429 }
430 if (toChannel == null) {
431 throw new IllegalArgumentException("toChannel must not be null.");
432 }
Jeff Brown4532e612012-04-05 14:27:12 -0700433 return nativeTransferTouchFocus(mPtr, fromChannel, toChannel);
Jeff Browne6504122010-09-27 14:52:15 -0700434 }
Jeff Brown05dc66a2011-03-02 14:41:58 -0800435
Jeff Brown1a84fd12011-06-02 01:26:32 -0700436 /**
437 * Set the pointer speed.
438 * @param speed The pointer speed as a value between -7 (slowest) and 7 (fastest)
439 * where 0 is the default speed.
440 */
Jeff Brownac143512012-04-05 18:57:33 -0700441 @Override
442 public void tryPointerSpeed(int speed) {
443 if (!checkCallingPermission(android.Manifest.permission.SET_POINTER_SPEED,
444 "tryPointerSpeed()")) {
445 throw new SecurityException("Requires SET_POINTER_SPEED permission");
446 }
447
448 setPointerSpeedUnchecked(speed);
Jeff Brown1a84fd12011-06-02 01:26:32 -0700449 }
450
451 public void updatePointerSpeedFromSettings() {
Jeff Brownac143512012-04-05 18:57:33 -0700452 int speed = getPointerSpeedSetting();
453 setPointerSpeedUnchecked(speed);
454 }
455
456 private void setPointerSpeedUnchecked(int speed) {
457 speed = Math.min(Math.max(speed, InputManager.MIN_POINTER_SPEED),
458 InputManager.MAX_POINTER_SPEED);
459 nativeSetPointerSpeed(mPtr, speed);
Jeff Brown1a84fd12011-06-02 01:26:32 -0700460 }
461
462 private void registerPointerSpeedSettingObserver() {
463 mContext.getContentResolver().registerContentObserver(
464 Settings.System.getUriFor(Settings.System.POINTER_SPEED), true,
Jeff Brown4532e612012-04-05 14:27:12 -0700465 new ContentObserver(mHandler) {
Jeff Brown1a84fd12011-06-02 01:26:32 -0700466 @Override
467 public void onChange(boolean selfChange) {
468 updatePointerSpeedFromSettings();
469 }
470 });
471 }
472
Jeff Brownac143512012-04-05 18:57:33 -0700473 private int getPointerSpeedSetting() {
474 int speed = InputManager.DEFAULT_POINTER_SPEED;
Jeff Brown1a84fd12011-06-02 01:26:32 -0700475 try {
476 speed = Settings.System.getInt(mContext.getContentResolver(),
477 Settings.System.POINTER_SPEED);
478 } catch (SettingNotFoundException snfe) {
479 }
480 return speed;
481 }
482
Jeff Browndaf4a122011-08-26 17:14:14 -0700483 public void updateShowTouchesFromSettings() {
484 int setting = getShowTouchesSetting(0);
Jeff Brown4532e612012-04-05 14:27:12 -0700485 nativeSetShowTouches(mPtr, setting != 0);
Jeff Browndaf4a122011-08-26 17:14:14 -0700486 }
487
488 private void registerShowTouchesSettingObserver() {
489 mContext.getContentResolver().registerContentObserver(
490 Settings.System.getUriFor(Settings.System.SHOW_TOUCHES), true,
Jeff Brown4532e612012-04-05 14:27:12 -0700491 new ContentObserver(mHandler) {
Jeff Browndaf4a122011-08-26 17:14:14 -0700492 @Override
493 public void onChange(boolean selfChange) {
494 updateShowTouchesFromSettings();
495 }
496 });
497 }
498
499 private int getShowTouchesSetting(int defaultValue) {
500 int result = defaultValue;
501 try {
502 result = Settings.System.getInt(mContext.getContentResolver(),
503 Settings.System.SHOW_TOUCHES);
504 } catch (SettingNotFoundException snfe) {
505 }
506 return result;
507 }
508
Jeff Brown4532e612012-04-05 14:27:12 -0700509 @Override
510 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
511 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
512 != PackageManager.PERMISSION_GRANTED) {
513 pw.println("Permission Denial: can't dump InputManager from from pid="
514 + Binder.getCallingPid()
515 + ", uid=" + Binder.getCallingUid());
516 return;
517 }
518
519 pw.println("INPUT MANAGER (dumpsys input)\n");
520 String dumpStr = nativeDump(mPtr);
Jeff Browne33348b2010-07-15 23:54:05 -0700521 if (dumpStr != null) {
522 pw.println(dumpStr);
523 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700524 }
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800525
Jeff Brownac143512012-04-05 18:57:33 -0700526 private boolean checkCallingPermission(String permission, String func) {
527 // Quick check: if the calling permission is me, it's all okay.
528 if (Binder.getCallingPid() == Process.myPid()) {
529 return true;
530 }
531
532 if (mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED) {
533 return true;
534 }
535 String msg = "Permission Denial: " + func + " from pid="
536 + Binder.getCallingPid()
537 + ", uid=" + Binder.getCallingUid()
538 + " requires " + permission;
539 Slog.w(TAG, msg);
540 return false;
541 }
542
Jeff Brown4532e612012-04-05 14:27:12 -0700543 // Called by the heartbeat to ensure locks are not held indefinitely (for deadlock detection).
Jeff Brown89ef0722011-08-10 16:25:21 -0700544 public void monitor() {
545 synchronized (mInputFilterLock) { }
Jeff Brown4532e612012-04-05 14:27:12 -0700546 nativeMonitor(mPtr);
Jeff Brown89ef0722011-08-10 16:25:21 -0700547 }
548
Jeff Brown4532e612012-04-05 14:27:12 -0700549 // Native callback.
550 private void notifyConfigurationChanged(long whenNanos) {
551 mCallbacks.notifyConfigurationChanged();
552 }
553
554 // Native callback.
555 private void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
556 mCallbacks.notifyLidSwitchChanged(whenNanos, lidOpen);
557 }
558
559 // Native callback.
560 private void notifyInputChannelBroken(InputWindowHandle inputWindowHandle) {
561 mCallbacks.notifyInputChannelBroken(inputWindowHandle);
562 }
563
564 // Native callback.
565 private long notifyANR(InputApplicationHandle inputApplicationHandle,
566 InputWindowHandle inputWindowHandle) {
567 return mCallbacks.notifyANR(inputApplicationHandle, inputWindowHandle);
568 }
569
570 // Native callback.
571 final boolean filterInputEvent(InputEvent event, int policyFlags) {
572 synchronized (mInputFilterLock) {
573 if (mInputFilter != null) {
574 mInputFilter.filterInputEvent(event, policyFlags);
575 return false;
576 }
577 }
578 event.recycle();
579 return true;
580 }
581
582 // Native callback.
583 private int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn) {
584 return mCallbacks.interceptKeyBeforeQueueing(
585 event, policyFlags, isScreenOn);
586 }
587
588 // Native callback.
589 private int interceptMotionBeforeQueueingWhenScreenOff(int policyFlags) {
590 return mCallbacks.interceptMotionBeforeQueueingWhenScreenOff(policyFlags);
591 }
592
593 // Native callback.
594 private long interceptKeyBeforeDispatching(InputWindowHandle focus,
595 KeyEvent event, int policyFlags) {
596 return mCallbacks.interceptKeyBeforeDispatching(focus, event, policyFlags);
597 }
598
599 // Native callback.
600 private KeyEvent dispatchUnhandledKey(InputWindowHandle focus,
601 KeyEvent event, int policyFlags) {
602 return mCallbacks.dispatchUnhandledKey(focus, event, policyFlags);
603 }
604
605 // Native callback.
606 private boolean checkInjectEventsPermission(int injectorPid, int injectorUid) {
607 return mContext.checkPermission(android.Manifest.permission.INJECT_EVENTS,
608 injectorPid, injectorUid) == PackageManager.PERMISSION_GRANTED;
609 }
610
611 // Native callback.
612 private int getVirtualKeyQuietTimeMillis() {
613 return mContext.getResources().getInteger(
614 com.android.internal.R.integer.config_virtualKeyQuietTimeMillis);
615 }
616
617 // Native callback.
618 private String[] getExcludedDeviceNames() {
619 ArrayList<String> names = new ArrayList<String>();
620
621 // Read partner-provided list of excluded input devices
622 XmlPullParser parser = null;
623 // Environment.getRootDirectory() is a fancy way of saying ANDROID_ROOT or "/system".
624 File confFile = new File(Environment.getRootDirectory(), EXCLUDED_DEVICES_PATH);
625 FileReader confreader = null;
626 try {
627 confreader = new FileReader(confFile);
628 parser = Xml.newPullParser();
629 parser.setInput(confreader);
630 XmlUtils.beginDocument(parser, "devices");
631
632 while (true) {
633 XmlUtils.nextElement(parser);
634 if (!"device".equals(parser.getName())) {
635 break;
636 }
637 String name = parser.getAttributeValue(null, "name");
638 if (name != null) {
639 names.add(name);
640 }
641 }
642 } catch (FileNotFoundException e) {
643 // It's ok if the file does not exist.
644 } catch (Exception e) {
645 Slog.e(TAG, "Exception while parsing '" + confFile.getAbsolutePath() + "'", e);
646 } finally {
647 try { if (confreader != null) confreader.close(); } catch (IOException e) { }
648 }
649
650 return names.toArray(new String[names.size()]);
651 }
652
653 // Native callback.
654 private int getKeyRepeatTimeout() {
655 return ViewConfiguration.getKeyRepeatTimeout();
656 }
657
658 // Native callback.
659 private int getKeyRepeatDelay() {
660 return ViewConfiguration.getKeyRepeatDelay();
661 }
662
663 // Native callback.
664 private int getHoverTapTimeout() {
665 return ViewConfiguration.getHoverTapTimeout();
666 }
667
668 // Native callback.
669 private int getHoverTapSlop() {
670 return ViewConfiguration.getHoverTapSlop();
671 }
672
673 // Native callback.
674 private int getDoubleTapTimeout() {
675 return ViewConfiguration.getDoubleTapTimeout();
676 }
677
678 // Native callback.
679 private int getLongPressTimeout() {
680 return ViewConfiguration.getLongPressTimeout();
681 }
682
683 // Native callback.
684 private int getPointerLayer() {
685 return mCallbacks.getPointerLayer();
686 }
687
688 // Native callback.
689 private PointerIcon getPointerIcon() {
690 return PointerIcon.getDefaultIcon(mContext);
691 }
692
693 /**
694 * Callback interface implemented by the Window Manager.
695 */
696 public interface Callbacks {
697 public void notifyConfigurationChanged();
698
699 public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen);
700
701 public void notifyInputChannelBroken(InputWindowHandle inputWindowHandle);
702
703 public long notifyANR(InputApplicationHandle inputApplicationHandle,
704 InputWindowHandle inputWindowHandle);
705
706 public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn);
707
708 public int interceptMotionBeforeQueueingWhenScreenOff(int policyFlags);
709
710 public long interceptKeyBeforeDispatching(InputWindowHandle focus,
711 KeyEvent event, int policyFlags);
712
713 public KeyEvent dispatchUnhandledKey(InputWindowHandle focus,
714 KeyEvent event, int policyFlags);
715
716 public int getPointerLayer();
717 }
718
719 /**
720 * Hosting interface for input filters to call back into the input manager.
721 */
Jeff Brown0029c662011-03-30 02:25:18 -0700722 private final class InputFilterHost implements InputFilter.Host {
723 private boolean mDisconnected;
724
725 public void disconnectLocked() {
726 mDisconnected = true;
727 }
728
729 public void sendInputEvent(InputEvent event, int policyFlags) {
730 if (event == null) {
731 throw new IllegalArgumentException("event must not be null");
732 }
733
734 synchronized (mInputFilterLock) {
735 if (!mDisconnected) {
Jeff Brownac143512012-04-05 18:57:33 -0700736 nativeInjectInputEvent(mPtr, event, 0, 0,
737 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC, 0,
Jeff Brown0029c662011-03-30 02:25:18 -0700738 policyFlags | WindowManagerPolicy.FLAG_FILTERED);
739 }
740 }
741 }
742 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700743}