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