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