InputDevice.java revision af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78b
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.hardware.input.InputManager; 20import android.os.Parcel; 21import android.os.Parcelable; 22 23import java.util.ArrayList; 24import java.util.List; 25 26/** 27 * Describes the capabilities of a particular input device. 28 * <p> 29 * Each input device may support multiple classes of input. For example, a multi-function 30 * keyboard may compose the capabilities of a standard keyboard together with a track pad mouse 31 * or other pointing device. 32 * </p><p> 33 * Some input devices present multiple distinguishable sources of input. 34 * Applications can query the framework about the characteristics of each distinct source. 35 * </p><p> 36 * As a further wrinkle, different kinds of input sources uses different coordinate systems 37 * to describe motion events. Refer to the comments on the input source constants for 38 * the appropriate interpretation. 39 * </p> 40 */ 41public final class InputDevice implements Parcelable { 42 private final int mId; 43 private final int mGeneration; 44 private final String mName; 45 private final String mDescriptor; 46 private final int mSources; 47 private final int mKeyboardType; 48 private final KeyCharacterMap mKeyCharacterMap; 49 private final ArrayList<MotionRange> mMotionRanges = new ArrayList<MotionRange>(); 50 51 /** 52 * A mask for input source classes. 53 * 54 * Each distinct input source constant has one or more input source class bits set to 55 * specify the desired interpretation for its input events. 56 */ 57 public static final int SOURCE_CLASS_MASK = 0x000000ff; 58 59 /** 60 * The input source has buttons or keys. 61 * Examples: {@link #SOURCE_KEYBOARD}, {@link #SOURCE_DPAD}. 62 * 63 * A {@link KeyEvent} should be interpreted as a button or key press. 64 * 65 * Use {@link #getKeyCharacterMap} to query the device's button and key mappings. 66 */ 67 public static final int SOURCE_CLASS_BUTTON = 0x00000001; 68 69 /** 70 * The input source is a pointing device associated with a display. 71 * Examples: {@link #SOURCE_TOUCHSCREEN}, {@link #SOURCE_MOUSE}. 72 * 73 * A {@link MotionEvent} should be interpreted as absolute coordinates in 74 * display units according to the {@link View} hierarchy. Pointer down/up indicated when 75 * the finger touches the display or when the selection button is pressed/released. 76 * 77 * Use {@link #getMotionRange} to query the range of the pointing device. Some devices permit 78 * touches outside the display area so the effective range may be somewhat smaller or larger 79 * than the actual display size. 80 */ 81 public static final int SOURCE_CLASS_POINTER = 0x00000002; 82 83 /** 84 * The input source is a trackball navigation device. 85 * Examples: {@link #SOURCE_TRACKBALL}. 86 * 87 * A {@link MotionEvent} should be interpreted as relative movements in device-specific 88 * units used for navigation purposes. Pointer down/up indicates when the selection button 89 * is pressed/released. 90 * 91 * Use {@link #getMotionRange} to query the range of motion. 92 */ 93 public static final int SOURCE_CLASS_TRACKBALL = 0x00000004; 94 95 /** 96 * The input source is an absolute positioning device not associated with a display 97 * (unlike {@link #SOURCE_CLASS_POINTER}). 98 * 99 * A {@link MotionEvent} should be interpreted as absolute coordinates in 100 * device-specific surface units. 101 * 102 * Use {@link #getMotionRange} to query the range of positions. 103 */ 104 public static final int SOURCE_CLASS_POSITION = 0x00000008; 105 106 /** 107 * The input source is a joystick. 108 * 109 * A {@link MotionEvent} should be interpreted as absolute joystick movements. 110 * 111 * Use {@link #getMotionRange} to query the range of positions. 112 */ 113 public static final int SOURCE_CLASS_JOYSTICK = 0x00000010; 114 115 /** 116 * The input source is unknown. 117 */ 118 public static final int SOURCE_UNKNOWN = 0x00000000; 119 120 /** 121 * The input source is a keyboard. 122 * 123 * This source indicates pretty much anything that has buttons. Use 124 * {@link #getKeyboardType()} to determine whether the keyboard has alphabetic keys 125 * and can be used to enter text. 126 * 127 * @see #SOURCE_CLASS_BUTTON 128 */ 129 public static final int SOURCE_KEYBOARD = 0x00000100 | SOURCE_CLASS_BUTTON; 130 131 /** 132 * The input source is a DPad. 133 * 134 * @see #SOURCE_CLASS_BUTTON 135 */ 136 public static final int SOURCE_DPAD = 0x00000200 | SOURCE_CLASS_BUTTON; 137 138 /** 139 * The input source is a game pad. 140 * (It may also be a {@link #SOURCE_JOYSTICK}). 141 * 142 * @see #SOURCE_CLASS_BUTTON 143 */ 144 public static final int SOURCE_GAMEPAD = 0x00000400 | SOURCE_CLASS_BUTTON; 145 146 /** 147 * The input source is a touch screen pointing device. 148 * 149 * @see #SOURCE_CLASS_POINTER 150 */ 151 public static final int SOURCE_TOUCHSCREEN = 0x00001000 | SOURCE_CLASS_POINTER; 152 153 /** 154 * The input source is a mouse pointing device. 155 * This code is also used for other mouse-like pointing devices such as trackpads 156 * and trackpoints. 157 * 158 * @see #SOURCE_CLASS_POINTER 159 */ 160 public static final int SOURCE_MOUSE = 0x00002000 | SOURCE_CLASS_POINTER; 161 162 /** 163 * The input source is a stylus pointing device. 164 * 165 * @see #SOURCE_CLASS_POINTER 166 */ 167 public static final int SOURCE_STYLUS = 0x00004000 | SOURCE_CLASS_POINTER; 168 169 /** 170 * The input source is a trackball. 171 * 172 * @see #SOURCE_CLASS_TRACKBALL 173 */ 174 public static final int SOURCE_TRACKBALL = 0x00010000 | SOURCE_CLASS_TRACKBALL; 175 176 /** 177 * The input source is a touch pad or digitizer tablet that is not 178 * associated with a display (unlike {@link #SOURCE_TOUCHSCREEN}). 179 * 180 * @see #SOURCE_CLASS_POSITION 181 */ 182 public static final int SOURCE_TOUCHPAD = 0x00100000 | SOURCE_CLASS_POSITION; 183 184 /** 185 * The input source is a joystick. 186 * (It may also be a {@link #SOURCE_GAMEPAD}). 187 * 188 * @see #SOURCE_CLASS_JOYSTICK 189 */ 190 public static final int SOURCE_JOYSTICK = 0x01000000 | SOURCE_CLASS_JOYSTICK; 191 192 /** 193 * A special input source constant that is used when filtering input devices 194 * to match devices that provide any type of input source. 195 */ 196 public static final int SOURCE_ANY = 0xffffff00; 197 198 /** 199 * Constant for retrieving the range of values for {@link MotionEvent#AXIS_X}. 200 * 201 * @see #getMotionRange 202 * @deprecated Use {@link MotionEvent#AXIS_X} instead. 203 */ 204 @Deprecated 205 public static final int MOTION_RANGE_X = MotionEvent.AXIS_X; 206 207 /** 208 * Constant for retrieving the range of values for {@link MotionEvent#AXIS_Y}. 209 * 210 * @see #getMotionRange 211 * @deprecated Use {@link MotionEvent#AXIS_Y} instead. 212 */ 213 @Deprecated 214 public static final int MOTION_RANGE_Y = MotionEvent.AXIS_Y; 215 216 /** 217 * Constant for retrieving the range of values for {@link MotionEvent#AXIS_PRESSURE}. 218 * 219 * @see #getMotionRange 220 * @deprecated Use {@link MotionEvent#AXIS_PRESSURE} instead. 221 */ 222 @Deprecated 223 public static final int MOTION_RANGE_PRESSURE = MotionEvent.AXIS_PRESSURE; 224 225 /** 226 * Constant for retrieving the range of values for {@link MotionEvent#AXIS_SIZE}. 227 * 228 * @see #getMotionRange 229 * @deprecated Use {@link MotionEvent#AXIS_SIZE} instead. 230 */ 231 @Deprecated 232 public static final int MOTION_RANGE_SIZE = MotionEvent.AXIS_SIZE; 233 234 /** 235 * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOUCH_MAJOR}. 236 * 237 * @see #getMotionRange 238 * @deprecated Use {@link MotionEvent#AXIS_TOUCH_MAJOR} instead. 239 */ 240 @Deprecated 241 public static final int MOTION_RANGE_TOUCH_MAJOR = MotionEvent.AXIS_TOUCH_MAJOR; 242 243 /** 244 * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOUCH_MINOR}. 245 * 246 * @see #getMotionRange 247 * @deprecated Use {@link MotionEvent#AXIS_TOUCH_MINOR} instead. 248 */ 249 @Deprecated 250 public static final int MOTION_RANGE_TOUCH_MINOR = MotionEvent.AXIS_TOUCH_MINOR; 251 252 /** 253 * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOOL_MAJOR}. 254 * 255 * @see #getMotionRange 256 * @deprecated Use {@link MotionEvent#AXIS_TOOL_MAJOR} instead. 257 */ 258 @Deprecated 259 public static final int MOTION_RANGE_TOOL_MAJOR = MotionEvent.AXIS_TOOL_MAJOR; 260 261 /** 262 * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOOL_MINOR}. 263 * 264 * @see #getMotionRange 265 * @deprecated Use {@link MotionEvent#AXIS_TOOL_MINOR} instead. 266 */ 267 @Deprecated 268 public static final int MOTION_RANGE_TOOL_MINOR = MotionEvent.AXIS_TOOL_MINOR; 269 270 /** 271 * Constant for retrieving the range of values for {@link MotionEvent#AXIS_ORIENTATION}. 272 * 273 * @see #getMotionRange 274 * @deprecated Use {@link MotionEvent#AXIS_ORIENTATION} instead. 275 */ 276 @Deprecated 277 public static final int MOTION_RANGE_ORIENTATION = MotionEvent.AXIS_ORIENTATION; 278 279 /** 280 * There is no keyboard. 281 */ 282 public static final int KEYBOARD_TYPE_NONE = 0; 283 284 /** 285 * The keyboard is not fully alphabetic. It may be a numeric keypad or an assortment 286 * of buttons that are not mapped as alphabetic keys suitable for text input. 287 */ 288 public static final int KEYBOARD_TYPE_NON_ALPHABETIC = 1; 289 290 /** 291 * The keyboard supports a complement of alphabetic keys. 292 */ 293 public static final int KEYBOARD_TYPE_ALPHABETIC = 2; 294 295 public static final Parcelable.Creator<InputDevice> CREATOR = 296 new Parcelable.Creator<InputDevice>() { 297 public InputDevice createFromParcel(Parcel in) { 298 return new InputDevice(in); 299 } 300 public InputDevice[] newArray(int size) { 301 return new InputDevice[size]; 302 } 303 }; 304 305 // Called by native code. 306 private InputDevice(int id, int generation, String name, String descriptor, int sources, 307 int keyboardType, KeyCharacterMap keyCharacterMap) { 308 mId = id; 309 mGeneration = generation; 310 mName = name; 311 mDescriptor = descriptor; 312 mSources = sources; 313 mKeyboardType = keyboardType; 314 mKeyCharacterMap = keyCharacterMap; 315 } 316 317 private InputDevice(Parcel in) { 318 mId = in.readInt(); 319 mGeneration = in.readInt(); 320 mName = in.readString(); 321 mDescriptor = in.readString(); 322 mSources = in.readInt(); 323 mKeyboardType = in.readInt(); 324 mKeyCharacterMap = KeyCharacterMap.CREATOR.createFromParcel(in); 325 326 for (;;) { 327 int axis = in.readInt(); 328 if (axis < 0) { 329 break; 330 } 331 addMotionRange(axis, in.readInt(), 332 in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat()); 333 } 334 } 335 336 /** 337 * Gets information about the input device with the specified id. 338 * @param id The device id. 339 * @return The input device or null if not found. 340 */ 341 public static InputDevice getDevice(int id) { 342 return InputManager.getInstance().getInputDevice(id); 343 } 344 345 /** 346 * Gets the ids of all input devices in the system. 347 * @return The input device ids. 348 */ 349 public static int[] getDeviceIds() { 350 return InputManager.getInstance().getInputDeviceIds(); 351 } 352 353 /** 354 * Gets the input device id. 355 * <p> 356 * Each input device receives a unique id when it is first configured 357 * by the system. The input device id may change when the system is restarted or if the 358 * input device is disconnected, reconnected or reconfigured at any time. 359 * If you require a stable identifier for a device that persists across 360 * boots and reconfigurations, use {@link #getDescriptor()}. 361 * </p> 362 * 363 * @return The input device id. 364 */ 365 public int getId() { 366 return mId; 367 } 368 369 /** 370 * Gets a generation number for this input device. 371 * The generation number is incremented whenever the device is reconfigured and its 372 * properties may have changed. 373 * 374 * @return The generation number. 375 * 376 * @hide 377 */ 378 public int getGeneration() { 379 return mGeneration; 380 } 381 382 /** 383 * Gets the input device descriptor, which is a stable identifier for an input device. 384 * <p> 385 * An input device descriptor uniquely identifies an input device. Its value 386 * is intended to be persistent across system restarts, and should not change even 387 * if the input device is disconnected, reconnected or reconfigured at any time. 388 * </p><p> 389 * It is possible for there to be multiple {@link InputDevice} instances that have the 390 * same input device descriptor. This might happen in situations where a single 391 * human input device registers multiple {@link InputDevice} instances (HID collections) 392 * that describe separate features of the device, such as a keyboard that also 393 * has a trackpad. Alternately, it may be that the input devices are simply 394 * indistinguishable, such as two keyboards made by the same manufacturer. 395 * </p><p> 396 * The input device descriptor returned by {@link #getDescriptor} should only bt 397 * used when an application needs to remember settings associated with a particular 398 * input device. For all other purposes when referring to a logical 399 * {@link InputDevice} instance at runtime use the id returned by {@link #getId()}. 400 * </p> 401 * 402 * @return The input device descriptor. 403 */ 404 public String getDescriptor() { 405 return mDescriptor; 406 } 407 408 /** 409 * Returns true if the device is a virtual input device rather than a real one, 410 * such as the virtual keyboard (see {@link KeyCharacterMap#VIRTUAL_KEYBOARD}). 411 * <p> 412 * Virtual input devices are provided to implement system-level functionality 413 * and should not be seen or configured by users. 414 * </p> 415 * 416 * @return True if the device is virtual. 417 * 418 * @see KeyCharacterMap#VIRTUAL_KEYBOARD 419 */ 420 public boolean isVirtual() { 421 return mId < 0; 422 } 423 424 /** 425 * Gets the name of this input device. 426 * @return The input device name. 427 */ 428 public String getName() { 429 return mName; 430 } 431 432 /** 433 * Gets the input sources supported by this input device as a combined bitfield. 434 * @return The supported input sources. 435 */ 436 public int getSources() { 437 return mSources; 438 } 439 440 /** 441 * Gets the keyboard type. 442 * @return The keyboard type. 443 */ 444 public int getKeyboardType() { 445 return mKeyboardType; 446 } 447 448 /** 449 * Gets the key character map associated with this input device. 450 * @return The key character map. 451 */ 452 public KeyCharacterMap getKeyCharacterMap() { 453 return mKeyCharacterMap; 454 } 455 456 /** 457 * Gets information about the range of values for a particular {@link MotionEvent} axis. 458 * If the device supports multiple sources, the same axis may have different meanings 459 * for each source. Returns information about the first axis found for any source. 460 * To obtain information about the axis for a specific source, use 461 * {@link #getMotionRange(int, int)}. 462 * 463 * @param axis The axis constant. 464 * @return The range of values, or null if the requested axis is not 465 * supported by the device. 466 * 467 * @see MotionEvent#AXIS_X 468 * @see MotionEvent#AXIS_Y 469 * @see #getSupportedAxes() 470 */ 471 public MotionRange getMotionRange(int axis) { 472 final int numRanges = mMotionRanges.size(); 473 for (int i = 0; i < numRanges; i++) { 474 final MotionRange range = mMotionRanges.get(i); 475 if (range.mAxis == axis) { 476 return range; 477 } 478 } 479 return null; 480 } 481 482 /** 483 * Gets information about the range of values for a particular {@link MotionEvent} axis 484 * used by a particular source on the device. 485 * If the device supports multiple sources, the same axis may have different meanings 486 * for each source. 487 * 488 * @param axis The axis constant. 489 * @param source The source for which to return information. 490 * @return The range of values, or null if the requested axis is not 491 * supported by the device. 492 * 493 * @see MotionEvent#AXIS_X 494 * @see MotionEvent#AXIS_Y 495 * @see #getSupportedAxes() 496 */ 497 public MotionRange getMotionRange(int axis, int source) { 498 final int numRanges = mMotionRanges.size(); 499 for (int i = 0; i < numRanges; i++) { 500 final MotionRange range = mMotionRanges.get(i); 501 if (range.mAxis == axis && range.mSource == source) { 502 return range; 503 } 504 } 505 return null; 506 } 507 508 /** 509 * Gets the ranges for all axes supported by the device. 510 * @return The motion ranges for the device. 511 * 512 * @see #getMotionRange(int, int) 513 */ 514 public List<MotionRange> getMotionRanges() { 515 return mMotionRanges; 516 } 517 518 // Called from native code. 519 private void addMotionRange(int axis, int source, 520 float min, float max, float flat, float fuzz) { 521 mMotionRanges.add(new MotionRange(axis, source, min, max, flat, fuzz)); 522 } 523 524 /** 525 * Provides information about the range of values for a particular {@link MotionEvent} axis. 526 * 527 * @see InputDevice#getMotionRange(int) 528 */ 529 public static final class MotionRange { 530 private int mAxis; 531 private int mSource; 532 private float mMin; 533 private float mMax; 534 private float mFlat; 535 private float mFuzz; 536 537 private MotionRange(int axis, int source, float min, float max, float flat, float fuzz) { 538 mAxis = axis; 539 mSource = source; 540 mMin = min; 541 mMax = max; 542 mFlat = flat; 543 mFuzz = fuzz; 544 } 545 546 /** 547 * Gets the axis id. 548 * @return The axis id. 549 */ 550 public int getAxis() { 551 return mAxis; 552 } 553 554 /** 555 * Gets the source for which the axis is defined. 556 * @return The source. 557 */ 558 public int getSource() { 559 return mSource; 560 } 561 562 /** 563 * Gets the inclusive minimum value for the axis. 564 * @return The inclusive minimum value. 565 */ 566 public float getMin() { 567 return mMin; 568 } 569 570 /** 571 * Gets the inclusive maximum value for the axis. 572 * @return The inclusive maximum value. 573 */ 574 public float getMax() { 575 return mMax; 576 } 577 578 /** 579 * Gets the range of the axis (difference between maximum and minimum). 580 * @return The range of values. 581 */ 582 public float getRange() { 583 return mMax - mMin; 584 } 585 586 /** 587 * Gets the extent of the center flat position with respect to this axis. 588 * <p> 589 * For example, a flat value of 8 means that the center position is between -8 and +8. 590 * This value is mainly useful for calibrating self-centering devices. 591 * </p> 592 * @return The extent of the center flat position. 593 */ 594 public float getFlat() { 595 return mFlat; 596 } 597 598 /** 599 * Gets the error tolerance for input device measurements with respect to this axis. 600 * <p> 601 * For example, a value of 2 indicates that the measured value may be up to +/- 2 units 602 * away from the actual value due to noise and device sensitivity limitations. 603 * </p> 604 * @return The error tolerance. 605 */ 606 public float getFuzz() { 607 return mFuzz; 608 } 609 } 610 611 @Override 612 public void writeToParcel(Parcel out, int flags) { 613 out.writeInt(mId); 614 out.writeInt(mGeneration); 615 out.writeString(mName); 616 out.writeString(mDescriptor); 617 out.writeInt(mSources); 618 out.writeInt(mKeyboardType); 619 mKeyCharacterMap.writeToParcel(out, flags); 620 621 final int numRanges = mMotionRanges.size(); 622 for (int i = 0; i < numRanges; i++) { 623 MotionRange range = mMotionRanges.get(i); 624 out.writeInt(range.mAxis); 625 out.writeInt(range.mSource); 626 out.writeFloat(range.mMin); 627 out.writeFloat(range.mMax); 628 out.writeFloat(range.mFlat); 629 out.writeFloat(range.mFuzz); 630 } 631 out.writeInt(-1); 632 } 633 634 @Override 635 public int describeContents() { 636 return 0; 637 } 638 639 @Override 640 public String toString() { 641 StringBuilder description = new StringBuilder(); 642 description.append("Input Device ").append(mId).append(": ").append(mName).append("\n"); 643 description.append(" Descriptor: ").append(mDescriptor).append("\n"); 644 description.append(" Generation: ").append(mGeneration).append("\n"); 645 646 description.append(" Keyboard Type: "); 647 switch (mKeyboardType) { 648 case KEYBOARD_TYPE_NONE: 649 description.append("none"); 650 break; 651 case KEYBOARD_TYPE_NON_ALPHABETIC: 652 description.append("non-alphabetic"); 653 break; 654 case KEYBOARD_TYPE_ALPHABETIC: 655 description.append("alphabetic"); 656 break; 657 } 658 description.append("\n"); 659 660 description.append(" Sources: 0x").append(Integer.toHexString(mSources)).append(" ("); 661 appendSourceDescriptionIfApplicable(description, SOURCE_KEYBOARD, "keyboard"); 662 appendSourceDescriptionIfApplicable(description, SOURCE_DPAD, "dpad"); 663 appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHSCREEN, "touchscreen"); 664 appendSourceDescriptionIfApplicable(description, SOURCE_MOUSE, "mouse"); 665 appendSourceDescriptionIfApplicable(description, SOURCE_STYLUS, "stylus"); 666 appendSourceDescriptionIfApplicable(description, SOURCE_TRACKBALL, "trackball"); 667 appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHPAD, "touchpad"); 668 appendSourceDescriptionIfApplicable(description, SOURCE_JOYSTICK, "joystick"); 669 appendSourceDescriptionIfApplicable(description, SOURCE_GAMEPAD, "gamepad"); 670 description.append(" )\n"); 671 672 final int numAxes = mMotionRanges.size(); 673 for (int i = 0; i < numAxes; i++) { 674 MotionRange range = mMotionRanges.get(i); 675 description.append(" ").append(MotionEvent.axisToString(range.mAxis)); 676 description.append(": source=0x").append(Integer.toHexString(range.mSource)); 677 description.append(" min=").append(range.mMin); 678 description.append(" max=").append(range.mMax); 679 description.append(" flat=").append(range.mFlat); 680 description.append(" fuzz=").append(range.mFuzz); 681 description.append("\n"); 682 } 683 return description.toString(); 684 } 685 686 private void appendSourceDescriptionIfApplicable(StringBuilder description, int source, 687 String sourceName) { 688 if ((mSources & source) == source) { 689 description.append(" "); 690 description.append(sourceName); 691 } 692 } 693} 694