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