1 /*
2  * Copyright (C) 2012 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.hardware.input;
18 
19 import static com.android.input.flags.Flags.FLAG_INPUT_DEVICE_VIEW_BEHAVIOR_API;
20 import static com.android.input.flags.Flags.FLAG_DEVICE_ASSOCIATIONS;
21 import static com.android.hardware.input.Flags.keyboardLayoutPreviewFlag;
22 
23 import android.Manifest;
24 import android.annotation.FlaggedApi;
25 import android.annotation.FloatRange;
26 import android.annotation.IntDef;
27 import android.annotation.NonNull;
28 import android.annotation.Nullable;
29 import android.annotation.RequiresPermission;
30 import android.annotation.SdkConstant;
31 import android.annotation.SdkConstant.SdkConstantType;
32 import android.annotation.SuppressLint;
33 import android.annotation.SystemService;
34 import android.annotation.TestApi;
35 import android.annotation.UserIdInt;
36 import android.app.ActivityThread;
37 import android.compat.annotation.ChangeId;
38 import android.compat.annotation.UnsupportedAppUsage;
39 import android.content.Context;
40 import android.graphics.drawable.Drawable;
41 import android.hardware.BatteryState;
42 import android.os.Build;
43 import android.os.Handler;
44 import android.os.IBinder;
45 import android.os.InputEventInjectionSync;
46 import android.os.RemoteException;
47 import android.os.SystemClock;
48 import android.os.Vibrator;
49 import android.util.Log;
50 import android.view.Display;
51 import android.view.InputDevice;
52 import android.view.InputEvent;
53 import android.view.InputMonitor;
54 import android.view.KeyEvent;
55 import android.view.MotionEvent;
56 import android.view.PointerIcon;
57 import android.view.VerifiedInputEvent;
58 import android.view.WindowManager.LayoutParams;
59 import android.view.inputmethod.InputMethodInfo;
60 import android.view.inputmethod.InputMethodSubtype;
61 
62 import java.lang.annotation.Retention;
63 import java.lang.annotation.RetentionPolicy;
64 import java.util.ArrayList;
65 import java.util.List;
66 import java.util.Map;
67 import java.util.Objects;
68 import java.util.concurrent.Executor;
69 
70 /**
71  * Provides information about input devices and available key layouts.
72  */
73 @SystemService(Context.INPUT_SERVICE)
74 public final class InputManager {
75     private static final String TAG = "InputManager";
76     // To enable these logs, run: 'adb shell setprop log.tag.InputManager DEBUG' (requires restart)
77     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
78 
79     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
80     private final IInputManager mIm;
81 
82     /**
83      * Whether a PointerIcon is shown for stylus pointers.
84      * Obtain using {@link #isStylusPointerIconEnabled()}.
85      */
86     @Nullable
87     private Boolean mIsStylusPointerIconEnabled = null;
88 
89     /**
90      * Broadcast Action: Query available keyboard layouts.
91      * <p>
92      * The input manager service locates available keyboard layouts
93      * by querying broadcast receivers that are registered for this action.
94      * An application can offer additional keyboard layouts to the user
95      * by declaring a suitable broadcast receiver in its manifest.
96      * </p><p>
97      * Here is an example broadcast receiver declaration that an application
98      * might include in its AndroidManifest.xml to advertise keyboard layouts.
99      * The meta-data specifies a resource that contains a description of each keyboard
100      * layout that is provided by the application.
101      * <pre><code>
102      * &lt;receiver android:name=".InputDeviceReceiver"
103      *         android:label="@string/keyboard_layouts_label">
104      *     &lt;intent-filter>
105      *         &lt;action android:name="android.hardware.input.action.QUERY_KEYBOARD_LAYOUTS" />
106      *     &lt;/intent-filter>
107      *     &lt;meta-data android:name="android.hardware.input.metadata.KEYBOARD_LAYOUTS"
108      *             android:resource="@xml/keyboard_layouts" />
109      * &lt;/receiver>
110      * </code></pre>
111      * </p><p>
112      * In the above example, the <code>@xml/keyboard_layouts</code> resource refers to
113      * an XML resource whose root element is <code>&lt;keyboard-layouts></code> that
114      * contains zero or more <code>&lt;keyboard-layout></code> elements.
115      * Each <code>&lt;keyboard-layout></code> element specifies the name, label, and location
116      * of a key character map for a particular keyboard layout.  The label on the receiver
117      * is used to name the collection of keyboard layouts provided by this receiver in the
118      * keyboard layout settings.
119      * <pre><code>
120      * &lt;?xml version="1.0" encoding="utf-8"?>
121      * &lt;keyboard-layouts xmlns:android="http://schemas.android.com/apk/res/android">
122      *     &lt;keyboard-layout android:name="keyboard_layout_english_us"
123      *             android:label="@string/keyboard_layout_english_us_label"
124      *             android:keyboardLayout="@raw/keyboard_layout_english_us" />
125      * &lt;/keyboard-layouts>
126      * </pre></code>
127      * </p><p>
128      * The <code>android:name</code> attribute specifies an identifier by which
129      * the keyboard layout will be known in the package.
130      * The <code>android:label</code> attribute specifies a human-readable descriptive
131      * label to describe the keyboard layout in the user interface, such as "English (US)".
132      * The <code>android:keyboardLayout</code> attribute refers to a
133      * <a href="https://source.android.com/docs/core/interaction/input/key-character-map-files">
134      * key character map</a> resource that defines the keyboard layout.
135      * The <code>android:keyboardLocale</code> attribute specifies a comma separated list of BCP 47
136      * language tags depicting the locales supported by the keyboard layout. This attribute is
137      * optional and will be used for auto layout selection for external physical keyboards.
138      * The <code>android:keyboardLayoutType</code> attribute specifies the layoutType for the
139      * keyboard layout. This can be either empty or one of the following supported layout types:
140      * qwerty, qwertz, azerty, dvorak, colemak, workman, extended, turkish_q, turkish_f. This
141      * attribute is optional and will be used for auto layout selection for external physical
142      * keyboards.
143      * </p>
144      */
145     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
146     public static final String ACTION_QUERY_KEYBOARD_LAYOUTS =
147             "android.hardware.input.action.QUERY_KEYBOARD_LAYOUTS";
148 
149     /**
150      * Metadata Key: Keyboard layout metadata associated with
151      * {@link #ACTION_QUERY_KEYBOARD_LAYOUTS}.
152      * <p>
153      * Specifies the resource id of a XML resource that describes the keyboard
154      * layouts that are provided by the application.
155      * </p>
156      */
157     public static final String META_DATA_KEYBOARD_LAYOUTS =
158             "android.hardware.input.metadata.KEYBOARD_LAYOUTS";
159 
160     /**
161      * Prevent touches from being consumed by apps if these touches passed through a non-trusted
162      * window from a different UID and are considered unsafe.
163      *
164      * @hide
165      */
166     @TestApi
167     @ChangeId
168     public static final long BLOCK_UNTRUSTED_TOUCHES = 158002302L;
169 
170     /**
171      * Input Event Injection Synchronization Mode: None.
172      * Never blocks.  Injection is asynchronous and is assumed always to be successful.
173      * @hide
174      */
175     public static final int INJECT_INPUT_EVENT_MODE_ASYNC = InputEventInjectionSync.NONE;
176 
177     /**
178      * Input Event Injection Synchronization Mode: Wait for result.
179      * Waits for previous events to be dispatched so that the input dispatcher can
180      * determine whether input event injection will be permitted based on the current
181      * input focus.  Does not wait for the input event to finish being handled
182      * by the application.
183      * @hide
184      */
185     public static final int INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT =
186             InputEventInjectionSync.WAIT_FOR_RESULT;
187 
188     /**
189      * Input Event Injection Synchronization Mode: Wait for finish.
190      * Waits for the event to be delivered to the application and handled.
191      * @hide
192      */
193     @UnsupportedAppUsage(trackingBug = 171972397)
194     public static final int INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH =
195             InputEventInjectionSync.WAIT_FOR_FINISHED;
196 
197     /** @hide */
198     @Retention(RetentionPolicy.SOURCE)
199     @IntDef(prefix = { "SWITCH_STATE_" }, value = {
200             SWITCH_STATE_UNKNOWN,
201             SWITCH_STATE_OFF,
202             SWITCH_STATE_ON
203     })
204     public @interface SwitchState {}
205 
206     /** @hide */
207     @Retention(RetentionPolicy.SOURCE)
208     @IntDef(prefix = { "REMAPPABLE_MODIFIER_KEY_" }, value = {
209             RemappableModifierKey.REMAPPABLE_MODIFIER_KEY_CTRL_LEFT,
210             RemappableModifierKey.REMAPPABLE_MODIFIER_KEY_CTRL_RIGHT,
211             RemappableModifierKey.REMAPPABLE_MODIFIER_KEY_META_LEFT,
212             RemappableModifierKey.REMAPPABLE_MODIFIER_KEY_META_RIGHT,
213             RemappableModifierKey.REMAPPABLE_MODIFIER_KEY_ALT_LEFT,
214             RemappableModifierKey.REMAPPABLE_MODIFIER_KEY_ALT_RIGHT,
215             RemappableModifierKey.REMAPPABLE_MODIFIER_KEY_SHIFT_LEFT,
216             RemappableModifierKey.REMAPPABLE_MODIFIER_KEY_SHIFT_RIGHT,
217             RemappableModifierKey.REMAPPABLE_MODIFIER_KEY_CAPS_LOCK,
218     })
219     public @interface RemappableModifierKey {
220         int REMAPPABLE_MODIFIER_KEY_CTRL_LEFT = KeyEvent.KEYCODE_CTRL_LEFT;
221         int REMAPPABLE_MODIFIER_KEY_CTRL_RIGHT = KeyEvent.KEYCODE_CTRL_RIGHT;
222         int REMAPPABLE_MODIFIER_KEY_META_LEFT = KeyEvent.KEYCODE_META_LEFT;
223         int REMAPPABLE_MODIFIER_KEY_META_RIGHT = KeyEvent.KEYCODE_META_RIGHT;
224         int REMAPPABLE_MODIFIER_KEY_ALT_LEFT = KeyEvent.KEYCODE_ALT_LEFT;
225         int REMAPPABLE_MODIFIER_KEY_ALT_RIGHT = KeyEvent.KEYCODE_ALT_RIGHT;
226         int REMAPPABLE_MODIFIER_KEY_SHIFT_LEFT = KeyEvent.KEYCODE_SHIFT_LEFT;
227         int REMAPPABLE_MODIFIER_KEY_SHIFT_RIGHT = KeyEvent.KEYCODE_SHIFT_RIGHT;
228         int REMAPPABLE_MODIFIER_KEY_CAPS_LOCK = KeyEvent.KEYCODE_CAPS_LOCK;
229     }
230 
231     /**
232      * Switch State: Unknown.
233      *
234      * The system has yet to report a valid value for the switch.
235      * @hide
236      */
237     public static final int SWITCH_STATE_UNKNOWN = -1;
238 
239     /**
240      * Switch State: Off.
241      * @hide
242      */
243     public static final int SWITCH_STATE_OFF = 0;
244 
245     /**
246      * Switch State: On.
247      * @hide
248      */
249     public static final int SWITCH_STATE_ON = 1;
250 
251     private final InputManagerGlobal mGlobal;
252     private final Context mContext;
253 
254     /** @hide */
InputManager(Context context)255     public InputManager(Context context) {
256         mGlobal = InputManagerGlobal.getInstance();
257         mIm = mGlobal.getInputManagerService();
258         mContext = context;
259     }
260 
261     /**
262      * Gets an instance of the input manager.
263      *
264      *  Warning: The usage of this method is not supported!
265      *
266      *  @return The input manager instance.
267      *  Use {@link Context#getSystemService(Class)}
268      *  to obtain the InputManager instance.
269      *
270      * TODO (b/277717573): Soft remove this API in version V.
271      * TODO (b/277039664): Migrate app usage off this API.
272      *
273      * @hide
274      */
275     @Deprecated
276     @UnsupportedAppUsage
getInstance()277     public static InputManager getInstance() {
278         return Objects.requireNonNull(ActivityThread.currentApplication())
279                 .getSystemService(InputManager.class);
280     }
281 
282     /**
283      * Get the current VelocityTracker strategy.
284      * @hide
285      */
getVelocityTrackerStrategy()286     public String getVelocityTrackerStrategy() {
287         return mGlobal.getVelocityTrackerStrategy();
288     }
289 
290     /**
291      * Gets information about the input device with the specified id.
292      * @param id The device id.
293      * @return The input device or null if not found.
294      */
295     @Nullable
getInputDevice(int id)296     public InputDevice getInputDevice(int id) {
297         return mGlobal.getInputDevice(id);
298     }
299 
300     /**
301      * Gets the {@link InputDevice.ViewBehavior} of the input device with a given {@code id}.
302      *
303      * <p>Use this API to query a fresh view behavior instance whenever the input device
304      * changes.
305      *
306      * @param deviceId the id of the input device whose view behavior is being requested.
307      * @return the view behavior of the input device with the provided id, or {@code null} if there
308      *      is not input device with the provided id.
309      */
310     @FlaggedApi(FLAG_INPUT_DEVICE_VIEW_BEHAVIOR_API)
311     @Nullable
getInputDeviceViewBehavior(int deviceId)312     public InputDevice.ViewBehavior getInputDeviceViewBehavior(int deviceId) {
313         InputDevice device = getInputDevice(deviceId);
314         return device == null ? null : device.getViewBehavior();
315     }
316 
317     /**
318      * Gets information about the input device with the specified descriptor.
319      * @param descriptor The input device descriptor.
320      * @return The input device or null if not found.
321      * @hide
322      */
getInputDeviceByDescriptor(String descriptor)323     public InputDevice getInputDeviceByDescriptor(String descriptor) {
324         return mGlobal.getInputDeviceByDescriptor(descriptor);
325     }
326 
327     /**
328      * Gets the ids of all input devices in the system.
329      * @return The input device ids.
330      */
getInputDeviceIds()331     public int[] getInputDeviceIds() {
332         return mGlobal.getInputDeviceIds();
333     }
334 
335     /**
336      * Enables an InputDevice.
337      * <p>
338      * Requires {@link android.Manifest.permission#DISABLE_INPUT_DEVICE}.
339      * </p>
340      *
341      * @param id The input device Id.
342      *
343      * @hide
344      */
enableInputDevice(int id)345     public void enableInputDevice(int id) {
346         mGlobal.enableInputDevice(id);
347     }
348 
349     /**
350      * Disables an InputDevice.
351      * <p>
352      * Requires {@link android.Manifest.permission#DISABLE_INPUT_DEVICE}.
353      * </p>
354      *
355      * @param id The input device Id.
356      *
357      * @hide
358      */
disableInputDevice(int id)359     public void disableInputDevice(int id) {
360         mGlobal.disableInputDevice(id);
361     }
362 
363     /**
364      * Registers an input device listener to receive notifications about when
365      * input devices are added, removed or changed.
366      *
367      * @param listener The listener to register.
368      * @param handler The handler on which the listener should be invoked, or null
369      * if the listener should be invoked on the calling thread's looper.
370      *
371      * @see #unregisterInputDeviceListener
372      */
registerInputDeviceListener(InputDeviceListener listener, Handler handler)373     public void registerInputDeviceListener(InputDeviceListener listener, Handler handler) {
374         mGlobal.registerInputDeviceListener(listener, handler);
375     }
376 
377     /**
378      * Unregisters an input device listener.
379      *
380      * @param listener The listener to unregister.
381      *
382      * @see #registerInputDeviceListener
383      */
unregisterInputDeviceListener(InputDeviceListener listener)384     public void unregisterInputDeviceListener(InputDeviceListener listener) {
385         mGlobal.unregisterInputDeviceListener(listener);
386     }
387 
388     /**
389      * Queries whether the device is in tablet mode.
390      *
391      * @return The tablet switch state which is one of {@link #SWITCH_STATE_UNKNOWN},
392      * {@link #SWITCH_STATE_OFF} or {@link #SWITCH_STATE_ON}.
393      * @hide
394      */
395     @SwitchState
isInTabletMode()396     public int isInTabletMode() {
397         try {
398             return mIm.isInTabletMode();
399         } catch (RemoteException ex) {
400             throw ex.rethrowFromSystemServer();
401         }
402     }
403 
404     /**
405      * Register a tablet mode changed listener.
406      *
407      * @param listener The listener to register.
408      * @param handler The handler on which the listener should be invoked, or null
409      * if the listener should be invoked on the calling thread's looper.
410      * @hide
411      */
registerOnTabletModeChangedListener( OnTabletModeChangedListener listener, Handler handler)412     public void registerOnTabletModeChangedListener(
413             OnTabletModeChangedListener listener, Handler handler) {
414         mGlobal.registerOnTabletModeChangedListener(listener, handler);
415     }
416 
417     /**
418      * Unregister a tablet mode changed listener.
419      *
420      * @param listener The listener to unregister.
421      * @hide
422      */
unregisterOnTabletModeChangedListener(OnTabletModeChangedListener listener)423     public void unregisterOnTabletModeChangedListener(OnTabletModeChangedListener listener) {
424         mGlobal.unregisterOnTabletModeChangedListener(listener);
425     }
426 
427     /**
428      * Queries whether the device's microphone is muted
429      *
430      * @return The mic mute switch state which is one of {@link #SWITCH_STATE_UNKNOWN},
431      * {@link #SWITCH_STATE_OFF} or {@link #SWITCH_STATE_ON}.
432      * @hide
433      */
434     @SwitchState
isMicMuted()435     public int isMicMuted() {
436         try {
437             return mIm.isMicMuted();
438         } catch (RemoteException ex) {
439             throw ex.rethrowFromSystemServer();
440         }
441     }
442 
443     /**
444      * Gets information about all supported keyboard layouts.
445      * <p>
446      * The input manager consults the built-in keyboard layouts as well
447      * as all keyboard layouts advertised by applications using a
448      * {@link #ACTION_QUERY_KEYBOARD_LAYOUTS} broadcast receiver.
449      * </p>
450      *
451      * @return A list of all supported keyboard layouts.
452      *
453      * @hide
454      */
getKeyboardLayouts()455     public KeyboardLayout[] getKeyboardLayouts() {
456         try {
457             return mIm.getKeyboardLayouts();
458         } catch (RemoteException ex) {
459             throw ex.rethrowFromSystemServer();
460         }
461     }
462 
463     /**
464      * Returns the descriptors of all supported keyboard layouts.
465      * <p>
466      * The input manager consults the built-in keyboard layouts as well as all keyboard layouts
467      * advertised by applications using a {@link #ACTION_QUERY_KEYBOARD_LAYOUTS} broadcast receiver.
468      * </p>
469      *
470      * @return The ids of all keyboard layouts which are supported by the specified input device.
471      *
472      * @hide
473      */
474     @TestApi
475     @NonNull
476     @SuppressLint("UnflaggedApi")
getKeyboardLayoutDescriptors()477     public List<String> getKeyboardLayoutDescriptors() {
478         KeyboardLayout[] layouts = getKeyboardLayouts();
479         List<String> res = new ArrayList<>();
480         for (KeyboardLayout kl : layouts) {
481             res.add(kl.getDescriptor());
482         }
483         return res;
484     }
485 
486     /**
487      * Returns the layout type of the queried layout
488      * <p>
489      * The input manager consults the built-in keyboard layouts as well as all keyboard layouts
490      * advertised by applications using a {@link #ACTION_QUERY_KEYBOARD_LAYOUTS} broadcast receiver.
491      * </p>
492      *
493      * @param layoutDescriptor The layout descriptor of the queried layout
494      * @return layout type of the queried layout
495      *
496      * @hide
497      */
498     @TestApi
499     @NonNull
getKeyboardLayoutTypeForLayoutDescriptor(@onNull String layoutDescriptor)500     public String getKeyboardLayoutTypeForLayoutDescriptor(@NonNull String layoutDescriptor) {
501         KeyboardLayout layout = getKeyboardLayout(layoutDescriptor);
502         return layout == null ? "" : layout.getLayoutType();
503     }
504 
505     /**
506      * TODO(b/330517633): Cleanup the unsupported API
507      * @hide
508      */
509     @NonNull
getKeyboardLayoutsForInputDevice( @onNull InputDeviceIdentifier identifier)510     public KeyboardLayout[] getKeyboardLayoutsForInputDevice(
511             @NonNull InputDeviceIdentifier identifier) {
512         return new KeyboardLayout[0];
513     }
514 
515     /**
516      * Gets the keyboard layout with the specified descriptor.
517      *
518      * @param keyboardLayoutDescriptor The keyboard layout descriptor, as returned by
519      * {@link KeyboardLayout#getDescriptor()}.
520      * @return The keyboard layout, or null if it could not be loaded.
521      *
522      * @hide
523      */
524     @Nullable
getKeyboardLayout(String keyboardLayoutDescriptor)525     public KeyboardLayout getKeyboardLayout(String keyboardLayoutDescriptor) {
526         if (keyboardLayoutDescriptor == null) {
527             throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null");
528         }
529 
530         try {
531             return mIm.getKeyboardLayout(keyboardLayoutDescriptor);
532         } catch (RemoteException ex) {
533             throw ex.rethrowFromSystemServer();
534         }
535     }
536 
537     /**
538      * TODO(b/330517633): Cleanup the unsupported API
539      * @hide
540      */
541     @Nullable
getCurrentKeyboardLayoutForInputDevice( @onNull InputDeviceIdentifier identifier)542     public String getCurrentKeyboardLayoutForInputDevice(
543             @NonNull InputDeviceIdentifier identifier) {
544         return null;
545     }
546 
547     /**
548      * TODO(b/330517633): Cleanup the unsupported API
549      * @hide
550      */
setCurrentKeyboardLayoutForInputDevice(@onNull InputDeviceIdentifier identifier, @NonNull String keyboardLayoutDescriptor)551     public void setCurrentKeyboardLayoutForInputDevice(@NonNull InputDeviceIdentifier identifier,
552             @NonNull String keyboardLayoutDescriptor) {}
553 
554     /**
555      * TODO(b/330517633): Cleanup the unsupported API
556      * @hide
557      */
getEnabledKeyboardLayoutsForInputDevice(InputDeviceIdentifier identifier)558     public String[] getEnabledKeyboardLayoutsForInputDevice(InputDeviceIdentifier identifier) {
559         return new String[0];
560     }
561 
562     /**
563      * TODO(b/330517633): Cleanup the unsupported API
564      * @hide
565      */
addKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier, String keyboardLayoutDescriptor)566     public void addKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier,
567             String keyboardLayoutDescriptor) {
568     }
569 
570     /**
571      * TODO(b/330517633): Cleanup the unsupported API
572      * @hide
573      */
574     @RequiresPermission(Manifest.permission.SET_KEYBOARD_LAYOUT)
removeKeyboardLayoutForInputDevice(@onNull InputDeviceIdentifier identifier, @NonNull String keyboardLayoutDescriptor)575     public void removeKeyboardLayoutForInputDevice(@NonNull InputDeviceIdentifier identifier,
576             @NonNull String keyboardLayoutDescriptor) {
577     }
578 
579     /**
580      * Remaps modifier keys. Remapping a modifier key to itself will clear any previous remappings
581      * for that key.
582      *
583      * @param fromKey The modifier key getting remapped.
584      * @param toKey The modifier key that it is remapped to.
585      *
586      * @hide
587      */
588     @TestApi
589     @RequiresPermission(Manifest.permission.REMAP_MODIFIER_KEYS)
remapModifierKey(@emappableModifierKey int fromKey, @RemappableModifierKey int toKey)590     public void remapModifierKey(@RemappableModifierKey int fromKey,
591             @RemappableModifierKey int toKey) {
592         try {
593             mIm.remapModifierKey(fromKey, toKey);
594         } catch (RemoteException ex) {
595             throw ex.rethrowFromSystemServer();
596         }
597     }
598 
599     /**
600      * Clears all existing modifier key remappings
601      *
602      * @hide
603      */
604     @TestApi
605     @RequiresPermission(Manifest.permission.REMAP_MODIFIER_KEYS)
clearAllModifierKeyRemappings()606     public void clearAllModifierKeyRemappings() {
607         try {
608             mIm.clearAllModifierKeyRemappings();
609         } catch (RemoteException ex) {
610             throw ex.rethrowFromSystemServer();
611         }
612     }
613 
614     /**
615      * Provides the current modifier key remapping
616      *
617      * @return a {fromKey, toKey} map that contains the existing modifier key remappings..
618      * {@link RemappableModifierKey}
619      *
620      * @hide
621      */
622     @TestApi
623     @NonNull
624     @SuppressWarnings("unchecked")
625     @RequiresPermission(Manifest.permission.REMAP_MODIFIER_KEYS)
getModifierKeyRemapping()626     public Map<Integer, Integer> getModifierKeyRemapping() {
627         try {
628             return mIm.getModifierKeyRemapping();
629         } catch (RemoteException ex) {
630             throw ex.rethrowFromSystemServer();
631         }
632     }
633 
634     /**
635      * Gets the TouchCalibration applied to the specified input device's coordinates.
636      *
637      * @param inputDeviceDescriptor The input device descriptor.
638      * @return The TouchCalibration currently assigned for use with the given
639      * input device. If none is set, an identity TouchCalibration is returned.
640      *
641      * @hide
642      */
getTouchCalibration(String inputDeviceDescriptor, int surfaceRotation)643     public TouchCalibration getTouchCalibration(String inputDeviceDescriptor, int surfaceRotation) {
644         try {
645             return mIm.getTouchCalibrationForInputDevice(inputDeviceDescriptor, surfaceRotation);
646         } catch (RemoteException ex) {
647             throw ex.rethrowFromSystemServer();
648         }
649     }
650 
651     /**
652      * Sets the TouchCalibration to apply to the specified input device's coordinates.
653      * <p>
654      * This method may have the side-effect of causing the input device in question
655      * to be reconfigured. Requires {@link android.Manifest.permission#SET_INPUT_CALIBRATION}.
656      * </p>
657      *
658      * @param inputDeviceDescriptor The input device descriptor.
659      * @param calibration The calibration to be applied
660      *
661      * @hide
662      */
setTouchCalibration(String inputDeviceDescriptor, int surfaceRotation, TouchCalibration calibration)663     public void setTouchCalibration(String inputDeviceDescriptor, int surfaceRotation,
664             TouchCalibration calibration) {
665         try {
666             mIm.setTouchCalibrationForInputDevice(inputDeviceDescriptor, surfaceRotation, calibration);
667         } catch (RemoteException ex) {
668             throw ex.rethrowFromSystemServer();
669         }
670     }
671 
672     /**
673      * Gets the keyboard layout descriptor for the specified input device, userId, imeInfo and
674      * imeSubtype.
675      *
676      * @param identifier Identifier for the input device
677      * @param userId user profile ID
678      * @param imeInfo contains IME information like imeId, etc.
679      * @param imeSubtype contains IME subtype information like input languageTag, layoutType, etc.
680      * @return The keyboard layout descriptor, or null if no keyboard layout has been set.
681      *
682      * @hide
683      */
684     @NonNull
getKeyboardLayoutForInputDevice( @onNull InputDeviceIdentifier identifier, @UserIdInt int userId, @NonNull InputMethodInfo imeInfo, @Nullable InputMethodSubtype imeSubtype)685     public KeyboardLayoutSelectionResult getKeyboardLayoutForInputDevice(
686             @NonNull InputDeviceIdentifier identifier, @UserIdInt int userId,
687             @NonNull InputMethodInfo imeInfo, @Nullable InputMethodSubtype imeSubtype) {
688         try {
689             return mIm.getKeyboardLayoutForInputDevice(identifier, userId, imeInfo, imeSubtype);
690         } catch (RemoteException ex) {
691             throw ex.rethrowFromSystemServer();
692         }
693     }
694 
695     /**
696      * Sets the keyboard layout descriptor for the specified input device, userId, imeInfo and
697      * imeSubtype.
698      *
699      * <p>
700      * This method may have the side-effect of causing the input device in question to be
701      * reconfigured.
702      * </p>
703      *
704      * @param identifier The identifier for the input device.
705      * @param userId user profile ID
706      * @param imeInfo contains IME information like imeId, etc.
707      * @param imeSubtype contains IME subtype information like input languageTag, layoutType, etc.
708      * @param keyboardLayoutDescriptor The keyboard layout descriptor to use, must not be null.
709      *
710      * @hide
711      */
712     @RequiresPermission(Manifest.permission.SET_KEYBOARD_LAYOUT)
setKeyboardLayoutForInputDevice(@onNull InputDeviceIdentifier identifier, @UserIdInt int userId, @NonNull InputMethodInfo imeInfo, @Nullable InputMethodSubtype imeSubtype, @NonNull String keyboardLayoutDescriptor)713     public void setKeyboardLayoutForInputDevice(@NonNull InputDeviceIdentifier identifier,
714             @UserIdInt int userId, @NonNull InputMethodInfo imeInfo,
715             @Nullable InputMethodSubtype imeSubtype, @NonNull String keyboardLayoutDescriptor) {
716         if (identifier == null) {
717             throw new IllegalArgumentException("identifier must not be null");
718         }
719         if (keyboardLayoutDescriptor == null) {
720             throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null");
721         }
722 
723         try {
724             mIm.setKeyboardLayoutForInputDevice(identifier, userId, imeInfo, imeSubtype,
725                     keyboardLayoutDescriptor);
726         } catch (RemoteException ex) {
727             throw ex.rethrowFromSystemServer();
728         }
729     }
730 
731     /**
732      * Gets all keyboard layouts that are enabled for the specified input device, userId, imeInfo
733      * and imeSubtype.
734      *
735      * @param identifier The identifier for the input device.
736      * @param userId user profile ID
737      * @param imeInfo contains IME information like imeId, etc.
738      * @param imeSubtype contains IME subtype information like input languageTag, layoutType, etc.
739      * @return The keyboard layout descriptors.
740      *
741      * @hide
742      */
getKeyboardLayoutListForInputDevice(InputDeviceIdentifier identifier, @UserIdInt int userId, @NonNull InputMethodInfo imeInfo, @Nullable InputMethodSubtype imeSubtype)743     public KeyboardLayout[] getKeyboardLayoutListForInputDevice(InputDeviceIdentifier identifier,
744             @UserIdInt int userId, @NonNull InputMethodInfo imeInfo,
745             @Nullable InputMethodSubtype imeSubtype) {
746         if (identifier == null) {
747             throw new IllegalArgumentException("inputDeviceDescriptor must not be null");
748         }
749 
750         try {
751             return mIm.getKeyboardLayoutListForInputDevice(identifier, userId, imeInfo, imeSubtype);
752         } catch (RemoteException ex) {
753             throw ex.rethrowFromSystemServer();
754         }
755     }
756 
757     /**
758      * Returns the mouse pointer speed.
759      *
760      * <p>The pointer speed is a value between {@link InputSettings#MIN_POINTER_SPEED} and
761      * {@link InputSettings#MAX_POINTER_SPEED}, the default value being
762      * {@link InputSettings#DEFAULT_POINTER_SPEED}.
763      *
764      * <p> Note that while setting the mouse pointer speed, it's possible that the input reader has
765      * only received this value and has not yet completed reconfiguring itself with this value.
766      *
767      * @hide
768      */
769     @SuppressLint("UnflaggedApi") // TestApi without associated feature.
770     @TestApi
getMousePointerSpeed()771     public int getMousePointerSpeed() {
772         try {
773             return mIm.getMousePointerSpeed();
774         } catch (RemoteException ex) {
775             throw ex.rethrowFromSystemServer();
776         }
777     }
778 
779     /**
780      * Changes the mouse pointer speed temporarily, but does not save the setting.
781      * <p>
782      * Requires {@link android.Manifest.permission#SET_POINTER_SPEED}.
783      * </p>
784      *
785      * @param speed The pointer speed as a value between {@link InputSettings#MIN_POINTER_SPEED} and
786      * {@link InputSettings#MAX_POINTER_SPEED}, or the default value {@link InputSettings#DEFAULT_POINTER_SPEED}.
787      *
788      * @hide
789      */
tryPointerSpeed(int speed)790     public void tryPointerSpeed(int speed) {
791         if (speed < InputSettings.MIN_POINTER_SPEED || speed > InputSettings.MAX_POINTER_SPEED) {
792             throw new IllegalArgumentException("speed out of range");
793         }
794 
795         try {
796             mIm.tryPointerSpeed(speed);
797         } catch (RemoteException ex) {
798             throw ex.rethrowFromSystemServer();
799         }
800     }
801 
802     /**
803      * Returns the maximum allowed obscuring opacity per UID to propagate touches.
804      *
805      * <p>For certain window types (eg. {@link LayoutParams#TYPE_APPLICATION_OVERLAY}), the decision
806      * of honoring {@link LayoutParams#FLAG_NOT_TOUCHABLE} or not depends on the combined obscuring
807      * opacity of the windows above the touch-consuming window, per UID. Check documentation of
808      * {@link LayoutParams#FLAG_NOT_TOUCHABLE} for more details.
809      *
810      * <p>The value returned is between 0 (inclusive) and 1 (inclusive).
811      *
812      * @see LayoutParams#FLAG_NOT_TOUCHABLE
813      */
814     @FloatRange(from = 0, to = 1)
getMaximumObscuringOpacityForTouch()815     public float getMaximumObscuringOpacityForTouch() {
816         return InputSettings.getMaximumObscuringOpacityForTouch(mContext);
817     }
818 
819     /**
820      * Queries the framework about whether any physical keys exist on any currently attached input
821      * devices that are capable of producing the given array of key codes.
822      *
823      * @param keyCodes The array of key codes to query.
824      * @return A new array of the same size as the key codes array whose elements
825      * are set to true if at least one attached keyboard supports the corresponding key code
826      * at the same index in the key codes array.
827      *
828      * @hide
829      */
deviceHasKeys(int[] keyCodes)830     public boolean[] deviceHasKeys(int[] keyCodes) {
831         return deviceHasKeys(-1, keyCodes);
832     }
833 
834     /**
835      * Queries the framework about whether any physical keys exist on the specified input device
836      * that are capable of producing the given array of key codes.
837      *
838      * @param id The id of the input device to query or -1 to consult all devices.
839      * @param keyCodes The array of key codes to query.
840      * @return A new array of the same size as the key codes array whose elements are set to true
841      * if the given device could produce the corresponding key code at the same index in the key
842      * codes array.
843      *
844      * @hide
845      */
deviceHasKeys(int id, int[] keyCodes)846     public boolean[] deviceHasKeys(int id, int[] keyCodes) {
847         return mGlobal.deviceHasKeys(id, keyCodes);
848     }
849 
850     /**
851      * Gets the {@link android.view.KeyEvent key code} produced by the given location on a reference
852      * QWERTY keyboard layout.
853      * <p>
854      * This API is useful for querying the physical location of keys that change the character
855      * produced based on the current locale and keyboard layout.
856      * <p>
857      * @see InputDevice#getKeyCodeForKeyLocation(int) for examples.
858      *
859      * @param locationKeyCode The location of a key specified as a key code on the QWERTY layout.
860      * This provides a consistent way of referring to the physical location of a key independently
861      * of the current keyboard layout. Also see the
862      * <a href="https://www.w3.org/TR/2017/CR-uievents-code-20170601/#key-alphanumeric-writing-system">
863      * hypothetical keyboard</a> provided by the W3C, which may be helpful for identifying the
864      * physical location of a key.
865      * @return The key code produced by the key at the specified location, given the current
866      * keyboard layout. Returns {@link KeyEvent#KEYCODE_UNKNOWN} if the device does not specify
867      * {@link InputDevice#SOURCE_KEYBOARD} or the requested mapping cannot be determined.
868      *
869      * @hide
870      */
getKeyCodeForKeyLocation(int deviceId, int locationKeyCode)871     public int getKeyCodeForKeyLocation(int deviceId, int locationKeyCode) {
872         return mGlobal.getKeyCodeForKeyLocation(deviceId, locationKeyCode);
873     }
874 
875     /**
876      * Provides a Keyboard layout preview of a particular dimension.
877      *
878      * @param keyboardLayout Layout whose preview is requested. If null, will return preview of
879      *                       the default Keyboard layout defined by {@code Generic.kl}.
880      * @param width Expected width of the drawable
881      * @param height Expected height of the drawable
882      *
883      * NOTE: Width and height will auto-adjust to the width and height of the ImageView that
884      * shows the drawable but this allows the caller to provide an intrinsic width and height of
885      * the drawable allowing the ImageView to properly wrap the drawable content.
886      *
887      * @hide
888      */
889     @Nullable
getKeyboardLayoutPreview(@ullable KeyboardLayout keyboardLayout, int width, int height)890     public Drawable getKeyboardLayoutPreview(@Nullable KeyboardLayout keyboardLayout, int width,
891             int height) {
892         if (!keyboardLayoutPreviewFlag()) {
893             return null;
894         }
895         PhysicalKeyLayout keyLayout = new PhysicalKeyLayout(
896                 mGlobal.getKeyCharacterMap(keyboardLayout), keyboardLayout);
897         return new KeyboardLayoutPreviewDrawable(mContext, keyLayout, width, height);
898     }
899 
900     /**
901      * Injects an input event into the event system, targeting windows owned by the provided uid.
902      *
903      * If a valid targetUid is provided, the system will only consider injecting the input event
904      * into windows owned by the provided uid. If the input event is targeted at a window that is
905      * not owned by the provided uid, input injection will fail and a RemoteException will be
906      * thrown.
907      *
908      * The synchronization mode determines whether the method blocks while waiting for
909      * input injection to proceed.
910      * <p>
911      * Requires the {@link android.Manifest.permission#INJECT_EVENTS} permission.
912      * </p><p>
913      * Make sure you correctly set the event time and input source of the event
914      * before calling this method.
915      * </p>
916      *
917      * @param event The event to inject.
918      * @param mode The synchronization mode.  One of:
919      * {@link android.os.InputEventInjectionSync#NONE},
920      * {@link android.os.InputEventInjectionSync#WAIT_FOR_RESULT}, or
921      * {@link android.os.InputEventInjectionSync#WAIT_FOR_FINISHED}.
922      * @param targetUid The uid to target, or {@link android.os.Process#INVALID_UID} to target all
923      *                 windows.
924      * @return True if input event injection succeeded.
925      *
926      * @hide
927      */
928     @RequiresPermission(Manifest.permission.INJECT_EVENTS)
injectInputEvent(InputEvent event, int mode, int targetUid)929     public boolean injectInputEvent(InputEvent event, int mode, int targetUid) {
930         return mGlobal.injectInputEvent(event, mode, targetUid);
931     }
932 
933     /**
934      * Injects an input event into the event system on behalf of an application.
935      * The synchronization mode determines whether the method blocks while waiting for
936      * input injection to proceed.
937      * <p>
938      * Requires the {@link android.Manifest.permission#INJECT_EVENTS} permission.
939      * </p><p>
940      * Make sure you correctly set the event time and input source of the event
941      * before calling this method.
942      * </p>
943      *
944      * @param event The event to inject.
945      * @param mode The synchronization mode.  One of:
946      * {@link android.os.InputEventInjectionSync#NONE},
947      * {@link android.os.InputEventInjectionSync#WAIT_FOR_RESULT}, or
948      * {@link android.os.InputEventInjectionSync#WAIT_FOR_FINISHED}.
949      * @return True if input event injection succeeded.
950      *
951      * @hide
952      */
953     @RequiresPermission(Manifest.permission.INJECT_EVENTS)
954     @UnsupportedAppUsage
injectInputEvent(InputEvent event, int mode)955     public boolean injectInputEvent(InputEvent event, int mode) {
956         return mGlobal.injectInputEvent(event, mode);
957     }
958 
959     /**
960      * Verify the details of an {@link android.view.InputEvent} that came from the system.
961      * If the event did not come from the system, or its details could not be verified, then this
962      * will return {@code null}. Receiving {@code null} does not mean that the event did not
963      * originate from the system, just that we were unable to verify it. This can
964      * happen for a number of reasons during normal operation.
965      *
966      * @param event The {@link android.view.InputEvent} to check.
967      *
968      * @return {@link android.view.VerifiedInputEvent}, which is a subset of the provided
969      *     {@link android.view.InputEvent}, or {@code null} if the event could not be verified.
970      */
971     @Nullable
verifyInputEvent(@onNull InputEvent event)972     public VerifiedInputEvent verifyInputEvent(@NonNull InputEvent event) {
973         try {
974             return mIm.verifyInputEvent(event);
975         } catch (RemoteException ex) {
976             throw ex.rethrowFromSystemServer();
977         }
978     }
979 
980     /**
981      * This method exists for backwards-compatibility, and is a no-op.
982      *
983      * @deprecated
984      * @hide
985      */
986     @UnsupportedAppUsage
setPointerIconType(int iconId)987     public void setPointerIconType(int iconId) {
988         Log.e(TAG, "setPointerIcon: Unsupported app usage!");
989     }
990 
991     /** @hide */
setPointerIcon(PointerIcon icon, int displayId, int deviceId, int pointerId, IBinder inputToken)992     public boolean setPointerIcon(PointerIcon icon, int displayId, int deviceId, int pointerId,
993             IBinder inputToken) {
994         return mGlobal.setPointerIcon(icon, displayId, deviceId, pointerId, inputToken);
995     }
996 
997     /**
998      * Check if showing a {@link android.view.PointerIcon} for styluses is enabled.
999      *
1000      * @return true if a pointer icon will be shown over the location of a
1001      * stylus pointer, false if there is no pointer icon shown for styluses.
1002      */
isStylusPointerIconEnabled()1003     public boolean isStylusPointerIconEnabled() {
1004         if (mIsStylusPointerIconEnabled == null) {
1005             mIsStylusPointerIconEnabled = InputSettings.isStylusPointerIconEnabled(mContext);
1006         }
1007         return mIsStylusPointerIconEnabled;
1008     }
1009 
1010     /**
1011      * Request or release pointer capture.
1012      * <p>
1013      * When in capturing mode, the pointer icon disappears and all mouse events are dispatched to
1014      * the window which has requested the capture. Relative position changes are available through
1015      * {@link MotionEvent#getX} and {@link MotionEvent#getY}.
1016      *
1017      * @param enable true when requesting pointer capture, false when releasing.
1018      *
1019      * @hide
1020      */
requestPointerCapture(IBinder windowToken, boolean enable)1021     public void requestPointerCapture(IBinder windowToken, boolean enable) {
1022         mGlobal.requestPointerCapture(windowToken, enable);
1023     }
1024 
1025     /**
1026      * Monitor input on the specified display for gestures.
1027      *
1028      * @hide
1029      */
monitorGestureInput(String name, int displayId)1030     public InputMonitor monitorGestureInput(String name, int displayId) {
1031         return mGlobal.monitorGestureInput(name, displayId);
1032     }
1033 
1034     /**
1035      * Add a runtime association between the input port and the display port. This overrides any
1036      * static associations.
1037      * @param inputPort the port of the input device
1038      * @param displayPort the physical port of the associated display
1039      * <p>
1040      * Requires {@link android.Manifest.permission#ASSOCIATE_INPUT_DEVICE_TO_DISPLAY}.
1041      * </p>
1042      * @hide
1043      */
1044     @RequiresPermission(android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY)
addPortAssociation(@onNull String inputPort, int displayPort)1045     public void addPortAssociation(@NonNull String inputPort, int displayPort) {
1046         try {
1047             mIm.addPortAssociation(inputPort, displayPort);
1048         } catch (RemoteException ex) {
1049             throw ex.rethrowFromSystemServer();
1050         }
1051     }
1052 
1053     /**
1054      * Remove the runtime association between the input port and the display port. Any existing
1055      * static association for the cleared input port will be restored.
1056      * @param inputPort the port of the input device to be cleared
1057      * <p>
1058      * Requires {@link android.Manifest.permission#ASSOCIATE_INPUT_DEVICE_TO_DISPLAY}.
1059      * </p>
1060      * @hide
1061      */
1062     @RequiresPermission(android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY)
removePortAssociation(@onNull String inputPort)1063     public void removePortAssociation(@NonNull String inputPort) {
1064         try {
1065             mIm.removePortAssociation(inputPort);
1066         } catch (RemoteException ex) {
1067             throw ex.rethrowFromSystemServer();
1068         }
1069     }
1070 
1071     /**
1072      * Add a runtime association between the input port and display, by unique id. Input ports are
1073      * expected to be unique.
1074      * @param inputPort the port of the input device
1075      * @param displayUniqueId the unique id of the associated display
1076      * <p>
1077      * Requires {@link android.Manifest.permission#ASSOCIATE_INPUT_DEVICE_TO_DISPLAY}.
1078      * </p>
1079      * @hide
1080      */
1081     @RequiresPermission(android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY)
1082     @TestApi
addUniqueIdAssociationByPort(@onNull String inputPort, @NonNull String displayUniqueId)1083     public void addUniqueIdAssociationByPort(@NonNull String inputPort,
1084             @NonNull String displayUniqueId) {
1085         mGlobal.addUniqueIdAssociationByPort(inputPort, displayUniqueId);
1086     }
1087 
1088     /**
1089      * Removes a runtime association between the input device and display.
1090      * @param inputPort the port of the input device
1091      * <p>
1092      * Requires {@link android.Manifest.permission#ASSOCIATE_INPUT_DEVICE_TO_DISPLAY}.
1093      * </p>
1094      * @hide
1095      */
1096     @RequiresPermission(android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY)
1097     @TestApi
removeUniqueIdAssociationByPort(@onNull String inputPort)1098     public void removeUniqueIdAssociationByPort(@NonNull String inputPort) {
1099         mGlobal.removeUniqueIdAssociationByPort(inputPort);
1100     }
1101 
1102     /**
1103      * Add a runtime association between the input device name and display, by descriptor. Input
1104      * device descriptors are expected to be unique per physical device, though one physical
1105      * device can have multiple virtual input devices that possess the same descriptor.
1106      * E.g. a keyboard with built in trackpad will be 2 different input devices with the same
1107      * descriptor.
1108      * @param inputDeviceDescriptor the descriptor of the input device
1109      * @param displayUniqueId the unique id of the associated display
1110      * <p>
1111      * Requires {@link android.Manifest.permissions.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY}.
1112      * </p>
1113      * @hide
1114      */
1115     @FlaggedApi(FLAG_DEVICE_ASSOCIATIONS)
1116     @RequiresPermission(android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY)
1117     @TestApi
addUniqueIdAssociationByDescriptor(@onNull String inputDeviceDescriptor, @NonNull String displayUniqueId)1118     public void addUniqueIdAssociationByDescriptor(@NonNull String inputDeviceDescriptor,
1119                                                    @NonNull String displayUniqueId) {
1120         mGlobal.addUniqueIdAssociationByDescriptor(inputDeviceDescriptor, displayUniqueId);
1121     }
1122 
1123     /**
1124      * Removes a runtime association between the input device and display.
1125     }
1126 
1127     /**
1128      * Removes a runtime association between the input device and display.
1129      * @param inputDeviceDescriptor the descriptor of the input device
1130      * <p>
1131      * Requires {@link android.Manifest.permissions.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY}.
1132      * </p>
1133      * @hide
1134      */
1135     @FlaggedApi(FLAG_DEVICE_ASSOCIATIONS)
1136     @RequiresPermission(android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY)
1137     @TestApi
removeUniqueIdAssociationByDescriptor(@onNull String inputDeviceDescriptor)1138     public void removeUniqueIdAssociationByDescriptor(@NonNull String inputDeviceDescriptor) {
1139         mGlobal.removeUniqueIdAssociationByDescriptor(inputDeviceDescriptor);
1140     }
1141 
1142     /**
1143      * Reports the version of the Universal Stylus Initiative (USI) protocol supported by the given
1144      * display, if any.
1145      *
1146      * @return the USI version supported by the display, or null if the device does not support USI
1147      * @see <a href="https://universalstylus.org">Universal Stylus Initiative</a>
1148      */
1149     @Nullable
getHostUsiVersion(@onNull Display display)1150     public HostUsiVersion getHostUsiVersion(@NonNull Display display) {
1151         return mGlobal.getHostUsiVersion(display);
1152     }
1153 
1154     /**
1155      * Returns the Bluetooth address of this input device, if known.
1156      *
1157      * The returned string is always null if this input device is not connected
1158      * via Bluetooth, or if the Bluetooth address of the device cannot be
1159      * determined. The returned address will look like: "11:22:33:44:55:66".
1160      * @hide
1161      */
1162     @RequiresPermission(Manifest.permission.BLUETOOTH)
1163     @Nullable
getInputDeviceBluetoothAddress(int deviceId)1164     public String getInputDeviceBluetoothAddress(int deviceId) {
1165         return mGlobal.getInputDeviceBluetoothAddress(deviceId);
1166     }
1167 
1168     /**
1169      * Gets a vibrator service associated with an input device, always creates a new instance.
1170      * @return The vibrator, never null.
1171      * @hide
1172      */
getInputDeviceVibrator(int deviceId, int vibratorId)1173     public Vibrator getInputDeviceVibrator(int deviceId, int vibratorId) {
1174         return new InputDeviceVibrator(deviceId, vibratorId);
1175     }
1176 
1177     /**
1178      * Cancel all ongoing pointer gestures on all displays.
1179      * @hide
1180      */
cancelCurrentTouch()1181     public void cancelCurrentTouch() {
1182         mGlobal.cancelCurrentTouch();
1183     }
1184 
1185     /**
1186      * Pilfer pointers from an input channel.
1187      *
1188      * Takes all the current pointer event streams that are currently being sent to the given
1189      * input channel and generates appropriate cancellations for all other windows that are
1190      * receiving these pointers.
1191      *
1192      * This API is intended to be used in conjunction with spy windows. When a spy window pilfers
1193      * pointers, the foreground windows and all other spy windows that are receiving any of the
1194      * pointers that are currently being dispatched to the pilfering window will have those pointers
1195      * canceled. Only the pilfering window will continue to receive events for the affected pointers
1196      * until the pointer is lifted.
1197      *
1198      * This method should be used with caution as unexpected pilfering can break fundamental user
1199      * interactions.
1200      *
1201      * @see android.os.InputConfig#SPY
1202      * @hide
1203      */
1204     @RequiresPermission(Manifest.permission.MONITOR_INPUT)
pilferPointers(IBinder inputChannelToken)1205     public void pilferPointers(IBinder inputChannelToken) {
1206         mGlobal.pilferPointers(inputChannelToken);
1207     }
1208 
1209     /**
1210      * Adds a battery listener to be notified about {@link BatteryState} changes for an input
1211      * device. The same listener can be registered for multiple input devices.
1212      * The listener will be notified of the initial battery state of the device after it is
1213      * successfully registered.
1214      * @param deviceId the input device that should be monitored
1215      * @param executor an executor on which the callback will be called
1216      * @param listener the {@link InputDeviceBatteryListener}
1217      * @see #removeInputDeviceBatteryListener(int, InputDeviceBatteryListener)
1218      * @hide
1219      */
addInputDeviceBatteryListener(int deviceId, @NonNull Executor executor, @NonNull InputDeviceBatteryListener listener)1220     public void addInputDeviceBatteryListener(int deviceId, @NonNull Executor executor,
1221             @NonNull InputDeviceBatteryListener listener) {
1222         mGlobal.addInputDeviceBatteryListener(deviceId, executor, listener);
1223     }
1224 
1225     /**
1226      * Removes a previously registered battery listener for an input device.
1227      * @see #addInputDeviceBatteryListener(int, Executor, InputDeviceBatteryListener)
1228      * @hide
1229      */
removeInputDeviceBatteryListener(int deviceId, @NonNull InputDeviceBatteryListener listener)1230     public void removeInputDeviceBatteryListener(int deviceId,
1231             @NonNull InputDeviceBatteryListener listener) {
1232         mGlobal.removeInputDeviceBatteryListener(deviceId, listener);
1233     }
1234 
1235     /**
1236      * Whether there is a gesture-compatible touchpad connected to the device.
1237      * @hide
1238      */
areTouchpadGesturesAvailable(@onNull Context context)1239     public boolean areTouchpadGesturesAvailable(@NonNull Context context) {
1240         // TODO: implement the right logic
1241         return true;
1242     }
1243 
1244     /**
1245      * Registers a Keyboard backlight change listener to be notified about {@link
1246      * KeyboardBacklightState} changes for connected keyboard devices.
1247      *
1248      * @param executor an executor on which the callback will be called
1249      * @param listener the {@link KeyboardBacklightListener}
1250      * @hide
1251      * @see #unregisterKeyboardBacklightListener(KeyboardBacklightListener)
1252      * @throws IllegalArgumentException if {@code listener} has already been registered previously.
1253      * @throws NullPointerException if {@code listener} or {@code executor} is null.
1254      */
1255     @RequiresPermission(Manifest.permission.MONITOR_KEYBOARD_BACKLIGHT)
registerKeyboardBacklightListener(@onNull Executor executor, @NonNull KeyboardBacklightListener listener)1256     public void registerKeyboardBacklightListener(@NonNull Executor executor,
1257             @NonNull KeyboardBacklightListener listener) throws IllegalArgumentException {
1258         mGlobal.registerKeyboardBacklightListener(executor, listener);
1259     }
1260 
1261     /**
1262      * Unregisters a previously added Keyboard backlight change listener.
1263      *
1264      * @param listener the {@link KeyboardBacklightListener}
1265      * @see #registerKeyboardBacklightListener(Executor, KeyboardBacklightListener)
1266      * @hide
1267      */
1268     @RequiresPermission(Manifest.permission.MONITOR_KEYBOARD_BACKLIGHT)
unregisterKeyboardBacklightListener( @onNull KeyboardBacklightListener listener)1269     public void unregisterKeyboardBacklightListener(
1270             @NonNull KeyboardBacklightListener listener) {
1271         mGlobal.unregisterKeyboardBacklightListener(listener);
1272     }
1273 
1274     /**
1275      * Registers a Sticky modifier state change listener to be notified about {@link
1276      * StickyModifierState} changes.
1277      *
1278      * @param executor an executor on which the callback will be called
1279      * @param listener the {@link StickyModifierStateListener}
1280      * @throws IllegalArgumentException if {@code listener} has already been registered previously.
1281      * @throws NullPointerException     if {@code listener} or {@code executor} is null.
1282      * @hide
1283      * @see #unregisterStickyModifierStateListener(StickyModifierStateListener)
1284      */
1285     @RequiresPermission(Manifest.permission.MONITOR_STICKY_MODIFIER_STATE)
registerStickyModifierStateListener(@onNull Executor executor, @NonNull StickyModifierStateListener listener)1286     public void registerStickyModifierStateListener(@NonNull Executor executor,
1287             @NonNull StickyModifierStateListener listener) throws IllegalArgumentException {
1288         if (!InputSettings.isAccessibilityStickyKeysFeatureEnabled()) {
1289             return;
1290         }
1291         mGlobal.registerStickyModifierStateListener(executor, listener);
1292     }
1293 
1294     /**
1295      * Unregisters a previously added Sticky modifier state change listener.
1296      *
1297      * @param listener the {@link StickyModifierStateListener}
1298      * @hide
1299      * @see #registerStickyModifierStateListener(Executor, StickyModifierStateListener)
1300      */
1301     @RequiresPermission(Manifest.permission.MONITOR_STICKY_MODIFIER_STATE)
unregisterStickyModifierStateListener( @onNull StickyModifierStateListener listener)1302     public void unregisterStickyModifierStateListener(
1303             @NonNull StickyModifierStateListener listener) {
1304         if (!InputSettings.isAccessibilityStickyKeysFeatureEnabled()) {
1305             return;
1306         }
1307         mGlobal.unregisterStickyModifierStateListener(listener);
1308     }
1309 
1310     /**
1311      * A callback used to be notified about battery state changes for an input device. The
1312      * {@link #onBatteryStateChanged(int, long, BatteryState)} method will be called once after the
1313      * listener is successfully registered to provide the initial battery state of the device.
1314      * @see InputDevice#getBatteryState()
1315      * @see #addInputDeviceBatteryListener(int, Executor, InputDeviceBatteryListener)
1316      * @see #removeInputDeviceBatteryListener(int, InputDeviceBatteryListener)
1317      * @hide
1318      */
1319     public interface InputDeviceBatteryListener {
1320         /**
1321          * Called when the battery state of an input device changes.
1322          * @param deviceId the input device for which the battery changed.
1323          * @param eventTimeMillis the time (in ms) when the battery change took place.
1324          *        This timestamp is in the {@link SystemClock#uptimeMillis()} time base.
1325          * @param batteryState the new battery state, never null.
1326          */
onBatteryStateChanged( int deviceId, long eventTimeMillis, @NonNull BatteryState batteryState)1327         void onBatteryStateChanged(
1328                 int deviceId, long eventTimeMillis, @NonNull BatteryState batteryState);
1329     }
1330 
1331     /**
1332      * Listens for changes in input devices.
1333      */
1334     public interface InputDeviceListener {
1335         /**
1336          * Called whenever an input device has been added to the system.
1337          * Use {@link #getInputDevice(int)} to get more information about the device.
1338          *
1339          * @param deviceId The id of the input device that was added.
1340          */
onInputDeviceAdded(int deviceId)1341         void onInputDeviceAdded(int deviceId);
1342 
1343         /**
1344          * Called whenever an input device has been removed from the system.
1345          *
1346          * @param deviceId The id of the input device that was removed.
1347          */
onInputDeviceRemoved(int deviceId)1348         void onInputDeviceRemoved(int deviceId);
1349 
1350         /**
1351          * Called whenever the properties of an input device have changed since they
1352          * were last queried.  Use {@link InputManager#getInputDevice} to get
1353          * a fresh {@link InputDevice} object with the new properties.
1354          *
1355          * @param deviceId The id of the input device that changed.
1356          */
onInputDeviceChanged(int deviceId)1357         void onInputDeviceChanged(int deviceId);
1358     }
1359 
1360     /** @hide */
1361     public interface OnTabletModeChangedListener {
1362         /**
1363          * Called whenever the device goes into or comes out of tablet mode.
1364          *
1365          * @param whenNanos The time at which the device transitioned into or
1366          * out of tablet mode. This is given in nanoseconds in the
1367          * {@link SystemClock#uptimeMillis} time base.
1368          */
onTabletModeChanged(long whenNanos, boolean inTabletMode)1369         void onTabletModeChanged(long whenNanos, boolean inTabletMode);
1370     }
1371 
1372     /**
1373      * A callback used to be notified about keyboard backlight state changes for keyboard device.
1374      * The {@link #onKeyboardBacklightChanged(int, KeyboardBacklightState, boolean)} method
1375      * will be called once after the listener is successfully registered to provide the initial
1376      * keyboard backlight state of the device.
1377      * @see #registerKeyboardBacklightListener(Executor, KeyboardBacklightListener)
1378      * @see #unregisterKeyboardBacklightListener(KeyboardBacklightListener)
1379      * @hide
1380      */
1381     public interface KeyboardBacklightListener {
1382         /**
1383          * Called when the keyboard backlight brightness level changes.
1384          * @param deviceId the keyboard for which the backlight brightness changed.
1385          * @param state the new keyboard backlight state, never null.
1386          * @param isTriggeredByKeyPress whether brightness change was triggered by the user
1387          *                              pressing up/down key on the keyboard.
1388          */
onKeyboardBacklightChanged( int deviceId, @NonNull KeyboardBacklightState state, boolean isTriggeredByKeyPress)1389         void onKeyboardBacklightChanged(
1390                 int deviceId, @NonNull KeyboardBacklightState state, boolean isTriggeredByKeyPress);
1391     }
1392 
1393     /**
1394      * A callback used to be notified about sticky modifier state changes when A11y Sticky keys
1395      * feature is enabled.
1396      *
1397      * @see #registerStickyModifierStateListener(Executor, StickyModifierStateListener)
1398      * @see #unregisterStickyModifierStateListener(StickyModifierStateListener)
1399      * @hide
1400      */
1401     public interface StickyModifierStateListener {
1402         /**
1403          * Called when the sticky modifier state changes.
1404          * This method will be called once after the listener is successfully registered to provide
1405          * the initial modifier state.
1406          *
1407          * @param state the new sticky modifier state, never null.
1408          */
onStickyModifierStateChanged(@onNull StickyModifierState state)1409         void onStickyModifierStateChanged(@NonNull StickyModifierState state);
1410     }
1411 }
1412