1 /* 2 * Copyright (C) 2023 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 android.Manifest; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.RequiresPermission; 23 import android.content.Context; 24 import android.hardware.BatteryState; 25 import android.hardware.SensorManager; 26 import android.hardware.input.InputManager.InputDeviceBatteryListener; 27 import android.hardware.input.InputManager.InputDeviceListener; 28 import android.hardware.input.InputManager.KeyboardBacklightListener; 29 import android.hardware.input.InputManager.OnTabletModeChangedListener; 30 import android.hardware.lights.Light; 31 import android.hardware.lights.LightState; 32 import android.hardware.lights.LightsManager; 33 import android.hardware.lights.LightsRequest; 34 import android.os.Binder; 35 import android.os.CombinedVibration; 36 import android.os.Handler; 37 import android.os.IBinder; 38 import android.os.IVibratorStateListener; 39 import android.os.InputEventInjectionSync; 40 import android.os.Looper; 41 import android.os.Message; 42 import android.os.Process; 43 import android.os.RemoteException; 44 import android.os.ServiceManager; 45 import android.os.VibrationEffect; 46 import android.os.Vibrator; 47 import android.os.VibratorManager; 48 import android.util.Log; 49 import android.util.SparseArray; 50 import android.view.Display; 51 import android.view.InputDevice; 52 import android.view.InputEvent; 53 import android.view.InputMonitor; 54 import android.view.PointerIcon; 55 56 import com.android.internal.annotations.GuardedBy; 57 import com.android.internal.os.SomeArgs; 58 59 import java.util.ArrayList; 60 import java.util.List; 61 import java.util.Objects; 62 import java.util.concurrent.Executor; 63 64 /** 65 * Manages communication with the input manager service on behalf of 66 * an application process. You're probably looking for {@link InputManager}. 67 * 68 * @hide 69 */ 70 public final class InputManagerGlobal { 71 private static final String TAG = "InputManagerGlobal"; 72 // To enable these logs, run: 'adb shell setprop log.tag.InputManagerGlobal DEBUG' 73 // (requires restart) 74 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); 75 76 @GuardedBy("mInputDeviceListeners") 77 @Nullable private SparseArray<InputDevice> mInputDevices; 78 @GuardedBy("mInputDeviceListeners") 79 @Nullable private InputDevicesChangedListener mInputDevicesChangedListener; 80 @GuardedBy("mInputDeviceListeners") 81 private final ArrayList<InputDeviceListenerDelegate> mInputDeviceListeners = new ArrayList<>(); 82 83 @GuardedBy("mOnTabletModeChangedListeners") 84 private final ArrayList<OnTabletModeChangedListenerDelegate> mOnTabletModeChangedListeners = 85 new ArrayList<>(); 86 87 private final Object mBatteryListenersLock = new Object(); 88 // Maps a deviceId whose battery is currently being monitored to an entry containing the 89 // registered listeners for that device. 90 @GuardedBy("mBatteryListenersLock") 91 @Nullable private SparseArray<RegisteredBatteryListeners> mBatteryListeners; 92 @GuardedBy("mBatteryListenersLock") 93 @Nullable private IInputDeviceBatteryListener mInputDeviceBatteryListener; 94 95 private final Object mKeyboardBacklightListenerLock = new Object(); 96 @GuardedBy("mKeyboardBacklightListenerLock") 97 @Nullable private ArrayList<KeyboardBacklightListenerDelegate> mKeyboardBacklightListeners; 98 @GuardedBy("mKeyboardBacklightListenerLock") 99 @Nullable private IKeyboardBacklightListener mKeyboardBacklightListener; 100 101 @Nullable private InputDeviceSensorManager mInputDeviceSensorManager; 102 103 private static InputManagerGlobal sInstance; 104 105 private final String mVelocityTrackerStrategy; 106 107 private final IInputManager mIm; 108 InputManagerGlobal(IInputManager im)109 public InputManagerGlobal(IInputManager im) { 110 mIm = im; 111 String strategy = null; 112 try { 113 strategy = mIm.getVelocityTrackerStrategy(); 114 } catch (RemoteException ex) { 115 Log.w(TAG, "Could not get VelocityTracker strategy: " + ex); 116 } 117 mVelocityTrackerStrategy = strategy; 118 } 119 120 /** 121 * Gets an instance of the input manager global singleton. 122 * 123 * @return The input manager instance, may be null early in system startup 124 * before the input manager has been fully initialized. 125 */ getInstance()126 public static InputManagerGlobal getInstance() { 127 synchronized (InputManagerGlobal.class) { 128 if (sInstance == null) { 129 IBinder b = ServiceManager.getService(Context.INPUT_SERVICE); 130 if (b != null) { 131 sInstance = new InputManagerGlobal(IInputManager.Stub.asInterface(b)); 132 } 133 } 134 return sInstance; 135 } 136 } 137 getInputManagerService()138 public IInputManager getInputManagerService() { 139 return mIm; 140 } 141 142 /** 143 * Gets an instance of the input manager. 144 * 145 * @return The input manager instance. 146 */ resetInstance(IInputManager inputManagerService)147 public static InputManagerGlobal resetInstance(IInputManager inputManagerService) { 148 synchronized (InputManager.class) { 149 sInstance = new InputManagerGlobal(inputManagerService); 150 return sInstance; 151 } 152 } 153 154 /** 155 * Clear the instance of the input manager. 156 */ clearInstance()157 public static void clearInstance() { 158 synchronized (InputManagerGlobal.class) { 159 sInstance = null; 160 } 161 } 162 163 /** 164 * Get the current VelocityTracker strategy. 165 * Only works when the system has fully booted up. 166 */ getVelocityTrackerStrategy()167 public String getVelocityTrackerStrategy() { 168 return mVelocityTrackerStrategy; 169 } 170 171 /** 172 * @see InputManager#getInputDevice(int) 173 */ 174 @Nullable getInputDevice(int id)175 public InputDevice getInputDevice(int id) { 176 synchronized (mInputDeviceListeners) { 177 populateInputDevicesLocked(); 178 179 int index = mInputDevices.indexOfKey(id); 180 if (index < 0) { 181 return null; 182 } 183 184 InputDevice inputDevice = mInputDevices.valueAt(index); 185 if (inputDevice == null) { 186 try { 187 inputDevice = mIm.getInputDevice(id); 188 } catch (RemoteException ex) { 189 throw ex.rethrowFromSystemServer(); 190 } 191 if (inputDevice != null) { 192 mInputDevices.setValueAt(index, inputDevice); 193 } 194 } 195 return inputDevice; 196 } 197 } 198 199 @GuardedBy("mInputDeviceListeners") populateInputDevicesLocked()200 private void populateInputDevicesLocked() { 201 if (mInputDevicesChangedListener == null) { 202 final InputDevicesChangedListener 203 listener = new InputDevicesChangedListener(); 204 try { 205 mIm.registerInputDevicesChangedListener(listener); 206 } catch (RemoteException ex) { 207 throw ex.rethrowFromSystemServer(); 208 } 209 mInputDevicesChangedListener = listener; 210 } 211 212 if (mInputDevices == null) { 213 final int[] ids; 214 try { 215 ids = mIm.getInputDeviceIds(); 216 } catch (RemoteException ex) { 217 throw ex.rethrowFromSystemServer(); 218 } 219 220 mInputDevices = new SparseArray<>(); 221 for (int id : ids) { 222 mInputDevices.put(id, null); 223 } 224 } 225 } 226 227 private final class InputDevicesChangedListener extends IInputDevicesChangedListener.Stub { 228 @Override onInputDevicesChanged(int[] deviceIdAndGeneration)229 public void onInputDevicesChanged(int[] deviceIdAndGeneration) throws RemoteException { 230 InputManagerGlobal.this.onInputDevicesChanged(deviceIdAndGeneration); 231 } 232 } 233 onInputDevicesChanged(int[] deviceIdAndGeneration)234 private void onInputDevicesChanged(int[] deviceIdAndGeneration) { 235 if (DEBUG) { 236 Log.d(TAG, "Received input devices changed."); 237 } 238 239 synchronized (mInputDeviceListeners) { 240 for (int i = mInputDevices.size(); --i > 0; ) { 241 final int deviceId = mInputDevices.keyAt(i); 242 if (!containsDeviceId(deviceIdAndGeneration, deviceId)) { 243 if (DEBUG) { 244 Log.d(TAG, "Device removed: " + deviceId); 245 } 246 mInputDevices.removeAt(i); 247 sendMessageToInputDeviceListenersLocked( 248 InputDeviceListenerDelegate.MSG_DEVICE_REMOVED, deviceId); 249 } 250 } 251 252 for (int i = 0; i < deviceIdAndGeneration.length; i += 2) { 253 final int deviceId = deviceIdAndGeneration[i]; 254 int index = mInputDevices.indexOfKey(deviceId); 255 if (index >= 0) { 256 final InputDevice device = mInputDevices.valueAt(index); 257 if (device != null) { 258 final int generation = deviceIdAndGeneration[i + 1]; 259 if (device.getGeneration() != generation) { 260 if (DEBUG) { 261 Log.d(TAG, "Device changed: " + deviceId); 262 } 263 mInputDevices.setValueAt(index, null); 264 sendMessageToInputDeviceListenersLocked( 265 InputDeviceListenerDelegate.MSG_DEVICE_CHANGED, deviceId); 266 } 267 } 268 } else { 269 if (DEBUG) { 270 Log.d(TAG, "Device added: " + deviceId); 271 } 272 mInputDevices.put(deviceId, null); 273 sendMessageToInputDeviceListenersLocked( 274 InputDeviceListenerDelegate.MSG_DEVICE_ADDED, deviceId); 275 } 276 } 277 } 278 } 279 280 private static final class InputDeviceListenerDelegate extends Handler { 281 public final InputDeviceListener mListener; 282 static final int MSG_DEVICE_ADDED = 1; 283 static final int MSG_DEVICE_REMOVED = 2; 284 static final int MSG_DEVICE_CHANGED = 3; 285 InputDeviceListenerDelegate(InputDeviceListener listener, Handler handler)286 InputDeviceListenerDelegate(InputDeviceListener listener, Handler handler) { 287 super(handler != null ? handler.getLooper() : Looper.myLooper()); 288 mListener = listener; 289 } 290 291 @Override handleMessage(Message msg)292 public void handleMessage(Message msg) { 293 switch (msg.what) { 294 case MSG_DEVICE_ADDED: 295 mListener.onInputDeviceAdded(msg.arg1); 296 break; 297 case MSG_DEVICE_REMOVED: 298 mListener.onInputDeviceRemoved(msg.arg1); 299 break; 300 case MSG_DEVICE_CHANGED: 301 mListener.onInputDeviceChanged(msg.arg1); 302 break; 303 } 304 } 305 } 306 containsDeviceId(int[] deviceIdAndGeneration, int deviceId)307 private static boolean containsDeviceId(int[] deviceIdAndGeneration, int deviceId) { 308 for (int i = 0; i < deviceIdAndGeneration.length; i += 2) { 309 if (deviceIdAndGeneration[i] == deviceId) { 310 return true; 311 } 312 } 313 return false; 314 } 315 316 @GuardedBy("mInputDeviceListeners") sendMessageToInputDeviceListenersLocked(int what, int deviceId)317 private void sendMessageToInputDeviceListenersLocked(int what, int deviceId) { 318 final int numListeners = mInputDeviceListeners.size(); 319 for (int i = 0; i < numListeners; i++) { 320 InputDeviceListenerDelegate listener = mInputDeviceListeners.get(i); 321 listener.sendMessage(listener.obtainMessage(what, deviceId, 0)); 322 } 323 } 324 325 /** 326 * @see InputManager#registerInputDeviceListener 327 */ registerInputDeviceListener(InputDeviceListener listener, Handler handler)328 public void registerInputDeviceListener(InputDeviceListener listener, Handler handler) { 329 Objects.requireNonNull(listener, "listener must not be null"); 330 331 synchronized (mInputDeviceListeners) { 332 populateInputDevicesLocked(); 333 int index = findInputDeviceListenerLocked(listener); 334 if (index < 0) { 335 mInputDeviceListeners.add(new InputDeviceListenerDelegate(listener, handler)); 336 } 337 } 338 } 339 340 /** 341 * @see InputManager#unregisterInputDeviceListener 342 */ unregisterInputDeviceListener(InputDeviceListener listener)343 public void unregisterInputDeviceListener(InputDeviceListener listener) { 344 if (listener == null) { 345 throw new IllegalArgumentException("listener must not be null"); 346 } 347 348 synchronized (mInputDeviceListeners) { 349 int index = findInputDeviceListenerLocked(listener); 350 if (index >= 0) { 351 InputDeviceListenerDelegate d = mInputDeviceListeners.get(index); 352 d.removeCallbacksAndMessages(null); 353 mInputDeviceListeners.remove(index); 354 } 355 } 356 } 357 358 @GuardedBy("mInputDeviceListeners") findInputDeviceListenerLocked(InputDeviceListener listener)359 private int findInputDeviceListenerLocked(InputDeviceListener listener) { 360 final int numListeners = mInputDeviceListeners.size(); 361 for (int i = 0; i < numListeners; i++) { 362 if (mInputDeviceListeners.get(i).mListener == listener) { 363 return i; 364 } 365 } 366 return -1; 367 } 368 369 /** 370 * @see InputManager#getInputDeviceIds 371 */ getInputDeviceIds()372 public int[] getInputDeviceIds() { 373 synchronized (mInputDeviceListeners) { 374 populateInputDevicesLocked(); 375 376 final int count = mInputDevices.size(); 377 final int[] ids = new int[count]; 378 for (int i = 0; i < count; i++) { 379 ids[i] = mInputDevices.keyAt(i); 380 } 381 return ids; 382 } 383 } 384 385 /** 386 * @see InputManager#isInputDeviceEnabled(int) 387 */ isInputDeviceEnabled(int id)388 public boolean isInputDeviceEnabled(int id) { 389 try { 390 return mIm.isInputDeviceEnabled(id); 391 } catch (RemoteException ex) { 392 Log.w(TAG, "Could not check enabled status of input device with id = " + id); 393 throw ex.rethrowFromSystemServer(); 394 } 395 } 396 397 /** 398 * @see InputManager#enableInputDevice(int) 399 */ enableInputDevice(int id)400 public void enableInputDevice(int id) { 401 try { 402 mIm.enableInputDevice(id); 403 } catch (RemoteException ex) { 404 Log.w(TAG, "Could not enable input device with id = " + id); 405 throw ex.rethrowFromSystemServer(); 406 } 407 } 408 409 /** 410 * @see InputManager#disableInputDevice(int) 411 */ disableInputDevice(int id)412 public void disableInputDevice(int id) { 413 try { 414 mIm.disableInputDevice(id); 415 } catch (RemoteException ex) { 416 Log.w(TAG, "Could not disable input device with id = " + id); 417 throw ex.rethrowFromSystemServer(); 418 } 419 } 420 421 /** 422 * @see InputManager#getInputDeviceByDescriptor 423 */ getInputDeviceByDescriptor(String descriptor)424 InputDevice getInputDeviceByDescriptor(String descriptor) { 425 Objects.requireNonNull(descriptor, "descriptor must not be null."); 426 427 synchronized (mInputDeviceListeners) { 428 populateInputDevicesLocked(); 429 430 int numDevices = mInputDevices.size(); 431 for (int i = 0; i < numDevices; i++) { 432 InputDevice inputDevice = mInputDevices.valueAt(i); 433 if (inputDevice == null) { 434 int id = mInputDevices.keyAt(i); 435 try { 436 inputDevice = mIm.getInputDevice(id); 437 } catch (RemoteException ex) { 438 throw ex.rethrowFromSystemServer(); 439 } 440 if (inputDevice == null) { 441 continue; 442 } 443 mInputDevices.setValueAt(i, inputDevice); 444 } 445 if (descriptor.equals(inputDevice.getDescriptor())) { 446 return inputDevice; 447 } 448 } 449 return null; 450 } 451 } 452 453 /** 454 * @see InputManager#getHostUsiVersion 455 */ 456 @Nullable getHostUsiVersion(@onNull Display display)457 HostUsiVersion getHostUsiVersion(@NonNull Display display) { 458 Objects.requireNonNull(display, "display should not be null"); 459 460 // Return the first valid USI version reported by any input device associated with 461 // the display. 462 synchronized (mInputDeviceListeners) { 463 populateInputDevicesLocked(); 464 465 for (int i = 0; i < mInputDevices.size(); i++) { 466 final InputDevice device = getInputDevice(mInputDevices.keyAt(i)); 467 if (device != null && device.getAssociatedDisplayId() == display.getDisplayId()) { 468 if (device.getHostUsiVersion() != null) { 469 return device.getHostUsiVersion(); 470 } 471 } 472 } 473 } 474 475 // If there are no input devices that report a valid USI version, see if there is a config 476 // that specifies the USI version for the display. This is to handle cases where the USI 477 // input device is not registered by the kernel/driver all the time. 478 try { 479 return mIm.getHostUsiVersionFromDisplayConfig(display.getDisplayId()); 480 } catch (RemoteException e) { 481 throw e.rethrowFromSystemServer(); 482 } 483 } 484 onTabletModeChanged(long whenNanos, boolean inTabletMode)485 private void onTabletModeChanged(long whenNanos, boolean inTabletMode) { 486 if (DEBUG) { 487 Log.d(TAG, "Received tablet mode changed: " 488 + "whenNanos=" + whenNanos + ", inTabletMode=" + inTabletMode); 489 } 490 synchronized (mOnTabletModeChangedListeners) { 491 final int numListeners = mOnTabletModeChangedListeners.size(); 492 for (int i = 0; i < numListeners; i++) { 493 OnTabletModeChangedListenerDelegate listener = 494 mOnTabletModeChangedListeners.get(i); 495 listener.sendTabletModeChanged(whenNanos, inTabletMode); 496 } 497 } 498 } 499 500 private final class TabletModeChangedListener extends ITabletModeChangedListener.Stub { 501 @Override onTabletModeChanged(long whenNanos, boolean inTabletMode)502 public void onTabletModeChanged(long whenNanos, boolean inTabletMode) { 503 InputManagerGlobal.this.onTabletModeChanged(whenNanos, inTabletMode); 504 } 505 } 506 507 private static final class OnTabletModeChangedListenerDelegate extends Handler { 508 private static final int MSG_TABLET_MODE_CHANGED = 0; 509 510 public final OnTabletModeChangedListener mListener; 511 OnTabletModeChangedListenerDelegate( OnTabletModeChangedListener listener, Handler handler)512 OnTabletModeChangedListenerDelegate( 513 OnTabletModeChangedListener listener, Handler handler) { 514 super(handler != null ? handler.getLooper() : Looper.myLooper()); 515 mListener = listener; 516 } 517 sendTabletModeChanged(long whenNanos, boolean inTabletMode)518 public void sendTabletModeChanged(long whenNanos, boolean inTabletMode) { 519 SomeArgs args = SomeArgs.obtain(); 520 args.argi1 = (int) whenNanos; 521 args.argi2 = (int) (whenNanos >> 32); 522 args.arg1 = inTabletMode; 523 obtainMessage(MSG_TABLET_MODE_CHANGED, args).sendToTarget(); 524 } 525 526 @Override handleMessage(Message msg)527 public void handleMessage(Message msg) { 528 if (msg.what == MSG_TABLET_MODE_CHANGED) { 529 SomeArgs args = (SomeArgs) msg.obj; 530 long whenNanos = (args.argi1 & 0xFFFFFFFFL) | ((long) args.argi2 << 32); 531 boolean inTabletMode = (boolean) args.arg1; 532 mListener.onTabletModeChanged(whenNanos, inTabletMode); 533 } 534 } 535 } 536 537 /** 538 * @see InputManager#registerInputDeviceListener(InputDeviceListener, Handler) 539 */ registerOnTabletModeChangedListener( OnTabletModeChangedListener listener, Handler handler)540 void registerOnTabletModeChangedListener( 541 OnTabletModeChangedListener listener, Handler handler) { 542 Objects.requireNonNull(listener, "listener must not be null"); 543 544 synchronized (mOnTabletModeChangedListeners) { 545 if (mOnTabletModeChangedListeners == null) { 546 initializeTabletModeListenerLocked(); 547 } 548 int idx = findOnTabletModeChangedListenerLocked(listener); 549 if (idx < 0) { 550 OnTabletModeChangedListenerDelegate d = 551 new OnTabletModeChangedListenerDelegate(listener, handler); 552 mOnTabletModeChangedListeners.add(d); 553 } 554 } 555 } 556 557 /** 558 * @see InputManager#unregisterOnTabletModeChangedListener(OnTabletModeChangedListener) 559 */ unregisterOnTabletModeChangedListener(OnTabletModeChangedListener listener)560 void unregisterOnTabletModeChangedListener(OnTabletModeChangedListener listener) { 561 Objects.requireNonNull(listener, "listener must not be null"); 562 563 synchronized (mOnTabletModeChangedListeners) { 564 int idx = findOnTabletModeChangedListenerLocked(listener); 565 if (idx >= 0) { 566 OnTabletModeChangedListenerDelegate d = mOnTabletModeChangedListeners.remove(idx); 567 d.removeCallbacksAndMessages(null); 568 } 569 } 570 } 571 572 @GuardedBy("mOnTabletModeChangedListeners") initializeTabletModeListenerLocked()573 private void initializeTabletModeListenerLocked() { 574 final TabletModeChangedListener listener = new TabletModeChangedListener(); 575 try { 576 mIm.registerTabletModeChangedListener(listener); 577 } catch (RemoteException ex) { 578 throw ex.rethrowFromSystemServer(); 579 } 580 } 581 582 @GuardedBy("mOnTabletModeChangedListeners") findOnTabletModeChangedListenerLocked(OnTabletModeChangedListener listener)583 private int findOnTabletModeChangedListenerLocked(OnTabletModeChangedListener listener) { 584 final int n = mOnTabletModeChangedListeners.size(); 585 for (int i = 0; i < n; i++) { 586 if (mOnTabletModeChangedListeners.get(i).mListener == listener) { 587 return i; 588 } 589 } 590 return -1; 591 } 592 593 private static final class RegisteredBatteryListeners { 594 final List<InputDeviceBatteryListenerDelegate> mDelegates = new ArrayList<>(); 595 IInputDeviceBatteryState mInputDeviceBatteryState; 596 } 597 598 private static final class InputDeviceBatteryListenerDelegate { 599 final InputDeviceBatteryListener mListener; 600 final Executor mExecutor; 601 InputDeviceBatteryListenerDelegate(InputDeviceBatteryListener listener, Executor executor)602 InputDeviceBatteryListenerDelegate(InputDeviceBatteryListener listener, Executor executor) { 603 mListener = listener; 604 mExecutor = executor; 605 } 606 notifyBatteryStateChanged(IInputDeviceBatteryState state)607 void notifyBatteryStateChanged(IInputDeviceBatteryState state) { 608 mExecutor.execute(() -> 609 mListener.onBatteryStateChanged(state.deviceId, state.updateTime, 610 new LocalBatteryState(state.isPresent, state.status, state.capacity))); 611 } 612 } 613 614 /** 615 * @see InputManager#addInputDeviceBatteryListener(int, Executor, InputDeviceBatteryListener) 616 */ addInputDeviceBatteryListener(int deviceId, @NonNull Executor executor, @NonNull InputDeviceBatteryListener listener)617 public void addInputDeviceBatteryListener(int deviceId, @NonNull Executor executor, 618 @NonNull InputDeviceBatteryListener listener) { 619 Objects.requireNonNull(executor, "executor should not be null"); 620 Objects.requireNonNull(listener, "listener should not be null"); 621 622 synchronized (mBatteryListenersLock) { 623 if (mBatteryListeners == null) { 624 mBatteryListeners = new SparseArray<>(); 625 mInputDeviceBatteryListener = new LocalInputDeviceBatteryListener(); 626 } 627 RegisteredBatteryListeners listenersForDevice = mBatteryListeners.get(deviceId); 628 if (listenersForDevice == null) { 629 // The deviceId is currently not being monitored for battery changes. 630 // Start monitoring the device. 631 listenersForDevice = new RegisteredBatteryListeners(); 632 mBatteryListeners.put(deviceId, listenersForDevice); 633 try { 634 mIm.registerBatteryListener(deviceId, mInputDeviceBatteryListener); 635 } catch (RemoteException e) { 636 throw e.rethrowFromSystemServer(); 637 } 638 } else { 639 // The deviceId is already being monitored for battery changes. 640 // Ensure that the listener is not already registered. 641 final int numDelegates = listenersForDevice.mDelegates.size(); 642 for (int i = 0; i < numDelegates; i++) { 643 InputDeviceBatteryListener registeredListener = 644 listenersForDevice.mDelegates.get(i).mListener; 645 if (Objects.equals(listener, registeredListener)) { 646 throw new IllegalArgumentException( 647 "Attempting to register an InputDeviceBatteryListener that has " 648 + "already been registered for deviceId: " 649 + deviceId); 650 } 651 } 652 } 653 final InputDeviceBatteryListenerDelegate delegate = 654 new InputDeviceBatteryListenerDelegate(listener, executor); 655 listenersForDevice.mDelegates.add(delegate); 656 657 // Notify the listener immediately if we already have the latest battery state. 658 if (listenersForDevice.mInputDeviceBatteryState != null) { 659 delegate.notifyBatteryStateChanged(listenersForDevice.mInputDeviceBatteryState); 660 } 661 } 662 } 663 664 /** 665 * @see InputManager#removeInputDeviceBatteryListener(int, InputDeviceBatteryListener) 666 */ removeInputDeviceBatteryListener(int deviceId, @NonNull InputDeviceBatteryListener listener)667 void removeInputDeviceBatteryListener(int deviceId, 668 @NonNull InputDeviceBatteryListener listener) { 669 Objects.requireNonNull(listener, "listener should not be null"); 670 671 synchronized (mBatteryListenersLock) { 672 if (mBatteryListeners == null) { 673 return; 674 } 675 RegisteredBatteryListeners listenersForDevice = mBatteryListeners.get(deviceId); 676 if (listenersForDevice == null) { 677 // The deviceId is not currently being monitored. 678 return; 679 } 680 final List<InputDeviceBatteryListenerDelegate> delegates = 681 listenersForDevice.mDelegates; 682 for (int i = 0; i < delegates.size();) { 683 if (Objects.equals(listener, delegates.get(i).mListener)) { 684 delegates.remove(i); 685 continue; 686 } 687 i++; 688 } 689 if (!delegates.isEmpty()) { 690 return; 691 } 692 693 // There are no more battery listeners for this deviceId. Stop monitoring this device. 694 mBatteryListeners.remove(deviceId); 695 try { 696 mIm.unregisterBatteryListener(deviceId, mInputDeviceBatteryListener); 697 } catch (RemoteException e) { 698 throw e.rethrowFromSystemServer(); 699 } 700 if (mBatteryListeners.size() == 0) { 701 // There are no more devices being monitored, so the registered 702 // IInputDeviceBatteryListener will be automatically dropped by the server. 703 mBatteryListeners = null; 704 mInputDeviceBatteryListener = null; 705 } 706 } 707 } 708 709 private class LocalInputDeviceBatteryListener extends IInputDeviceBatteryListener.Stub { 710 @Override onBatteryStateChanged(IInputDeviceBatteryState state)711 public void onBatteryStateChanged(IInputDeviceBatteryState state) { 712 synchronized (mBatteryListenersLock) { 713 if (mBatteryListeners == null) return; 714 final RegisteredBatteryListeners entry = mBatteryListeners.get(state.deviceId); 715 if (entry == null) return; 716 717 entry.mInputDeviceBatteryState = state; 718 final int numDelegates = entry.mDelegates.size(); 719 for (int i = 0; i < numDelegates; i++) { 720 entry.mDelegates.get(i) 721 .notifyBatteryStateChanged(entry.mInputDeviceBatteryState); 722 } 723 } 724 } 725 } 726 727 /** 728 * @see #getInputDeviceBatteryState(int, boolean) 729 */ 730 @NonNull getInputDeviceBatteryState(int deviceId, boolean hasBattery)731 public BatteryState getInputDeviceBatteryState(int deviceId, boolean hasBattery) { 732 if (!hasBattery) { 733 return new LocalBatteryState(); 734 } 735 try { 736 final IInputDeviceBatteryState state = mIm.getBatteryState(deviceId); 737 return new LocalBatteryState(state.isPresent, state.status, state.capacity); 738 } catch (RemoteException ex) { 739 throw ex.rethrowFromSystemServer(); 740 } 741 } 742 743 // Implementation of the android.hardware.BatteryState interface used to report the battery 744 // state via the InputDevice#getBatteryState() and InputDeviceBatteryListener interfaces. 745 private static final class LocalBatteryState extends BatteryState { 746 private final boolean mIsPresent; 747 private final int mStatus; 748 private final float mCapacity; 749 LocalBatteryState()750 LocalBatteryState() { 751 this(false /*isPresent*/, BatteryState.STATUS_UNKNOWN, Float.NaN /*capacity*/); 752 } 753 LocalBatteryState(boolean isPresent, int status, float capacity)754 LocalBatteryState(boolean isPresent, int status, float capacity) { 755 mIsPresent = isPresent; 756 mStatus = status; 757 mCapacity = capacity; 758 } 759 760 @Override isPresent()761 public boolean isPresent() { 762 return mIsPresent; 763 } 764 765 @Override getStatus()766 public int getStatus() { 767 return mStatus; 768 } 769 770 @Override getCapacity()771 public float getCapacity() { 772 return mCapacity; 773 } 774 } 775 776 private static final class KeyboardBacklightListenerDelegate { 777 final InputManager.KeyboardBacklightListener mListener; 778 final Executor mExecutor; 779 KeyboardBacklightListenerDelegate(KeyboardBacklightListener listener, Executor executor)780 KeyboardBacklightListenerDelegate(KeyboardBacklightListener listener, Executor executor) { 781 mListener = listener; 782 mExecutor = executor; 783 } 784 notifyKeyboardBacklightChange(int deviceId, IKeyboardBacklightState state, boolean isTriggeredByKeyPress)785 void notifyKeyboardBacklightChange(int deviceId, IKeyboardBacklightState state, 786 boolean isTriggeredByKeyPress) { 787 mExecutor.execute(() -> 788 mListener.onKeyboardBacklightChanged(deviceId, 789 new LocalKeyboardBacklightState(state.brightnessLevel, 790 state.maxBrightnessLevel), isTriggeredByKeyPress)); 791 } 792 } 793 794 private class LocalKeyboardBacklightListener extends IKeyboardBacklightListener.Stub { 795 796 @Override onBrightnessChanged(int deviceId, IKeyboardBacklightState state, boolean isTriggeredByKeyPress)797 public void onBrightnessChanged(int deviceId, IKeyboardBacklightState state, 798 boolean isTriggeredByKeyPress) { 799 synchronized (mKeyboardBacklightListenerLock) { 800 if (mKeyboardBacklightListeners == null) return; 801 final int numListeners = mKeyboardBacklightListeners.size(); 802 for (int i = 0; i < numListeners; i++) { 803 mKeyboardBacklightListeners.get(i) 804 .notifyKeyboardBacklightChange(deviceId, state, isTriggeredByKeyPress); 805 } 806 } 807 } 808 } 809 810 // Implementation of the android.hardware.input.KeyboardBacklightState interface used to report 811 // the keyboard backlight state via the KeyboardBacklightListener interfaces. 812 private static final class LocalKeyboardBacklightState extends KeyboardBacklightState { 813 814 private final int mBrightnessLevel; 815 private final int mMaxBrightnessLevel; 816 LocalKeyboardBacklightState(int brightnessLevel, int maxBrightnessLevel)817 LocalKeyboardBacklightState(int brightnessLevel, int maxBrightnessLevel) { 818 mBrightnessLevel = brightnessLevel; 819 mMaxBrightnessLevel = maxBrightnessLevel; 820 } 821 822 @Override getBrightnessLevel()823 public int getBrightnessLevel() { 824 return mBrightnessLevel; 825 } 826 827 @Override getMaxBrightnessLevel()828 public int getMaxBrightnessLevel() { 829 return mMaxBrightnessLevel; 830 } 831 } 832 833 /** 834 * @see InputManager#registerKeyboardBacklightListener(Executor, KeyboardBacklightListener) 835 */ 836 @RequiresPermission(Manifest.permission.MONITOR_KEYBOARD_BACKLIGHT) registerKeyboardBacklightListener(@onNull Executor executor, @NonNull KeyboardBacklightListener listener)837 void registerKeyboardBacklightListener(@NonNull Executor executor, 838 @NonNull KeyboardBacklightListener listener) throws IllegalArgumentException { 839 Objects.requireNonNull(executor, "executor should not be null"); 840 Objects.requireNonNull(listener, "listener should not be null"); 841 842 synchronized (mKeyboardBacklightListenerLock) { 843 if (mKeyboardBacklightListener == null) { 844 mKeyboardBacklightListeners = new ArrayList<>(); 845 mKeyboardBacklightListener = new LocalKeyboardBacklightListener(); 846 847 try { 848 mIm.registerKeyboardBacklightListener(mKeyboardBacklightListener); 849 } catch (RemoteException e) { 850 throw e.rethrowFromSystemServer(); 851 } 852 } 853 final int numListeners = mKeyboardBacklightListeners.size(); 854 for (int i = 0; i < numListeners; i++) { 855 if (mKeyboardBacklightListeners.get(i).mListener == listener) { 856 throw new IllegalArgumentException("Listener has already been registered!"); 857 } 858 } 859 KeyboardBacklightListenerDelegate delegate = 860 new KeyboardBacklightListenerDelegate(listener, executor); 861 mKeyboardBacklightListeners.add(delegate); 862 } 863 } 864 865 /** 866 * @see InputManager#unregisterKeyboardBacklightListener(KeyboardBacklightListener) 867 */ 868 @RequiresPermission(Manifest.permission.MONITOR_KEYBOARD_BACKLIGHT) unregisterKeyboardBacklightListener( @onNull KeyboardBacklightListener listener)869 void unregisterKeyboardBacklightListener( 870 @NonNull KeyboardBacklightListener listener) { 871 Objects.requireNonNull(listener, "listener should not be null"); 872 873 synchronized (mKeyboardBacklightListenerLock) { 874 if (mKeyboardBacklightListeners == null) { 875 return; 876 } 877 mKeyboardBacklightListeners.removeIf((delegate) -> delegate.mListener == listener); 878 if (mKeyboardBacklightListeners.isEmpty()) { 879 try { 880 mIm.unregisterKeyboardBacklightListener(mKeyboardBacklightListener); 881 } catch (RemoteException e) { 882 throw e.rethrowFromSystemServer(); 883 } 884 mKeyboardBacklightListeners = null; 885 mKeyboardBacklightListener = null; 886 } 887 } 888 } 889 890 /** 891 * @see InputManager#getKeyboardLayoutsForInputDevice(InputDeviceIdentifier) 892 */ 893 @NonNull getKeyboardLayoutsForInputDevice( @onNull InputDeviceIdentifier identifier)894 public KeyboardLayout[] getKeyboardLayoutsForInputDevice( 895 @NonNull InputDeviceIdentifier identifier) { 896 try { 897 return mIm.getKeyboardLayoutsForInputDevice(identifier); 898 } catch (RemoteException ex) { 899 throw ex.rethrowFromSystemServer(); 900 } 901 } 902 903 /** 904 * @see InputManager#setCurrentKeyboardLayoutForInputDevice 905 * (InputDeviceIdentifier, String) 906 */ 907 @RequiresPermission(Manifest.permission.SET_KEYBOARD_LAYOUT) setCurrentKeyboardLayoutForInputDevice( @onNull InputDeviceIdentifier identifier, @NonNull String keyboardLayoutDescriptor)908 public void setCurrentKeyboardLayoutForInputDevice( 909 @NonNull InputDeviceIdentifier identifier, 910 @NonNull String keyboardLayoutDescriptor) { 911 Objects.requireNonNull(identifier, "identifier must not be null"); 912 Objects.requireNonNull(keyboardLayoutDescriptor, 913 "keyboardLayoutDescriptor must not be null"); 914 try { 915 mIm.setCurrentKeyboardLayoutForInputDevice(identifier, 916 keyboardLayoutDescriptor); 917 } catch (RemoteException ex) { 918 throw ex.rethrowFromSystemServer(); 919 } 920 } 921 922 /** 923 * @see InputDevice#getSensorManager() 924 */ 925 @NonNull getInputDeviceSensorManager(int deviceId)926 public SensorManager getInputDeviceSensorManager(int deviceId) { 927 if (mInputDeviceSensorManager == null) { 928 mInputDeviceSensorManager = new InputDeviceSensorManager(this); 929 } 930 return mInputDeviceSensorManager.getSensorManager(deviceId); 931 } 932 933 /** 934 * @see InputManager#getSensorList(int) 935 */ getSensorList(int deviceId)936 InputSensorInfo[] getSensorList(int deviceId) { 937 try { 938 return mIm.getSensorList(deviceId); 939 } catch (RemoteException ex) { 940 throw ex.rethrowFromSystemServer(); 941 } 942 } 943 944 /** 945 * @see InputManager#enableSensor(int, int, int, int) 946 */ enableSensor(int deviceId, int sensorType, int samplingPeriodUs, int maxBatchReportLatencyUs)947 boolean enableSensor(int deviceId, int sensorType, int samplingPeriodUs, 948 int maxBatchReportLatencyUs) { 949 try { 950 return mIm.enableSensor(deviceId, sensorType, samplingPeriodUs, 951 maxBatchReportLatencyUs); 952 } catch (RemoteException ex) { 953 throw ex.rethrowFromSystemServer(); 954 } 955 } 956 957 /** 958 * @see InputManager#disableSensor(int, int) 959 */ disableSensor(int deviceId, int sensorType)960 void disableSensor(int deviceId, int sensorType) { 961 try { 962 mIm.disableSensor(deviceId, sensorType); 963 } catch (RemoteException ex) { 964 throw ex.rethrowFromSystemServer(); 965 } 966 } 967 968 /** 969 * @see InputManager#flushSensor(int, int) 970 */ flushSensor(int deviceId, int sensorType)971 boolean flushSensor(int deviceId, int sensorType) { 972 try { 973 return mIm.flushSensor(deviceId, sensorType); 974 } catch (RemoteException ex) { 975 throw ex.rethrowFromSystemServer(); 976 } 977 } 978 979 /** 980 * @see InputManager#registerSensorListener(IInputSensorEventListener) 981 */ registerSensorListener(IInputSensorEventListener listener)982 boolean registerSensorListener(IInputSensorEventListener listener) { 983 try { 984 return mIm.registerSensorListener(listener); 985 } catch (RemoteException ex) { 986 throw ex.rethrowFromSystemServer(); 987 } 988 } 989 990 /** 991 * @see InputManager#unregisterSensorListener(IInputSensorEventListener) 992 */ unregisterSensorListener(IInputSensorEventListener listener)993 void unregisterSensorListener(IInputSensorEventListener listener) { 994 try { 995 mIm.unregisterSensorListener(listener); 996 } catch (RemoteException ex) { 997 throw ex.rethrowFromSystemServer(); 998 } 999 } 1000 1001 /** 1002 * @see InputDevice#getLightsManager() 1003 */ 1004 @NonNull getInputDeviceLightsManager(int deviceId)1005 public LightsManager getInputDeviceLightsManager(int deviceId) { 1006 return new InputDeviceLightsManager(deviceId); 1007 } 1008 1009 /** 1010 * Gets a list of light objects associated with an input device. 1011 * @return The list of lights, never null. 1012 */ getLights(int deviceId)1013 @NonNull List<Light> getLights(int deviceId) { 1014 try { 1015 return mIm.getLights(deviceId); 1016 } catch (RemoteException e) { 1017 throw e.rethrowFromSystemServer(); 1018 } 1019 } 1020 1021 /** 1022 * Returns the state of an input device light. 1023 * @return the light state 1024 */ getLightState(int deviceId, @NonNull Light light)1025 @NonNull LightState getLightState(int deviceId, @NonNull Light light) { 1026 try { 1027 return mIm.getLightState(deviceId, light.getId()); 1028 } catch (RemoteException e) { 1029 throw e.rethrowFromSystemServer(); 1030 } 1031 } 1032 1033 /** 1034 * Request to modify the states of multiple lights. 1035 * 1036 * @param request the settings for lights that should change 1037 */ requestLights(int deviceId, @NonNull LightsRequest request, IBinder token)1038 void requestLights(int deviceId, @NonNull LightsRequest request, IBinder token) { 1039 try { 1040 List<Integer> lightIdList = request.getLights(); 1041 int[] lightIds = new int[lightIdList.size()]; 1042 for (int i = 0; i < lightIds.length; i++) { 1043 lightIds[i] = lightIdList.get(i); 1044 } 1045 List<LightState> lightStateList = request.getLightStates(); 1046 mIm.setLightStates(deviceId, lightIds, 1047 lightStateList.toArray(new LightState[0]), 1048 token); 1049 } catch (RemoteException e) { 1050 throw e.rethrowFromSystemServer(); 1051 } 1052 } 1053 1054 /** 1055 * Open light session for input device manager 1056 * 1057 * @param token The token for the light session 1058 */ openLightSession(int deviceId, String opPkg, @NonNull IBinder token)1059 void openLightSession(int deviceId, String opPkg, @NonNull IBinder token) { 1060 try { 1061 mIm.openLightSession(deviceId, opPkg, token); 1062 } catch (RemoteException e) { 1063 throw e.rethrowFromSystemServer(); 1064 } 1065 } 1066 1067 /** 1068 * Close light session 1069 * 1070 */ closeLightSession(int deviceId, @NonNull IBinder token)1071 void closeLightSession(int deviceId, @NonNull IBinder token) { 1072 try { 1073 mIm.closeLightSession(deviceId, token); 1074 } catch (RemoteException e) { 1075 throw e.rethrowFromSystemServer(); 1076 } 1077 } 1078 1079 /** 1080 * @see InputManager#getInputDeviceVibrator(int, int) 1081 */ getInputDeviceVibrator(int deviceId, int vibratorId)1082 public Vibrator getInputDeviceVibrator(int deviceId, int vibratorId) { 1083 return new InputDeviceVibrator(deviceId, vibratorId); 1084 } 1085 1086 /** 1087 * @see InputDevice#getVibratorManager() 1088 */ 1089 @NonNull getInputDeviceVibratorManager(int deviceId)1090 public VibratorManager getInputDeviceVibratorManager(int deviceId) { 1091 return new InputDeviceVibratorManager(deviceId); 1092 } 1093 1094 /* 1095 * Get the list of device vibrators 1096 * @return The list of vibrators IDs 1097 */ getVibratorIds(int deviceId)1098 int[] getVibratorIds(int deviceId) { 1099 try { 1100 return mIm.getVibratorIds(deviceId); 1101 } catch (RemoteException ex) { 1102 throw ex.rethrowFromSystemServer(); 1103 } 1104 } 1105 1106 /* 1107 * Perform vibration effect 1108 */ vibrate(int deviceId, VibrationEffect effect, IBinder token)1109 void vibrate(int deviceId, VibrationEffect effect, IBinder token) { 1110 try { 1111 mIm.vibrate(deviceId, effect, token); 1112 } catch (RemoteException ex) { 1113 throw ex.rethrowFromSystemServer(); 1114 } 1115 } 1116 1117 /* 1118 * Perform combined vibration effect 1119 */ vibrate(int deviceId, CombinedVibration effect, IBinder token)1120 void vibrate(int deviceId, CombinedVibration effect, IBinder token) { 1121 try { 1122 mIm.vibrateCombined(deviceId, effect, token); 1123 } catch (RemoteException ex) { 1124 throw ex.rethrowFromSystemServer(); 1125 } 1126 } 1127 1128 /* 1129 * Cancel an ongoing vibration 1130 */ cancelVibrate(int deviceId, IBinder token)1131 void cancelVibrate(int deviceId, IBinder token) { 1132 try { 1133 mIm.cancelVibrate(deviceId, token); 1134 } catch (RemoteException ex) { 1135 throw ex.rethrowFromSystemServer(); 1136 } 1137 } 1138 1139 /* 1140 * Check if input device is vibrating 1141 */ isVibrating(int deviceId)1142 boolean isVibrating(int deviceId) { 1143 try { 1144 return mIm.isVibrating(deviceId); 1145 } catch (RemoteException ex) { 1146 throw ex.rethrowFromSystemServer(); 1147 } 1148 } 1149 1150 /** 1151 * Register input device vibrator state listener 1152 */ registerVibratorStateListener(int deviceId, IVibratorStateListener listener)1153 boolean registerVibratorStateListener(int deviceId, IVibratorStateListener listener) { 1154 try { 1155 return mIm.registerVibratorStateListener(deviceId, listener); 1156 } catch (RemoteException ex) { 1157 throw ex.rethrowFromSystemServer(); 1158 } 1159 } 1160 1161 /** 1162 * Unregister input device vibrator state listener 1163 */ unregisterVibratorStateListener(int deviceId, IVibratorStateListener listener)1164 boolean unregisterVibratorStateListener(int deviceId, IVibratorStateListener listener) { 1165 try { 1166 return mIm.unregisterVibratorStateListener(deviceId, listener); 1167 } catch (RemoteException ex) { 1168 throw ex.rethrowFromSystemServer(); 1169 } 1170 } 1171 1172 /** 1173 * @see InputManager#deviceHasKeys(int[]) 1174 */ deviceHasKeys(int[] keyCodes)1175 public boolean[] deviceHasKeys(int[] keyCodes) { 1176 return deviceHasKeys(-1, keyCodes); 1177 } 1178 1179 /** 1180 * @see InputManager#deviceHasKeys(int, int[]) 1181 */ deviceHasKeys(int id, int[] keyCodes)1182 public boolean[] deviceHasKeys(int id, int[] keyCodes) { 1183 boolean[] ret = new boolean[keyCodes.length]; 1184 try { 1185 mIm.hasKeys(id, InputDevice.SOURCE_ANY, keyCodes, ret); 1186 } catch (RemoteException e) { 1187 throw e.rethrowFromSystemServer(); 1188 } 1189 return ret; 1190 } 1191 1192 /** 1193 * @see InputManager#getKeyCodeForKeyLocation(int, int) 1194 */ getKeyCodeForKeyLocation(int deviceId, int locationKeyCode)1195 public int getKeyCodeForKeyLocation(int deviceId, int locationKeyCode) { 1196 try { 1197 return mIm.getKeyCodeForKeyLocation(deviceId, locationKeyCode); 1198 } catch (RemoteException e) { 1199 throw e.rethrowFromSystemServer(); 1200 } 1201 } 1202 1203 /** 1204 * @see InputManager#injectInputEvent(InputEvent, int, int) 1205 */ 1206 injectInputEvent(InputEvent event, int mode, int targetUid)1207 public boolean injectInputEvent(InputEvent event, int mode, int targetUid) { 1208 Objects.requireNonNull(event , "event must not be null"); 1209 1210 if (mode != InputEventInjectionSync.NONE 1211 && mode != InputEventInjectionSync.WAIT_FOR_FINISHED 1212 && mode != InputEventInjectionSync.WAIT_FOR_RESULT) { 1213 throw new IllegalArgumentException("mode is invalid"); 1214 } 1215 1216 try { 1217 return mIm.injectInputEventToTarget(event, mode, targetUid); 1218 } catch (RemoteException ex) { 1219 throw ex.rethrowFromSystemServer(); 1220 } 1221 } 1222 1223 /** 1224 * @see InputManager#injectInputEvent(InputEvent, int) 1225 */ injectInputEvent(InputEvent event, int mode)1226 public boolean injectInputEvent(InputEvent event, int mode) { 1227 return injectInputEvent(event, mode, Process.INVALID_UID); 1228 } 1229 1230 /** 1231 * @see InputManager#setPointerIconType(int) 1232 */ setPointerIconType(int iconId)1233 public void setPointerIconType(int iconId) { 1234 try { 1235 mIm.setPointerIconType(iconId); 1236 } catch (RemoteException ex) { 1237 throw ex.rethrowFromSystemServer(); 1238 } 1239 } 1240 1241 /** 1242 * @see InputManager#setCustomPointerIcon(PointerIcon) 1243 */ setCustomPointerIcon(PointerIcon icon)1244 public void setCustomPointerIcon(PointerIcon icon) { 1245 try { 1246 mIm.setCustomPointerIcon(icon); 1247 } catch (RemoteException ex) { 1248 throw ex.rethrowFromSystemServer(); 1249 } 1250 } 1251 1252 /** 1253 * @see InputManager#requestPointerCapture(IBinder, boolean) 1254 */ requestPointerCapture(IBinder windowToken, boolean enable)1255 public void requestPointerCapture(IBinder windowToken, boolean enable) { 1256 try { 1257 mIm.requestPointerCapture(windowToken, enable); 1258 } catch (RemoteException ex) { 1259 throw ex.rethrowFromSystemServer(); 1260 } 1261 } 1262 1263 /** 1264 * @see InputManager#monitorGestureInput(String, int) 1265 */ monitorGestureInput(String name, int displayId)1266 public InputMonitor monitorGestureInput(String name, int displayId) { 1267 try { 1268 return mIm.monitorGestureInput(new Binder(), name, displayId); 1269 } catch (RemoteException ex) { 1270 throw ex.rethrowFromSystemServer(); 1271 } 1272 } 1273 1274 /** 1275 * @see InputManager#addUniqueIdAssociation(String, String) 1276 */ addUniqueIdAssociation(@onNull String inputPort, @NonNull String displayUniqueId)1277 public void addUniqueIdAssociation(@NonNull String inputPort, @NonNull String displayUniqueId) { 1278 try { 1279 mIm.addUniqueIdAssociation(inputPort, displayUniqueId); 1280 } catch (RemoteException e) { 1281 throw e.rethrowFromSystemServer(); 1282 } 1283 } 1284 1285 /** 1286 * @see InputManager#removeUniqueIdAssociation(String) 1287 */ removeUniqueIdAssociation(@onNull String inputPort)1288 public void removeUniqueIdAssociation(@NonNull String inputPort) { 1289 try { 1290 mIm.removeUniqueIdAssociation(inputPort); 1291 } catch (RemoteException e) { 1292 throw e.rethrowFromSystemServer(); 1293 } 1294 } 1295 1296 /** 1297 * @see InputManager#getInputDeviceBluetoothAddress(int) 1298 */ 1299 @RequiresPermission(Manifest.permission.BLUETOOTH) 1300 @Nullable getInputDeviceBluetoothAddress(int deviceId)1301 public String getInputDeviceBluetoothAddress(int deviceId) { 1302 try { 1303 return mIm.getInputDeviceBluetoothAddress(deviceId); 1304 } catch (RemoteException e) { 1305 throw e.rethrowFromSystemServer(); 1306 } 1307 } 1308 1309 /** 1310 * @see InputManager#cancelCurrentTouch() 1311 */ cancelCurrentTouch()1312 public void cancelCurrentTouch() { 1313 try { 1314 mIm.cancelCurrentTouch(); 1315 } catch (RemoteException e) { 1316 throw e.rethrowFromSystemServer(); 1317 } 1318 } 1319 1320 /** 1321 * @see InputManager#pilferPointers(IBinder) 1322 */ 1323 @RequiresPermission(Manifest.permission.MONITOR_INPUT) pilferPointers(IBinder inputChannelToken)1324 public void pilferPointers(IBinder inputChannelToken) { 1325 try { 1326 mIm.pilferPointers(inputChannelToken); 1327 } catch (RemoteException e) { 1328 throw e.rethrowFromSystemServer(); 1329 } 1330 } 1331 } 1332