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