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