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