InputDevice.java revision dc1ab4b5cc274b7d744c11a939bb5910becec5e0
1/* 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 android.view; 18 19import android.os.Parcel; 20import android.os.Parcelable; 21import android.os.RemoteException; 22import android.os.ServiceManager; 23 24/** 25 * Describes the capabilities of a particular input device. 26 * <p> 27 * Each input device may support multiple classes of input. For example, a multifunction 28 * keyboard may compose the capabilities of a standard keyboard together with a track pad mouse 29 * or other pointing device. 30 * </p><p> 31 * Some input devices present multiple distinguishable sources of input. 32 * Applications can query the framework about the characteristics of each distinct source. 33 * </p><p> 34 * As a further wrinkle, different kinds of input sources uses different coordinate systems 35 * to describe motion events. Refer to the comments on the input source constants for 36 * the appropriate interpretation. 37 * </p> 38 */ 39public final class InputDevice implements Parcelable { 40 private int mId; 41 private String mName; 42 private int mSources; 43 private int mKeyboardType; 44 45 private MotionRange[] mMotionRanges; 46 47 /** 48 * A mask for input source classes. 49 * 50 * Each distinct input source constant has one or more input source class bits set to 51 * specify the desired interpretation for its input events. 52 */ 53 public static final int SOURCE_CLASS_MASK = 0x000000ff; 54 55 /** 56 * The input source has buttons or keys. 57 * Examples: {@link #SOURCE_KEYBOARD}, {@link #SOURCE_DPAD}. 58 * 59 * A {@link KeyEvent} should be interpreted as a button or key press. 60 * 61 * Use {@link #getKeyCharacterMap} to query the device's button and key mappings. 62 */ 63 public static final int SOURCE_CLASS_BUTTON = 0x00000001; 64 65 /** 66 * The input source is a pointing device associated with a display. 67 * Examples: {@link #SOURCE_TOUCHSCREEN}, {@link #SOURCE_MOUSE}. 68 * 69 * A {@link MotionEvent} should be interpreted as absolute coordinates in 70 * display units according to the {@link View} hierarchy. Pointer down/up indicated when 71 * the finger touches the display or when the selection button is pressed/released. 72 * 73 * Use {@link #getMotionRange} to query the range of the pointing device. Some devices permit 74 * touches outside the display area so the effective range may be somewhat smaller or larger 75 * than the actual display size. 76 */ 77 public static final int SOURCE_CLASS_POINTER = 0x00000002; 78 79 /** 80 * The input source is a trackball navigation device. 81 * Examples: {@link #SOURCE_TRACKBALL}. 82 * 83 * A {@link MotionEvent} should be interpreted as relative movements in device-specific 84 * units used for navigation purposes. Pointer down/up indicates when the selection button 85 * is pressed/released. 86 * 87 * Use {@link #getMotionRange} to query the range of motion. 88 */ 89 public static final int SOURCE_CLASS_TRACKBALL = 0x00000004; 90 91 /** 92 * The input source is an absolute positioning device not associated with a display 93 * (unlike {@link #SOURCE_CLASS_POINTER}). 94 * 95 * A {@link MotionEvent} should be interpreted as absolute coordinates in 96 * device-specific surface units. 97 * 98 * Use {@link #getMotionRange} to query the range of positions. 99 */ 100 public static final int SOURCE_CLASS_POSITION = 0x00000008; 101 102 /** 103 * The input source is unknown. 104 */ 105 public static final int SOURCE_UNKNOWN = 0x00000000; 106 107 /** 108 * The input source is a keyboard. 109 * 110 * @see #SOURCE_CLASS_BUTTON 111 */ 112 public static final int SOURCE_KEYBOARD = 0x00000100 | SOURCE_CLASS_BUTTON; 113 114 /** 115 * The input source is a DPad. 116 * 117 * @see #SOURCE_CLASS_BUTTON 118 */ 119 public static final int SOURCE_DPAD = 0x00000200 | SOURCE_CLASS_BUTTON; 120 121 /** 122 * The input source is a touch screen pointing device. 123 * 124 * @see #SOURCE_CLASS_POINTER 125 */ 126 public static final int SOURCE_TOUCHSCREEN = 0x00001000 | SOURCE_CLASS_POINTER; 127 128 /** 129 * The input source is a mouse pointing device. 130 * This code is also used for other mouse-like pointing devices such as trackpads 131 * and trackpoints. 132 * 133 * @see #SOURCE_CLASS_POINTER 134 */ 135 public static final int SOURCE_MOUSE = 0x00002000 | SOURCE_CLASS_POINTER; 136 137 /** 138 * The input source is a trackball. 139 * 140 * @see #SOURCE_CLASS_TRACKBALL 141 */ 142 public static final int SOURCE_TRACKBALL = 0x00010000 | SOURCE_CLASS_TRACKBALL; 143 144 /** 145 * The input source is a touch pad or digitizer tablet that is not 146 * associated with a display (unlike {@link #SOURCE_TOUCHSCREEN}). 147 * 148 * @see #SOURCE_CLASS_POSITION 149 */ 150 public static final int SOURCE_TOUCHPAD = 0x00100000 | SOURCE_CLASS_POSITION; 151 152 /** 153 * A special input source constant that is used when filtering input devices 154 * to match devices that provide any type of input source. 155 */ 156 public static final int SOURCE_ANY = 0xffffff00; 157 158 /** 159 * Constant for retrieving the range of values for {@link MotionEvent.PointerCoords#x}. 160 * 161 * @see #getMotionRange 162 */ 163 public static final int MOTION_RANGE_X = 0; 164 165 /** 166 * Constant for retrieving the range of values for {@link MotionEvent.PointerCoords#y}. 167 * 168 * @see #getMotionRange 169 */ 170 public static final int MOTION_RANGE_Y = 1; 171 172 /** 173 * Constant for retrieving the range of values for {@link MotionEvent.PointerCoords#pressure}. 174 * 175 * @see #getMotionRange 176 */ 177 public static final int MOTION_RANGE_PRESSURE = 2; 178 179 /** 180 * Constant for retrieving the range of values for {@link MotionEvent.PointerCoords#size}. 181 * 182 * @see #getMotionRange 183 */ 184 public static final int MOTION_RANGE_SIZE = 3; 185 186 /** 187 * Constant for retrieving the range of values for {@link MotionEvent.PointerCoords#touchMajor}. 188 * 189 * @see #getMotionRange 190 */ 191 public static final int MOTION_RANGE_TOUCH_MAJOR = 4; 192 193 /** 194 * Constant for retrieving the range of values for {@link MotionEvent.PointerCoords#touchMinor}. 195 * 196 * @see #getMotionRange 197 */ 198 public static final int MOTION_RANGE_TOUCH_MINOR = 5; 199 200 /** 201 * Constant for retrieving the range of values for {@link MotionEvent.PointerCoords#toolMajor}. 202 * 203 * @see #getMotionRange 204 */ 205 public static final int MOTION_RANGE_TOOL_MAJOR = 6; 206 207 /** 208 * Constant for retrieving the range of values for {@link MotionEvent.PointerCoords#toolMinor}. 209 * 210 * @see #getMotionRange 211 */ 212 public static final int MOTION_RANGE_TOOL_MINOR = 7; 213 214 /** 215 * Constant for retrieving the range of values for 216 * {@link MotionEvent.PointerCoords#orientation}. 217 * 218 * @see #getMotionRange 219 */ 220 public static final int MOTION_RANGE_ORIENTATION = 8; 221 222 private static final int MOTION_RANGE_LAST = MOTION_RANGE_ORIENTATION; 223 224 /** 225 * There is no keyboard. 226 */ 227 public static final int KEYBOARD_TYPE_NONE = 0; 228 229 /** 230 * The keyboard is not fully alphabetic. It may be a numeric keypad or an assortment 231 * of buttons that are not mapped as alphabetic keys suitable for text input. 232 */ 233 public static final int KEYBOARD_TYPE_NON_ALPHABETIC = 1; 234 235 /** 236 * The keyboard supports a complement of alphabetic keys. 237 */ 238 public static final int KEYBOARD_TYPE_ALPHABETIC = 2; 239 240 // Called by native code. 241 private InputDevice() { 242 mMotionRanges = new MotionRange[MOTION_RANGE_LAST + 1]; 243 } 244 245 /** 246 * Gets information about the input device with the specified id. 247 * @param id The device id. 248 * @return The input device or null if not found. 249 */ 250 public static InputDevice getDevice(int id) { 251 IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window")); 252 try { 253 return wm.getInputDevice(id); 254 } catch (RemoteException ex) { 255 throw new RuntimeException( 256 "Could not get input device information from Window Manager.", ex); 257 } 258 } 259 260 /** 261 * Gets the ids of all input devices in the system. 262 * @return The input device ids. 263 */ 264 public static int[] getDeviceIds() { 265 IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window")); 266 try { 267 return wm.getInputDeviceIds(); 268 } catch (RemoteException ex) { 269 throw new RuntimeException( 270 "Could not get input device ids from Window Manager.", ex); 271 } 272 } 273 274 /** 275 * Gets the input device id. 276 * @return The input device id. 277 */ 278 public int getId() { 279 return mId; 280 } 281 282 /** 283 * Gets the name of this input device. 284 * @return The input device name. 285 */ 286 public String getName() { 287 return mName; 288 } 289 290 /** 291 * Gets the input sources supported by this input device as a combined bitfield. 292 * @return The supported input sources. 293 */ 294 public int getSources() { 295 return mSources; 296 } 297 298 /** 299 * Gets the keyboard type. 300 * @return The keyboard type. 301 */ 302 public int getKeyboardType() { 303 return mKeyboardType; 304 } 305 306 /** 307 * Gets the key character map associated with this input device. 308 * @return The key character map. 309 */ 310 public KeyCharacterMap getKeyCharacterMap() { 311 return KeyCharacterMap.load(mId); 312 } 313 314 /** 315 * Gets information about the range of values for a particular {@link MotionEvent} 316 * coordinate. 317 * @param rangeType The motion range constant. 318 * @return The range of values, or null if the requested coordinate is not 319 * supported by the device. 320 */ 321 public MotionRange getMotionRange(int rangeType) { 322 if (rangeType < 0 || rangeType > MOTION_RANGE_LAST) { 323 throw new IllegalArgumentException("Requested range is out of bounds."); 324 } 325 326 return mMotionRanges[rangeType]; 327 } 328 329 private void addMotionRange(int rangeType, float min, float max, float flat, float fuzz) { 330 if (rangeType >= 0 && rangeType <= MOTION_RANGE_LAST) { 331 MotionRange range = new MotionRange(min, max, flat, fuzz); 332 mMotionRanges[rangeType] = range; 333 } 334 } 335 336 /** 337 * Provides information about the range of values for a particular {@link MotionEvent} 338 * coordinate. 339 */ 340 public static final class MotionRange { 341 private float mMin; 342 private float mMax; 343 private float mFlat; 344 private float mFuzz; 345 346 private MotionRange(float min, float max, float flat, float fuzz) { 347 mMin = min; 348 mMax = max; 349 mFlat = flat; 350 mFuzz = fuzz; 351 } 352 353 /** 354 * Gets the minimum value for the coordinate. 355 * @return The minimum value. 356 */ 357 public float getMin() { 358 return mMin; 359 } 360 361 /** 362 * Gets the maximum value for the coordinate. 363 * @return The minimum value. 364 */ 365 public float getMax() { 366 return mMax; 367 } 368 369 /** 370 * Gets the range of the coordinate (difference between maximum and minimum). 371 * @return The range of values. 372 */ 373 public float getRange() { 374 return mMax - mMin; 375 } 376 377 /** 378 * Gets the extent of the center flat position with respect to this coordinate. 379 * For example, a flat value of 8 means that the center position is between -8 and +8. 380 * This value is mainly useful for calibrating self-centering devices. 381 * @return The extent of the center flat position. 382 */ 383 public float getFlat() { 384 return mFlat; 385 } 386 387 /** 388 * Gets the error tolerance for input device measurements with respect to this coordinate. 389 * For example, a value of 2 indicates that the measured value may be up to +/- 2 units 390 * away from the actual value due to noise and device sensitivity limitations. 391 * @return The error tolerance. 392 */ 393 public float getFuzz() { 394 return mFuzz; 395 } 396 } 397 398 public static final Parcelable.Creator<InputDevice> CREATOR 399 = new Parcelable.Creator<InputDevice>() { 400 public InputDevice createFromParcel(Parcel in) { 401 InputDevice result = new InputDevice(); 402 result.readFromParcel(in); 403 return result; 404 } 405 406 public InputDevice[] newArray(int size) { 407 return new InputDevice[size]; 408 } 409 }; 410 411 private void readFromParcel(Parcel in) { 412 mId = in.readInt(); 413 mName = in.readString(); 414 mSources = in.readInt(); 415 mKeyboardType = in.readInt(); 416 417 for (;;) { 418 int rangeType = in.readInt(); 419 if (rangeType < 0) { 420 break; 421 } 422 423 addMotionRange(rangeType, 424 in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat()); 425 } 426 } 427 428 @Override 429 public void writeToParcel(Parcel out, int flags) { 430 out.writeInt(mId); 431 out.writeString(mName); 432 out.writeInt(mSources); 433 out.writeInt(mKeyboardType); 434 435 for (int i = 0; i <= MOTION_RANGE_LAST; i++) { 436 MotionRange range = mMotionRanges[i]; 437 if (range != null) { 438 out.writeInt(i); 439 out.writeFloat(range.mMin); 440 out.writeFloat(range.mMax); 441 out.writeFloat(range.mFlat); 442 out.writeFloat(range.mFuzz); 443 } 444 } 445 out.writeInt(-1); 446 } 447 448 @Override 449 public int describeContents() { 450 return 0; 451 } 452 453 @Override 454 public String toString() { 455 StringBuilder description = new StringBuilder(); 456 description.append("Input Device ").append(mId).append(": ").append(mName).append("\n"); 457 458 description.append(" Keyboard Type: "); 459 switch (mKeyboardType) { 460 case KEYBOARD_TYPE_NONE: 461 description.append("none"); 462 break; 463 case KEYBOARD_TYPE_NON_ALPHABETIC: 464 description.append("non-alphabetic"); 465 break; 466 case KEYBOARD_TYPE_ALPHABETIC: 467 description.append("alphabetic"); 468 break; 469 } 470 description.append("\n"); 471 472 description.append(" Sources:"); 473 appendSourceDescriptionIfApplicable(description, SOURCE_KEYBOARD, "keyboard"); 474 appendSourceDescriptionIfApplicable(description, SOURCE_DPAD, "dpad"); 475 appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHSCREEN, "touchscreen"); 476 appendSourceDescriptionIfApplicable(description, SOURCE_MOUSE, "mouse"); 477 appendSourceDescriptionIfApplicable(description, SOURCE_TRACKBALL, "trackball"); 478 appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHPAD, "touchpad"); 479 description.append("\n"); 480 481 appendRangeDescriptionIfApplicable(description, MOTION_RANGE_X, "x"); 482 appendRangeDescriptionIfApplicable(description, MOTION_RANGE_Y, "y"); 483 appendRangeDescriptionIfApplicable(description, MOTION_RANGE_PRESSURE, "pressure"); 484 appendRangeDescriptionIfApplicable(description, MOTION_RANGE_SIZE, "size"); 485 appendRangeDescriptionIfApplicable(description, MOTION_RANGE_TOUCH_MAJOR, "touchMajor"); 486 appendRangeDescriptionIfApplicable(description, MOTION_RANGE_TOUCH_MINOR, "touchMinor"); 487 appendRangeDescriptionIfApplicable(description, MOTION_RANGE_TOOL_MAJOR, "toolMajor"); 488 appendRangeDescriptionIfApplicable(description, MOTION_RANGE_TOOL_MINOR, "toolMinor"); 489 appendRangeDescriptionIfApplicable(description, MOTION_RANGE_ORIENTATION, "orientation"); 490 491 return description.toString(); 492 } 493 494 private void appendSourceDescriptionIfApplicable(StringBuilder description, int source, 495 String sourceName) { 496 if ((mSources & source) == source) { 497 description.append(" "); 498 description.append(sourceName); 499 } 500 } 501 502 private void appendRangeDescriptionIfApplicable(StringBuilder description, 503 int rangeType, String rangeName) { 504 MotionRange range = mMotionRanges[rangeType]; 505 if (range != null) { 506 description.append(" Range[").append(rangeName); 507 description.append("]: min=").append(range.mMin); 508 description.append(" max=").append(range.mMax); 509 description.append(" flat=").append(range.mFlat); 510 description.append(" fuzz=").append(range.mFuzz); 511 description.append("\n"); 512 } 513 } 514} 515