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