Home | History | Annotate | Download | only in view
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.view;
     18 
     19 import android.content.Context;
     20 import android.hardware.input.InputDeviceIdentifier;
     21 import android.hardware.input.InputManager;
     22 import android.os.Parcel;
     23 import android.os.Parcelable;
     24 import android.os.Vibrator;
     25 import android.os.NullVibrator;
     26 
     27 import java.util.ArrayList;
     28 import java.util.List;
     29 
     30 /**
     31  * Describes the capabilities of a particular input device.
     32  * <p>
     33  * Each input device may support multiple classes of input.  For example, a multi-function
     34  * keyboard may compose the capabilities of a standard keyboard together with a track pad mouse
     35  * or other pointing device.
     36  * </p><p>
     37  * Some input devices present multiple distinguishable sources of input.
     38  * Applications can query the framework about the characteristics of each distinct source.
     39  * </p><p>
     40  * As a further wrinkle, different kinds of input sources uses different coordinate systems
     41  * to describe motion events.  Refer to the comments on the input source constants for
     42  * the appropriate interpretation.
     43  * </p>
     44  */
     45 public final class InputDevice implements Parcelable {
     46     private final int mId;
     47     private final int mGeneration;
     48     private final int mControllerNumber;
     49     private final String mName;
     50     private final int mVendorId;
     51     private final int mProductId;
     52     private final String mDescriptor;
     53     private final InputDeviceIdentifier mIdentifier;
     54     private final boolean mIsExternal;
     55     private final int mSources;
     56     private final int mKeyboardType;
     57     private final KeyCharacterMap mKeyCharacterMap;
     58     private final boolean mHasVibrator;
     59     private final boolean 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 touch pad or digitizer tablet that is not
    241      * associated with a display (unlike {@link #SOURCE_TOUCHSCREEN}).
    242      *
    243      * @see #SOURCE_CLASS_POSITION
    244      */
    245     public static final int SOURCE_TOUCHPAD = 0x00100000 | SOURCE_CLASS_POSITION;
    246 
    247     /**
    248      * The input source is a touch device whose motions should be interpreted as navigation events.
    249      *
    250      * For example, an upward swipe should be as an upward focus traversal in the same manner as
    251      * pressing up on a D-Pad would be. Swipes to the left, right and down should be treated in a
    252      * similar manner.
    253      *
    254      * @see #SOURCE_CLASS_NONE
    255      */
    256     public static final int SOURCE_TOUCH_NAVIGATION = 0x00200000 | SOURCE_CLASS_NONE;
    257 
    258     /**
    259      * The input source is a rotating encoder device whose motions should be interpreted as akin to
    260      * those of a scroll wheel.
    261      *
    262      * @see #SOURCE_CLASS_NONE
    263      * {@hide}
    264      */
    265     public static final int SOURCE_ROTARY_ENCODER = 0x00400000 | SOURCE_CLASS_NONE;
    266 
    267     /**
    268      * The input source is a joystick.
    269      * (It may also be a {@link #SOURCE_GAMEPAD}).
    270      *
    271      * @see #SOURCE_CLASS_JOYSTICK
    272      */
    273     public static final int SOURCE_JOYSTICK = 0x01000000 | SOURCE_CLASS_JOYSTICK;
    274 
    275     /**
    276      * The input source is a device connected through HDMI-based bus.
    277      *
    278      * The key comes in through HDMI-CEC or MHL signal line, and is treated as if it were
    279      * generated by a locally connected DPAD or keyboard.
    280      */
    281     public static final int SOURCE_HDMI = 0x02000000 | SOURCE_CLASS_BUTTON;
    282 
    283     /**
    284      * A special input source constant that is used when filtering input devices
    285      * to match devices that provide any type of input source.
    286      */
    287     public static final int SOURCE_ANY = 0xffffff00;
    288 
    289     /**
    290      * Constant for retrieving the range of values for {@link MotionEvent#AXIS_X}.
    291      *
    292      * @see #getMotionRange
    293      * @deprecated Use {@link MotionEvent#AXIS_X} instead.
    294      */
    295     @Deprecated
    296     public static final int MOTION_RANGE_X = MotionEvent.AXIS_X;
    297 
    298     /**
    299      * Constant for retrieving the range of values for {@link MotionEvent#AXIS_Y}.
    300      *
    301      * @see #getMotionRange
    302      * @deprecated Use {@link MotionEvent#AXIS_Y} instead.
    303      */
    304     @Deprecated
    305     public static final int MOTION_RANGE_Y = MotionEvent.AXIS_Y;
    306 
    307     /**
    308      * Constant for retrieving the range of values for {@link MotionEvent#AXIS_PRESSURE}.
    309      *
    310      * @see #getMotionRange
    311      * @deprecated Use {@link MotionEvent#AXIS_PRESSURE} instead.
    312      */
    313     @Deprecated
    314     public static final int MOTION_RANGE_PRESSURE = MotionEvent.AXIS_PRESSURE;
    315 
    316     /**
    317      * Constant for retrieving the range of values for {@link MotionEvent#AXIS_SIZE}.
    318      *
    319      * @see #getMotionRange
    320      * @deprecated Use {@link MotionEvent#AXIS_SIZE} instead.
    321      */
    322     @Deprecated
    323     public static final int MOTION_RANGE_SIZE = MotionEvent.AXIS_SIZE;
    324 
    325     /**
    326      * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOUCH_MAJOR}.
    327      *
    328      * @see #getMotionRange
    329      * @deprecated Use {@link MotionEvent#AXIS_TOUCH_MAJOR} instead.
    330      */
    331     @Deprecated
    332     public static final int MOTION_RANGE_TOUCH_MAJOR = MotionEvent.AXIS_TOUCH_MAJOR;
    333 
    334     /**
    335      * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOUCH_MINOR}.
    336      *
    337      * @see #getMotionRange
    338      * @deprecated Use {@link MotionEvent#AXIS_TOUCH_MINOR} instead.
    339      */
    340     @Deprecated
    341     public static final int MOTION_RANGE_TOUCH_MINOR = MotionEvent.AXIS_TOUCH_MINOR;
    342 
    343     /**
    344      * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOOL_MAJOR}.
    345      *
    346      * @see #getMotionRange
    347      * @deprecated Use {@link MotionEvent#AXIS_TOOL_MAJOR} instead.
    348      */
    349     @Deprecated
    350     public static final int MOTION_RANGE_TOOL_MAJOR = MotionEvent.AXIS_TOOL_MAJOR;
    351 
    352     /**
    353      * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOOL_MINOR}.
    354      *
    355      * @see #getMotionRange
    356      * @deprecated Use {@link MotionEvent#AXIS_TOOL_MINOR} instead.
    357      */
    358     @Deprecated
    359     public static final int MOTION_RANGE_TOOL_MINOR = MotionEvent.AXIS_TOOL_MINOR;
    360 
    361     /**
    362      * Constant for retrieving the range of values for {@link MotionEvent#AXIS_ORIENTATION}.
    363      *
    364      * @see #getMotionRange
    365      * @deprecated Use {@link MotionEvent#AXIS_ORIENTATION} instead.
    366      */
    367     @Deprecated
    368     public static final int MOTION_RANGE_ORIENTATION = MotionEvent.AXIS_ORIENTATION;
    369 
    370     /**
    371      * There is no keyboard.
    372      */
    373     public static final int KEYBOARD_TYPE_NONE = 0;
    374 
    375     /**
    376      * The keyboard is not fully alphabetic.  It may be a numeric keypad or an assortment
    377      * of buttons that are not mapped as alphabetic keys suitable for text input.
    378      */
    379     public static final int KEYBOARD_TYPE_NON_ALPHABETIC = 1;
    380 
    381     /**
    382      * The keyboard supports a complement of alphabetic keys.
    383      */
    384     public static final int KEYBOARD_TYPE_ALPHABETIC = 2;
    385 
    386     public static final Parcelable.Creator<InputDevice> CREATOR =
    387             new Parcelable.Creator<InputDevice>() {
    388         public InputDevice createFromParcel(Parcel in) {
    389             return new InputDevice(in);
    390         }
    391         public InputDevice[] newArray(int size) {
    392             return new InputDevice[size];
    393         }
    394     };
    395 
    396     // Called by native code.
    397     private InputDevice(int id, int generation, int controllerNumber, String name, int vendorId,
    398             int productId, String descriptor, boolean isExternal, int sources, int keyboardType,
    399             KeyCharacterMap keyCharacterMap, boolean hasVibrator, boolean hasMicrophone,
    400             boolean hasButtonUnderPad) {
    401         mId = id;
    402         mGeneration = generation;
    403         mControllerNumber = controllerNumber;
    404         mName = name;
    405         mVendorId = vendorId;
    406         mProductId = productId;
    407         mDescriptor = descriptor;
    408         mIsExternal = isExternal;
    409         mSources = sources;
    410         mKeyboardType = keyboardType;
    411         mKeyCharacterMap = keyCharacterMap;
    412         mHasVibrator = hasVibrator;
    413         mHasMicrophone = hasMicrophone;
    414         mHasButtonUnderPad = hasButtonUnderPad;
    415         mIdentifier = new InputDeviceIdentifier(descriptor, vendorId, productId);
    416     }
    417 
    418     private InputDevice(Parcel in) {
    419         mId = in.readInt();
    420         mGeneration = in.readInt();
    421         mControllerNumber = in.readInt();
    422         mName = in.readString();
    423         mVendorId = in.readInt();
    424         mProductId = in.readInt();
    425         mDescriptor = in.readString();
    426         mIsExternal = in.readInt() != 0;
    427         mSources = in.readInt();
    428         mKeyboardType = in.readInt();
    429         mKeyCharacterMap = KeyCharacterMap.CREATOR.createFromParcel(in);
    430         mHasVibrator = in.readInt() != 0;
    431         mHasMicrophone = in.readInt() != 0;
    432         mHasButtonUnderPad = in.readInt() != 0;
    433         mIdentifier = new InputDeviceIdentifier(mDescriptor, mVendorId, mProductId);
    434 
    435         for (;;) {
    436             int axis = in.readInt();
    437             if (axis < 0) {
    438                 break;
    439             }
    440             addMotionRange(axis, in.readInt(), in.readFloat(), in.readFloat(), in.readFloat(),
    441                     in.readFloat(), in.readFloat());
    442         }
    443     }
    444 
    445     /**
    446      * Gets information about the input device with the specified id.
    447      * @param id The device id.
    448      * @return The input device or null if not found.
    449      */
    450     public static InputDevice getDevice(int id) {
    451         return InputManager.getInstance().getInputDevice(id);
    452     }
    453 
    454     /**
    455      * Gets the ids of all input devices in the system.
    456      * @return The input device ids.
    457      */
    458     public static int[] getDeviceIds() {
    459         return InputManager.getInstance().getInputDeviceIds();
    460     }
    461 
    462     /**
    463      * Gets the input device id.
    464      * <p>
    465      * Each input device receives a unique id when it is first configured
    466      * by the system.  The input device id may change when the system is restarted or if the
    467      * input device is disconnected, reconnected or reconfigured at any time.
    468      * If you require a stable identifier for a device that persists across
    469      * boots and reconfigurations, use {@link #getDescriptor()}.
    470      * </p>
    471      *
    472      * @return The input device id.
    473      */
    474     public int getId() {
    475         return mId;
    476     }
    477 
    478     /**
    479      * The controller number for a given input device.
    480      * <p>
    481      * Each gamepad or joystick is given a unique, positive controller number when initially
    482      * configured by the system. This number may change due to events such as device disconnects /
    483      * reconnects or user initiated reassignment. Any change in number will trigger an event that
    484      * can be observed by registering an {@link InputManager.InputDeviceListener}.
    485      * </p>
    486      * <p>
    487      * All input devices which are not gamepads or joysticks will be assigned a controller number
    488      * of 0.
    489      * </p>
    490      *
    491      * @return The controller number of the device.
    492      */
    493     public int getControllerNumber() {
    494         return mControllerNumber;
    495     }
    496 
    497     /**
    498      * The set of identifying information for type of input device. This
    499      * information can be used by the system to configure appropriate settings
    500      * for the device.
    501      *
    502      * @return The identifier object for this device
    503      * @hide
    504      */
    505     public InputDeviceIdentifier getIdentifier() {
    506         return mIdentifier;
    507     }
    508 
    509     /**
    510      * Gets a generation number for this input device.
    511      * The generation number is incremented whenever the device is reconfigured and its
    512      * properties may have changed.
    513      *
    514      * @return The generation number.
    515      *
    516      * @hide
    517      */
    518     public int getGeneration() {
    519         return mGeneration;
    520     }
    521 
    522     /**
    523      * Gets the vendor id for the given device, if available.
    524      * <p>
    525      * A vendor id uniquely identifies the company who manufactured the device. A value of 0 will
    526      * be assigned where a vendor id is not available.
    527      * </p>
    528      *
    529      * @return The vendor id of a given device
    530      */
    531     public int getVendorId() {
    532         return mVendorId;
    533     }
    534 
    535     /**
    536      * Gets the product id for the given device, if available.
    537      * <p>
    538      * A product id uniquely identifies which product within the address space of a given vendor,
    539      * identified by the device's vendor id. A value of 0 will be assigned where a product id is
    540      * not available.
    541      * </p>
    542      *
    543      * @return The product id of a given device
    544      */
    545     public int getProductId() {
    546         return mProductId;
    547     }
    548 
    549     /**
    550      * Gets the input device descriptor, which is a stable identifier for an input device.
    551      * <p>
    552      * An input device descriptor uniquely identifies an input device.  Its value
    553      * is intended to be persistent across system restarts, and should not change even
    554      * if the input device is disconnected, reconnected or reconfigured at any time.
    555      * </p><p>
    556      * It is possible for there to be multiple {@link InputDevice} instances that have the
    557      * same input device descriptor.  This might happen in situations where a single
    558      * human input device registers multiple {@link InputDevice} instances (HID collections)
    559      * that describe separate features of the device, such as a keyboard that also
    560      * has a trackpad.  Alternately, it may be that the input devices are simply
    561      * indistinguishable, such as two keyboards made by the same manufacturer.
    562      * </p><p>
    563      * The input device descriptor returned by {@link #getDescriptor} should only be
    564      * used when an application needs to remember settings associated with a particular
    565      * input device.  For all other purposes when referring to a logical
    566      * {@link InputDevice} instance at runtime use the id returned by {@link #getId()}.
    567      * </p>
    568      *
    569      * @return The input device descriptor.
    570      */
    571     public String getDescriptor() {
    572         return mDescriptor;
    573     }
    574 
    575     /**
    576      * Returns true if the device is a virtual input device rather than a real one,
    577      * such as the virtual keyboard (see {@link KeyCharacterMap#VIRTUAL_KEYBOARD}).
    578      * <p>
    579      * Virtual input devices are provided to implement system-level functionality
    580      * and should not be seen or configured by users.
    581      * </p>
    582      *
    583      * @return True if the device is virtual.
    584      *
    585      * @see KeyCharacterMap#VIRTUAL_KEYBOARD
    586      */
    587     public boolean isVirtual() {
    588         return mId < 0;
    589     }
    590 
    591     /**
    592      * Returns true if the device is external (connected to USB or Bluetooth or some other
    593      * peripheral bus), otherwise it is built-in.
    594      *
    595      * @return True if the device is external.
    596      *
    597      * @hide
    598      */
    599     public boolean isExternal() {
    600         return mIsExternal;
    601     }
    602 
    603     /**
    604      * Returns true if the device is a full keyboard.
    605      *
    606      * @return True if the device is a full keyboard.
    607      *
    608      * @hide
    609      */
    610     public boolean isFullKeyboard() {
    611         return (mSources & SOURCE_KEYBOARD) == SOURCE_KEYBOARD
    612                 && mKeyboardType == KEYBOARD_TYPE_ALPHABETIC;
    613     }
    614 
    615     /**
    616      * Gets the name of this input device.
    617      * @return The input device name.
    618      */
    619     public String getName() {
    620         return mName;
    621     }
    622 
    623     /**
    624      * Gets the input sources supported by this input device as a combined bitfield.
    625      * @return The supported input sources.
    626      */
    627     public int getSources() {
    628         return mSources;
    629     }
    630 
    631     /**
    632      * Determines whether the input device supports the given source or sources.
    633      *
    634      * @param source The input source or sources to check against. This can be a generic device
    635      * type such as {@link InputDevice#SOURCE_MOUSE}, a more generic device class, such as
    636      * {@link InputDevice#SOURCE_CLASS_POINTER}, or a combination of sources bitwise ORed together.
    637      * @return Whether the device can produce all of the given sources.
    638      */
    639     public boolean supportsSource(int source) {
    640         return (mSources & source) == source;
    641     }
    642 
    643     /**
    644      * Gets the keyboard type.
    645      * @return The keyboard type.
    646      */
    647     public int getKeyboardType() {
    648         return mKeyboardType;
    649     }
    650 
    651     /**
    652      * Gets the key character map associated with this input device.
    653      * @return The key character map.
    654      */
    655     public KeyCharacterMap getKeyCharacterMap() {
    656         return mKeyCharacterMap;
    657     }
    658 
    659     /**
    660      * Gets whether the device is capable of producing the list of keycodes.
    661      * @param keys The list of android keycodes to check for.
    662      * @return An array of booleans where each member specifies whether the device is capable of
    663      * generating the keycode given by the corresponding value at the same index in the keys array.
    664      */
    665     public boolean[] hasKeys(int... keys) {
    666         return InputManager.getInstance().deviceHasKeys(mId, keys);
    667     }
    668 
    669     /**
    670      * Gets information about the range of values for a particular {@link MotionEvent} axis.
    671      * If the device supports multiple sources, the same axis may have different meanings
    672      * for each source.  Returns information about the first axis found for any source.
    673      * To obtain information about the axis for a specific source, use
    674      * {@link #getMotionRange(int, int)}.
    675      *
    676      * @param axis The axis constant.
    677      * @return The range of values, or null if the requested axis is not
    678      * supported by the device.
    679      *
    680      * @see MotionEvent#AXIS_X
    681      * @see MotionEvent#AXIS_Y
    682      */
    683     public MotionRange getMotionRange(int axis) {
    684         final int numRanges = mMotionRanges.size();
    685         for (int i = 0; i < numRanges; i++) {
    686             final MotionRange range = mMotionRanges.get(i);
    687             if (range.mAxis == axis) {
    688                 return range;
    689             }
    690         }
    691         return null;
    692     }
    693 
    694     /**
    695      * Gets information about the range of values for a particular {@link MotionEvent} axis
    696      * used by a particular source on the device.
    697      * If the device supports multiple sources, the same axis may have different meanings
    698      * for each source.
    699      *
    700      * @param axis The axis constant.
    701      * @param source The source for which to return information.
    702      * @return The range of values, or null if the requested axis is not
    703      * supported by the device.
    704      *
    705      * @see MotionEvent#AXIS_X
    706      * @see MotionEvent#AXIS_Y
    707      */
    708     public MotionRange getMotionRange(int axis, int source) {
    709         final int numRanges = mMotionRanges.size();
    710         for (int i = 0; i < numRanges; i++) {
    711             final MotionRange range = mMotionRanges.get(i);
    712             if (range.mAxis == axis && range.mSource == source) {
    713                 return range;
    714             }
    715         }
    716         return null;
    717     }
    718 
    719     /**
    720      * Gets the ranges for all axes supported by the device.
    721      * @return The motion ranges for the device.
    722      *
    723      * @see #getMotionRange(int, int)
    724      */
    725     public List<MotionRange> getMotionRanges() {
    726         return mMotionRanges;
    727     }
    728 
    729     // Called from native code.
    730     private void addMotionRange(int axis, int source,
    731             float min, float max, float flat, float fuzz, float resolution) {
    732         mMotionRanges.add(new MotionRange(axis, source, min, max, flat, fuzz, resolution));
    733     }
    734 
    735     /**
    736      * Gets the vibrator service associated with the device, if there is one.
    737      * Even if the device does not have a vibrator, the result is never null.
    738      * Use {@link Vibrator#hasVibrator} to determine whether a vibrator is
    739      * present.
    740      *
    741      * Note that the vibrator associated with the device may be different from
    742      * the system vibrator.  To obtain an instance of the system vibrator instead, call
    743      * {@link Context#getSystemService} with {@link Context#VIBRATOR_SERVICE} as argument.
    744      *
    745      * @return The vibrator service associated with the device, never null.
    746      */
    747     public Vibrator getVibrator() {
    748         synchronized (mMotionRanges) {
    749             if (mVibrator == null) {
    750                 if (mHasVibrator) {
    751                     mVibrator = InputManager.getInstance().getInputDeviceVibrator(mId);
    752                 } else {
    753                     mVibrator = NullVibrator.getInstance();
    754                 }
    755             }
    756             return mVibrator;
    757         }
    758     }
    759 
    760     /**
    761      * Reports whether the device has a built-in microphone.
    762      * @return Whether the device has a built-in microphone.
    763      */
    764     public boolean hasMicrophone() {
    765         return mHasMicrophone;
    766     }
    767 
    768     /**
    769      * Reports whether the device has a button under its touchpad
    770      * @return Whether the device has a button under its touchpad
    771      * @hide
    772      */
    773     public boolean hasButtonUnderPad() {
    774         return mHasButtonUnderPad;
    775     }
    776 
    777     /**
    778      * Sets the current pointer type.
    779      * @param pointerType the type of the pointer icon.
    780      * @hide
    781      */
    782     public void setPointerType(int pointerType) {
    783         InputManager.getInstance().setPointerIconType(pointerType);
    784     }
    785 
    786     /**
    787      * Specifies the current custom pointer.
    788      * @param icon the icon data.
    789      * @hide
    790      */
    791     public void setCustomPointerIcon(PointerIcon icon) {
    792         InputManager.getInstance().setCustomPointerIcon(icon);
    793     }
    794 
    795     /**
    796      * Provides information about the range of values for a particular {@link MotionEvent} axis.
    797      *
    798      * @see InputDevice#getMotionRange(int)
    799      */
    800     public static final class MotionRange {
    801         private int mAxis;
    802         private int mSource;
    803         private float mMin;
    804         private float mMax;
    805         private float mFlat;
    806         private float mFuzz;
    807         private float mResolution;
    808 
    809         private MotionRange(int axis, int source, float min, float max, float flat, float fuzz,
    810                 float resolution) {
    811             mAxis = axis;
    812             mSource = source;
    813             mMin = min;
    814             mMax = max;
    815             mFlat = flat;
    816             mFuzz = fuzz;
    817             mResolution = resolution;
    818         }
    819 
    820         /**
    821          * Gets the axis id.
    822          * @return The axis id.
    823          */
    824         public int getAxis() {
    825             return mAxis;
    826         }
    827 
    828         /**
    829          * Gets the source for which the axis is defined.
    830          * @return The source.
    831          */
    832         public int getSource() {
    833             return mSource;
    834         }
    835 
    836 
    837         /**
    838          * Determines whether the event is from the given source.
    839          *
    840          * @param source The input source to check against. This can be a specific device type,
    841          * such as {@link InputDevice#SOURCE_TOUCH_NAVIGATION}, or a more generic device class,
    842          * such as {@link InputDevice#SOURCE_CLASS_POINTER}.
    843          * @return Whether the event is from the given source.
    844          */
    845         public boolean isFromSource(int source) {
    846             return (getSource() & source) == source;
    847         }
    848 
    849         /**
    850          * Gets the inclusive minimum value for the axis.
    851          * @return The inclusive minimum value.
    852          */
    853         public float getMin() {
    854             return mMin;
    855         }
    856 
    857         /**
    858          * Gets the inclusive maximum value for the axis.
    859          * @return The inclusive maximum value.
    860          */
    861         public float getMax() {
    862             return mMax;
    863         }
    864 
    865         /**
    866          * Gets the range of the axis (difference between maximum and minimum).
    867          * @return The range of values.
    868          */
    869         public float getRange() {
    870             return mMax - mMin;
    871         }
    872 
    873         /**
    874          * Gets the extent of the center flat position with respect to this axis.
    875          * <p>
    876          * For example, a flat value of 8 means that the center position is between -8 and +8.
    877          * This value is mainly useful for calibrating self-centering devices.
    878          * </p>
    879          * @return The extent of the center flat position.
    880          */
    881         public float getFlat() {
    882             return mFlat;
    883         }
    884 
    885         /**
    886          * Gets the error tolerance for input device measurements with respect to this axis.
    887          * <p>
    888          * For example, a value of 2 indicates that the measured value may be up to +/- 2 units
    889          * away from the actual value due to noise and device sensitivity limitations.
    890          * </p>
    891          * @return The error tolerance.
    892          */
    893         public float getFuzz() {
    894             return mFuzz;
    895         }
    896 
    897         /**
    898          * Gets the resolution for input device measurements with respect to this axis.
    899          * @return The resolution in units per millimeter, or units per radian for rotational axes.
    900          */
    901         public float getResolution() {
    902             return mResolution;
    903         }
    904     }
    905 
    906     @Override
    907     public void writeToParcel(Parcel out, int flags) {
    908         out.writeInt(mId);
    909         out.writeInt(mGeneration);
    910         out.writeInt(mControllerNumber);
    911         out.writeString(mName);
    912         out.writeInt(mVendorId);
    913         out.writeInt(mProductId);
    914         out.writeString(mDescriptor);
    915         out.writeInt(mIsExternal ? 1 : 0);
    916         out.writeInt(mSources);
    917         out.writeInt(mKeyboardType);
    918         mKeyCharacterMap.writeToParcel(out, flags);
    919         out.writeInt(mHasVibrator ? 1 : 0);
    920         out.writeInt(mHasMicrophone ? 1 : 0);
    921         out.writeInt(mHasButtonUnderPad ? 1 : 0);
    922 
    923         final int numRanges = mMotionRanges.size();
    924         for (int i = 0; i < numRanges; i++) {
    925             MotionRange range = mMotionRanges.get(i);
    926             out.writeInt(range.mAxis);
    927             out.writeInt(range.mSource);
    928             out.writeFloat(range.mMin);
    929             out.writeFloat(range.mMax);
    930             out.writeFloat(range.mFlat);
    931             out.writeFloat(range.mFuzz);
    932             out.writeFloat(range.mResolution);
    933         }
    934         out.writeInt(-1);
    935     }
    936 
    937     @Override
    938     public int describeContents() {
    939         return 0;
    940     }
    941 
    942     @Override
    943     public String toString() {
    944         StringBuilder description = new StringBuilder();
    945         description.append("Input Device ").append(mId).append(": ").append(mName).append("\n");
    946         description.append("  Descriptor: ").append(mDescriptor).append("\n");
    947         description.append("  Generation: ").append(mGeneration).append("\n");
    948         description.append("  Location: ").append(mIsExternal ? "external" : "built-in").append("\n");
    949 
    950         description.append("  Keyboard Type: ");
    951         switch (mKeyboardType) {
    952             case KEYBOARD_TYPE_NONE:
    953                 description.append("none");
    954                 break;
    955             case KEYBOARD_TYPE_NON_ALPHABETIC:
    956                 description.append("non-alphabetic");
    957                 break;
    958             case KEYBOARD_TYPE_ALPHABETIC:
    959                 description.append("alphabetic");
    960                 break;
    961         }
    962         description.append("\n");
    963 
    964         description.append("  Has Vibrator: ").append(mHasVibrator).append("\n");
    965 
    966         description.append("  Has mic: ").append(mHasMicrophone).append("\n");
    967 
    968         description.append("  Sources: 0x").append(Integer.toHexString(mSources)).append(" (");
    969         appendSourceDescriptionIfApplicable(description, SOURCE_KEYBOARD, "keyboard");
    970         appendSourceDescriptionIfApplicable(description, SOURCE_DPAD, "dpad");
    971         appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHSCREEN, "touchscreen");
    972         appendSourceDescriptionIfApplicable(description, SOURCE_MOUSE, "mouse");
    973         appendSourceDescriptionIfApplicable(description, SOURCE_STYLUS, "stylus");
    974         appendSourceDescriptionIfApplicable(description, SOURCE_TRACKBALL, "trackball");
    975         appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHPAD, "touchpad");
    976         appendSourceDescriptionIfApplicable(description, SOURCE_JOYSTICK, "joystick");
    977         appendSourceDescriptionIfApplicable(description, SOURCE_GAMEPAD, "gamepad");
    978         description.append(" )\n");
    979 
    980         final int numAxes = mMotionRanges.size();
    981         for (int i = 0; i < numAxes; i++) {
    982             MotionRange range = mMotionRanges.get(i);
    983             description.append("    ").append(MotionEvent.axisToString(range.mAxis));
    984             description.append(": source=0x").append(Integer.toHexString(range.mSource));
    985             description.append(" min=").append(range.mMin);
    986             description.append(" max=").append(range.mMax);
    987             description.append(" flat=").append(range.mFlat);
    988             description.append(" fuzz=").append(range.mFuzz);
    989             description.append(" resolution=").append(range.mResolution);
    990             description.append("\n");
    991         }
    992         return description.toString();
    993     }
    994 
    995     private void appendSourceDescriptionIfApplicable(StringBuilder description, int source,
    996             String sourceName) {
    997         if ((mSources & source) == source) {
    998             description.append(" ");
    999             description.append(sourceName);
   1000         }
   1001     }
   1002 }
   1003