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