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