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