blob: 024aec5f9563fd6311edb25e850e9b3b8af610c2 [file] [log] [blame]
Jeff Brown46b9ac0a2010-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
17package com.android.server;
18
19import com.android.internal.util.XmlUtils;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070020
21import org.xmlpull.v1.XmlPullParser;
22
23import android.content.Context;
Jeff Brown349703e2010-06-22 01:27:15 -070024import android.content.pm.PackageManager;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070025import android.content.res.Configuration;
26import android.os.Environment;
Jeff Brownae9fc032010-08-18 15:51:08 -070027import android.os.SystemProperties;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070028import android.util.Slog;
29import android.util.Xml;
30import android.view.InputChannel;
Jeff Brown8d608662010-08-30 03:02:23 -070031import android.view.InputDevice;
Jeff Brown6ec402b2010-07-28 15:48:59 -070032import android.view.InputEvent;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070033import android.view.Surface;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070034
35import java.io.BufferedReader;
36import java.io.File;
37import java.io.FileInputStream;
38import java.io.FileNotFoundException;
39import java.io.FileReader;
40import java.io.IOException;
41import java.io.InputStreamReader;
42import java.io.PrintWriter;
43import java.util.ArrayList;
Jeff Brown8d608662010-08-30 03:02:23 -070044import java.util.Properties;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070045
46/*
47 * Wraps the C++ InputManager and provides its callbacks.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070048 */
49public class InputManager {
50 static final String TAG = "InputManager";
51
52 private final Callbacks mCallbacks;
53 private final Context mContext;
54 private final WindowManagerService mWindowManagerService;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070055
56 private int mTouchScreenConfig;
57 private int mKeyboardConfig;
58 private int mNavigationConfig;
59
60 private static native void nativeInit(Callbacks callbacks);
61 private static native void nativeStart();
62 private static native void nativeSetDisplaySize(int displayId, int width, int height);
63 private static native void nativeSetDisplayOrientation(int displayId, int rotation);
64
Jeff Brown6d0fec22010-07-23 21:28:06 -070065 private static native int nativeGetScanCodeState(int deviceId, int sourceMask,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070066 int scanCode);
Jeff Brown6d0fec22010-07-23 21:28:06 -070067 private static native int nativeGetKeyCodeState(int deviceId, int sourceMask,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070068 int keyCode);
Jeff Brown6d0fec22010-07-23 21:28:06 -070069 private static native int nativeGetSwitchState(int deviceId, int sourceMask,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070070 int sw);
Jeff Brown6d0fec22010-07-23 21:28:06 -070071 private static native boolean nativeHasKeys(int deviceId, int sourceMask,
72 int[] keyCodes, boolean[] keyExists);
Jeff Browna41ca772010-08-11 14:46:32 -070073 private static native void nativeRegisterInputChannel(InputChannel inputChannel,
74 boolean monitor);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070075 private static native void nativeUnregisterInputChannel(InputChannel inputChannel);
Jeff Brown6ec402b2010-07-28 15:48:59 -070076 private static native int nativeInjectInputEvent(InputEvent event,
77 int injectorPid, int injectorUid, int syncMode, int timeoutMillis);
Jeff Brown349703e2010-06-22 01:27:15 -070078 private static native void nativeSetInputWindows(InputWindow[] windows);
79 private static native void nativeSetInputDispatchMode(boolean enabled, boolean frozen);
80 private static native void nativeSetFocusedApplication(InputApplication application);
Jeff Brown8d608662010-08-30 03:02:23 -070081 private static native InputDevice nativeGetInputDevice(int deviceId);
82 private static native int[] nativeGetInputDeviceIds();
Jeff Browne33348b2010-07-15 23:54:05 -070083 private static native String nativeDump();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070084
Jeff Brown7fbdc842010-06-17 20:52:56 -070085 // Input event injection constants defined in InputDispatcher.h.
86 static final int INPUT_EVENT_INJECTION_SUCCEEDED = 0;
87 static final int INPUT_EVENT_INJECTION_PERMISSION_DENIED = 1;
88 static final int INPUT_EVENT_INJECTION_FAILED = 2;
89 static final int INPUT_EVENT_INJECTION_TIMED_OUT = 3;
90
Jeff Brown6ec402b2010-07-28 15:48:59 -070091 // Input event injection synchronization modes defined in InputDispatcher.h
92 static final int INPUT_EVENT_INJECTION_SYNC_NONE = 0;
93 static final int INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT = 1;
94 static final int INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH = 2;
95
Jeff Brown6d0fec22010-07-23 21:28:06 -070096 // Key states (may be returned by queries about the current state of a
97 // particular key code, scan code or switch).
98
99 /** The key state is unknown or the requested key itself is not supported. */
100 public static final int KEY_STATE_UNKNOWN = -1;
101
102 /** The key is up. /*/
103 public static final int KEY_STATE_UP = 0;
104
105 /** The key is down. */
106 public static final int KEY_STATE_DOWN = 1;
107
108 /** The key is down but is a virtual key press that is being emulated by the system. */
109 public static final int KEY_STATE_VIRTUAL = 2;
110
Jeff Browne33348b2010-07-15 23:54:05 -0700111 public InputManager(Context context, WindowManagerService windowManagerService) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700112 this.mContext = context;
113 this.mWindowManagerService = windowManagerService;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700114
115 this.mCallbacks = new Callbacks();
116
117 mTouchScreenConfig = Configuration.TOUCHSCREEN_NOTOUCH;
118 mKeyboardConfig = Configuration.KEYBOARD_NOKEYS;
119 mNavigationConfig = Configuration.NAVIGATION_NONAV;
120
121 init();
122 }
123
124 private void init() {
125 Slog.i(TAG, "Initializing input manager");
126 nativeInit(mCallbacks);
127 }
128
129 public void start() {
130 Slog.i(TAG, "Starting input manager");
131 nativeStart();
132 }
133
134 public void setDisplaySize(int displayId, int width, int height) {
135 if (width <= 0 || height <= 0) {
136 throw new IllegalArgumentException("Invalid display id or dimensions.");
137 }
138
139 Slog.i(TAG, "Setting display #" + displayId + " size to " + width + "x" + height);
140 nativeSetDisplaySize(displayId, width, height);
141 }
142
143 public void setDisplayOrientation(int displayId, int rotation) {
144 if (rotation < Surface.ROTATION_0 || rotation > Surface.ROTATION_270) {
145 throw new IllegalArgumentException("Invalid rotation.");
146 }
147
148 Slog.i(TAG, "Setting display #" + displayId + " orientation to " + rotation);
149 nativeSetDisplayOrientation(displayId, rotation);
150 }
151
152 public void getInputConfiguration(Configuration config) {
153 if (config == null) {
154 throw new IllegalArgumentException("config must not be null.");
155 }
156
157 config.touchscreen = mTouchScreenConfig;
158 config.keyboard = mKeyboardConfig;
159 config.navigation = mNavigationConfig;
160 }
161
Jeff Brown6d0fec22010-07-23 21:28:06 -0700162 /**
163 * Gets the current state of a key or button by key code.
164 * @param deviceId The input device id, or -1 to consult all devices.
165 * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to
166 * consider all input sources. An input device is consulted if at least one of its
167 * non-class input source bits matches the specified source mask.
168 * @param keyCode The key code to check.
169 * @return The key state.
170 */
171 public int getKeyCodeState(int deviceId, int sourceMask, int keyCode) {
172 return nativeGetKeyCodeState(deviceId, sourceMask, keyCode);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700173 }
174
Jeff Brown6d0fec22010-07-23 21:28:06 -0700175 /**
176 * Gets the current state of a key or button by scan code.
177 * @param deviceId The input device id, or -1 to consult all devices.
178 * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to
179 * consider all input sources. An input device is consulted if at least one of its
180 * non-class input source bits matches the specified source mask.
181 * @param scanCode The scan code to check.
182 * @return The key state.
183 */
184 public int getScanCodeState(int deviceId, int sourceMask, int scanCode) {
185 return nativeGetScanCodeState(deviceId, sourceMask, scanCode);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700186 }
187
Jeff Brown6d0fec22010-07-23 21:28:06 -0700188 /**
189 * Gets the current state of a switch by switch code.
190 * @param deviceId The input device id, or -1 to consult all devices.
191 * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to
192 * consider all input sources. An input device is consulted if at least one of its
193 * non-class input source bits matches the specified source mask.
194 * @param switchCode The switch code to check.
195 * @return The switch state.
196 */
197 public int getSwitchState(int deviceId, int sourceMask, int switchCode) {
198 return nativeGetSwitchState(deviceId, sourceMask, switchCode);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700199 }
200
Jeff Brown6d0fec22010-07-23 21:28:06 -0700201 /**
202 * Determines whether the specified key codes are supported by a particular device.
203 * @param deviceId The input device id, or -1 to consult all devices.
204 * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to
205 * consider all input sources. An input device is consulted if at least one of its
206 * non-class input source bits matches the specified source mask.
207 * @param keyCodes The array of key codes to check.
208 * @param keyExists An array at least as large as keyCodes whose entries will be set
209 * to true or false based on the presence or absence of support for the corresponding
210 * key codes.
211 * @return True if the lookup was successful, false otherwise.
212 */
213 public boolean hasKeys(int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700214 if (keyCodes == null) {
215 throw new IllegalArgumentException("keyCodes must not be null.");
216 }
Jeff Brown6d0fec22010-07-23 21:28:06 -0700217 if (keyExists == null || keyExists.length < keyCodes.length) {
218 throw new IllegalArgumentException("keyExists must not be null and must be at "
219 + "least as large as keyCodes.");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700220 }
221
Jeff Brown6d0fec22010-07-23 21:28:06 -0700222 return nativeHasKeys(deviceId, sourceMask, keyCodes, keyExists);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700223 }
224
Jeff Browna41ca772010-08-11 14:46:32 -0700225 /**
226 * Creates an input channel that will receive all input from the input dispatcher.
227 * @param inputChannelName The input channel name.
228 * @return The input channel.
229 */
230 public InputChannel monitorInput(String inputChannelName) {
231 if (inputChannelName == null) {
232 throw new IllegalArgumentException("inputChannelName must not be null.");
233 }
234
235 InputChannel[] inputChannels = InputChannel.openInputChannelPair(inputChannelName);
236 nativeRegisterInputChannel(inputChannels[0], true);
237 inputChannels[0].dispose(); // don't need to retain the Java object reference
238 return inputChannels[1];
239 }
240
241 /**
242 * Registers an input channel so that it can be used as an input event target.
243 * @param inputChannel The input channel to register.
244 */
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700245 public void registerInputChannel(InputChannel inputChannel) {
246 if (inputChannel == null) {
247 throw new IllegalArgumentException("inputChannel must not be null.");
248 }
249
Jeff Browna41ca772010-08-11 14:46:32 -0700250 nativeRegisterInputChannel(inputChannel, false);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700251 }
252
Jeff Browna41ca772010-08-11 14:46:32 -0700253 /**
254 * Unregisters an input channel.
255 * @param inputChannel The input channel to unregister.
256 */
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700257 public void unregisterInputChannel(InputChannel inputChannel) {
258 if (inputChannel == null) {
259 throw new IllegalArgumentException("inputChannel must not be null.");
260 }
261
262 nativeUnregisterInputChannel(inputChannel);
263 }
264
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700265 /**
Jeff Brown6ec402b2010-07-28 15:48:59 -0700266 * Injects an input event into the event system on behalf of an application.
267 * The synchronization mode determines whether the method blocks while waiting for
268 * input injection to proceed.
269 *
270 * {@link #INPUT_EVENT_INJECTION_SYNC_NONE} never blocks. Injection is asynchronous and
271 * is assumed always to be successful.
272 *
273 * {@link #INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT} waits for previous events to be
274 * dispatched so that the input dispatcher can determine whether input event injection will
275 * be permitted based on the current input focus. Does not wait for the input event to
276 * finish processing.
277 *
278 * {@link #INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH} waits for the input event to
279 * be completely processed.
280 *
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700281 * @param event The event to inject.
Jeff Brown7fbdc842010-06-17 20:52:56 -0700282 * @param injectorPid The pid of the injecting application.
283 * @param injectorUid The uid of the injecting application.
Jeff Brown6ec402b2010-07-28 15:48:59 -0700284 * @param syncMode The synchronization mode.
Jeff Brown7fbdc842010-06-17 20:52:56 -0700285 * @param timeoutMillis The injection timeout in milliseconds.
286 * @return One of the INPUT_EVENT_INJECTION_XXX constants.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700287 */
Jeff Brown6ec402b2010-07-28 15:48:59 -0700288 public int injectInputEvent(InputEvent event, int injectorPid, int injectorUid,
289 int syncMode, int timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700290 if (event == null) {
291 throw new IllegalArgumentException("event must not be null");
292 }
293 if (injectorPid < 0 || injectorUid < 0) {
294 throw new IllegalArgumentException("injectorPid and injectorUid must not be negative.");
295 }
296 if (timeoutMillis <= 0) {
297 throw new IllegalArgumentException("timeoutMillis must be positive");
298 }
Jeff Brown6ec402b2010-07-28 15:48:59 -0700299
300 return nativeInjectInputEvent(event, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700301 }
302
Jeff Brown8d608662010-08-30 03:02:23 -0700303 /**
304 * Gets information about the input device with the specified id.
305 * @param id The device id.
306 * @return The input device or null if not found.
307 */
308 public InputDevice getInputDevice(int deviceId) {
309 return nativeGetInputDevice(deviceId);
310 }
311
312 /**
313 * Gets the ids of all input devices in the system.
314 * @return The input device ids.
315 */
316 public int[] getInputDeviceIds() {
317 return nativeGetInputDeviceIds();
318 }
319
Jeff Brown349703e2010-06-22 01:27:15 -0700320 public void setInputWindows(InputWindow[] windows) {
321 nativeSetInputWindows(windows);
322 }
323
324 public void setFocusedApplication(InputApplication application) {
325 nativeSetFocusedApplication(application);
326 }
327
Jeff Brown349703e2010-06-22 01:27:15 -0700328 public void setInputDispatchMode(boolean enabled, boolean frozen) {
329 nativeSetInputDispatchMode(enabled, frozen);
330 }
331
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700332 public void dump(PrintWriter pw) {
Jeff Browne33348b2010-07-15 23:54:05 -0700333 String dumpStr = nativeDump();
334 if (dumpStr != null) {
335 pw.println(dumpStr);
336 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700337 }
338
339 private static final class VirtualKeyDefinition {
340 public int scanCode;
341
342 // configured position data, specified in display coords
343 public int centerX;
344 public int centerY;
345 public int width;
346 public int height;
347 }
348
Jeff Brown8d608662010-08-30 03:02:23 -0700349 private static final class InputDeviceCalibration {
350 public String[] keys;
351 public String[] values;
352 }
353
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700354 /*
355 * Callbacks from native.
356 */
357 private class Callbacks {
358 static final String TAG = "InputManager-Callbacks";
359
360 private static final boolean DEBUG_VIRTUAL_KEYS = false;
361 private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml";
Jeff Brown8d608662010-08-30 03:02:23 -0700362 private static final String CALIBRATION_DIR_PATH = "usr/idc/";
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700363
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700364 @SuppressWarnings("unused")
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700365 public void virtualKeyDownFeedback() {
366 mWindowManagerService.mInputMonitor.virtualKeyDownFeedback();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700367 }
368
369 @SuppressWarnings("unused")
370 public void notifyConfigurationChanged(long whenNanos,
371 int touchScreenConfig, int keyboardConfig, int navigationConfig) {
372 mTouchScreenConfig = touchScreenConfig;
373 mKeyboardConfig = keyboardConfig;
374 mNavigationConfig = navigationConfig;
375
376 mWindowManagerService.sendNewConfiguration();
377 }
378
379 @SuppressWarnings("unused")
380 public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700381 mWindowManagerService.mInputMonitor.notifyLidSwitchChanged(whenNanos, lidOpen);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700382 }
383
384 @SuppressWarnings("unused")
Jeff Brown7fbdc842010-06-17 20:52:56 -0700385 public void notifyInputChannelBroken(InputChannel inputChannel) {
Jeff Brown349703e2010-06-22 01:27:15 -0700386 mWindowManagerService.mInputMonitor.notifyInputChannelBroken(inputChannel);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700387 }
Jeff Brown7fbdc842010-06-17 20:52:56 -0700388
389 @SuppressWarnings("unused")
Jeff Brown519e0242010-09-15 15:18:56 -0700390 public long notifyANR(Object token, InputChannel inputChannel) {
391 return mWindowManagerService.mInputMonitor.notifyANR(token, inputChannel);
Jeff Brown349703e2010-06-22 01:27:15 -0700392 }
393
394 @SuppressWarnings("unused")
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700395 public int interceptKeyBeforeQueueing(long whenNanos, int keyCode, boolean down,
396 int policyFlags, boolean isScreenOn) {
397 return mWindowManagerService.mInputMonitor.interceptKeyBeforeQueueing(
398 whenNanos, keyCode, down, policyFlags, isScreenOn);
Jeff Brown349703e2010-06-22 01:27:15 -0700399 }
400
401 @SuppressWarnings("unused")
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700402 public boolean interceptKeyBeforeDispatching(InputChannel focus, int action,
403 int flags, int keyCode, int metaState, int repeatCount, int policyFlags) {
Jeff Brown349703e2010-06-22 01:27:15 -0700404 return mWindowManagerService.mInputMonitor.interceptKeyBeforeDispatching(focus,
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700405 action, flags, keyCode, metaState, repeatCount, policyFlags);
Jeff Brown349703e2010-06-22 01:27:15 -0700406 }
407
408 @SuppressWarnings("unused")
409 public boolean checkInjectEventsPermission(int injectorPid, int injectorUid) {
410 return mContext.checkPermission(
411 android.Manifest.permission.INJECT_EVENTS, injectorPid, injectorUid)
412 == PackageManager.PERMISSION_GRANTED;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700413 }
414
415 @SuppressWarnings("unused")
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700416 public boolean filterTouchEvents() {
417 return mContext.getResources().getBoolean(
418 com.android.internal.R.bool.config_filterTouchEvents);
419 }
420
421 @SuppressWarnings("unused")
422 public boolean filterJumpyTouchEvents() {
423 return mContext.getResources().getBoolean(
424 com.android.internal.R.bool.config_filterJumpyTouchEvents);
425 }
426
427 @SuppressWarnings("unused")
428 public VirtualKeyDefinition[] getVirtualKeyDefinitions(String deviceName) {
429 ArrayList<VirtualKeyDefinition> keys = new ArrayList<VirtualKeyDefinition>();
430
431 try {
432 FileInputStream fis = new FileInputStream(
433 "/sys/board_properties/virtualkeys." + deviceName);
434 InputStreamReader isr = new InputStreamReader(fis);
435 BufferedReader br = new BufferedReader(isr, 2048);
436 String str = br.readLine();
437 if (str != null) {
438 String[] it = str.split(":");
439 if (DEBUG_VIRTUAL_KEYS) Slog.v(TAG, "***** VIRTUAL KEYS: " + it);
440 final int N = it.length-6;
441 for (int i=0; i<=N; i+=6) {
442 if (!"0x01".equals(it[i])) {
Jeff Brown8d608662010-08-30 03:02:23 -0700443 Slog.w(TAG, "Unknown virtual key type at elem #"
444 + i + ": " + it[i] + " for device " + deviceName);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700445 continue;
446 }
447 try {
448 VirtualKeyDefinition key = new VirtualKeyDefinition();
449 key.scanCode = Integer.parseInt(it[i+1]);
450 key.centerX = Integer.parseInt(it[i+2]);
451 key.centerY = Integer.parseInt(it[i+3]);
452 key.width = Integer.parseInt(it[i+4]);
453 key.height = Integer.parseInt(it[i+5]);
454 if (DEBUG_VIRTUAL_KEYS) Slog.v(TAG, "Virtual key "
455 + key.scanCode + ": center=" + key.centerX + ","
456 + key.centerY + " size=" + key.width + "x"
457 + key.height);
458 keys.add(key);
459 } catch (NumberFormatException e) {
Jeff Brown8d608662010-08-30 03:02:23 -0700460 Slog.w(TAG, "Bad number in virtual key definition at region "
461 + i + " in: " + str + " for device " + deviceName, e);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700462 }
463 }
464 }
465 br.close();
466 } catch (FileNotFoundException e) {
Jeff Brown8d608662010-08-30 03:02:23 -0700467 Slog.i(TAG, "No virtual keys found for device " + deviceName + ".");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700468 } catch (IOException e) {
Jeff Brown8d608662010-08-30 03:02:23 -0700469 Slog.w(TAG, "Error reading virtual keys for device " + deviceName + ".", e);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700470 }
471
472 return keys.toArray(new VirtualKeyDefinition[keys.size()]);
473 }
474
475 @SuppressWarnings("unused")
Jeff Brown8d608662010-08-30 03:02:23 -0700476 public InputDeviceCalibration getInputDeviceCalibration(String deviceName) {
477 // Calibration is specified as a sequence of colon-delimited key value pairs.
478 Properties properties = new Properties();
479 File calibrationFile = new File(Environment.getRootDirectory(),
480 CALIBRATION_DIR_PATH + deviceName + ".idc");
481 if (calibrationFile.exists()) {
482 try {
483 properties.load(new FileInputStream(calibrationFile));
484 } catch (IOException ex) {
485 Slog.w(TAG, "Error reading input device calibration properties for device "
486 + deviceName + " from " + calibrationFile + ".", ex);
487 }
488 } else {
489 Slog.i(TAG, "No input device calibration properties found for device "
490 + deviceName + ".");
491 return null;
492 }
493
494 InputDeviceCalibration calibration = new InputDeviceCalibration();
495 calibration.keys = properties.keySet().toArray(new String[properties.size()]);
496 calibration.values = properties.values().toArray(new String[properties.size()]);
497 return calibration;
498 }
499
500 @SuppressWarnings("unused")
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700501 public String[] getExcludedDeviceNames() {
502 ArrayList<String> names = new ArrayList<String>();
503
504 // Read partner-provided list of excluded input devices
505 XmlPullParser parser = null;
506 // Environment.getRootDirectory() is a fancy way of saying ANDROID_ROOT or "/system".
507 File confFile = new File(Environment.getRootDirectory(), EXCLUDED_DEVICES_PATH);
508 FileReader confreader = null;
509 try {
510 confreader = new FileReader(confFile);
511 parser = Xml.newPullParser();
512 parser.setInput(confreader);
513 XmlUtils.beginDocument(parser, "devices");
514
515 while (true) {
516 XmlUtils.nextElement(parser);
517 if (!"device".equals(parser.getName())) {
518 break;
519 }
520 String name = parser.getAttributeValue(null, "name");
521 if (name != null) {
522 names.add(name);
523 }
524 }
525 } catch (FileNotFoundException e) {
526 // It's ok if the file does not exist.
527 } catch (Exception e) {
528 Slog.e(TAG, "Exception while parsing '" + confFile.getAbsolutePath() + "'", e);
529 } finally {
530 try { if (confreader != null) confreader.close(); } catch (IOException e) { }
531 }
532
533 return names.toArray(new String[names.size()]);
534 }
Jeff Brownae9fc032010-08-18 15:51:08 -0700535
536 @SuppressWarnings("unused")
537 public int getMaxEventsPerSecond() {
538 int result = 0;
539 try {
540 result = Integer.parseInt(SystemProperties.get("windowsmgr.max_events_per_sec"));
541 } catch (NumberFormatException e) {
542 }
543 if (result < 1) {
Jeff Brown3d8c9bd2010-08-18 17:48:53 -0700544 result = 60;
Jeff Brownae9fc032010-08-18 15:51:08 -0700545 }
546 return result;
547 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700548 }
549}