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