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