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