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