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