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 17 package android.view; 18 19 import android.content.Context; 20 import android.hardware.input.InputDeviceIdentifier; 21 import android.hardware.input.InputManager; 22 import android.os.NullVibrator; 23 import android.os.Parcel; 24 import android.os.Parcelable; 25 import android.os.Vibrator; 26 27 import java.util.ArrayList; 28 import java.util.List; 29 30 /** 31 * Describes the capabilities of a particular input device. 32 * <p> 33 * Each input device may support multiple classes of input. For example, a multi-function 34 * keyboard may compose the capabilities of a standard keyboard together with a track pad mouse 35 * or other pointing device. 36 * </p><p> 37 * Some input devices present multiple distinguishable sources of input. 38 * Applications can query the framework about the characteristics of each distinct source. 39 * </p><p> 40 * As a further wrinkle, different kinds of input sources uses different coordinate systems 41 * to describe motion events. Refer to the comments on the input source constants for 42 * the appropriate interpretation. 43 * </p> 44 */ 45 public final class InputDevice implements Parcelable { 46 private final int mId; 47 private final int mGeneration; 48 private final int mControllerNumber; 49 private final String mName; 50 private final int mVendorId; 51 private final int mProductId; 52 private final String mDescriptor; 53 private final InputDeviceIdentifier mIdentifier; 54 private final boolean mIsExternal; 55 private final int mSources; 56 private final int mKeyboardType; 57 private final KeyCharacterMap mKeyCharacterMap; 58 private final boolean mHasVibrator; 59 private final boolean mHasMicrophone; 60 private final boolean mHasButtonUnderPad; 61 private final ArrayList<MotionRange> mMotionRanges = new ArrayList<MotionRange>(); 62 63 private Vibrator mVibrator; // guarded by mMotionRanges during initialization 64 65 /** 66 * A mask for input source classes. 67 * 68 * Each distinct input source constant has one or more input source class bits set to 69 * specify the desired interpretation for its input events. 70 */ 71 public static final int SOURCE_CLASS_MASK = 0x000000ff; 72 73 /** 74 * The input source has no class. 75 * 76 * It is up to the application to determine how to handle the device based on the device type. 77 */ 78 public static final int SOURCE_CLASS_NONE = 0x00000000; 79 80 /** 81 * The input source has buttons or keys. 82 * Examples: {@link #SOURCE_KEYBOARD}, {@link #SOURCE_DPAD}. 83 * 84 * A {@link KeyEvent} should be interpreted as a button or key press. 85 * 86 * Use {@link #getKeyCharacterMap} to query the device's button and key mappings. 87 */ 88 public static final int SOURCE_CLASS_BUTTON = 0x00000001; 89 90 /** 91 * The input source is a pointing device associated with a display. 92 * Examples: {@link #SOURCE_TOUCHSCREEN}, {@link #SOURCE_MOUSE}. 93 * 94 * A {@link MotionEvent} should be interpreted as absolute coordinates in 95 * display units according to the {@link View} hierarchy. Pointer down/up indicated when 96 * the finger touches the display or when the selection button is pressed/released. 97 * 98 * Use {@link #getMotionRange} to query the range of the pointing device. Some devices permit 99 * touches outside the display area so the effective range may be somewhat smaller or larger 100 * than the actual display size. 101 */ 102 public static final int SOURCE_CLASS_POINTER = 0x00000002; 103 104 /** 105 * The input source is a trackball navigation device. 106 * Examples: {@link #SOURCE_TRACKBALL}. 107 * 108 * A {@link MotionEvent} should be interpreted as relative movements in device-specific 109 * units used for navigation purposes. Pointer down/up indicates when the selection button 110 * is pressed/released. 111 * 112 * Use {@link #getMotionRange} to query the range of motion. 113 */ 114 public static final int SOURCE_CLASS_TRACKBALL = 0x00000004; 115 116 /** 117 * The input source is an absolute positioning device not associated with a display 118 * (unlike {@link #SOURCE_CLASS_POINTER}). 119 * 120 * A {@link MotionEvent} should be interpreted as absolute coordinates in 121 * device-specific surface units. 122 * 123 * Use {@link #getMotionRange} to query the range of positions. 124 */ 125 public static final int SOURCE_CLASS_POSITION = 0x00000008; 126 127 /** 128 * The input source is a joystick. 129 * 130 * A {@link MotionEvent} should be interpreted as absolute joystick movements. 131 * 132 * Use {@link #getMotionRange} to query the range of positions. 133 */ 134 public static final int SOURCE_CLASS_JOYSTICK = 0x00000010; 135 136 /** 137 * The input source is unknown. 138 */ 139 public static final int SOURCE_UNKNOWN = 0x00000000; 140 141 /** 142 * The input source is a keyboard. 143 * 144 * This source indicates pretty much anything that has buttons. Use 145 * {@link #getKeyboardType()} to determine whether the keyboard has alphabetic keys 146 * and can be used to enter text. 147 * 148 * @see #SOURCE_CLASS_BUTTON 149 */ 150 public static final int SOURCE_KEYBOARD = 0x00000100 | SOURCE_CLASS_BUTTON; 151 152 /** 153 * The input source is a DPad. 154 * 155 * @see #SOURCE_CLASS_BUTTON 156 */ 157 public static final int SOURCE_DPAD = 0x00000200 | SOURCE_CLASS_BUTTON; 158 159 /** 160 * The input source is a game pad. 161 * (It may also be a {@link #SOURCE_JOYSTICK}). 162 * 163 * @see #SOURCE_CLASS_BUTTON 164 */ 165 public static final int SOURCE_GAMEPAD = 0x00000400 | SOURCE_CLASS_BUTTON; 166 167 /** 168 * The input source is a touch screen pointing device. 169 * 170 * @see #SOURCE_CLASS_POINTER 171 */ 172 public static final int SOURCE_TOUCHSCREEN = 0x00001000 | SOURCE_CLASS_POINTER; 173 174 /** 175 * The input source is a mouse pointing device. 176 * This code is also used for other mouse-like pointing devices such as trackpads 177 * and trackpoints. 178 * 179 * @see #SOURCE_CLASS_POINTER 180 */ 181 public static final int SOURCE_MOUSE = 0x00002000 | SOURCE_CLASS_POINTER; 182 183 /** 184 * The input source is a stylus pointing device. 185 * <p> 186 * Note that this bit merely indicates that an input device is capable of obtaining 187 * input from a stylus. To determine whether a given touch event was produced 188 * by a stylus, examine the tool type returned by {@link MotionEvent#getToolType(int)} 189 * for each individual pointer. 190 * </p><p> 191 * A single touch event may multiple pointers with different tool types, 192 * such as an event that has one pointer with tool type 193 * {@link MotionEvent#TOOL_TYPE_FINGER} and another pointer with tool type 194 * {@link MotionEvent#TOOL_TYPE_STYLUS}. So it is important to examine 195 * the tool type of each pointer, regardless of the source reported 196 * by {@link MotionEvent#getSource()}. 197 * </p> 198 * 199 * @see #SOURCE_CLASS_POINTER 200 */ 201 public static final int SOURCE_STYLUS = 0x00004000 | SOURCE_CLASS_POINTER; 202 203 /** 204 * The input device is a Bluetooth stylus. 205 * <p> 206 * Note that this bit merely indicates that an input device is capable of 207 * obtaining input from a Bluetooth stylus. To determine whether a given 208 * touch event was produced by a stylus, examine the tool type returned by 209 * {@link MotionEvent#getToolType(int)} for each individual pointer. 210 * </p><p> 211 * A single touch event may multiple pointers with different tool types, 212 * such as an event that has one pointer with tool type 213 * {@link MotionEvent#TOOL_TYPE_FINGER} and another pointer with tool type 214 * {@link MotionEvent#TOOL_TYPE_STYLUS}. So it is important to examine 215 * the tool type of each pointer, regardless of the source reported 216 * by {@link MotionEvent#getSource()}. 217 * </p><p> 218 * A bluetooth stylus generally receives its pressure and button state 219 * information from the stylus itself, and derives the rest from another 220 * source. For example, a Bluetooth stylus used in conjunction with a 221 * touchscreen would derive its contact position and pointer size from the 222 * touchscreen and may not be any more accurate than other tools such as 223 * fingers. 224 * </p> 225 * 226 * @see #SOURCE_STYLUS 227 * @see #SOURCE_CLASS_POINTER 228 */ 229 public static final int SOURCE_BLUETOOTH_STYLUS = 230 0x00008000 | SOURCE_STYLUS; 231 232 /** 233 * The input source is a trackball. 234 * 235 * @see #SOURCE_CLASS_TRACKBALL 236 */ 237 public static final int SOURCE_TRACKBALL = 0x00010000 | SOURCE_CLASS_TRACKBALL; 238 239 /** 240 * The input source is a mouse device whose relative motions should be interpreted as 241 * navigation events. 242 * 243 * @see #SOURCE_CLASS_TRACKBALL 244 */ 245 public static final int SOURCE_MOUSE_RELATIVE = 0x00020000 | SOURCE_CLASS_TRACKBALL; 246 247 /** 248 * The input source is a touch pad or digitizer tablet that is not 249 * associated with a display (unlike {@link #SOURCE_TOUCHSCREEN}). 250 * 251 * @see #SOURCE_CLASS_POSITION 252 */ 253 public static final int SOURCE_TOUCHPAD = 0x00100000 | SOURCE_CLASS_POSITION; 254 255 /** 256 * The input source is a touch device whose motions should be interpreted as navigation events. 257 * 258 * For example, an upward swipe should be as an upward focus traversal in the same manner as 259 * pressing up on a D-Pad would be. Swipes to the left, right and down should be treated in a 260 * similar manner. 261 * 262 * @see #SOURCE_CLASS_NONE 263 */ 264 public static final int SOURCE_TOUCH_NAVIGATION = 0x00200000 | SOURCE_CLASS_NONE; 265 266 /** 267 * The input source is a rotating encoder device whose motions should be interpreted as akin to 268 * those of a scroll wheel. 269 * 270 * @see #SOURCE_CLASS_NONE 271 */ 272 public static final int SOURCE_ROTARY_ENCODER = 0x00400000 | SOURCE_CLASS_NONE; 273 274 /** 275 * The input source is a joystick. 276 * (It may also be a {@link #SOURCE_GAMEPAD}). 277 * 278 * @see #SOURCE_CLASS_JOYSTICK 279 */ 280 public static final int SOURCE_JOYSTICK = 0x01000000 | SOURCE_CLASS_JOYSTICK; 281 282 /** 283 * The input source is a device connected through HDMI-based bus. 284 * 285 * The key comes in through HDMI-CEC or MHL signal line, and is treated as if it were 286 * generated by a locally connected DPAD or keyboard. 287 */ 288 public static final int SOURCE_HDMI = 0x02000000 | SOURCE_CLASS_BUTTON; 289 290 /** 291 * A special input source constant that is used when filtering input devices 292 * to match devices that provide any type of input source. 293 */ 294 public static final int SOURCE_ANY = 0xffffff00; 295 296 /** 297 * Constant for retrieving the range of values for {@link MotionEvent#AXIS_X}. 298 * 299 * @see #getMotionRange 300 * @deprecated Use {@link MotionEvent#AXIS_X} instead. 301 */ 302 @Deprecated 303 public static final int MOTION_RANGE_X = MotionEvent.AXIS_X; 304 305 /** 306 * Constant for retrieving the range of values for {@link MotionEvent#AXIS_Y}. 307 * 308 * @see #getMotionRange 309 * @deprecated Use {@link MotionEvent#AXIS_Y} instead. 310 */ 311 @Deprecated 312 public static final int MOTION_RANGE_Y = MotionEvent.AXIS_Y; 313 314 /** 315 * Constant for retrieving the range of values for {@link MotionEvent#AXIS_PRESSURE}. 316 * 317 * @see #getMotionRange 318 * @deprecated Use {@link MotionEvent#AXIS_PRESSURE} instead. 319 */ 320 @Deprecated 321 public static final int MOTION_RANGE_PRESSURE = MotionEvent.AXIS_PRESSURE; 322 323 /** 324 * Constant for retrieving the range of values for {@link MotionEvent#AXIS_SIZE}. 325 * 326 * @see #getMotionRange 327 * @deprecated Use {@link MotionEvent#AXIS_SIZE} instead. 328 */ 329 @Deprecated 330 public static final int MOTION_RANGE_SIZE = MotionEvent.AXIS_SIZE; 331 332 /** 333 * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOUCH_MAJOR}. 334 * 335 * @see #getMotionRange 336 * @deprecated Use {@link MotionEvent#AXIS_TOUCH_MAJOR} instead. 337 */ 338 @Deprecated 339 public static final int MOTION_RANGE_TOUCH_MAJOR = MotionEvent.AXIS_TOUCH_MAJOR; 340 341 /** 342 * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOUCH_MINOR}. 343 * 344 * @see #getMotionRange 345 * @deprecated Use {@link MotionEvent#AXIS_TOUCH_MINOR} instead. 346 */ 347 @Deprecated 348 public static final int MOTION_RANGE_TOUCH_MINOR = MotionEvent.AXIS_TOUCH_MINOR; 349 350 /** 351 * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOOL_MAJOR}. 352 * 353 * @see #getMotionRange 354 * @deprecated Use {@link MotionEvent#AXIS_TOOL_MAJOR} instead. 355 */ 356 @Deprecated 357 public static final int MOTION_RANGE_TOOL_MAJOR = MotionEvent.AXIS_TOOL_MAJOR; 358 359 /** 360 * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOOL_MINOR}. 361 * 362 * @see #getMotionRange 363 * @deprecated Use {@link MotionEvent#AXIS_TOOL_MINOR} instead. 364 */ 365 @Deprecated 366 public static final int MOTION_RANGE_TOOL_MINOR = MotionEvent.AXIS_TOOL_MINOR; 367 368 /** 369 * Constant for retrieving the range of values for {@link MotionEvent#AXIS_ORIENTATION}. 370 * 371 * @see #getMotionRange 372 * @deprecated Use {@link MotionEvent#AXIS_ORIENTATION} instead. 373 */ 374 @Deprecated 375 public static final int MOTION_RANGE_ORIENTATION = MotionEvent.AXIS_ORIENTATION; 376 377 /** 378 * There is no keyboard. 379 */ 380 public static final int KEYBOARD_TYPE_NONE = 0; 381 382 /** 383 * The keyboard is not fully alphabetic. It may be a numeric keypad or an assortment 384 * of buttons that are not mapped as alphabetic keys suitable for text input. 385 */ 386 public static final int KEYBOARD_TYPE_NON_ALPHABETIC = 1; 387 388 /** 389 * The keyboard supports a complement of alphabetic keys. 390 */ 391 public static final int KEYBOARD_TYPE_ALPHABETIC = 2; 392 393 private static final int MAX_RANGES = 1000; 394 395 public static final Parcelable.Creator<InputDevice> CREATOR = 396 new Parcelable.Creator<InputDevice>() { 397 public InputDevice createFromParcel(Parcel in) { 398 return new InputDevice(in); 399 } 400 public InputDevice[] newArray(int size) { 401 return new InputDevice[size]; 402 } 403 }; 404 405 // Called by native code. InputDevice(int id, int generation, int controllerNumber, String name, int vendorId, int productId, String descriptor, boolean isExternal, int sources, int keyboardType, KeyCharacterMap keyCharacterMap, boolean hasVibrator, boolean hasMicrophone, boolean hasButtonUnderPad)406 private InputDevice(int id, int generation, int controllerNumber, String name, int vendorId, 407 int productId, String descriptor, boolean isExternal, int sources, int keyboardType, 408 KeyCharacterMap keyCharacterMap, boolean hasVibrator, boolean hasMicrophone, 409 boolean hasButtonUnderPad) { 410 mId = id; 411 mGeneration = generation; 412 mControllerNumber = controllerNumber; 413 mName = name; 414 mVendorId = vendorId; 415 mProductId = productId; 416 mDescriptor = descriptor; 417 mIsExternal = isExternal; 418 mSources = sources; 419 mKeyboardType = keyboardType; 420 mKeyCharacterMap = keyCharacterMap; 421 mHasVibrator = hasVibrator; 422 mHasMicrophone = hasMicrophone; 423 mHasButtonUnderPad = hasButtonUnderPad; 424 mIdentifier = new InputDeviceIdentifier(descriptor, vendorId, productId); 425 } 426 InputDevice(Parcel in)427 private InputDevice(Parcel in) { 428 mId = in.readInt(); 429 mGeneration = in.readInt(); 430 mControllerNumber = in.readInt(); 431 mName = in.readString(); 432 mVendorId = in.readInt(); 433 mProductId = in.readInt(); 434 mDescriptor = in.readString(); 435 mIsExternal = in.readInt() != 0; 436 mSources = in.readInt(); 437 mKeyboardType = in.readInt(); 438 mKeyCharacterMap = KeyCharacterMap.CREATOR.createFromParcel(in); 439 mHasVibrator = in.readInt() != 0; 440 mHasMicrophone = in.readInt() != 0; 441 mHasButtonUnderPad = in.readInt() != 0; 442 mIdentifier = new InputDeviceIdentifier(mDescriptor, mVendorId, mProductId); 443 444 int numRanges = in.readInt(); 445 if (numRanges > MAX_RANGES) { 446 numRanges = MAX_RANGES; 447 } 448 449 for (int i = 0; i < numRanges; i++) { 450 addMotionRange(in.readInt(), in.readInt(), in.readFloat(), in.readFloat(), 451 in.readFloat(), in.readFloat(), in.readFloat()); 452 } 453 } 454 455 /** 456 * Gets information about the input device with the specified id. 457 * @param id The device id. 458 * @return The input device or null if not found. 459 */ getDevice(int id)460 public static InputDevice getDevice(int id) { 461 return InputManager.getInstance().getInputDevice(id); 462 } 463 464 /** 465 * Gets the ids of all input devices in the system. 466 * @return The input device ids. 467 */ getDeviceIds()468 public static int[] getDeviceIds() { 469 return InputManager.getInstance().getInputDeviceIds(); 470 } 471 472 /** 473 * Gets the input device id. 474 * <p> 475 * Each input device receives a unique id when it is first configured 476 * by the system. The input device id may change when the system is restarted or if the 477 * input device is disconnected, reconnected or reconfigured at any time. 478 * If you require a stable identifier for a device that persists across 479 * boots and reconfigurations, use {@link #getDescriptor()}. 480 * </p> 481 * 482 * @return The input device id. 483 */ getId()484 public int getId() { 485 return mId; 486 } 487 488 /** 489 * The controller number for a given input device. 490 * <p> 491 * Each gamepad or joystick is given a unique, positive controller number when initially 492 * configured by the system. This number may change due to events such as device disconnects / 493 * reconnects or user initiated reassignment. Any change in number will trigger an event that 494 * can be observed by registering an {@link InputManager.InputDeviceListener}. 495 * </p> 496 * <p> 497 * All input devices which are not gamepads or joysticks will be assigned a controller number 498 * of 0. 499 * </p> 500 * 501 * @return The controller number of the device. 502 */ getControllerNumber()503 public int getControllerNumber() { 504 return mControllerNumber; 505 } 506 507 /** 508 * The set of identifying information for type of input device. This 509 * information can be used by the system to configure appropriate settings 510 * for the device. 511 * 512 * @return The identifier object for this device 513 * @hide 514 */ getIdentifier()515 public InputDeviceIdentifier getIdentifier() { 516 return mIdentifier; 517 } 518 519 /** 520 * Gets a generation number for this input device. 521 * The generation number is incremented whenever the device is reconfigured and its 522 * properties may have changed. 523 * 524 * @return The generation number. 525 * 526 * @hide 527 */ getGeneration()528 public int getGeneration() { 529 return mGeneration; 530 } 531 532 /** 533 * Gets the vendor id for the given device, if available. 534 * <p> 535 * A vendor id uniquely identifies the company who manufactured the device. A value of 0 will 536 * be assigned where a vendor id is not available. 537 * </p> 538 * 539 * @return The vendor id of a given device 540 */ getVendorId()541 public int getVendorId() { 542 return mVendorId; 543 } 544 545 /** 546 * Gets the product id for the given device, if available. 547 * <p> 548 * A product id uniquely identifies which product within the address space of a given vendor, 549 * identified by the device's vendor id. A value of 0 will be assigned where a product id is 550 * not available. 551 * </p> 552 * 553 * @return The product id of a given device 554 */ getProductId()555 public int getProductId() { 556 return mProductId; 557 } 558 559 /** 560 * Gets the input device descriptor, which is a stable identifier for an input device. 561 * <p> 562 * An input device descriptor uniquely identifies an input device. Its value 563 * is intended to be persistent across system restarts, and should not change even 564 * if the input device is disconnected, reconnected or reconfigured at any time. 565 * </p><p> 566 * It is possible for there to be multiple {@link InputDevice} instances that have the 567 * same input device descriptor. This might happen in situations where a single 568 * human input device registers multiple {@link InputDevice} instances (HID collections) 569 * that describe separate features of the device, such as a keyboard that also 570 * has a trackpad. Alternately, it may be that the input devices are simply 571 * indistinguishable, such as two keyboards made by the same manufacturer. 572 * </p><p> 573 * The input device descriptor returned by {@link #getDescriptor} should only be 574 * used when an application needs to remember settings associated with a particular 575 * input device. For all other purposes when referring to a logical 576 * {@link InputDevice} instance at runtime use the id returned by {@link #getId()}. 577 * </p> 578 * 579 * @return The input device descriptor. 580 */ getDescriptor()581 public String getDescriptor() { 582 return mDescriptor; 583 } 584 585 /** 586 * Returns true if the device is a virtual input device rather than a real one, 587 * such as the virtual keyboard (see {@link KeyCharacterMap#VIRTUAL_KEYBOARD}). 588 * <p> 589 * Virtual input devices are provided to implement system-level functionality 590 * and should not be seen or configured by users. 591 * </p> 592 * 593 * @return True if the device is virtual. 594 * 595 * @see KeyCharacterMap#VIRTUAL_KEYBOARD 596 */ isVirtual()597 public boolean isVirtual() { 598 return mId < 0; 599 } 600 601 /** 602 * Returns true if the device is external (connected to USB or Bluetooth or some other 603 * peripheral bus), otherwise it is built-in. 604 * 605 * @return True if the device is external. 606 * 607 * @hide 608 */ isExternal()609 public boolean isExternal() { 610 return mIsExternal; 611 } 612 613 /** 614 * Returns true if the device is a full keyboard. 615 * 616 * @return True if the device is a full keyboard. 617 * 618 * @hide 619 */ isFullKeyboard()620 public boolean isFullKeyboard() { 621 return (mSources & SOURCE_KEYBOARD) == SOURCE_KEYBOARD 622 && mKeyboardType == KEYBOARD_TYPE_ALPHABETIC; 623 } 624 625 /** 626 * Gets the name of this input device. 627 * @return The input device name. 628 */ getName()629 public String getName() { 630 return mName; 631 } 632 633 /** 634 * Gets the input sources supported by this input device as a combined bitfield. 635 * @return The supported input sources. 636 */ getSources()637 public int getSources() { 638 return mSources; 639 } 640 641 /** 642 * Determines whether the input device supports the given source or sources. 643 * 644 * @param source The input source or sources to check against. This can be a generic device 645 * type such as {@link InputDevice#SOURCE_MOUSE}, a more generic device class, such as 646 * {@link InputDevice#SOURCE_CLASS_POINTER}, or a combination of sources bitwise ORed together. 647 * @return Whether the device can produce all of the given sources. 648 */ supportsSource(int source)649 public boolean supportsSource(int source) { 650 return (mSources & source) == source; 651 } 652 653 /** 654 * Gets the keyboard type. 655 * @return The keyboard type. 656 */ getKeyboardType()657 public int getKeyboardType() { 658 return mKeyboardType; 659 } 660 661 /** 662 * Gets the key character map associated with this input device. 663 * @return The key character map. 664 */ getKeyCharacterMap()665 public KeyCharacterMap getKeyCharacterMap() { 666 return mKeyCharacterMap; 667 } 668 669 /** 670 * Gets whether the device is capable of producing the list of keycodes. 671 * @param keys The list of android keycodes to check for. 672 * @return An array of booleans where each member specifies whether the device is capable of 673 * generating the keycode given by the corresponding value at the same index in the keys array. 674 */ hasKeys(int... keys)675 public boolean[] hasKeys(int... keys) { 676 return InputManager.getInstance().deviceHasKeys(mId, keys); 677 } 678 679 /** 680 * Gets information about the range of values for a particular {@link MotionEvent} axis. 681 * If the device supports multiple sources, the same axis may have different meanings 682 * for each source. Returns information about the first axis found for any source. 683 * To obtain information about the axis for a specific source, use 684 * {@link #getMotionRange(int, int)}. 685 * 686 * @param axis The axis constant. 687 * @return The range of values, or null if the requested axis is not 688 * supported by the device. 689 * 690 * @see MotionEvent#AXIS_X 691 * @see MotionEvent#AXIS_Y 692 */ getMotionRange(int axis)693 public MotionRange getMotionRange(int axis) { 694 final int numRanges = mMotionRanges.size(); 695 for (int i = 0; i < numRanges; i++) { 696 final MotionRange range = mMotionRanges.get(i); 697 if (range.mAxis == axis) { 698 return range; 699 } 700 } 701 return null; 702 } 703 704 /** 705 * Gets information about the range of values for a particular {@link MotionEvent} axis 706 * used by a particular source on the device. 707 * If the device supports multiple sources, the same axis may have different meanings 708 * for each source. 709 * 710 * @param axis The axis constant. 711 * @param source The source for which to return information. 712 * @return The range of values, or null if the requested axis is not 713 * supported by the device. 714 * 715 * @see MotionEvent#AXIS_X 716 * @see MotionEvent#AXIS_Y 717 */ getMotionRange(int axis, int source)718 public MotionRange getMotionRange(int axis, int source) { 719 final int numRanges = mMotionRanges.size(); 720 for (int i = 0; i < numRanges; i++) { 721 final MotionRange range = mMotionRanges.get(i); 722 if (range.mAxis == axis && range.mSource == source) { 723 return range; 724 } 725 } 726 return null; 727 } 728 729 /** 730 * Gets the ranges for all axes supported by the device. 731 * @return The motion ranges for the device. 732 * 733 * @see #getMotionRange(int, int) 734 */ getMotionRanges()735 public List<MotionRange> getMotionRanges() { 736 return mMotionRanges; 737 } 738 739 // Called from native code. addMotionRange(int axis, int source, float min, float max, float flat, float fuzz, float resolution)740 private void addMotionRange(int axis, int source, 741 float min, float max, float flat, float fuzz, float resolution) { 742 mMotionRanges.add(new MotionRange(axis, source, min, max, flat, fuzz, resolution)); 743 } 744 745 /** 746 * Gets the vibrator service associated with the device, if there is one. 747 * Even if the device does not have a vibrator, the result is never null. 748 * Use {@link Vibrator#hasVibrator} to determine whether a vibrator is 749 * present. 750 * 751 * Note that the vibrator associated with the device may be different from 752 * the system vibrator. To obtain an instance of the system vibrator instead, call 753 * {@link Context#getSystemService} with {@link Context#VIBRATOR_SERVICE} as argument. 754 * 755 * @return The vibrator service associated with the device, never null. 756 */ getVibrator()757 public Vibrator getVibrator() { 758 synchronized (mMotionRanges) { 759 if (mVibrator == null) { 760 if (mHasVibrator) { 761 mVibrator = InputManager.getInstance().getInputDeviceVibrator(mId); 762 } else { 763 mVibrator = NullVibrator.getInstance(); 764 } 765 } 766 return mVibrator; 767 } 768 } 769 770 /** 771 * Reports whether the device has a built-in microphone. 772 * @return Whether the device has a built-in microphone. 773 */ hasMicrophone()774 public boolean hasMicrophone() { 775 return mHasMicrophone; 776 } 777 778 /** 779 * Reports whether the device has a button under its touchpad 780 * @return Whether the device has a button under its touchpad 781 * @hide 782 */ hasButtonUnderPad()783 public boolean hasButtonUnderPad() { 784 return mHasButtonUnderPad; 785 } 786 787 /** 788 * Sets the current pointer type. 789 * @param pointerType the type of the pointer icon. 790 * @hide 791 */ setPointerType(int pointerType)792 public void setPointerType(int pointerType) { 793 InputManager.getInstance().setPointerIconType(pointerType); 794 } 795 796 /** 797 * Specifies the current custom pointer. 798 * @param icon the icon data. 799 * @hide 800 */ setCustomPointerIcon(PointerIcon icon)801 public void setCustomPointerIcon(PointerIcon icon) { 802 InputManager.getInstance().setCustomPointerIcon(icon); 803 } 804 805 /** 806 * Provides information about the range of values for a particular {@link MotionEvent} axis. 807 * 808 * @see InputDevice#getMotionRange(int) 809 */ 810 public static final class MotionRange { 811 private int mAxis; 812 private int mSource; 813 private float mMin; 814 private float mMax; 815 private float mFlat; 816 private float mFuzz; 817 private float mResolution; 818 MotionRange(int axis, int source, float min, float max, float flat, float fuzz, float resolution)819 private MotionRange(int axis, int source, float min, float max, float flat, float fuzz, 820 float resolution) { 821 mAxis = axis; 822 mSource = source; 823 mMin = min; 824 mMax = max; 825 mFlat = flat; 826 mFuzz = fuzz; 827 mResolution = resolution; 828 } 829 830 /** 831 * Gets the axis id. 832 * @return The axis id. 833 */ getAxis()834 public int getAxis() { 835 return mAxis; 836 } 837 838 /** 839 * Gets the source for which the axis is defined. 840 * @return The source. 841 */ getSource()842 public int getSource() { 843 return mSource; 844 } 845 846 847 /** 848 * Determines whether the event is from the given source. 849 * 850 * @param source The input source to check against. This can be a specific device type, 851 * such as {@link InputDevice#SOURCE_TOUCH_NAVIGATION}, or a more generic device class, 852 * such as {@link InputDevice#SOURCE_CLASS_POINTER}. 853 * @return Whether the event is from the given source. 854 */ isFromSource(int source)855 public boolean isFromSource(int source) { 856 return (getSource() & source) == source; 857 } 858 859 /** 860 * Gets the inclusive minimum value for the axis. 861 * @return The inclusive minimum value. 862 */ getMin()863 public float getMin() { 864 return mMin; 865 } 866 867 /** 868 * Gets the inclusive maximum value for the axis. 869 * @return The inclusive maximum value. 870 */ getMax()871 public float getMax() { 872 return mMax; 873 } 874 875 /** 876 * Gets the range of the axis (difference between maximum and minimum). 877 * @return The range of values. 878 */ getRange()879 public float getRange() { 880 return mMax - mMin; 881 } 882 883 /** 884 * Gets the extent of the center flat position with respect to this axis. 885 * <p> 886 * For example, a flat value of 8 means that the center position is between -8 and +8. 887 * This value is mainly useful for calibrating self-centering devices. 888 * </p> 889 * @return The extent of the center flat position. 890 */ getFlat()891 public float getFlat() { 892 return mFlat; 893 } 894 895 /** 896 * Gets the error tolerance for input device measurements with respect to this axis. 897 * <p> 898 * For example, a value of 2 indicates that the measured value may be up to +/- 2 units 899 * away from the actual value due to noise and device sensitivity limitations. 900 * </p> 901 * @return The error tolerance. 902 */ getFuzz()903 public float getFuzz() { 904 return mFuzz; 905 } 906 907 /** 908 * Gets the resolution for input device measurements with respect to this axis. 909 * @return The resolution in units per millimeter, or units per radian for rotational axes. 910 */ getResolution()911 public float getResolution() { 912 return mResolution; 913 } 914 } 915 916 @Override writeToParcel(Parcel out, int flags)917 public void writeToParcel(Parcel out, int flags) { 918 out.writeInt(mId); 919 out.writeInt(mGeneration); 920 out.writeInt(mControllerNumber); 921 out.writeString(mName); 922 out.writeInt(mVendorId); 923 out.writeInt(mProductId); 924 out.writeString(mDescriptor); 925 out.writeInt(mIsExternal ? 1 : 0); 926 out.writeInt(mSources); 927 out.writeInt(mKeyboardType); 928 mKeyCharacterMap.writeToParcel(out, flags); 929 out.writeInt(mHasVibrator ? 1 : 0); 930 out.writeInt(mHasMicrophone ? 1 : 0); 931 out.writeInt(mHasButtonUnderPad ? 1 : 0); 932 933 final int numRanges = mMotionRanges.size(); 934 out.writeInt(numRanges); 935 for (int i = 0; i < numRanges; i++) { 936 MotionRange range = mMotionRanges.get(i); 937 out.writeInt(range.mAxis); 938 out.writeInt(range.mSource); 939 out.writeFloat(range.mMin); 940 out.writeFloat(range.mMax); 941 out.writeFloat(range.mFlat); 942 out.writeFloat(range.mFuzz); 943 out.writeFloat(range.mResolution); 944 } 945 } 946 947 @Override describeContents()948 public int describeContents() { 949 return 0; 950 } 951 952 @Override toString()953 public String toString() { 954 StringBuilder description = new StringBuilder(); 955 description.append("Input Device ").append(mId).append(": ").append(mName).append("\n"); 956 description.append(" Descriptor: ").append(mDescriptor).append("\n"); 957 description.append(" Generation: ").append(mGeneration).append("\n"); 958 description.append(" Location: ").append(mIsExternal ? "external" : "built-in").append("\n"); 959 960 description.append(" Keyboard Type: "); 961 switch (mKeyboardType) { 962 case KEYBOARD_TYPE_NONE: 963 description.append("none"); 964 break; 965 case KEYBOARD_TYPE_NON_ALPHABETIC: 966 description.append("non-alphabetic"); 967 break; 968 case KEYBOARD_TYPE_ALPHABETIC: 969 description.append("alphabetic"); 970 break; 971 } 972 description.append("\n"); 973 974 description.append(" Has Vibrator: ").append(mHasVibrator).append("\n"); 975 976 description.append(" Has mic: ").append(mHasMicrophone).append("\n"); 977 978 description.append(" Sources: 0x").append(Integer.toHexString(mSources)).append(" ("); 979 appendSourceDescriptionIfApplicable(description, SOURCE_KEYBOARD, "keyboard"); 980 appendSourceDescriptionIfApplicable(description, SOURCE_DPAD, "dpad"); 981 appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHSCREEN, "touchscreen"); 982 appendSourceDescriptionIfApplicable(description, SOURCE_MOUSE, "mouse"); 983 appendSourceDescriptionIfApplicable(description, SOURCE_STYLUS, "stylus"); 984 appendSourceDescriptionIfApplicable(description, SOURCE_TRACKBALL, "trackball"); 985 appendSourceDescriptionIfApplicable(description, SOURCE_MOUSE_RELATIVE, "mouse_relative"); 986 appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHPAD, "touchpad"); 987 appendSourceDescriptionIfApplicable(description, SOURCE_JOYSTICK, "joystick"); 988 appendSourceDescriptionIfApplicable(description, SOURCE_GAMEPAD, "gamepad"); 989 description.append(" )\n"); 990 991 final int numAxes = mMotionRanges.size(); 992 for (int i = 0; i < numAxes; i++) { 993 MotionRange range = mMotionRanges.get(i); 994 description.append(" ").append(MotionEvent.axisToString(range.mAxis)); 995 description.append(": source=0x").append(Integer.toHexString(range.mSource)); 996 description.append(" min=").append(range.mMin); 997 description.append(" max=").append(range.mMax); 998 description.append(" flat=").append(range.mFlat); 999 description.append(" fuzz=").append(range.mFuzz); 1000 description.append(" resolution=").append(range.mResolution); 1001 description.append("\n"); 1002 } 1003 return description.toString(); 1004 } 1005 appendSourceDescriptionIfApplicable(StringBuilder description, int source, String sourceName)1006 private void appendSourceDescriptionIfApplicable(StringBuilder description, int source, 1007 String sourceName) { 1008 if ((mSources & source) == source) { 1009 description.append(" "); 1010 description.append(sourceName); 1011 } 1012 } 1013 } 1014