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