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.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.
    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 
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    561     public int getSources() {
    562         return mSources;
    563     }
    564 
    565     /**
    566      * Gets the keyboard type.
    567      * @return The keyboard type.
    568      */
    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      */
    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      */
    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      */
    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      */
    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      */
    647     public List<MotionRange> getMotionRanges() {
    648         return mMotionRanges;
    649     }
    650 
    651     // Called from native code.
    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      */
    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      */
    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 
    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          */
    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          */
    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          */
    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          */
    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          */
    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          */
    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          */
    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          */
    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          */
    797         public float getResolution() {
    798             return mResolution;
    799         }
    800     }
    801 
    802     @Override
    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
    833     public int describeContents() {
    834         return 0;
    835     }
    836 
    837     @Override
    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 
    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