1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.input; 18 19 import static android.provider.DeviceConfig.NAMESPACE_INPUT_NATIVE_BOOT; 20 import static android.view.KeyEvent.KEYCODE_UNKNOWN; 21 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; 22 23 import android.Manifest; 24 import android.annotation.EnforcePermission; 25 import android.annotation.NonNull; 26 import android.annotation.Nullable; 27 import android.annotation.UserIdInt; 28 import android.app.ActivityManagerInternal; 29 import android.bluetooth.BluetoothAdapter; 30 import android.bluetooth.BluetoothDevice; 31 import android.content.BroadcastReceiver; 32 import android.content.Context; 33 import android.content.Intent; 34 import android.content.IntentFilter; 35 import android.content.pm.PackageManager; 36 import android.graphics.PixelFormat; 37 import android.graphics.PointF; 38 import android.hardware.SensorPrivacyManager; 39 import android.hardware.SensorPrivacyManager.Sensors; 40 import android.hardware.SensorPrivacyManagerInternal; 41 import android.hardware.display.DisplayManagerInternal; 42 import android.hardware.display.DisplayViewport; 43 import android.hardware.input.HostUsiVersion; 44 import android.hardware.input.IInputDeviceBatteryListener; 45 import android.hardware.input.IInputDeviceBatteryState; 46 import android.hardware.input.IInputDevicesChangedListener; 47 import android.hardware.input.IInputManager; 48 import android.hardware.input.IInputSensorEventListener; 49 import android.hardware.input.IKeyboardBacklightListener; 50 import android.hardware.input.IStickyModifierStateListener; 51 import android.hardware.input.ITabletModeChangedListener; 52 import android.hardware.input.InputDeviceIdentifier; 53 import android.hardware.input.InputManager; 54 import android.hardware.input.InputSensorInfo; 55 import android.hardware.input.InputSettings; 56 import android.hardware.input.KeyboardLayout; 57 import android.hardware.input.KeyboardLayoutSelectionResult; 58 import android.hardware.input.TouchCalibration; 59 import android.hardware.lights.Light; 60 import android.hardware.lights.LightState; 61 import android.media.AudioManager; 62 import android.os.Binder; 63 import android.os.CombinedVibration; 64 import android.os.Environment; 65 import android.os.Handler; 66 import android.os.IBinder; 67 import android.os.IVibratorStateListener; 68 import android.os.InputEventInjectionResult; 69 import android.os.InputEventInjectionSync; 70 import android.os.Looper; 71 import android.os.Message; 72 import android.os.Process; 73 import android.os.RemoteCallbackList; 74 import android.os.RemoteException; 75 import android.os.ResultReceiver; 76 import android.os.ShellCallback; 77 import android.os.UserHandle; 78 import android.os.VibrationEffect; 79 import android.os.vibrator.StepSegment; 80 import android.os.vibrator.VibrationEffectSegment; 81 import android.provider.DeviceConfig; 82 import android.text.TextUtils; 83 import android.util.ArrayMap; 84 import android.util.IndentingPrintWriter; 85 import android.util.Log; 86 import android.util.Slog; 87 import android.util.SparseArray; 88 import android.util.SparseBooleanArray; 89 import android.view.Display; 90 import android.view.IInputFilter; 91 import android.view.IInputFilterHost; 92 import android.view.IInputMonitorHost; 93 import android.view.InputApplicationHandle; 94 import android.view.InputChannel; 95 import android.view.InputDevice; 96 import android.view.InputEvent; 97 import android.view.InputMonitor; 98 import android.view.KeyCharacterMap; 99 import android.view.KeyEvent; 100 import android.view.PointerIcon; 101 import android.view.Surface; 102 import android.view.SurfaceControl; 103 import android.view.VerifiedInputEvent; 104 import android.view.ViewConfiguration; 105 import android.view.WindowManager; 106 import android.view.inputmethod.InputMethodInfo; 107 import android.view.inputmethod.InputMethodSubtype; 108 109 import com.android.internal.R; 110 import com.android.internal.annotations.GuardedBy; 111 import com.android.internal.annotations.VisibleForTesting; 112 import com.android.internal.inputmethod.InputMethodSubtypeHandle; 113 import com.android.internal.os.SomeArgs; 114 import com.android.internal.util.DumpUtils; 115 import com.android.internal.util.Preconditions; 116 import com.android.server.DisplayThread; 117 import com.android.server.LocalServices; 118 import com.android.server.Watchdog; 119 import com.android.server.input.InputManagerInternal.LidSwitchCallback; 120 import com.android.server.input.debug.FocusEventDebugView; 121 import com.android.server.inputmethod.InputMethodManagerInternal; 122 import com.android.server.policy.WindowManagerPolicy; 123 124 import libcore.io.IoUtils; 125 126 import java.io.File; 127 import java.io.FileDescriptor; 128 import java.io.FileInputStream; 129 import java.io.FileNotFoundException; 130 import java.io.FileWriter; 131 import java.io.IOException; 132 import java.io.InputStream; 133 import java.io.PrintWriter; 134 import java.util.ArrayList; 135 import java.util.Arrays; 136 import java.util.HashMap; 137 import java.util.List; 138 import java.util.Map; 139 import java.util.Objects; 140 import java.util.OptionalInt; 141 import java.util.function.Consumer; 142 143 /** The system implementation of {@link IInputManager} that manages input devices. */ 144 public class InputManagerService extends IInputManager.Stub 145 implements Watchdog.Monitor { 146 static final String TAG = "InputManager"; 147 // To enable these logs, run: 'adb shell setprop log.tag.InputManager DEBUG' (requires restart) 148 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); 149 150 private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml"; 151 private static final String PORT_ASSOCIATIONS_PATH = "etc/input-port-associations.xml"; 152 153 // Feature flag name for the strategy to be used in VelocityTracker 154 private static final String VELOCITYTRACKER_STRATEGY_PROPERTY = "velocitytracker_strategy"; 155 156 private static final int MSG_DELIVER_INPUT_DEVICES_CHANGED = 1; 157 private static final int MSG_RELOAD_DEVICE_ALIASES = 2; 158 private static final int MSG_DELIVER_TABLET_MODE_CHANGED = 3; 159 160 private static final int DEFAULT_VIBRATION_MAGNITUDE = 192; 161 private static final AdditionalDisplayInputProperties 162 DEFAULT_ADDITIONAL_DISPLAY_INPUT_PROPERTIES = new AdditionalDisplayInputProperties(); 163 164 private final NativeInputManagerService mNative; 165 166 private final Context mContext; 167 private final InputManagerHandler mHandler; 168 private DisplayManagerInternal mDisplayManagerInternal; 169 170 private InputMethodManagerInternal mInputMethodManagerInternal; 171 172 private final File mDoubleTouchGestureEnableFile; 173 174 private WindowManagerCallbacks mWindowManagerCallbacks; 175 private WiredAccessoryCallbacks mWiredAccessoryCallbacks; 176 private boolean mSystemReady; 177 178 private final Object mTabletModeLock = new Object(); 179 // List of currently registered tablet mode changed listeners by process id 180 @GuardedBy("mTabletModeLock") 181 private final SparseArray<TabletModeChangedListenerRecord> mTabletModeChangedListeners = 182 new SparseArray<>(); 183 private final List<TabletModeChangedListenerRecord> mTempTabletModeChangedListenersToNotify = 184 new ArrayList<>(); 185 186 private final Object mSensorEventLock = new Object(); 187 // List of currently registered sensor event listeners by process id 188 @GuardedBy("mSensorEventLock") 189 private final SparseArray<SensorEventListenerRecord> mSensorEventListeners = 190 new SparseArray<>(); 191 private final List<SensorEventListenerRecord> mSensorEventListenersToNotify = 192 new ArrayList<>(); 193 private final List<SensorEventListenerRecord> mSensorAccuracyListenersToNotify = 194 new ArrayList<>(); 195 196 // Persistent data store. Must be locked each time during use. 197 private final PersistentDataStore mDataStore = new PersistentDataStore(); 198 199 // List of currently registered input devices changed listeners by process id. 200 private final Object mInputDevicesLock = new Object(); 201 @GuardedBy("mInputDevicesLock") 202 private boolean mInputDevicesChangedPending; 203 @GuardedBy("mInputDevicesLock") 204 private InputDevice[] mInputDevices = new InputDevice[0]; 205 @GuardedBy("mInputDevicesLock") 206 private final SparseArray<InputDevicesChangedListenerRecord> mInputDevicesChangedListeners = 207 new SparseArray<>(); 208 private final ArrayList<InputDevicesChangedListenerRecord> 209 mTempInputDevicesChangedListenersToNotify = new ArrayList<>(); // handler thread only 210 211 // State for vibrator tokens. 212 private final Object mVibratorLock = new Object(); 213 private final Map<IBinder, VibratorToken> mVibratorTokens = new ArrayMap<>(); 214 private int mNextVibratorTokenValue; 215 216 // List of currently registered vibrator state changed listeners by device id. 217 @GuardedBy("mVibratorLock") 218 private final SparseArray<RemoteCallbackList<IVibratorStateListener>> mVibratorStateListeners = 219 new SparseArray<>(); 220 // List of vibrator states by device id. 221 @GuardedBy("mVibratorLock") 222 private final SparseBooleanArray mIsVibrating = new SparseBooleanArray(); 223 private final Object mLightLock = new Object(); 224 // State for light tokens. A light token marks a lights manager session, it is generated 225 // by light session open() and deleted in session close(). 226 // When lights session requests light states, the token will be used to find the light session. 227 @GuardedBy("mLightLock") 228 private final ArrayMap<IBinder, LightSession> mLightSessions = new ArrayMap<>(); 229 230 // State for lid switch 231 // Lock for the lid switch state. Held when triggering callbacks to guarantee lid switch events 232 // are delivered in order. For ex, when a new lid switch callback is registered the lock is held 233 // while the callback is processing the initial lid switch event which guarantees that any 234 // events that occur at the same time are delivered after the callback has returned. 235 private final Object mLidSwitchLock = new Object(); 236 @GuardedBy("mLidSwitchLock") 237 private final List<LidSwitchCallback> mLidSwitchCallbacks = new ArrayList<>(); 238 239 // State for the currently installed input filter. 240 final Object mInputFilterLock = new Object(); 241 @GuardedBy("mInputFilterLock") 242 IInputFilter mInputFilter; 243 @GuardedBy("mInputFilterLock") 244 InputFilterHost mInputFilterHost; 245 246 // The associations of input devices to displays by port. Maps from input device port (String) 247 // to display id (int). Currently only accessed by InputReader. 248 private final Map<String, Integer> mStaticAssociations; 249 private final Object mAssociationsLock = new Object(); 250 @GuardedBy("mAssociationsLock") 251 private final Map<String, Integer> mRuntimeAssociations = new ArrayMap<>(); 252 253 // The associations of input devices to displays by port. Maps from {InputDevice#mName} (String) 254 // to {DisplayInfo#uniqueId} (String) so that events from the Input Device go to a 255 // specific display. 256 @GuardedBy("mAssociationsLock") 257 private final Map<String, String> mUniqueIdAssociationsByPort = new ArrayMap<>(); 258 259 // The associations of input devices to displays by descriptor. Maps from 260 // {InputDevice#mDescriptor} to {DisplayInfo#uniqueId} (String) so that events from the 261 // input device go to a specific display. 262 @GuardedBy("mAssociationsLock") 263 private final Map<String, String> mUniqueIdAssociationsByDescriptor = new ArrayMap<>(); 264 265 // The map from input port (String) to the keyboard layout identifiers (comma separated string 266 // containing language tag and layout type) associated with the corresponding keyboard device. 267 // Currently only accessed by InputReader. 268 @GuardedBy("mAssociationsLock") 269 private final Map<String, String> mKeyboardLayoutAssociations = new ArrayMap<>(); 270 271 // Stores input ports associated with device types. For example, adding an association 272 // {"123", "touchNavigation"} here would mean that a touch device appearing at port "123" would 273 // enumerate as a "touch navigation" device rather than the default "touchpad as a mouse 274 // pointer" device. 275 @GuardedBy("mAssociationsLock") 276 private final Map<String, String> mDeviceTypeAssociations = new ArrayMap<>(); 277 278 // Guards per-display input properties and properties relating to the mouse pointer. 279 // Threads can wait on this lock to be notified the next time the display on which the mouse 280 // pointer is shown has changed. 281 // WARNING: Do not call other services outside of input while holding this lock. 282 private final Object mAdditionalDisplayInputPropertiesLock = new Object(); 283 284 @GuardedBy("mAdditionalDisplayInputPropertiesLock") 285 private final SparseArray<AdditionalDisplayInputProperties> mAdditionalDisplayInputProperties = 286 new SparseArray<>(); 287 288 // Holds all the registered gesture monitors that are implemented as spy windows. The spy 289 // windows are mapped by their InputChannel tokens. 290 @GuardedBy("mInputMonitors") 291 final Map<IBinder, GestureMonitorSpyWindow> mInputMonitors = new HashMap<>(); 292 293 // Watches for settings changes and updates the native side appropriately. 294 private final InputSettingsObserver mSettingsObserver; 295 296 // Manages Keyboard layouts for Physical keyboards 297 private final KeyboardLayoutManager mKeyboardLayoutManager; 298 299 // Manages battery state for input devices. 300 private final BatteryController mBatteryController; 301 302 // Manages Keyboard backlight 303 private final KeyboardBacklightControllerInterface mKeyboardBacklightController; 304 305 // Manages Sticky modifier state 306 private final StickyModifierStateController mStickyModifierStateController; 307 308 // Manages Keyboard microphone mute led 309 private final KeyboardLedController mKeyboardLedController; 310 311 // Manages Keyboard modifier keys remapping 312 private final KeyRemapper mKeyRemapper; 313 314 // Manages loading PointerIcons 315 private final PointerIconCache mPointerIconCache; 316 317 // Maximum number of milliseconds to wait for input event injection. 318 private static final int INJECTION_TIMEOUT_MILLIS = 30 * 1000; 319 320 // Key states (may be returned by queries about the current state of a 321 // particular key code, scan code or switch). 322 323 /** The key state is unknown or the requested key itself is not supported. */ 324 public static final int KEY_STATE_UNKNOWN = -1; 325 326 /** The key is up. /*/ 327 public static final int KEY_STATE_UP = 0; 328 329 /** The key is down. */ 330 public static final int KEY_STATE_DOWN = 1; 331 332 /** The key is down but is a virtual key press that is being emulated by the system. */ 333 public static final int KEY_STATE_VIRTUAL = 2; 334 335 /** Scan code: Mouse / trackball button. */ 336 public static final int BTN_MOUSE = 0x110; 337 338 // Switch code values must match bionic/libc/kernel/common/linux/input.h 339 /** Switch code: Lid switch. When set, lid is shut. */ 340 public static final int SW_LID = 0x00; 341 342 /** Switch code: Tablet mode switch. 343 * When set, the device is in tablet mode (i.e. no keyboard is connected). 344 */ 345 public static final int SW_TABLET_MODE = 0x01; 346 347 /** Switch code: Keypad slide. When set, keyboard is exposed. */ 348 public static final int SW_KEYPAD_SLIDE = 0x0a; 349 350 /** Switch code: Headphone. When set, headphone is inserted. */ 351 public static final int SW_HEADPHONE_INSERT = 0x02; 352 353 /** Switch code: Microphone. When set, microphone is inserted. */ 354 public static final int SW_MICROPHONE_INSERT = 0x04; 355 356 /** Switch code: Line out. When set, Line out (hi-Z) is inserted. */ 357 public static final int SW_LINEOUT_INSERT = 0x06; 358 359 /** Switch code: Headphone/Microphone Jack. When set, something is inserted. */ 360 public static final int SW_JACK_PHYSICAL_INSERT = 0x07; 361 362 /** Switch code: Camera lens cover. When set the lens is covered. */ 363 public static final int SW_CAMERA_LENS_COVER = 0x09; 364 365 /** Switch code: Microphone. When set, the mic is muted. */ 366 public static final int SW_MUTE_DEVICE = 0x0e; 367 368 public static final int SW_LID_BIT = 1 << SW_LID; 369 public static final int SW_TABLET_MODE_BIT = 1 << SW_TABLET_MODE; 370 public static final int SW_KEYPAD_SLIDE_BIT = 1 << SW_KEYPAD_SLIDE; 371 public static final int SW_HEADPHONE_INSERT_BIT = 1 << SW_HEADPHONE_INSERT; 372 public static final int SW_MICROPHONE_INSERT_BIT = 1 << SW_MICROPHONE_INSERT; 373 public static final int SW_LINEOUT_INSERT_BIT = 1 << SW_LINEOUT_INSERT; 374 public static final int SW_JACK_PHYSICAL_INSERT_BIT = 1 << SW_JACK_PHYSICAL_INSERT; 375 public static final int SW_JACK_BITS = 376 SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT | SW_JACK_PHYSICAL_INSERT_BIT | SW_LINEOUT_INSERT_BIT; 377 public static final int SW_CAMERA_LENS_COVER_BIT = 1 << SW_CAMERA_LENS_COVER; 378 public static final int SW_MUTE_DEVICE_BIT = 1 << SW_MUTE_DEVICE; 379 380 // The following are layer numbers used for z-ordering the input overlay layers on the display. 381 // This is used for ordering layers inside {@code DisplayContent#getInputOverlayLayer()}. 382 // 383 // The layer where gesture monitors are added. 384 public static final int INPUT_OVERLAY_LAYER_GESTURE_MONITOR = 1; 385 // Place the handwriting layer above gesture monitors so that styluses cannot trigger 386 // system gestures (e.g. navigation bar, edge-back, etc) while there is an active 387 // handwriting session. 388 public static final int INPUT_OVERLAY_LAYER_HANDWRITING_SURFACE = 2; 389 390 391 private final String mVelocityTrackerStrategy; 392 393 /** Whether to use the dev/input/event or uevent subsystem for the audio jack. */ 394 final boolean mUseDevInputEventForAudioJack; 395 396 private final Object mFocusEventDebugViewLock = new Object(); 397 @GuardedBy("mFocusEventDebugViewLock") 398 @Nullable 399 private FocusEventDebugView mFocusEventDebugView; 400 private boolean mShowKeyPresses = false; 401 private boolean mShowRotaryInput = false; 402 403 /** Point of injection for test dependencies. */ 404 @VisibleForTesting 405 static class Injector { 406 private final Context mContext; 407 private final Looper mLooper; 408 private final UEventManager mUEventManager; 409 Injector(Context context, Looper looper, UEventManager uEventManager)410 Injector(Context context, Looper looper, UEventManager uEventManager) { 411 mContext = context; 412 mLooper = looper; 413 mUEventManager = uEventManager; 414 } 415 getContext()416 Context getContext() { 417 return mContext; 418 } 419 getLooper()420 Looper getLooper() { 421 return mLooper; 422 } 423 getUEventManager()424 UEventManager getUEventManager() { 425 return mUEventManager; 426 } 427 getNativeService(InputManagerService service)428 NativeInputManagerService getNativeService(InputManagerService service) { 429 return new NativeInputManagerService.NativeImpl(service, mLooper.getQueue()); 430 } 431 registerLocalService(InputManagerInternal localService)432 void registerLocalService(InputManagerInternal localService) { 433 LocalServices.addService(InputManagerInternal.class, localService); 434 } 435 } 436 InputManagerService(Context context)437 public InputManagerService(Context context) { 438 this(new Injector(context, DisplayThread.get().getLooper(), new UEventManager() {})); 439 } 440 441 @VisibleForTesting InputManagerService(Injector injector)442 InputManagerService(Injector injector) { 443 // The static association map is accessed by both java and native code, so it must be 444 // initialized before initializing the native service. 445 mStaticAssociations = loadStaticInputPortAssociations(); 446 447 mContext = injector.getContext(); 448 mHandler = new InputManagerHandler(injector.getLooper()); 449 mNative = injector.getNativeService(this); 450 mSettingsObserver = new InputSettingsObserver(mContext, mHandler, this, mNative); 451 mKeyboardLayoutManager = new KeyboardLayoutManager(mContext, mNative, mDataStore, 452 injector.getLooper()); 453 mBatteryController = new BatteryController(mContext, mNative, injector.getLooper(), 454 injector.getUEventManager()); 455 mKeyboardBacklightController = InputFeatureFlagProvider.isKeyboardBacklightControlEnabled() 456 ? new KeyboardBacklightController(mContext, mNative, mDataStore, 457 injector.getLooper(), injector.getUEventManager()) 458 : new KeyboardBacklightControllerInterface() {}; 459 mStickyModifierStateController = new StickyModifierStateController(); 460 mKeyboardLedController = new KeyboardLedController(mContext, injector.getLooper(), 461 mNative); 462 mKeyRemapper = new KeyRemapper(mContext, mNative, mDataStore, injector.getLooper()); 463 mPointerIconCache = new PointerIconCache(mContext, mNative); 464 465 mUseDevInputEventForAudioJack = 466 mContext.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack); 467 Slog.i(TAG, "Initializing input manager, mUseDevInputEventForAudioJack=" 468 + mUseDevInputEventForAudioJack); 469 470 String doubleTouchGestureEnablePath = mContext.getResources().getString( 471 R.string.config_doubleTouchGestureEnableFile); 472 mDoubleTouchGestureEnableFile = TextUtils.isEmpty(doubleTouchGestureEnablePath) ? null : 473 new File(doubleTouchGestureEnablePath); 474 475 mVelocityTrackerStrategy = DeviceConfig.getProperty( 476 NAMESPACE_INPUT_NATIVE_BOOT, VELOCITYTRACKER_STRATEGY_PROPERTY); 477 478 injector.registerLocalService(new LocalService()); 479 } 480 setWindowManagerCallbacks(WindowManagerCallbacks callbacks)481 public void setWindowManagerCallbacks(WindowManagerCallbacks callbacks) { 482 if (mWindowManagerCallbacks != null) { 483 unregisterLidSwitchCallbackInternal(mWindowManagerCallbacks); 484 } 485 mWindowManagerCallbacks = callbacks; 486 registerLidSwitchCallbackInternal(mWindowManagerCallbacks); 487 } 488 setWiredAccessoryCallbacks(WiredAccessoryCallbacks callbacks)489 public void setWiredAccessoryCallbacks(WiredAccessoryCallbacks callbacks) { 490 mWiredAccessoryCallbacks = callbacks; 491 } 492 registerLidSwitchCallbackInternal(@onNull LidSwitchCallback callback)493 void registerLidSwitchCallbackInternal(@NonNull LidSwitchCallback callback) { 494 synchronized (mLidSwitchLock) { 495 mLidSwitchCallbacks.add(callback); 496 497 // Skip triggering the initial callback if the system is not yet ready as the switch 498 // state will be reported as KEY_STATE_UNKNOWN. The callback will be triggered in 499 // systemRunning(). 500 if (mSystemReady) { 501 boolean lidOpen = getSwitchState(-1 /* deviceId */, InputDevice.SOURCE_ANY, SW_LID) 502 == KEY_STATE_UP; 503 callback.notifyLidSwitchChanged(0 /* whenNanos */, lidOpen); 504 } 505 } 506 } 507 unregisterLidSwitchCallbackInternal(@onNull LidSwitchCallback callback)508 void unregisterLidSwitchCallbackInternal(@NonNull LidSwitchCallback callback) { 509 synchronized (mLidSwitchLock) { 510 mLidSwitchCallbacks.remove(callback); 511 } 512 } 513 start()514 public void start() { 515 Slog.i(TAG, "Starting input manager"); 516 mNative.start(); 517 518 // Add ourselves to the Watchdog monitors. 519 Watchdog.getInstance().addMonitor(this); 520 } 521 522 // TODO(BT) Pass in parameter for bluetooth system systemRunning()523 public void systemRunning() { 524 if (DEBUG) { 525 Slog.d(TAG, "System ready."); 526 } 527 528 mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); 529 mInputMethodManagerInternal = 530 LocalServices.getService(InputMethodManagerInternal.class); 531 532 mSettingsObserver.registerAndUpdate(); 533 534 synchronized (mLidSwitchLock) { 535 mSystemReady = true; 536 537 // Send the initial lid switch state to any callback registered before the system was 538 // ready. 539 int switchState = getSwitchState(-1 /* deviceId */, InputDevice.SOURCE_ANY, SW_LID); 540 for (int i = 0; i < mLidSwitchCallbacks.size(); i++) { 541 LidSwitchCallback callback = mLidSwitchCallbacks.get(i); 542 callback.notifyLidSwitchChanged(0 /* whenNanos */, switchState == KEY_STATE_UP); 543 } 544 } 545 546 // Set the HW mic toggle switch state 547 final int micMuteState = getSwitchState(-1 /* deviceId */, InputDevice.SOURCE_ANY, 548 SW_MUTE_DEVICE); 549 if (micMuteState == InputManager.SWITCH_STATE_ON) { 550 setSensorPrivacy(Sensors.MICROPHONE, true); 551 } 552 // Set the HW camera toggle switch state 553 final int cameraMuteState = getSwitchState(-1 /* deviceId */, InputDevice.SOURCE_ANY, 554 SW_CAMERA_LENS_COVER); 555 if (cameraMuteState == InputManager.SWITCH_STATE_ON) { 556 setSensorPrivacy(Sensors.CAMERA, true); 557 } 558 559 IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_ALIAS_CHANGED); 560 mContext.registerReceiver(new BroadcastReceiver() { 561 @Override 562 public void onReceive(Context context, Intent intent) { 563 reloadDeviceAliases(); 564 } 565 }, filter, null, mHandler); 566 567 mHandler.sendEmptyMessage(MSG_RELOAD_DEVICE_ALIASES); 568 569 if (mWiredAccessoryCallbacks != null) { 570 mWiredAccessoryCallbacks.systemReady(); 571 } 572 573 mKeyboardLayoutManager.systemRunning(); 574 mBatteryController.systemRunning(); 575 mKeyboardBacklightController.systemRunning(); 576 mKeyboardLedController.systemRunning(); 577 mKeyRemapper.systemRunning(); 578 mPointerIconCache.systemRunning(); 579 } 580 reloadDeviceAliases()581 private void reloadDeviceAliases() { 582 if (DEBUG) { 583 Slog.d(TAG, "Reloading device names."); 584 } 585 mNative.reloadDeviceAliases(); 586 } 587 setDisplayViewportsInternal(List<DisplayViewport> viewports)588 private void setDisplayViewportsInternal(List<DisplayViewport> viewports) { 589 final DisplayViewport[] vArray = new DisplayViewport[viewports.size()]; 590 for (int i = viewports.size() - 1; i >= 0; --i) { 591 vArray[i] = viewports.get(i); 592 } 593 mNative.setDisplayViewports(vArray); 594 595 // Attempt to update the default pointer display when the viewports change. 596 // Take care to not make calls to window manager while holding internal locks. 597 mNative.setPointerDisplayId(mWindowManagerCallbacks.getPointerDisplayId()); 598 } 599 600 /** 601 * Gets the current state of a key or button by key code. 602 * @param deviceId The input device id, or -1 to consult all devices. 603 * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to 604 * consider all input sources. An input device is consulted if at least one of its 605 * non-class input source bits matches the specified source mask. 606 * @param keyCode The key code to check. 607 * @return The key state. 608 */ getKeyCodeState(int deviceId, int sourceMask, int keyCode)609 public int getKeyCodeState(int deviceId, int sourceMask, int keyCode) { 610 return mNative.getKeyCodeState(deviceId, sourceMask, keyCode); 611 } 612 613 /** 614 * Gets the current state of a key or button by scan code. 615 * @param deviceId The input device id, or -1 to consult all devices. 616 * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to 617 * consider all input sources. An input device is consulted if at least one of its 618 * non-class input source bits matches the specified source mask. 619 * @param scanCode The scan code to check. 620 * @return The key state. 621 */ getScanCodeState(int deviceId, int sourceMask, int scanCode)622 public int getScanCodeState(int deviceId, int sourceMask, int scanCode) { 623 return mNative.getScanCodeState(deviceId, sourceMask, scanCode); 624 } 625 626 /** 627 * Gets the current state of a switch by switch code. 628 * @param deviceId The input device id, or -1 to consult all devices. 629 * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to 630 * consider all input sources. An input device is consulted if at least one of its 631 * non-class input source bits matches the specified source mask. 632 * @param switchCode The switch code to check. 633 * @return The switch state. 634 */ getSwitchState(int deviceId, int sourceMask, int switchCode)635 public int getSwitchState(int deviceId, int sourceMask, int switchCode) { 636 return mNative.getSwitchState(deviceId, sourceMask, switchCode); 637 } 638 639 /** 640 * Determines whether the specified key codes are supported by a particular device. 641 * @param deviceId The input device id, or -1 to consult all devices. 642 * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to 643 * consider all input sources. An input device is consulted if at least one of its 644 * non-class input source bits matches the specified source mask. 645 * @param keyCodes The array of key codes to check. 646 * @param keyExists An array at least as large as keyCodes whose entries will be set 647 * to true or false based on the presence or absence of support for the corresponding 648 * key codes. 649 * @return True if the lookup was successful, false otherwise. 650 */ 651 @Override // Binder call hasKeys(int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists)652 public boolean hasKeys(int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists) { 653 Objects.requireNonNull(keyCodes, "keyCodes must not be null"); 654 Objects.requireNonNull(keyExists, "keyExists must not be null"); 655 if (keyExists.length < keyCodes.length) { 656 throw new IllegalArgumentException("keyExists must be at least as large as keyCodes"); 657 } 658 659 return mNative.hasKeys(deviceId, sourceMask, keyCodes, keyExists); 660 } 661 662 /** 663 * Returns the keyCode generated by the specified location on a US keyboard layout. 664 * This takes into consideration the currently active keyboard layout. 665 * 666 * @param deviceId The input device id. 667 * @param locationKeyCode The location of a key on a US keyboard layout. 668 * @return The KeyCode this physical key location produces. 669 */ 670 @Override // Binder call getKeyCodeForKeyLocation(int deviceId, int locationKeyCode)671 public int getKeyCodeForKeyLocation(int deviceId, int locationKeyCode) { 672 if (locationKeyCode <= KEYCODE_UNKNOWN || locationKeyCode > KeyEvent.getMaxKeyCode()) { 673 return KEYCODE_UNKNOWN; 674 } 675 return mNative.getKeyCodeForKeyLocation(deviceId, locationKeyCode); 676 } 677 678 @Override // Binder call getKeyCharacterMap(@onNull String layoutDescriptor)679 public KeyCharacterMap getKeyCharacterMap(@NonNull String layoutDescriptor) { 680 Objects.requireNonNull(layoutDescriptor, "layoutDescriptor must not be null"); 681 return mKeyboardLayoutManager.getKeyCharacterMap(layoutDescriptor); 682 } 683 684 /** 685 * Transfer the current touch gesture to the provided window. 686 * 687 * @param destChannelToken The token of the window or input channel that should receive the 688 * gesture 689 * @return True if the transfer succeeded, false if there was no active touch gesture happening 690 * @deprecated Use {@link #transferTouchGesture(IBinder, IBinder)} 691 */ 692 @Deprecated transferTouch(IBinder destChannelToken, int displayId)693 public boolean transferTouch(IBinder destChannelToken, int displayId) { 694 // TODO(b/162194035): Replace this with a SPY window 695 Objects.requireNonNull(destChannelToken, "destChannelToken must not be null"); 696 return mNative.transferTouch(destChannelToken, displayId); 697 } 698 699 /** 700 * Creates an input channel that will receive all input from the input dispatcher. 701 * @param inputChannelName The input channel name. 702 * @param displayId Target display id. 703 * @return The input channel. 704 */ monitorInput(String inputChannelName, int displayId)705 public InputChannel monitorInput(String inputChannelName, int displayId) { 706 Objects.requireNonNull(inputChannelName, "inputChannelName not be null"); 707 708 if (displayId < Display.DEFAULT_DISPLAY) { 709 throw new IllegalArgumentException("displayId must >= 0."); 710 } 711 712 return mNative.createInputMonitor(displayId, inputChannelName, Binder.getCallingPid()); 713 } 714 715 @NonNull createSpyWindowGestureMonitor(IBinder monitorToken, String name, SurfaceControl sc, int displayId, int pid, int uid)716 private InputChannel createSpyWindowGestureMonitor(IBinder monitorToken, String name, 717 SurfaceControl sc, int displayId, int pid, int uid) { 718 final InputChannel channel = createInputChannel(name); 719 720 try { 721 monitorToken.linkToDeath(() -> removeSpyWindowGestureMonitor(channel.getToken()), 0); 722 } catch (RemoteException e) { 723 Slog.i(TAG, "Client died before '" + name + "' could be created."); 724 return null; 725 } 726 synchronized (mInputMonitors) { 727 mInputMonitors.put(channel.getToken(), 728 new GestureMonitorSpyWindow(monitorToken, name, displayId, pid, uid, sc, 729 channel)); 730 } 731 732 final InputChannel outInputChannel = new InputChannel(); 733 channel.copyTo(outInputChannel); 734 return outInputChannel; 735 } 736 removeSpyWindowGestureMonitor(IBinder inputChannelToken)737 private void removeSpyWindowGestureMonitor(IBinder inputChannelToken) { 738 final GestureMonitorSpyWindow monitor; 739 synchronized (mInputMonitors) { 740 monitor = mInputMonitors.remove(inputChannelToken); 741 } 742 removeInputChannel(inputChannelToken); 743 if (monitor == null) return; 744 monitor.remove(); 745 } 746 747 /** 748 * Creates an input monitor that will receive pointer events for the purposes of system-wide 749 * gesture interpretation. 750 * 751 * @param requestedName The input channel name. 752 * @param displayId Target display id. 753 * @return The input channel. 754 */ 755 @Override // Binder call monitorGestureInput(IBinder monitorToken, @NonNull String requestedName, int displayId)756 public InputMonitor monitorGestureInput(IBinder monitorToken, @NonNull String requestedName, 757 int displayId) { 758 if (!checkCallingPermission(android.Manifest.permission.MONITOR_INPUT, 759 "monitorGestureInput()")) { 760 throw new SecurityException("Requires MONITOR_INPUT permission"); 761 } 762 Objects.requireNonNull(requestedName, "name must not be null."); 763 Objects.requireNonNull(monitorToken, "token must not be null."); 764 765 if (displayId < Display.DEFAULT_DISPLAY) { 766 throw new IllegalArgumentException("displayId must >= 0."); 767 } 768 final String name = "[Gesture Monitor] " + requestedName; 769 final int pid = Binder.getCallingPid(); 770 final int uid = Binder.getCallingUid(); 771 772 final long ident = Binder.clearCallingIdentity(); 773 try { 774 final SurfaceControl sc = mWindowManagerCallbacks.createSurfaceForGestureMonitor(name, 775 displayId); 776 if (sc == null) { 777 throw new IllegalArgumentException( 778 "Could not create gesture monitor surface on display: " + displayId); 779 } 780 781 final InputChannel inputChannel = createSpyWindowGestureMonitor( 782 monitorToken, name, sc, displayId, pid, uid); 783 return new InputMonitor(inputChannel, 784 new InputMonitorHost(inputChannel.getToken()), 785 new SurfaceControl(sc, "IMS.monitorGestureInput")); 786 } finally { 787 Binder.restoreCallingIdentity(ident); 788 } 789 } 790 791 /** 792 * Creates an input channel to be used as an input event target. 793 * 794 * @param name The name of this input channel 795 */ createInputChannel(String name)796 public InputChannel createInputChannel(String name) { 797 return mNative.createInputChannel(name); 798 } 799 800 /** 801 * Removes an input channel. 802 * @param connectionToken The input channel to unregister. 803 */ removeInputChannel(IBinder connectionToken)804 public void removeInputChannel(IBinder connectionToken) { 805 Objects.requireNonNull(connectionToken, "connectionToken must not be null"); 806 mNative.removeInputChannel(connectionToken); 807 } 808 809 /** 810 * Sets an input filter that will receive all input events before they are dispatched. 811 * The input filter may then reinterpret input events or inject new ones. 812 * 813 * To ensure consistency, the input dispatcher automatically drops all events 814 * in progress whenever an input filter is installed or uninstalled. After an input 815 * filter is uninstalled, it can no longer send input events unless it is reinstalled. 816 * Any events it attempts to send after it has been uninstalled will be dropped. 817 * 818 * @param filter The input filter, or null to remove the current filter. 819 */ setInputFilter(IInputFilter filter)820 public void setInputFilter(IInputFilter filter) { 821 synchronized (mInputFilterLock) { 822 final IInputFilter oldFilter = mInputFilter; 823 if (oldFilter == filter) { 824 return; // nothing to do 825 } 826 827 if (oldFilter != null) { 828 mInputFilter = null; 829 mInputFilterHost.disconnectLocked(); 830 mInputFilterHost = null; 831 try { 832 oldFilter.uninstall(); 833 } catch (RemoteException re) { 834 /* ignore */ 835 } 836 } 837 838 if (filter != null) { 839 mInputFilter = filter; 840 mInputFilterHost = new InputFilterHost(); 841 try { 842 filter.install(mInputFilterHost); 843 } catch (RemoteException re) { 844 /* ignore */ 845 } 846 } 847 848 mNative.setInputFilterEnabled(filter != null); 849 } 850 } 851 852 /** 853 * Set the state of the touch mode. 854 * 855 * WindowManager remains the source of truth of the touch mode state. 856 * However, we need to keep a copy of this state in input. 857 * 858 * The apps determine the touch mode state. Therefore, a single app will 859 * affect the global state. That state change needs to be propagated to 860 * other apps, when they become focused. 861 * 862 * When input dispatches focus to the apps, the touch mode state 863 * will be sent together with the focus change (but each one in its own event). 864 * 865 * @param inTouchMode true if the device is in touch mode 866 * @param pid the pid of the process that requested to switch touch mode state 867 * @param uid the uid of the process that requested to switch touch mode state 868 * @param hasPermission if set to {@code true} then no further authorization will be performed 869 * @param displayId the target display (ignored if device is configured with per display 870 * touch mode enabled) 871 * @return {@code true} if the touch mode was successfully changed, {@code false} otherwise 872 */ setInTouchMode(boolean inTouchMode, int pid, int uid, boolean hasPermission, int displayId)873 public boolean setInTouchMode(boolean inTouchMode, int pid, int uid, boolean hasPermission, 874 int displayId) { 875 return mNative.setInTouchMode(inTouchMode, pid, uid, hasPermission, displayId); 876 } 877 878 @Override // Binder call injectInputEvent(InputEvent event, int mode)879 public boolean injectInputEvent(InputEvent event, int mode) { 880 return injectInputEventToTarget(event, mode, Process.INVALID_UID); 881 } 882 883 @Override // Binder call injectInputEventToTarget(InputEvent event, int mode, int targetUid)884 public boolean injectInputEventToTarget(InputEvent event, int mode, int targetUid) { 885 if (!checkCallingPermission(android.Manifest.permission.INJECT_EVENTS, 886 "injectInputEvent()", true /*checkInstrumentationSource*/)) { 887 throw new SecurityException( 888 "Injecting input events requires the caller (or the source of the " 889 + "instrumentation, if any) to have the INJECT_EVENTS permission."); 890 } 891 // We are not checking if targetUid matches the callingUid, since having the permission 892 // already means you can inject into any window. 893 Objects.requireNonNull(event, "event must not be null"); 894 if (mode != InputEventInjectionSync.NONE 895 && mode != InputEventInjectionSync.WAIT_FOR_FINISHED 896 && mode != InputEventInjectionSync.WAIT_FOR_RESULT) { 897 throw new IllegalArgumentException("mode is invalid"); 898 } 899 900 final int pid = Binder.getCallingPid(); 901 final long ident = Binder.clearCallingIdentity(); 902 final boolean injectIntoUid = targetUid != Process.INVALID_UID; 903 final int result; 904 try { 905 result = mNative.injectInputEvent(event, injectIntoUid, 906 targetUid, mode, INJECTION_TIMEOUT_MILLIS, 907 WindowManagerPolicy.FLAG_DISABLE_KEY_REPEAT); 908 } finally { 909 Binder.restoreCallingIdentity(ident); 910 } 911 switch (result) { 912 case InputEventInjectionResult.SUCCEEDED: 913 return true; 914 case InputEventInjectionResult.TARGET_MISMATCH: 915 if (!injectIntoUid) { 916 throw new IllegalStateException("Injection should not result in TARGET_MISMATCH" 917 + " when it is not targeted into to a specific uid."); 918 } 919 throw new IllegalArgumentException( 920 "Targeted input event injection from pid " + pid 921 + " was not directed at a window owned by uid " 922 + targetUid + "."); 923 case InputEventInjectionResult.TIMED_OUT: 924 Slog.w(TAG, "Input event injection from pid " + pid + " timed out."); 925 return false; 926 case InputEventInjectionResult.FAILED: 927 default: 928 Slog.w(TAG, "Input event injection from pid " + pid + " failed."); 929 return false; 930 } 931 } 932 933 @Override // Binder call verifyInputEvent(InputEvent event)934 public VerifiedInputEvent verifyInputEvent(InputEvent event) { 935 Objects.requireNonNull(event, "event must not be null"); 936 return mNative.verifyInputEvent(event); 937 } 938 939 @Override // Binder call getVelocityTrackerStrategy()940 public String getVelocityTrackerStrategy() { 941 return mVelocityTrackerStrategy; 942 } 943 944 /** 945 * Gets information about the input device with the specified id. 946 * @param deviceId The device id. 947 * @return The input device or null if not found. 948 */ 949 @Override // Binder call getInputDevice(int deviceId)950 public InputDevice getInputDevice(int deviceId) { 951 synchronized (mInputDevicesLock) { 952 for (final InputDevice inputDevice : mInputDevices) { 953 if (inputDevice.getId() == deviceId) { 954 return inputDevice; 955 } 956 } 957 } 958 return null; 959 } 960 961 // Binder call 962 @Override enableInputDevice(int deviceId)963 public void enableInputDevice(int deviceId) { 964 if (!checkCallingPermission(android.Manifest.permission.DISABLE_INPUT_DEVICE, 965 "enableInputDevice()")) { 966 throw new SecurityException("Requires DISABLE_INPUT_DEVICE permission"); 967 } 968 mNative.enableInputDevice(deviceId); 969 } 970 971 // Binder call 972 @Override disableInputDevice(int deviceId)973 public void disableInputDevice(int deviceId) { 974 if (!checkCallingPermission(android.Manifest.permission.DISABLE_INPUT_DEVICE, 975 "disableInputDevice()")) { 976 throw new SecurityException("Requires DISABLE_INPUT_DEVICE permission"); 977 } 978 mNative.disableInputDevice(deviceId); 979 } 980 981 /** 982 * Gets the ids of all input devices in the system. 983 * @return The input device ids. 984 */ 985 @Override // Binder call getInputDeviceIds()986 public int[] getInputDeviceIds() { 987 synchronized (mInputDevicesLock) { 988 final int count = mInputDevices.length; 989 int[] ids = new int[count]; 990 for (int i = 0; i < count; i++) { 991 ids[i] = mInputDevices[i].getId(); 992 } 993 return ids; 994 } 995 } 996 997 /** 998 * Gets all input devices in the system. 999 * @return The array of input devices. 1000 */ getInputDevices()1001 public InputDevice[] getInputDevices() { 1002 synchronized (mInputDevicesLock) { 1003 return mInputDevices; 1004 } 1005 } 1006 1007 @Override // Binder call registerInputDevicesChangedListener(IInputDevicesChangedListener listener)1008 public void registerInputDevicesChangedListener(IInputDevicesChangedListener listener) { 1009 Objects.requireNonNull(listener, "listener must not be null"); 1010 1011 synchronized (mInputDevicesLock) { 1012 int callingPid = Binder.getCallingPid(); 1013 if (mInputDevicesChangedListeners.get(callingPid) != null) { 1014 throw new SecurityException("The calling process has already " 1015 + "registered an InputDevicesChangedListener."); 1016 } 1017 1018 InputDevicesChangedListenerRecord record = 1019 new InputDevicesChangedListenerRecord(callingPid, listener); 1020 try { 1021 IBinder binder = listener.asBinder(); 1022 binder.linkToDeath(record, 0); 1023 } catch (RemoteException ex) { 1024 // give up 1025 throw new RuntimeException(ex); 1026 } 1027 1028 mInputDevicesChangedListeners.put(callingPid, record); 1029 } 1030 } 1031 onInputDevicesChangedListenerDied(int pid)1032 private void onInputDevicesChangedListenerDied(int pid) { 1033 synchronized (mInputDevicesLock) { 1034 mInputDevicesChangedListeners.remove(pid); 1035 } 1036 } 1037 1038 // Must be called on handler. deliverInputDevicesChanged(InputDevice[] oldInputDevices)1039 private void deliverInputDevicesChanged(InputDevice[] oldInputDevices) { 1040 // Scan for changes. 1041 mTempInputDevicesChangedListenersToNotify.clear(); 1042 final int numListeners; 1043 final int[] deviceIdAndGeneration; 1044 synchronized (mInputDevicesLock) { 1045 if (!mInputDevicesChangedPending) { 1046 return; 1047 } 1048 mInputDevicesChangedPending = false; 1049 1050 numListeners = mInputDevicesChangedListeners.size(); 1051 for (int i = 0; i < numListeners; i++) { 1052 mTempInputDevicesChangedListenersToNotify.add( 1053 mInputDevicesChangedListeners.valueAt(i)); 1054 } 1055 1056 final int numDevices = mInputDevices.length; 1057 deviceIdAndGeneration = new int[numDevices * 2]; 1058 for (int i = 0; i < numDevices; i++) { 1059 final InputDevice inputDevice = mInputDevices[i]; 1060 deviceIdAndGeneration[i * 2] = inputDevice.getId(); 1061 deviceIdAndGeneration[i * 2 + 1] = inputDevice.getGeneration(); 1062 if (DEBUG) { 1063 Log.d(TAG, "device " + inputDevice.getId() + " generation " 1064 + inputDevice.getGeneration()); 1065 } 1066 } 1067 } 1068 1069 // Notify listeners. 1070 for (int i = 0; i < numListeners; i++) { 1071 mTempInputDevicesChangedListenersToNotify.get(i).notifyInputDevicesChanged( 1072 deviceIdAndGeneration); 1073 } 1074 mTempInputDevicesChangedListenersToNotify.clear(); 1075 } 1076 1077 @Override // Binder call & native callback getTouchCalibrationForInputDevice(String inputDeviceDescriptor, int surfaceRotation)1078 public TouchCalibration getTouchCalibrationForInputDevice(String inputDeviceDescriptor, 1079 int surfaceRotation) { 1080 Objects.requireNonNull(inputDeviceDescriptor, "inputDeviceDescriptor must not be null"); 1081 1082 synchronized (mDataStore) { 1083 return mDataStore.getTouchCalibration(inputDeviceDescriptor, surfaceRotation); 1084 } 1085 } 1086 1087 @Override // Binder call setTouchCalibrationForInputDevice(String inputDeviceDescriptor, int surfaceRotation, TouchCalibration calibration)1088 public void setTouchCalibrationForInputDevice(String inputDeviceDescriptor, int surfaceRotation, 1089 TouchCalibration calibration) { 1090 if (!checkCallingPermission(android.Manifest.permission.SET_INPUT_CALIBRATION, 1091 "setTouchCalibrationForInputDevice()")) { 1092 throw new SecurityException("Requires SET_INPUT_CALIBRATION permission"); 1093 } 1094 Objects.requireNonNull(inputDeviceDescriptor, "inputDeviceDescriptor must not be null"); 1095 Objects.requireNonNull(calibration, "calibration must not be null"); 1096 if (surfaceRotation < Surface.ROTATION_0 || surfaceRotation > Surface.ROTATION_270) { 1097 throw new IllegalArgumentException("surfaceRotation value out of bounds"); 1098 } 1099 1100 synchronized (mDataStore) { 1101 try { 1102 if (mDataStore.setTouchCalibration(inputDeviceDescriptor, surfaceRotation, 1103 calibration)) { 1104 mNative.reloadCalibration(); 1105 } 1106 } finally { 1107 mDataStore.saveIfNeeded(); 1108 } 1109 } 1110 } 1111 1112 @Override // Binder call isInTabletMode()1113 public int isInTabletMode() { 1114 if (!checkCallingPermission(android.Manifest.permission.TABLET_MODE, 1115 "isInTabletMode()")) { 1116 throw new SecurityException("Requires TABLET_MODE permission"); 1117 } 1118 return getSwitchState(-1, InputDevice.SOURCE_ANY, SW_TABLET_MODE); 1119 } 1120 1121 @Override // Binder call isMicMuted()1122 public int isMicMuted() { 1123 return getSwitchState(-1, InputDevice.SOURCE_ANY, SW_MUTE_DEVICE); 1124 } 1125 1126 @Override // Binder call registerTabletModeChangedListener(ITabletModeChangedListener listener)1127 public void registerTabletModeChangedListener(ITabletModeChangedListener listener) { 1128 if (!checkCallingPermission(android.Manifest.permission.TABLET_MODE, 1129 "registerTabletModeChangedListener()")) { 1130 throw new SecurityException("Requires TABLET_MODE_LISTENER permission"); 1131 } 1132 Objects.requireNonNull(listener, "event must not be null"); 1133 1134 synchronized (mTabletModeLock) { 1135 final int callingPid = Binder.getCallingPid(); 1136 if (mTabletModeChangedListeners.get(callingPid) != null) { 1137 throw new IllegalStateException("The calling process has already registered " 1138 + "a TabletModeChangedListener."); 1139 } 1140 TabletModeChangedListenerRecord record = 1141 new TabletModeChangedListenerRecord(callingPid, listener); 1142 try { 1143 IBinder binder = listener.asBinder(); 1144 binder.linkToDeath(record, 0); 1145 } catch (RemoteException ex) { 1146 throw new RuntimeException(ex); 1147 } 1148 mTabletModeChangedListeners.put(callingPid, record); 1149 } 1150 } 1151 onTabletModeChangedListenerDied(int pid)1152 private void onTabletModeChangedListenerDied(int pid) { 1153 synchronized (mTabletModeLock) { 1154 mTabletModeChangedListeners.remove(pid); 1155 } 1156 } 1157 1158 // Must be called on handler deliverTabletModeChanged(long whenNanos, boolean inTabletMode)1159 private void deliverTabletModeChanged(long whenNanos, boolean inTabletMode) { 1160 mTempTabletModeChangedListenersToNotify.clear(); 1161 final int numListeners; 1162 synchronized (mTabletModeLock) { 1163 numListeners = mTabletModeChangedListeners.size(); 1164 for (int i = 0; i < numListeners; i++) { 1165 mTempTabletModeChangedListenersToNotify.add( 1166 mTabletModeChangedListeners.valueAt(i)); 1167 } 1168 } 1169 for (int i = 0; i < numListeners; i++) { 1170 mTempTabletModeChangedListenersToNotify.get(i).notifyTabletModeChanged( 1171 whenNanos, inTabletMode); 1172 } 1173 } 1174 1175 @Override // Binder call getKeyboardLayouts()1176 public KeyboardLayout[] getKeyboardLayouts() { 1177 return mKeyboardLayoutManager.getKeyboardLayouts(); 1178 } 1179 1180 @Override // Binder call getKeyboardLayout(String keyboardLayoutDescriptor)1181 public KeyboardLayout getKeyboardLayout(String keyboardLayoutDescriptor) { 1182 return mKeyboardLayoutManager.getKeyboardLayout(keyboardLayoutDescriptor); 1183 } 1184 1185 @Override // Binder call getKeyboardLayoutForInputDevice( InputDeviceIdentifier identifier, @UserIdInt int userId, @NonNull InputMethodInfo imeInfo, @Nullable InputMethodSubtype imeSubtype)1186 public KeyboardLayoutSelectionResult getKeyboardLayoutForInputDevice( 1187 InputDeviceIdentifier identifier, @UserIdInt int userId, 1188 @NonNull InputMethodInfo imeInfo, @Nullable InputMethodSubtype imeSubtype) { 1189 return mKeyboardLayoutManager.getKeyboardLayoutForInputDevice(identifier, userId, 1190 imeInfo, imeSubtype); 1191 } 1192 1193 @EnforcePermission(Manifest.permission.SET_KEYBOARD_LAYOUT) 1194 @Override // Binder call setKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier, @UserIdInt int userId, @NonNull InputMethodInfo imeInfo, @Nullable InputMethodSubtype imeSubtype, String keyboardLayoutDescriptor)1195 public void setKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier, 1196 @UserIdInt int userId, @NonNull InputMethodInfo imeInfo, 1197 @Nullable InputMethodSubtype imeSubtype, String keyboardLayoutDescriptor) { 1198 super.setKeyboardLayoutForInputDevice_enforcePermission(); 1199 mKeyboardLayoutManager.setKeyboardLayoutForInputDevice(identifier, userId, imeInfo, 1200 imeSubtype, keyboardLayoutDescriptor); 1201 } 1202 1203 @Override // Binder call getKeyboardLayoutListForInputDevice(InputDeviceIdentifier identifier, @UserIdInt int userId, @NonNull InputMethodInfo imeInfo, @Nullable InputMethodSubtype imeSubtype)1204 public KeyboardLayout[] getKeyboardLayoutListForInputDevice(InputDeviceIdentifier identifier, 1205 @UserIdInt int userId, @NonNull InputMethodInfo imeInfo, 1206 @Nullable InputMethodSubtype imeSubtype) { 1207 return mKeyboardLayoutManager.getKeyboardLayoutListForInputDevice(identifier, userId, 1208 imeInfo, imeSubtype); 1209 } 1210 setFocusedApplication(int displayId, InputApplicationHandle application)1211 public void setFocusedApplication(int displayId, InputApplicationHandle application) { 1212 mNative.setFocusedApplication(displayId, application); 1213 } 1214 setFocusedDisplay(int displayId)1215 public void setFocusedDisplay(int displayId) { 1216 mNative.setFocusedDisplay(displayId); 1217 } 1218 1219 /** Clean up input window handles of the given display. */ onDisplayRemoved(int displayId)1220 public void onDisplayRemoved(int displayId) { 1221 updateAdditionalDisplayInputProperties(displayId, AdditionalDisplayInputProperties::reset); 1222 1223 // TODO(b/320763728): Rely on WindowInfosListener to determine when a display has been 1224 // removed in InputDispatcher instead of this callback. 1225 mNative.displayRemoved(displayId); 1226 } 1227 1228 @Override requestPointerCapture(IBinder inputChannelToken, boolean enabled)1229 public void requestPointerCapture(IBinder inputChannelToken, boolean enabled) { 1230 Objects.requireNonNull(inputChannelToken, "event must not be null"); 1231 1232 mNative.requestPointerCapture(inputChannelToken, enabled); 1233 } 1234 setInputDispatchMode(boolean enabled, boolean frozen)1235 public void setInputDispatchMode(boolean enabled, boolean frozen) { 1236 mNative.setInputDispatchMode(enabled, frozen); 1237 } 1238 setSystemUiLightsOut(boolean lightsOut)1239 public void setSystemUiLightsOut(boolean lightsOut) { 1240 mNative.setSystemUiLightsOut(lightsOut); 1241 } 1242 1243 /** 1244 * Start drag and drop. 1245 * 1246 * @param fromChannel The input channel that is currently receiving a touch gesture that should 1247 * be turned into the drag pointer. 1248 * @param dragAndDropChannel The input channel associated with the system drag window. 1249 * @return true if drag and drop was successfully started, false otherwise. 1250 */ startDragAndDrop(@onNull InputChannel fromChannel, @NonNull InputChannel dragAndDropChannel)1251 public boolean startDragAndDrop(@NonNull InputChannel fromChannel, 1252 @NonNull InputChannel dragAndDropChannel) { 1253 return mNative.transferTouchGesture(fromChannel.getToken(), dragAndDropChannel.getToken(), 1254 true /* isDragDrop */); 1255 } 1256 1257 /** 1258 * Atomically transfers an active touch gesture from one window to another, as identified by 1259 * their input channels. 1260 * 1261 * <p>Only the touch gesture that is currently being dispatched to a window associated with 1262 * {@code fromChannelToken} will be effected. That window will no longer receive 1263 * the touch gesture (i.e. it will receive {@link android.view.MotionEvent#ACTION_CANCEL}). 1264 * A window associated with the {@code toChannelToken} will receive the rest of the gesture 1265 * (i.e. beginning with {@link android.view.MotionEvent#ACTION_DOWN} or 1266 * {@link android.view.MotionEvent#ACTION_POINTER_DOWN}). 1267 * 1268 * <p>Transferring touch gestures will have no impact on focused windows. If the {@code 1269 * toChannelToken} window is focusable, this will not bring focus to that window. 1270 * 1271 * @param fromChannelToken The channel token of a window that has an active touch gesture. 1272 * @param toChannelToken The channel token of the window that should receive the gesture in 1273 * place of the first. 1274 * @return True if the transfer was successful. False if the specified windows don't exist, or 1275 * if the source window is not actively receiving a touch gesture at the time of the request. 1276 */ transferTouchGesture(@onNull IBinder fromChannelToken, @NonNull IBinder toChannelToken)1277 public boolean transferTouchGesture(@NonNull IBinder fromChannelToken, 1278 @NonNull IBinder toChannelToken) { 1279 Objects.requireNonNull(fromChannelToken); 1280 Objects.requireNonNull(toChannelToken); 1281 return mNative.transferTouchGesture(fromChannelToken, toChannelToken, 1282 false /* isDragDrop */); 1283 } 1284 1285 @Override // Binder call getMousePointerSpeed()1286 public int getMousePointerSpeed() { 1287 return mNative.getMousePointerSpeed(); 1288 } 1289 1290 @Override // Binder call tryPointerSpeed(int speed)1291 public void tryPointerSpeed(int speed) { 1292 if (!checkCallingPermission(android.Manifest.permission.SET_POINTER_SPEED, 1293 "tryPointerSpeed()")) { 1294 throw new SecurityException("Requires SET_POINTER_SPEED permission"); 1295 } 1296 1297 if (speed < InputSettings.MIN_POINTER_SPEED || speed > InputSettings.MAX_POINTER_SPEED) { 1298 throw new IllegalArgumentException("speed out of range"); 1299 } 1300 1301 setPointerSpeedUnchecked(speed); 1302 } 1303 setPointerSpeedUnchecked(int speed)1304 private void setPointerSpeedUnchecked(int speed) { 1305 speed = Math.min(Math.max(speed, InputSettings.MIN_POINTER_SPEED), 1306 InputSettings.MAX_POINTER_SPEED); 1307 mNative.setPointerSpeed(speed); 1308 } 1309 setMousePointerAccelerationEnabled(boolean enabled, int displayId)1310 private void setMousePointerAccelerationEnabled(boolean enabled, int displayId) { 1311 updateAdditionalDisplayInputProperties(displayId, 1312 properties -> properties.mousePointerAccelerationEnabled = enabled); 1313 } 1314 setPointerIconVisible(boolean visible, int displayId)1315 private void setPointerIconVisible(boolean visible, int displayId) { 1316 updateAdditionalDisplayInputProperties(displayId, 1317 properties -> properties.pointerIconVisible = visible); 1318 } 1319 setDisplayEligibilityForPointerCapture(int displayId, boolean isEligible)1320 private void setDisplayEligibilityForPointerCapture(int displayId, boolean isEligible) { 1321 mNative.setDisplayEligibilityForPointerCapture(displayId, isEligible); 1322 } 1323 1324 private static class VibrationInfo { 1325 private final long[] mPattern; 1326 private final int[] mAmplitudes; 1327 private final int mRepeat; 1328 getPattern()1329 public long[] getPattern() { 1330 return mPattern; 1331 } 1332 getAmplitudes()1333 public int[] getAmplitudes() { 1334 return mAmplitudes; 1335 } 1336 getRepeatIndex()1337 public int getRepeatIndex() { 1338 return mRepeat; 1339 } 1340 VibrationInfo(VibrationEffect effect)1341 VibrationInfo(VibrationEffect effect) { 1342 long[] pattern = null; 1343 int[] amplitudes = null; 1344 int patternRepeatIndex = -1; 1345 int amplitudeCount = -1; 1346 1347 if (effect instanceof VibrationEffect.Composed) { 1348 VibrationEffect.Composed composed = (VibrationEffect.Composed) effect; 1349 int segmentCount = composed.getSegments().size(); 1350 pattern = new long[segmentCount]; 1351 amplitudes = new int[segmentCount]; 1352 patternRepeatIndex = composed.getRepeatIndex(); 1353 amplitudeCount = 0; 1354 for (int i = 0; i < segmentCount; i++) { 1355 VibrationEffectSegment segment = composed.getSegments().get(i); 1356 if (composed.getRepeatIndex() == i) { 1357 patternRepeatIndex = amplitudeCount; 1358 } 1359 if (!(segment instanceof StepSegment)) { 1360 Slog.w(TAG, "Input devices don't support segment " + segment); 1361 amplitudeCount = -1; 1362 break; 1363 } 1364 float amplitude = ((StepSegment) segment).getAmplitude(); 1365 if (Float.compare(amplitude, VibrationEffect.DEFAULT_AMPLITUDE) == 0) { 1366 amplitudes[amplitudeCount] = DEFAULT_VIBRATION_MAGNITUDE; 1367 } else { 1368 amplitudes[amplitudeCount] = 1369 (int) (amplitude * VibrationEffect.MAX_AMPLITUDE); 1370 } 1371 pattern[amplitudeCount++] = segment.getDuration(); 1372 } 1373 } 1374 1375 if (amplitudeCount < 0) { 1376 Slog.w(TAG, "Only oneshot and step waveforms are supported on input devices"); 1377 mPattern = new long[0]; 1378 mAmplitudes = new int[0]; 1379 mRepeat = -1; 1380 } else { 1381 mRepeat = patternRepeatIndex; 1382 mPattern = new long[amplitudeCount]; 1383 mAmplitudes = new int[amplitudeCount]; 1384 System.arraycopy(pattern, 0, mPattern, 0, amplitudeCount); 1385 System.arraycopy(amplitudes, 0, mAmplitudes, 0, amplitudeCount); 1386 if (mRepeat >= mPattern.length) { 1387 throw new ArrayIndexOutOfBoundsException("Repeat index " + mRepeat 1388 + " must be within the bounds of the pattern.length " 1389 + mPattern.length); 1390 } 1391 } 1392 } 1393 } 1394 getVibratorToken(int deviceId, IBinder token)1395 private VibratorToken getVibratorToken(int deviceId, IBinder token) { 1396 VibratorToken v; 1397 synchronized (mVibratorLock) { 1398 v = mVibratorTokens.get(token); 1399 if (v == null) { 1400 v = new VibratorToken(deviceId, token, mNextVibratorTokenValue++); 1401 try { 1402 token.linkToDeath(v, 0); 1403 } catch (RemoteException ex) { 1404 // give up 1405 throw new RuntimeException(ex); 1406 } 1407 mVibratorTokens.put(token, v); 1408 } 1409 } 1410 return v; 1411 } 1412 1413 // Binder call 1414 @Override vibrate(int deviceId, VibrationEffect effect, IBinder token)1415 public void vibrate(int deviceId, VibrationEffect effect, IBinder token) { 1416 VibrationInfo info = new VibrationInfo(effect); 1417 VibratorToken v = getVibratorToken(deviceId, token); 1418 synchronized (v) { 1419 v.mVibrating = true; 1420 mNative.vibrate(deviceId, info.getPattern(), info.getAmplitudes(), 1421 info.getRepeatIndex(), v.mTokenValue); 1422 } 1423 } 1424 1425 // Binder call 1426 @Override getVibratorIds(int deviceId)1427 public int[] getVibratorIds(int deviceId) { 1428 return mNative.getVibratorIds(deviceId); 1429 } 1430 1431 // Binder call 1432 @Override isVibrating(int deviceId)1433 public boolean isVibrating(int deviceId) { 1434 return mNative.isVibrating(deviceId); 1435 } 1436 1437 // Binder call 1438 @Override vibrateCombined(int deviceId, CombinedVibration effect, IBinder token)1439 public void vibrateCombined(int deviceId, CombinedVibration effect, IBinder token) { 1440 VibratorToken v = getVibratorToken(deviceId, token); 1441 synchronized (v) { 1442 if (!(effect instanceof CombinedVibration.Mono) 1443 && !(effect instanceof CombinedVibration.Stereo)) { 1444 Slog.e(TAG, "Only Mono and Stereo effects are supported"); 1445 return; 1446 } 1447 1448 v.mVibrating = true; 1449 if (effect instanceof CombinedVibration.Mono) { 1450 CombinedVibration.Mono mono = (CombinedVibration.Mono) effect; 1451 VibrationInfo info = new VibrationInfo(mono.getEffect()); 1452 mNative.vibrate(deviceId, info.getPattern(), info.getAmplitudes(), 1453 info.getRepeatIndex(), v.mTokenValue); 1454 } else if (effect instanceof CombinedVibration.Stereo) { 1455 CombinedVibration.Stereo stereo = (CombinedVibration.Stereo) effect; 1456 SparseArray<VibrationEffect> effects = stereo.getEffects(); 1457 long[] pattern = new long[0]; 1458 int repeat = Integer.MIN_VALUE; 1459 SparseArray<int[]> amplitudes = new SparseArray<>(effects.size()); 1460 for (int i = 0; i < effects.size(); i++) { 1461 VibrationInfo info = new VibrationInfo(effects.valueAt(i)); 1462 // Pattern of all effects should be same 1463 if (pattern.length == 0) { 1464 pattern = info.getPattern(); 1465 } 1466 if (repeat == Integer.MIN_VALUE) { 1467 repeat = info.getRepeatIndex(); 1468 } 1469 amplitudes.put(effects.keyAt(i), info.getAmplitudes()); 1470 } 1471 mNative.vibrateCombined(deviceId, pattern, amplitudes, repeat, 1472 v.mTokenValue); 1473 } 1474 } 1475 } 1476 1477 // Binder call 1478 @Override cancelVibrate(int deviceId, IBinder token)1479 public void cancelVibrate(int deviceId, IBinder token) { 1480 VibratorToken v; 1481 synchronized (mVibratorLock) { 1482 v = mVibratorTokens.get(token); 1483 if (v == null || v.mDeviceId != deviceId) { 1484 return; // nothing to cancel 1485 } 1486 } 1487 1488 cancelVibrateIfNeeded(v); 1489 } 1490 onVibratorTokenDied(VibratorToken v)1491 void onVibratorTokenDied(VibratorToken v) { 1492 synchronized (mVibratorLock) { 1493 mVibratorTokens.remove(v.mToken); 1494 } 1495 1496 cancelVibrateIfNeeded(v); 1497 } 1498 cancelVibrateIfNeeded(VibratorToken v)1499 private void cancelVibrateIfNeeded(VibratorToken v) { 1500 synchronized (v) { 1501 if (v.mVibrating) { 1502 mNative.cancelVibrate(v.mDeviceId, v.mTokenValue); 1503 v.mVibrating = false; 1504 } 1505 } 1506 } 1507 1508 // Native callback. 1509 @SuppressWarnings("unused") notifyVibratorState(int deviceId, boolean isOn)1510 private void notifyVibratorState(int deviceId, boolean isOn) { 1511 if (DEBUG) { 1512 Slog.d(TAG, "notifyVibratorState: deviceId=" + deviceId + " isOn=" + isOn); 1513 } 1514 synchronized (mVibratorLock) { 1515 mIsVibrating.put(deviceId, isOn); 1516 notifyVibratorStateListenersLocked(deviceId); 1517 } 1518 } 1519 1520 @GuardedBy("mVibratorLock") notifyVibratorStateListenersLocked(int deviceId)1521 private void notifyVibratorStateListenersLocked(int deviceId) { 1522 if (!mVibratorStateListeners.contains(deviceId)) { 1523 if (DEBUG) { 1524 Slog.v(TAG, "Device " + deviceId + " doesn't have vibrator state listener."); 1525 } 1526 return; 1527 } 1528 RemoteCallbackList<IVibratorStateListener> listeners = 1529 mVibratorStateListeners.get(deviceId); 1530 final int length = listeners.beginBroadcast(); 1531 try { 1532 for (int i = 0; i < length; i++) { 1533 notifyVibratorStateListenerLocked(deviceId, listeners.getBroadcastItem(i)); 1534 } 1535 } finally { 1536 listeners.finishBroadcast(); 1537 } 1538 } 1539 1540 @GuardedBy("mVibratorLock") notifyVibratorStateListenerLocked(int deviceId, IVibratorStateListener listener)1541 private void notifyVibratorStateListenerLocked(int deviceId, IVibratorStateListener listener) { 1542 try { 1543 listener.onVibrating(mIsVibrating.get(deviceId)); 1544 } catch (RemoteException | RuntimeException e) { 1545 Slog.e(TAG, "Vibrator state listener failed to call", e); 1546 } 1547 } 1548 1549 @Override // Binder call registerVibratorStateListener(int deviceId, IVibratorStateListener listener)1550 public boolean registerVibratorStateListener(int deviceId, IVibratorStateListener listener) { 1551 Objects.requireNonNull(listener, "listener must not be null"); 1552 1553 RemoteCallbackList<IVibratorStateListener> listeners; 1554 synchronized (mVibratorLock) { 1555 if (!mVibratorStateListeners.contains(deviceId)) { 1556 listeners = new RemoteCallbackList<>(); 1557 mVibratorStateListeners.put(deviceId, listeners); 1558 } else { 1559 listeners = mVibratorStateListeners.get(deviceId); 1560 } 1561 1562 final long token = Binder.clearCallingIdentity(); 1563 try { 1564 if (!listeners.register(listener)) { 1565 Slog.e(TAG, "Could not register vibrator state listener " + listener); 1566 return false; 1567 } 1568 // Notify its callback after new client registered. 1569 notifyVibratorStateListenerLocked(deviceId, listener); 1570 return true; 1571 } finally { 1572 Binder.restoreCallingIdentity(token); 1573 } 1574 } 1575 } 1576 1577 @Override // Binder call unregisterVibratorStateListener(int deviceId, IVibratorStateListener listener)1578 public boolean unregisterVibratorStateListener(int deviceId, IVibratorStateListener listener) { 1579 synchronized (mVibratorLock) { 1580 final long token = Binder.clearCallingIdentity(); 1581 try { 1582 if (!mVibratorStateListeners.contains(deviceId)) { 1583 Slog.w(TAG, "Vibrator state listener " + deviceId + " doesn't exist"); 1584 return false; 1585 } 1586 RemoteCallbackList<IVibratorStateListener> listeners = 1587 mVibratorStateListeners.get(deviceId); 1588 return listeners.unregister(listener); 1589 } finally { 1590 Binder.restoreCallingIdentity(token); 1591 } 1592 } 1593 } 1594 1595 // Binder call 1596 @Override getBatteryState(int deviceId)1597 public IInputDeviceBatteryState getBatteryState(int deviceId) { 1598 return mBatteryController.getBatteryState(deviceId); 1599 } 1600 1601 // Binder call 1602 @Override setPointerIcon(PointerIcon icon, int displayId, int deviceId, int pointerId, IBinder inputToken)1603 public boolean setPointerIcon(PointerIcon icon, int displayId, int deviceId, int pointerId, 1604 IBinder inputToken) { 1605 Objects.requireNonNull(icon); 1606 return mNative.setPointerIcon(icon, displayId, deviceId, pointerId, inputToken); 1607 } 1608 1609 /** 1610 * Add a runtime association between the input port and the display port. This overrides any 1611 * static associations. 1612 * @param inputPort the port of the input device 1613 * @param displayPort the physical port of the associated display 1614 */ 1615 @Override // Binder call addPortAssociation(@onNull String inputPort, int displayPort)1616 public void addPortAssociation(@NonNull String inputPort, int displayPort) { 1617 if (!checkCallingPermission( 1618 android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY, 1619 "addPortAssociation()")) { 1620 throw new SecurityException( 1621 "Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY permission"); 1622 } 1623 1624 Objects.requireNonNull(inputPort); 1625 synchronized (mAssociationsLock) { 1626 mRuntimeAssociations.put(inputPort, displayPort); 1627 } 1628 mNative.notifyPortAssociationsChanged(); 1629 } 1630 1631 /** 1632 * Remove the runtime association between the input port and the display port. Any existing 1633 * static association for the cleared input port will be restored. 1634 * @param inputPort the port of the input device to be cleared 1635 */ 1636 @Override // Binder call removePortAssociation(@onNull String inputPort)1637 public void removePortAssociation(@NonNull String inputPort) { 1638 if (!checkCallingPermission( 1639 android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY, 1640 "removePortAssociation()")) { 1641 throw new SecurityException( 1642 "Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY permission"); 1643 } 1644 1645 Objects.requireNonNull(inputPort); 1646 synchronized (mAssociationsLock) { 1647 mRuntimeAssociations.remove(inputPort); 1648 } 1649 mNative.notifyPortAssociationsChanged(); 1650 } 1651 1652 @Override // Binder call addUniqueIdAssociationByPort(@onNull String inputPort, @NonNull String displayUniqueId)1653 public void addUniqueIdAssociationByPort(@NonNull String inputPort, 1654 @NonNull String displayUniqueId) { 1655 if (!checkCallingPermission( 1656 android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY, 1657 "addUniqueIdAssociation()")) { 1658 throw new SecurityException( 1659 "Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY permission"); 1660 } 1661 1662 Objects.requireNonNull(inputPort); 1663 Objects.requireNonNull(displayUniqueId); 1664 synchronized (mAssociationsLock) { 1665 mUniqueIdAssociationsByPort.put(inputPort, displayUniqueId); 1666 } 1667 mNative.changeUniqueIdAssociation(); 1668 } 1669 1670 @Override // Binder call removeUniqueIdAssociationByPort(@onNull String inputPort)1671 public void removeUniqueIdAssociationByPort(@NonNull String inputPort) { 1672 if (!checkCallingPermission( 1673 android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY, 1674 "removeUniqueIdAssociation()")) { 1675 throw new SecurityException("Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY permission"); 1676 } 1677 1678 Objects.requireNonNull(inputPort); 1679 synchronized (mAssociationsLock) { 1680 mUniqueIdAssociationsByPort.remove(inputPort); 1681 } 1682 mNative.changeUniqueIdAssociation(); 1683 } 1684 1685 /** 1686 * Adds a runtime association between the input device descriptor and the display unique id. 1687 * @param inputDeviceDescriptor the descriptor of the input device 1688 * @param displayUniqueId the unique ID of the display 1689 */ 1690 @Override // Binder call addUniqueIdAssociationByDescriptor(@onNull String inputDeviceDescriptor, @NonNull String displayUniqueId)1691 public void addUniqueIdAssociationByDescriptor(@NonNull String inputDeviceDescriptor, 1692 @NonNull String displayUniqueId) { 1693 if (!checkCallingPermission( 1694 android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY, 1695 "addUniqueIdAssociationByDescriptor()")) { 1696 throw new SecurityException( 1697 "Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY permission"); 1698 } 1699 1700 Objects.requireNonNull(inputDeviceDescriptor); 1701 Objects.requireNonNull(displayUniqueId); 1702 synchronized (mAssociationsLock) { 1703 mUniqueIdAssociationsByDescriptor.put(inputDeviceDescriptor, displayUniqueId); 1704 } 1705 mNative.changeUniqueIdAssociation(); 1706 } 1707 1708 /** 1709 * Removes the runtime association between the input device and the display. 1710 * @param inputDeviceDescriptor the descriptor of the input device 1711 */ 1712 @Override // Binder call removeUniqueIdAssociationByDescriptor(@onNull String inputDeviceDescriptor)1713 public void removeUniqueIdAssociationByDescriptor(@NonNull String inputDeviceDescriptor) { 1714 if (!checkCallingPermission( 1715 android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY, 1716 "removeUniqueIdAssociationByDescriptor()")) { 1717 throw new SecurityException( 1718 "Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY permission"); 1719 } 1720 1721 Objects.requireNonNull(inputDeviceDescriptor); 1722 synchronized (mAssociationsLock) { 1723 mUniqueIdAssociationsByDescriptor.remove(inputDeviceDescriptor); 1724 } 1725 mNative.changeUniqueIdAssociation(); 1726 } 1727 setTypeAssociationInternal(@onNull String inputPort, @NonNull String type)1728 void setTypeAssociationInternal(@NonNull String inputPort, @NonNull String type) { 1729 Objects.requireNonNull(inputPort); 1730 Objects.requireNonNull(type); 1731 synchronized (mAssociationsLock) { 1732 mDeviceTypeAssociations.put(inputPort, type); 1733 } 1734 mNative.changeTypeAssociation(); 1735 } 1736 unsetTypeAssociationInternal(@onNull String inputPort)1737 void unsetTypeAssociationInternal(@NonNull String inputPort) { 1738 Objects.requireNonNull(inputPort); 1739 synchronized (mAssociationsLock) { 1740 mDeviceTypeAssociations.remove(inputPort); 1741 } 1742 mNative.changeTypeAssociation(); 1743 } 1744 addKeyboardLayoutAssociation(@onNull String inputPort, @NonNull String languageTag, @NonNull String layoutType)1745 private void addKeyboardLayoutAssociation(@NonNull String inputPort, 1746 @NonNull String languageTag, @NonNull String layoutType) { 1747 Objects.requireNonNull(inputPort); 1748 Objects.requireNonNull(languageTag); 1749 Objects.requireNonNull(layoutType); 1750 1751 synchronized (mAssociationsLock) { 1752 mKeyboardLayoutAssociations.put(inputPort, 1753 TextUtils.formatSimple("%s,%s", languageTag, layoutType)); 1754 } 1755 mNative.changeKeyboardLayoutAssociation(); 1756 } 1757 removeKeyboardLayoutAssociation(@onNull String inputPort)1758 private void removeKeyboardLayoutAssociation(@NonNull String inputPort) { 1759 Objects.requireNonNull(inputPort); 1760 synchronized (mAssociationsLock) { 1761 mKeyboardLayoutAssociations.remove(inputPort); 1762 } 1763 mNative.changeKeyboardLayoutAssociation(); 1764 } 1765 1766 @Override // Binder call getSensorList(int deviceId)1767 public InputSensorInfo[] getSensorList(int deviceId) { 1768 return mNative.getSensorList(deviceId); 1769 } 1770 1771 @Override // Binder call registerSensorListener(IInputSensorEventListener listener)1772 public boolean registerSensorListener(IInputSensorEventListener listener) { 1773 if (DEBUG) { 1774 Slog.d(TAG, "registerSensorListener: listener=" + listener + " callingPid=" 1775 + Binder.getCallingPid()); 1776 } 1777 Objects.requireNonNull(listener, "listener must not be null"); 1778 1779 synchronized (mSensorEventLock) { 1780 int callingPid = Binder.getCallingPid(); 1781 if (mSensorEventListeners.get(callingPid) != null) { 1782 Slog.e(TAG, "The calling process " + callingPid + " has already " 1783 + "registered an InputSensorEventListener."); 1784 return false; 1785 } 1786 1787 SensorEventListenerRecord record = 1788 new SensorEventListenerRecord(callingPid, listener); 1789 try { 1790 IBinder binder = listener.asBinder(); 1791 binder.linkToDeath(record, 0); 1792 } catch (RemoteException ex) { 1793 // give up 1794 throw new RuntimeException(ex); 1795 } 1796 1797 mSensorEventListeners.put(callingPid, record); 1798 } 1799 return true; 1800 } 1801 1802 @Override // Binder call unregisterSensorListener(IInputSensorEventListener listener)1803 public void unregisterSensorListener(IInputSensorEventListener listener) { 1804 if (DEBUG) { 1805 Slog.d(TAG, "unregisterSensorListener: listener=" + listener + " callingPid=" 1806 + Binder.getCallingPid()); 1807 } 1808 1809 Objects.requireNonNull(listener, "listener must not be null"); 1810 1811 synchronized (mSensorEventLock) { 1812 int callingPid = Binder.getCallingPid(); 1813 if (mSensorEventListeners.get(callingPid) != null) { 1814 SensorEventListenerRecord record = mSensorEventListeners.get(callingPid); 1815 if (record.getListener().asBinder() != listener.asBinder()) { 1816 throw new IllegalArgumentException("listener is not registered"); 1817 } 1818 mSensorEventListeners.remove(callingPid); 1819 } 1820 } 1821 } 1822 1823 @Override // Binder call flushSensor(int deviceId, int sensorType)1824 public boolean flushSensor(int deviceId, int sensorType) { 1825 synchronized (mSensorEventLock) { 1826 int callingPid = Binder.getCallingPid(); 1827 SensorEventListenerRecord listener = mSensorEventListeners.get(callingPid); 1828 if (listener != null) { 1829 return mNative.flushSensor(deviceId, sensorType); 1830 } 1831 return false; 1832 } 1833 } 1834 1835 @Override // Binder call enableSensor(int deviceId, int sensorType, int samplingPeriodUs, int maxBatchReportLatencyUs)1836 public boolean enableSensor(int deviceId, int sensorType, int samplingPeriodUs, 1837 int maxBatchReportLatencyUs) { 1838 synchronized (mInputDevicesLock) { 1839 return mNative.enableSensor(deviceId, sensorType, samplingPeriodUs, 1840 maxBatchReportLatencyUs); 1841 } 1842 } 1843 1844 @Override // Binder call disableSensor(int deviceId, int sensorType)1845 public void disableSensor(int deviceId, int sensorType) { 1846 synchronized (mInputDevicesLock) { 1847 mNative.disableSensor(deviceId, sensorType); 1848 } 1849 } 1850 1851 /** 1852 * LightSession represents a light session for lights manager. 1853 */ 1854 private final class LightSession implements DeathRecipient { 1855 private final int mDeviceId; 1856 private final IBinder mToken; 1857 private final String mOpPkg; 1858 // The light ids and states that are requested by the light seesion 1859 private int[] mLightIds; 1860 private LightState[] mLightStates; 1861 LightSession(int deviceId, String opPkg, IBinder token)1862 LightSession(int deviceId, String opPkg, IBinder token) { 1863 mDeviceId = deviceId; 1864 mOpPkg = opPkg; 1865 mToken = token; 1866 } 1867 1868 @Override binderDied()1869 public void binderDied() { 1870 if (DEBUG) { 1871 Slog.d(TAG, "Light token died."); 1872 } 1873 synchronized (mLightLock) { 1874 closeLightSession(mDeviceId, mToken); 1875 mLightSessions.remove(mToken); 1876 } 1877 } 1878 } 1879 1880 /** 1881 * Returns the lights available for apps to control on the specified input device. 1882 * Only lights that aren't reserved for system use are available to apps. 1883 */ 1884 @Override // Binder call getLights(int deviceId)1885 public List<Light> getLights(int deviceId) { 1886 return mNative.getLights(deviceId); 1887 } 1888 1889 /** 1890 * Set specified light state with for a specific input device. 1891 */ setLightStateInternal(int deviceId, Light light, LightState lightState)1892 private void setLightStateInternal(int deviceId, Light light, LightState lightState) { 1893 Objects.requireNonNull(light, "light does not exist"); 1894 if (DEBUG) { 1895 Slog.d(TAG, "setLightStateInternal device " + deviceId + " light " + light 1896 + "lightState " + lightState); 1897 } 1898 if (light.getType() == Light.LIGHT_TYPE_PLAYER_ID) { 1899 mNative.setLightPlayerId(deviceId, light.getId(), lightState.getPlayerId()); 1900 } else { 1901 // Set ARGB format color to input device light 1902 // Refer to https://developer.android.com/reference/kotlin/android/graphics/Color 1903 mNative.setLightColor(deviceId, light.getId(), lightState.getColor()); 1904 } 1905 } 1906 1907 /** 1908 * Set multiple light states with multiple light ids for a specific input device. 1909 */ setLightStatesInternal(int deviceId, int[] lightIds, LightState[] lightStates)1910 private void setLightStatesInternal(int deviceId, int[] lightIds, LightState[] lightStates) { 1911 final List<Light> lights = mNative.getLights(deviceId); 1912 SparseArray<Light> lightArray = new SparseArray<>(); 1913 for (int i = 0; i < lights.size(); i++) { 1914 lightArray.put(lights.get(i).getId(), lights.get(i)); 1915 } 1916 for (int i = 0; i < lightIds.length; i++) { 1917 if (lightArray.contains(lightIds[i])) { 1918 setLightStateInternal(deviceId, lightArray.get(lightIds[i]), lightStates[i]); 1919 } 1920 } 1921 } 1922 1923 /** 1924 * Set states for multiple lights for an opened light session. 1925 */ 1926 @Override setLightStates(int deviceId, int[] lightIds, LightState[] lightStates, IBinder token)1927 public void setLightStates(int deviceId, int[] lightIds, LightState[] lightStates, 1928 IBinder token) { 1929 Preconditions.checkArgument(lightIds.length == lightStates.length, 1930 "lights and light states are not same length"); 1931 synchronized (mLightLock) { 1932 LightSession lightSession = mLightSessions.get(token); 1933 Preconditions.checkArgument(lightSession != null, "not registered"); 1934 Preconditions.checkState(lightSession.mDeviceId == deviceId, "Incorrect device ID"); 1935 lightSession.mLightIds = lightIds.clone(); 1936 lightSession.mLightStates = lightStates.clone(); 1937 if (DEBUG) { 1938 Slog.d(TAG, "setLightStates for " + lightSession.mOpPkg + " device " + deviceId); 1939 } 1940 } 1941 setLightStatesInternal(deviceId, lightIds, lightStates); 1942 } 1943 1944 @Override getLightState(int deviceId, int lightId)1945 public @Nullable LightState getLightState(int deviceId, int lightId) { 1946 synchronized (mLightLock) { 1947 int color = mNative.getLightColor(deviceId, lightId); 1948 int playerId = mNative.getLightPlayerId(deviceId, lightId); 1949 1950 return new LightState(color, playerId); 1951 } 1952 } 1953 1954 @Override openLightSession(int deviceId, String opPkg, IBinder token)1955 public void openLightSession(int deviceId, String opPkg, IBinder token) { 1956 Objects.requireNonNull(token); 1957 synchronized (mLightLock) { 1958 Preconditions.checkState(mLightSessions.get(token) == null, "already registered"); 1959 LightSession lightSession = new LightSession(deviceId, opPkg, token); 1960 try { 1961 token.linkToDeath(lightSession, 0); 1962 } catch (RemoteException ex) { 1963 // give up 1964 ex.rethrowAsRuntimeException(); 1965 } 1966 mLightSessions.put(token, lightSession); 1967 if (DEBUG) { 1968 Slog.d(TAG, "Open light session for " + opPkg + " device " + deviceId); 1969 } 1970 } 1971 } 1972 1973 @Override closeLightSession(int deviceId, IBinder token)1974 public void closeLightSession(int deviceId, IBinder token) { 1975 Objects.requireNonNull(token); 1976 synchronized (mLightLock) { 1977 LightSession lightSession = mLightSessions.get(token); 1978 Preconditions.checkState(lightSession != null, "not registered"); 1979 // Turn off the lights that were previously requested by the session to be closed. 1980 Arrays.fill(lightSession.mLightStates, new LightState(0)); 1981 setLightStatesInternal(deviceId, lightSession.mLightIds, 1982 lightSession.mLightStates); 1983 mLightSessions.remove(token); 1984 // If any other session is still pending with light request, apply the first session's 1985 // request. 1986 if (!mLightSessions.isEmpty()) { 1987 LightSession nextSession = mLightSessions.valueAt(0); 1988 setLightStatesInternal(deviceId, nextSession.mLightIds, nextSession.mLightStates); 1989 } 1990 } 1991 } 1992 1993 @Override cancelCurrentTouch()1994 public void cancelCurrentTouch() { 1995 if (!checkCallingPermission(android.Manifest.permission.MONITOR_INPUT, 1996 "cancelCurrentTouch()")) { 1997 throw new SecurityException("Requires MONITOR_INPUT permission"); 1998 } 1999 2000 mNative.cancelCurrentTouch(); 2001 } 2002 2003 @Override registerBatteryListener(int deviceId, IInputDeviceBatteryListener listener)2004 public void registerBatteryListener(int deviceId, IInputDeviceBatteryListener listener) { 2005 Objects.requireNonNull(listener); 2006 mBatteryController.registerBatteryListener(deviceId, listener, Binder.getCallingPid()); 2007 } 2008 2009 @Override unregisterBatteryListener(int deviceId, IInputDeviceBatteryListener listener)2010 public void unregisterBatteryListener(int deviceId, IInputDeviceBatteryListener listener) { 2011 Objects.requireNonNull(listener); 2012 mBatteryController.unregisterBatteryListener(deviceId, listener, Binder.getCallingPid()); 2013 } 2014 2015 @EnforcePermission(Manifest.permission.BLUETOOTH) 2016 @Override getInputDeviceBluetoothAddress(int deviceId)2017 public String getInputDeviceBluetoothAddress(int deviceId) { 2018 super.getInputDeviceBluetoothAddress_enforcePermission(); 2019 2020 final String address = mNative.getBluetoothAddress(deviceId); 2021 if (address == null) return null; 2022 if (!BluetoothAdapter.checkBluetoothAddress(address)) { 2023 throw new IllegalStateException("The Bluetooth address of input device " + deviceId 2024 + " should not be invalid: address=" + address); 2025 } 2026 return address; 2027 } 2028 2029 @EnforcePermission(Manifest.permission.MONITOR_INPUT) 2030 @Override pilferPointers(IBinder inputChannelToken)2031 public void pilferPointers(IBinder inputChannelToken) { 2032 super.pilferPointers_enforcePermission(); 2033 2034 Objects.requireNonNull(inputChannelToken); 2035 mNative.pilferPointers(inputChannelToken); 2036 } 2037 2038 @Override 2039 @EnforcePermission(Manifest.permission.MONITOR_KEYBOARD_BACKLIGHT) registerKeyboardBacklightListener(IKeyboardBacklightListener listener)2040 public void registerKeyboardBacklightListener(IKeyboardBacklightListener listener) { 2041 super.registerKeyboardBacklightListener_enforcePermission(); 2042 Objects.requireNonNull(listener); 2043 mKeyboardBacklightController.registerKeyboardBacklightListener(listener, 2044 Binder.getCallingPid()); 2045 } 2046 2047 @Override 2048 @EnforcePermission(Manifest.permission.MONITOR_KEYBOARD_BACKLIGHT) unregisterKeyboardBacklightListener(IKeyboardBacklightListener listener)2049 public void unregisterKeyboardBacklightListener(IKeyboardBacklightListener listener) { 2050 super.unregisterKeyboardBacklightListener_enforcePermission(); 2051 Objects.requireNonNull(listener); 2052 mKeyboardBacklightController.unregisterKeyboardBacklightListener(listener, 2053 Binder.getCallingPid()); 2054 } 2055 2056 @Override getHostUsiVersionFromDisplayConfig(int displayId)2057 public HostUsiVersion getHostUsiVersionFromDisplayConfig(int displayId) { 2058 return mDisplayManagerInternal.getHostUsiVersion(displayId); 2059 } 2060 2061 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)2062 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2063 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 2064 IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); 2065 2066 ipw.println("INPUT MANAGER (dumpsys input)\n"); 2067 String dumpStr = mNative.dump(); 2068 if (dumpStr != null) { 2069 pw.println(dumpStr); 2070 } 2071 2072 ipw.println("Input Manager Service (Java) State:"); 2073 ipw.increaseIndent(); 2074 dumpAssociations(ipw); 2075 dumpSpyWindowGestureMonitors(ipw); 2076 dumpDisplayInputPropertiesValues(ipw); 2077 mBatteryController.dump(ipw); 2078 mKeyboardBacklightController.dump(ipw); 2079 mKeyboardLedController.dump(ipw); 2080 } 2081 dumpAssociations(IndentingPrintWriter pw)2082 private void dumpAssociations(IndentingPrintWriter pw) { 2083 if (!mStaticAssociations.isEmpty()) { 2084 pw.println("Static Associations:"); 2085 mStaticAssociations.forEach((k, v) -> { 2086 pw.print(" port: " + k); 2087 pw.println(" display: " + v); 2088 }); 2089 } 2090 2091 synchronized (mAssociationsLock) { 2092 if (!mRuntimeAssociations.isEmpty()) { 2093 pw.println("Runtime Associations:"); 2094 mRuntimeAssociations.forEach((k, v) -> { 2095 pw.print(" port: " + k); 2096 pw.println(" display: " + v); 2097 }); 2098 } 2099 if (!mUniqueIdAssociationsByPort.isEmpty()) { 2100 pw.println("Unique Id Associations:"); 2101 mUniqueIdAssociationsByPort.forEach((k, v) -> { 2102 pw.print(" port: " + k); 2103 pw.println(" uniqueId: " + v); 2104 }); 2105 } 2106 if (!mUniqueIdAssociationsByDescriptor.isEmpty()) { 2107 pw.println("Unique Id Associations:"); 2108 mUniqueIdAssociationsByDescriptor.forEach((k, v) -> { 2109 pw.print(" descriptor: " + k); 2110 pw.println(" uniqueId: " + v); 2111 }); 2112 } 2113 if (!mDeviceTypeAssociations.isEmpty()) { 2114 pw.println("Type Associations:"); 2115 mDeviceTypeAssociations.forEach((k, v) -> { 2116 pw.print(" port: " + k); 2117 pw.println(" type: " + v); 2118 }); 2119 } 2120 } 2121 } 2122 dumpSpyWindowGestureMonitors(IndentingPrintWriter pw)2123 private void dumpSpyWindowGestureMonitors(IndentingPrintWriter pw) { 2124 synchronized (mInputMonitors) { 2125 if (mInputMonitors.isEmpty()) return; 2126 pw.println("Gesture Monitors (implemented as spy windows):"); 2127 int i = 0; 2128 for (final GestureMonitorSpyWindow monitor : mInputMonitors.values()) { 2129 pw.append(" " + i++ + ": ").println(monitor.dump()); 2130 } 2131 } 2132 } 2133 dumpDisplayInputPropertiesValues(IndentingPrintWriter pw)2134 private void dumpDisplayInputPropertiesValues(IndentingPrintWriter pw) { 2135 synchronized (mAdditionalDisplayInputPropertiesLock) { 2136 pw.println("mAdditionalDisplayInputProperties:"); 2137 pw.increaseIndent(); 2138 try { 2139 if (mAdditionalDisplayInputProperties.size() == 0) { 2140 pw.println("<none>"); 2141 return; 2142 } 2143 for (int i = 0; i < mAdditionalDisplayInputProperties.size(); i++) { 2144 pw.println("displayId: " + mAdditionalDisplayInputProperties.keyAt(i)); 2145 final AdditionalDisplayInputProperties properties = 2146 mAdditionalDisplayInputProperties.valueAt(i); 2147 pw.println("mousePointerAccelerationEnabled: " 2148 + properties.mousePointerAccelerationEnabled); 2149 pw.println("pointerIconVisible: " + properties.pointerIconVisible); 2150 } 2151 } finally { 2152 pw.decreaseIndent(); 2153 } 2154 } 2155 } checkCallingPermission(String permission, String func)2156 private boolean checkCallingPermission(String permission, String func) { 2157 return checkCallingPermission(permission, func, false /*checkInstrumentationSource*/); 2158 } 2159 checkCallingPermission(String permission, String func, boolean checkInstrumentationSource)2160 private boolean checkCallingPermission(String permission, String func, 2161 boolean checkInstrumentationSource) { 2162 // Quick check: if the calling permission is me, it's all okay. 2163 if (Binder.getCallingPid() == Process.myPid()) { 2164 return true; 2165 } 2166 2167 if (mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED) { 2168 return true; 2169 } 2170 2171 if (checkInstrumentationSource) { 2172 final ActivityManagerInternal ami = 2173 LocalServices.getService(ActivityManagerInternal.class); 2174 Objects.requireNonNull(ami, "ActivityManagerInternal should not be null."); 2175 final int instrumentationUid = ami.getInstrumentationSourceUid(Binder.getCallingUid()); 2176 if (instrumentationUid != Process.INVALID_UID) { 2177 // Clear the calling identity when checking if the instrumentation source has 2178 // permission because PackageManager will deny all permissions to some callers, 2179 // such as instant apps. 2180 final long token = Binder.clearCallingIdentity(); 2181 try { 2182 if (mContext.checkPermission(permission, -1 /*pid*/, instrumentationUid) 2183 == PackageManager.PERMISSION_GRANTED) { 2184 return true; 2185 } 2186 } finally { 2187 Binder.restoreCallingIdentity(token); 2188 } 2189 } 2190 } 2191 2192 String msg = "Permission Denial: " + func + " from pid=" 2193 + Binder.getCallingPid() 2194 + ", uid=" + Binder.getCallingUid() 2195 + " requires " + permission; 2196 Slog.w(TAG, msg); 2197 return false; 2198 } 2199 2200 // Called by the heartbeat to ensure locks are not held indefinitely (for deadlock detection). 2201 @Override monitor()2202 public void monitor() { 2203 synchronized (mInputFilterLock) { } 2204 synchronized (mAssociationsLock) { /* Test if blocked by associations lock. */} 2205 synchronized (mLidSwitchLock) { /* Test if blocked by lid switch lock. */ } 2206 synchronized (mInputMonitors) { /* Test if blocked by input monitor lock. */ } 2207 synchronized (mAdditionalDisplayInputPropertiesLock) { /* Test if blocked by props lock */ } 2208 mBatteryController.monitor(); 2209 mPointerIconCache.monitor(); 2210 mNative.monitor(); 2211 } 2212 2213 // Native callback. 2214 @SuppressWarnings("unused") notifyConfigurationChanged(long whenNanos)2215 private void notifyConfigurationChanged(long whenNanos) { 2216 mWindowManagerCallbacks.notifyConfigurationChanged(); 2217 } 2218 2219 // Native callback. 2220 @SuppressWarnings("unused") notifyInputDevicesChanged(InputDevice[] inputDevices)2221 private void notifyInputDevicesChanged(InputDevice[] inputDevices) { 2222 synchronized (mInputDevicesLock) { 2223 if (!mInputDevicesChangedPending) { 2224 mInputDevicesChangedPending = true; 2225 mHandler.obtainMessage(MSG_DELIVER_INPUT_DEVICES_CHANGED, 2226 mInputDevices).sendToTarget(); 2227 } 2228 2229 mInputDevices = inputDevices; 2230 } 2231 } 2232 2233 // Native callback. 2234 @SuppressWarnings("unused") notifySwitch(long whenNanos, int switchValues, int switchMask)2235 private void notifySwitch(long whenNanos, int switchValues, int switchMask) { 2236 if (DEBUG) { 2237 Slog.d(TAG, "notifySwitch: values=" + Integer.toHexString(switchValues) 2238 + ", mask=" + Integer.toHexString(switchMask)); 2239 } 2240 2241 if ((switchMask & SW_LID_BIT) != 0) { 2242 final boolean lidOpen = ((switchValues & SW_LID_BIT) == 0); 2243 synchronized (mLidSwitchLock) { 2244 if (mSystemReady) { 2245 for (int i = 0; i < mLidSwitchCallbacks.size(); i++) { 2246 LidSwitchCallback callbacks = mLidSwitchCallbacks.get(i); 2247 callbacks.notifyLidSwitchChanged(whenNanos, lidOpen); 2248 } 2249 } 2250 } 2251 } 2252 2253 if ((switchMask & SW_CAMERA_LENS_COVER_BIT) != 0) { 2254 final boolean lensCovered = ((switchValues & SW_CAMERA_LENS_COVER_BIT) != 0); 2255 mWindowManagerCallbacks.notifyCameraLensCoverSwitchChanged(whenNanos, lensCovered); 2256 // Use SW_CAMERA_LENS_COVER code for camera privacy toggles 2257 setSensorPrivacy(Sensors.CAMERA, lensCovered); 2258 } 2259 2260 if (mUseDevInputEventForAudioJack && (switchMask & SW_JACK_BITS) != 0) { 2261 mWiredAccessoryCallbacks.notifyWiredAccessoryChanged(whenNanos, switchValues, 2262 switchMask); 2263 } 2264 2265 if ((switchMask & SW_TABLET_MODE_BIT) != 0) { 2266 SomeArgs args = SomeArgs.obtain(); 2267 args.argi1 = (int) (whenNanos & 0xFFFFFFFF); 2268 args.argi2 = (int) (whenNanos >> 32); 2269 args.arg1 = (switchValues & SW_TABLET_MODE_BIT) != 0; 2270 mHandler.obtainMessage(MSG_DELIVER_TABLET_MODE_CHANGED, 2271 args).sendToTarget(); 2272 } 2273 2274 if ((switchMask & SW_MUTE_DEVICE_BIT) != 0) { 2275 final boolean micMute = ((switchValues & SW_MUTE_DEVICE_BIT) != 0); 2276 AudioManager audioManager = mContext.getSystemService(AudioManager.class); 2277 audioManager.setMicrophoneMuteFromSwitch(micMute); 2278 2279 setSensorPrivacy(Sensors.MICROPHONE, micMute); 2280 } 2281 } 2282 2283 // Set the sensor privacy state based on the hardware toggles switch states setSensorPrivacy(@ensorPrivacyManager.Sensors.Sensor int sensor, boolean enablePrivacy)2284 private void setSensorPrivacy(@SensorPrivacyManager.Sensors.Sensor int sensor, 2285 boolean enablePrivacy) { 2286 final SensorPrivacyManagerInternal sensorPrivacyManagerInternal = 2287 LocalServices.getService(SensorPrivacyManagerInternal.class); 2288 sensorPrivacyManagerInternal.setPhysicalToggleSensorPrivacy(UserHandle.USER_CURRENT, sensor, 2289 enablePrivacy); 2290 } 2291 2292 // Native callback. 2293 @SuppressWarnings("unused") notifyInputChannelBroken(IBinder token)2294 private void notifyInputChannelBroken(IBinder token) { 2295 synchronized (mInputMonitors) { 2296 if (mInputMonitors.containsKey(token)) { 2297 removeSpyWindowGestureMonitor(token); 2298 } 2299 } 2300 mWindowManagerCallbacks.notifyInputChannelBroken(token); 2301 } 2302 2303 // Native callback 2304 @SuppressWarnings("unused") notifyFocusChanged(IBinder oldToken, IBinder newToken)2305 private void notifyFocusChanged(IBinder oldToken, IBinder newToken) { 2306 mWindowManagerCallbacks.notifyFocusChanged(oldToken, newToken); 2307 } 2308 2309 // Native callback 2310 @SuppressWarnings("unused") notifyDropWindow(IBinder token, float x, float y)2311 private void notifyDropWindow(IBinder token, float x, float y) { 2312 mWindowManagerCallbacks.notifyDropWindow(token, x, y); 2313 } 2314 2315 // Native callback. 2316 @SuppressWarnings("unused") notifyNoFocusedWindowAnr(InputApplicationHandle inputApplicationHandle)2317 private void notifyNoFocusedWindowAnr(InputApplicationHandle inputApplicationHandle) { 2318 mWindowManagerCallbacks.notifyNoFocusedWindowAnr(inputApplicationHandle); 2319 } 2320 2321 // Native callback 2322 @SuppressWarnings("unused") notifyWindowUnresponsive(IBinder token, int pid, boolean isPidValid, String reason)2323 private void notifyWindowUnresponsive(IBinder token, int pid, boolean isPidValid, 2324 String reason) { 2325 mWindowManagerCallbacks.notifyWindowUnresponsive(token, 2326 isPidValid ? OptionalInt.of(pid) : OptionalInt.empty(), reason); 2327 } 2328 2329 // Native callback 2330 @SuppressWarnings("unused") notifyWindowResponsive(IBinder token, int pid, boolean isPidValid)2331 private void notifyWindowResponsive(IBinder token, int pid, boolean isPidValid) { 2332 mWindowManagerCallbacks.notifyWindowResponsive(token, 2333 isPidValid ? OptionalInt.of(pid) : OptionalInt.empty()); 2334 } 2335 2336 // Native callback. 2337 @SuppressWarnings("unused") notifySensorEvent(int deviceId, int sensorType, int accuracy, long timestamp, float[] values)2338 private void notifySensorEvent(int deviceId, int sensorType, int accuracy, long timestamp, 2339 float[] values) { 2340 if (DEBUG) { 2341 Slog.d(TAG, "notifySensorEvent: deviceId=" + deviceId + " sensorType=" 2342 + sensorType + " values=" + Arrays.toString(values)); 2343 } 2344 mSensorEventListenersToNotify.clear(); 2345 final int numListeners; 2346 synchronized (mSensorEventLock) { 2347 numListeners = mSensorEventListeners.size(); 2348 for (int i = 0; i < numListeners; i++) { 2349 mSensorEventListenersToNotify.add( 2350 mSensorEventListeners.valueAt(i)); 2351 } 2352 } 2353 for (int i = 0; i < numListeners; i++) { 2354 mSensorEventListenersToNotify.get(i).notifySensorEvent(deviceId, sensorType, 2355 accuracy, timestamp, values); 2356 } 2357 mSensorEventListenersToNotify.clear(); 2358 } 2359 2360 // Native callback. 2361 @SuppressWarnings("unused") notifySensorAccuracy(int deviceId, int sensorType, int accuracy)2362 private void notifySensorAccuracy(int deviceId, int sensorType, int accuracy) { 2363 mSensorAccuracyListenersToNotify.clear(); 2364 final int numListeners; 2365 synchronized (mSensorEventLock) { 2366 numListeners = mSensorEventListeners.size(); 2367 for (int i = 0; i < numListeners; i++) { 2368 mSensorAccuracyListenersToNotify.add(mSensorEventListeners.valueAt(i)); 2369 } 2370 } 2371 for (int i = 0; i < numListeners; i++) { 2372 mSensorAccuracyListenersToNotify.get(i).notifySensorAccuracy( 2373 deviceId, sensorType, accuracy); 2374 } 2375 mSensorAccuracyListenersToNotify.clear(); 2376 } 2377 2378 // Native callback. 2379 @SuppressWarnings("unused") filterInputEvent(InputEvent event, int policyFlags)2380 final boolean filterInputEvent(InputEvent event, int policyFlags) { 2381 synchronized (mInputFilterLock) { 2382 if (mInputFilter != null) { 2383 try { 2384 mInputFilter.filterInputEvent(event, policyFlags); 2385 } catch (RemoteException e) { 2386 /* ignore */ 2387 } 2388 return false; 2389 } 2390 } 2391 event.recycle(); 2392 return true; 2393 } 2394 2395 // Native callback. 2396 @SuppressWarnings("unused") interceptKeyBeforeQueueing(KeyEvent event, int policyFlags)2397 private int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) { 2398 synchronized (mFocusEventDebugViewLock) { 2399 if (mFocusEventDebugView != null) { 2400 mFocusEventDebugView.reportKeyEvent(event); 2401 } 2402 } 2403 return mWindowManagerCallbacks.interceptKeyBeforeQueueing(event, policyFlags); 2404 } 2405 2406 // Native callback. 2407 @SuppressWarnings("unused") interceptMotionBeforeQueueingNonInteractive(int displayId, int source, int action, long whenNanos, int policyFlags)2408 private int interceptMotionBeforeQueueingNonInteractive(int displayId, 2409 int source, int action, long whenNanos, int policyFlags) { 2410 return mWindowManagerCallbacks.interceptMotionBeforeQueueingNonInteractive( 2411 displayId, source, action, whenNanos, policyFlags); 2412 } 2413 2414 // Native callback. 2415 @SuppressWarnings("unused") interceptKeyBeforeDispatching(IBinder focus, KeyEvent event, int policyFlags)2416 private long interceptKeyBeforeDispatching(IBinder focus, KeyEvent event, int policyFlags) { 2417 return mWindowManagerCallbacks.interceptKeyBeforeDispatching(focus, event, policyFlags); 2418 } 2419 2420 // Native callback. 2421 @SuppressWarnings("unused") dispatchUnhandledKey(IBinder focus, KeyEvent event, int policyFlags)2422 private KeyEvent dispatchUnhandledKey(IBinder focus, KeyEvent event, int policyFlags) { 2423 return mWindowManagerCallbacks.dispatchUnhandledKey(focus, event, policyFlags); 2424 } 2425 2426 // Native callback. 2427 @SuppressWarnings("unused") onPointerDownOutsideFocus(IBinder touchedToken)2428 private void onPointerDownOutsideFocus(IBinder touchedToken) { 2429 mWindowManagerCallbacks.onPointerDownOutsideFocus(touchedToken); 2430 } 2431 2432 // Native callback. 2433 @SuppressWarnings("unused") getVirtualKeyQuietTimeMillis()2434 private int getVirtualKeyQuietTimeMillis() { 2435 return mContext.getResources().getInteger( 2436 com.android.internal.R.integer.config_virtualKeyQuietTimeMillis); 2437 } 2438 2439 // Native callback. 2440 @SuppressWarnings("unused") getExcludedDeviceNames()2441 private static String[] getExcludedDeviceNames() { 2442 List<String> names = new ArrayList<>(); 2443 // Read partner-provided list of excluded input devices 2444 // Environment.getRootDirectory() is a fancy way of saying ANDROID_ROOT or "/system". 2445 final File[] baseDirs = { 2446 Environment.getRootDirectory(), 2447 Environment.getVendorDirectory() 2448 }; 2449 for (File baseDir: baseDirs) { 2450 File confFile = new File(baseDir, EXCLUDED_DEVICES_PATH); 2451 try (InputStream stream = new FileInputStream(confFile)) { 2452 names.addAll(ConfigurationProcessor.processExcludedDeviceNames(stream)); 2453 } catch (FileNotFoundException e) { 2454 // It's ok if the file does not exist. 2455 } catch (Exception e) { 2456 Slog.e(TAG, "Could not parse '" + confFile.getAbsolutePath() + "'", e); 2457 } 2458 } 2459 return names.toArray(new String[0]); 2460 } 2461 2462 // Native callback. 2463 @SuppressWarnings("unused") isPerDisplayTouchModeEnabled()2464 private boolean isPerDisplayTouchModeEnabled() { 2465 return mContext.getResources().getBoolean( 2466 com.android.internal.R.bool.config_perDisplayFocusEnabled); 2467 } 2468 2469 // Native callback. 2470 @SuppressWarnings("unused") notifyStylusGestureStarted(int deviceId, long eventTime)2471 private void notifyStylusGestureStarted(int deviceId, long eventTime) { 2472 mBatteryController.notifyStylusGestureStarted(deviceId, eventTime); 2473 } 2474 2475 /** 2476 * Flatten a map into a string list, with value positioned directly next to the 2477 * key. 2478 * @return Flattened list 2479 */ flatten(@onNull Map<String, T> map)2480 private static <T> String[] flatten(@NonNull Map<String, T> map) { 2481 final List<String> list = new ArrayList<>(map.size() * 2); 2482 map.forEach((k, v)-> { 2483 list.add(k); 2484 list.add(v.toString()); 2485 }); 2486 return list.toArray(new String[0]); 2487 } 2488 2489 /** 2490 * Ports are highly platform-specific, so allow these to be specified in the odm/vendor 2491 * directory. 2492 */ loadStaticInputPortAssociations()2493 private static Map<String, Integer> loadStaticInputPortAssociations() { 2494 File baseDir = Environment.getOdmDirectory(); 2495 File confFile = new File(baseDir, PORT_ASSOCIATIONS_PATH); 2496 2497 if (!confFile.exists()) { 2498 baseDir = Environment.getVendorDirectory(); 2499 confFile = new File(baseDir, PORT_ASSOCIATIONS_PATH); 2500 } 2501 2502 try (final InputStream stream = new FileInputStream(confFile)) { 2503 return ConfigurationProcessor.processInputPortAssociations(stream); 2504 } catch (FileNotFoundException e) { 2505 // Most of the time, file will not exist, which is expected. 2506 } catch (Exception e) { 2507 Slog.e(TAG, "Could not parse '" + confFile.getAbsolutePath() + "'", e); 2508 } 2509 2510 return new HashMap<>(); 2511 } 2512 2513 // Native callback 2514 @SuppressWarnings("unused") getInputPortAssociations()2515 private String[] getInputPortAssociations() { 2516 final Map<String, Integer> associations = new HashMap<>(mStaticAssociations); 2517 2518 // merge the runtime associations. 2519 synchronized (mAssociationsLock) { 2520 associations.putAll(mRuntimeAssociations); 2521 } 2522 2523 return flatten(associations); 2524 } 2525 2526 // Native callback 2527 @SuppressWarnings("unused") getInputUniqueIdAssociationsByPort()2528 private String[] getInputUniqueIdAssociationsByPort() { 2529 final Map<String, String> associations; 2530 synchronized (mAssociationsLock) { 2531 associations = new HashMap<>(mUniqueIdAssociationsByPort); 2532 } 2533 2534 return flatten(associations); 2535 } 2536 2537 // Native callback 2538 @SuppressWarnings("unused") getInputUniqueIdAssociationsByDescriptor()2539 private String[] getInputUniqueIdAssociationsByDescriptor() { 2540 final Map<String, String> associations; 2541 synchronized (mAssociationsLock) { 2542 associations = new HashMap<>(mUniqueIdAssociationsByDescriptor); 2543 } 2544 2545 return flatten(associations); 2546 } 2547 2548 // Native callback 2549 @SuppressWarnings("unused") 2550 @VisibleForTesting getDeviceTypeAssociations()2551 String[] getDeviceTypeAssociations() { 2552 final Map<String, String> associations; 2553 synchronized (mAssociationsLock) { 2554 associations = new HashMap<>(mDeviceTypeAssociations); 2555 } 2556 2557 return flatten(associations); 2558 } 2559 2560 // Native callback 2561 @SuppressWarnings("unused") 2562 @VisibleForTesting getKeyboardLayoutAssociations()2563 private String[] getKeyboardLayoutAssociations() { 2564 final Map<String, String> configs = new ArrayMap<>(); 2565 synchronized (mAssociationsLock) { 2566 configs.putAll(mKeyboardLayoutAssociations); 2567 } 2568 return flatten(configs); 2569 } 2570 2571 /** 2572 * Gets if an input device could dispatch to the given display". 2573 * @param deviceId The input device id. 2574 * @param displayId The specific display id. 2575 * @return True if the device could dispatch to the given display, false otherwise. 2576 */ canDispatchToDisplay(int deviceId, int displayId)2577 public boolean canDispatchToDisplay(int deviceId, int displayId) { 2578 return mNative.canDispatchToDisplay(deviceId, displayId); 2579 } 2580 2581 // Native callback. 2582 @SuppressWarnings("unused") getHoverTapTimeout()2583 private int getHoverTapTimeout() { 2584 return ViewConfiguration.getHoverTapTimeout(); 2585 } 2586 2587 // Native callback. 2588 @SuppressWarnings("unused") getHoverTapSlop()2589 private int getHoverTapSlop() { 2590 return ViewConfiguration.getHoverTapSlop(); 2591 } 2592 2593 // Native callback. 2594 @SuppressWarnings("unused") getDoubleTapTimeout()2595 private int getDoubleTapTimeout() { 2596 return ViewConfiguration.getDoubleTapTimeout(); 2597 } 2598 2599 // Native callback. 2600 @SuppressWarnings("unused") getLongPressTimeout()2601 private int getLongPressTimeout() { 2602 return ViewConfiguration.getLongPressTimeout(); 2603 } 2604 2605 // Native callback. 2606 @SuppressWarnings("unused") getPointerLayer()2607 private int getPointerLayer() { 2608 return mWindowManagerCallbacks.getPointerLayer(); 2609 } 2610 2611 // Native callback. 2612 @SuppressWarnings("unused") getLoadedPointerIcon(int displayId, int type)2613 private @NonNull PointerIcon getLoadedPointerIcon(int displayId, int type) { 2614 return mPointerIconCache.getLoadedPointerIcon(displayId, type); 2615 } 2616 2617 // Native callback. 2618 @SuppressWarnings("unused") getParentSurfaceForPointers(int displayId)2619 private long getParentSurfaceForPointers(int displayId) { 2620 final SurfaceControl sc = mWindowManagerCallbacks.getParentSurfaceForPointers(displayId); 2621 if (sc == null) { 2622 return 0; 2623 } 2624 return sc.mNativeObject; 2625 } 2626 2627 // Native callback. 2628 @SuppressWarnings("unused") getKeyboardLayoutOverlay(InputDeviceIdentifier identifier, String languageTag, String layoutType)2629 private String[] getKeyboardLayoutOverlay(InputDeviceIdentifier identifier, String languageTag, 2630 String layoutType) { 2631 if (!mSystemReady) { 2632 return null; 2633 } 2634 return mKeyboardLayoutManager.getKeyboardLayoutOverlay(identifier, languageTag, layoutType); 2635 } 2636 2637 @EnforcePermission(Manifest.permission.REMAP_MODIFIER_KEYS) 2638 @Override // Binder call remapModifierKey(int fromKey, int toKey)2639 public void remapModifierKey(int fromKey, int toKey) { 2640 super.remapModifierKey_enforcePermission(); 2641 mKeyRemapper.remapKey(fromKey, toKey); 2642 } 2643 2644 @EnforcePermission(Manifest.permission.REMAP_MODIFIER_KEYS) 2645 @Override // Binder call clearAllModifierKeyRemappings()2646 public void clearAllModifierKeyRemappings() { 2647 super.clearAllModifierKeyRemappings_enforcePermission(); 2648 mKeyRemapper.clearAllKeyRemappings(); 2649 } 2650 2651 @EnforcePermission(Manifest.permission.REMAP_MODIFIER_KEYS) 2652 @Override // Binder call getModifierKeyRemapping()2653 public Map<Integer, Integer> getModifierKeyRemapping() { 2654 super.getModifierKeyRemapping_enforcePermission(); 2655 return mKeyRemapper.getKeyRemapping(); 2656 } 2657 2658 // Native callback. 2659 @SuppressWarnings("unused") getDeviceAlias(String uniqueId)2660 private String getDeviceAlias(String uniqueId) { 2661 if (BluetoothAdapter.checkBluetoothAddress(uniqueId)) { 2662 // TODO(BT) mBluetoothService.getRemoteAlias(uniqueId) 2663 return null; 2664 } 2665 return null; 2666 } 2667 2668 @Override 2669 @EnforcePermission(Manifest.permission.MONITOR_STICKY_MODIFIER_STATE) registerStickyModifierStateListener( @onNull IStickyModifierStateListener listener)2670 public void registerStickyModifierStateListener( 2671 @NonNull IStickyModifierStateListener listener) { 2672 super.registerStickyModifierStateListener_enforcePermission(); 2673 Objects.requireNonNull(listener); 2674 mStickyModifierStateController.registerStickyModifierStateListener(listener, 2675 Binder.getCallingPid()); 2676 } 2677 2678 @Override 2679 @EnforcePermission(Manifest.permission.MONITOR_STICKY_MODIFIER_STATE) unregisterStickyModifierStateListener( @onNull IStickyModifierStateListener listener)2680 public void unregisterStickyModifierStateListener( 2681 @NonNull IStickyModifierStateListener listener) { 2682 super.unregisterStickyModifierStateListener_enforcePermission(); 2683 Objects.requireNonNull(listener); 2684 mStickyModifierStateController.unregisterStickyModifierStateListener(listener, 2685 Binder.getCallingPid()); 2686 } 2687 2688 // Native callback 2689 @SuppressWarnings("unused") notifyStickyModifierStateChanged(int modifierState, int lockedModifierState)2690 void notifyStickyModifierStateChanged(int modifierState, int lockedModifierState) { 2691 mStickyModifierStateController.notifyStickyModifierStateChanged(modifierState, 2692 lockedModifierState); 2693 } 2694 2695 /** 2696 * Callback interface implemented by the Window Manager. 2697 */ 2698 public interface WindowManagerCallbacks extends LidSwitchCallback { 2699 /** 2700 * This callback is invoked when the configuration changes. 2701 */ notifyConfigurationChanged()2702 void notifyConfigurationChanged(); 2703 2704 /** 2705 * This callback is invoked when the pointer location changes. 2706 */ notifyPointerLocationChanged(boolean pointerLocationEnabled)2707 void notifyPointerLocationChanged(boolean pointerLocationEnabled); 2708 2709 /** 2710 * This callback is invoked when the camera lens cover switch changes state. 2711 * @param whenNanos the time when the change occurred 2712 * @param lensCovered true is the lens is covered 2713 */ notifyCameraLensCoverSwitchChanged(long whenNanos, boolean lensCovered)2714 void notifyCameraLensCoverSwitchChanged(long whenNanos, boolean lensCovered); 2715 2716 /** 2717 * This callback is invoked when an input channel is closed unexpectedly. 2718 * @param token the connection token of the broken channel 2719 */ notifyInputChannelBroken(IBinder token)2720 void notifyInputChannelBroken(IBinder token); 2721 2722 /** 2723 * Notify the window manager about the focused application that does not have any focused 2724 * window and is unable to respond to focused input events. 2725 */ notifyNoFocusedWindowAnr(InputApplicationHandle applicationHandle)2726 void notifyNoFocusedWindowAnr(InputApplicationHandle applicationHandle); 2727 2728 /** 2729 * Notify the window manager about a window that is unresponsive. 2730 * 2731 * @param token the token that can be used to look up the window 2732 * @param pid the pid of the window owner, if known 2733 * @param reason the reason why this connection is unresponsive 2734 */ notifyWindowUnresponsive(@onNull IBinder token, @NonNull OptionalInt pid, @NonNull String reason)2735 void notifyWindowUnresponsive(@NonNull IBinder token, @NonNull OptionalInt pid, 2736 @NonNull String reason); 2737 2738 /** 2739 * Notify the window manager about a window that has become responsive. 2740 * 2741 * @param token the token that can be used to look up the window 2742 * @param pid the pid of the window owner, if known 2743 */ notifyWindowResponsive(@onNull IBinder token, @NonNull OptionalInt pid)2744 void notifyWindowResponsive(@NonNull IBinder token, @NonNull OptionalInt pid); 2745 2746 /** 2747 * This callback is invoked when an event first arrives to InputDispatcher and before it is 2748 * placed onto InputDispatcher's queue. If this event is intercepted, it will never be 2749 * processed by InputDispacher. 2750 * @param event The key event that's arriving to InputDispatcher 2751 * @param policyFlags The policy flags 2752 * @return the flags that tell InputDispatcher how to handle the event (for example, whether 2753 * to pass it to the user) 2754 */ interceptKeyBeforeQueueing(KeyEvent event, int policyFlags)2755 int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags); 2756 2757 /** 2758 * Provides an opportunity for the window manager policy to intercept early motion event 2759 * processing when the device is in a non-interactive state since these events are normally 2760 * dropped. 2761 */ interceptMotionBeforeQueueingNonInteractive(int displayId, int source, int action, long whenNanos, int policyFlags)2762 int interceptMotionBeforeQueueingNonInteractive(int displayId, int source, int action, 2763 long whenNanos, int policyFlags); 2764 2765 /** 2766 * This callback is invoked just before the key is about to be sent to an application. 2767 * This allows the policy to make some last minute decisions on whether to intercept this 2768 * key. 2769 * @param token the window token that's about to receive this event 2770 * @param event the key event that's being dispatched 2771 * @param policyFlags the policy flags 2772 * @return negative value if the key should be skipped (not sent to the app). 0 if the key 2773 * should proceed getting dispatched to the app. positive value to indicate the additional 2774 * time delay, in nanoseconds, to wait before sending this key to the app. 2775 */ interceptKeyBeforeDispatching(IBinder token, KeyEvent event, int policyFlags)2776 long interceptKeyBeforeDispatching(IBinder token, KeyEvent event, int policyFlags); 2777 2778 /** 2779 * Dispatch unhandled key 2780 */ dispatchUnhandledKey(IBinder token, KeyEvent event, int policyFlags)2781 KeyEvent dispatchUnhandledKey(IBinder token, KeyEvent event, int policyFlags); 2782 getPointerLayer()2783 int getPointerLayer(); 2784 getPointerDisplayId()2785 int getPointerDisplayId(); 2786 2787 /** 2788 * Notifies window manager that a {@link android.view.MotionEvent#ACTION_DOWN} pointer event 2789 * occurred on a window that did not have focus. 2790 * 2791 * @param touchedToken The token for the window that received the input event. 2792 */ onPointerDownOutsideFocus(IBinder touchedToken)2793 void onPointerDownOutsideFocus(IBinder touchedToken); 2794 2795 /** 2796 * Called when the focused window has changed. 2797 */ notifyFocusChanged(IBinder oldToken, IBinder newToken)2798 void notifyFocusChanged(IBinder oldToken, IBinder newToken); 2799 2800 /** 2801 * Called when the drag over window has changed. 2802 */ notifyDropWindow(IBinder token, float x, float y)2803 void notifyDropWindow(IBinder token, float x, float y); 2804 2805 /** 2806 * Get the {@link SurfaceControl} that should be the parent for the surfaces created for 2807 * pointers such as the mouse cursor and touch spots for the given display. 2808 */ getParentSurfaceForPointers(int displayId)2809 SurfaceControl getParentSurfaceForPointers(int displayId); 2810 2811 /** 2812 * Create a {@link SurfaceControl} that can be configured to receive input over the entire 2813 * display to implement a gesture monitor. The surface will not have a graphical buffer. 2814 * @param name the name of the gesture monitor 2815 * @param displayId the display to create the window in 2816 * @return the SurfaceControl of the new layer container surface 2817 */ 2818 @Nullable createSurfaceForGestureMonitor(String name, int displayId)2819 SurfaceControl createSurfaceForGestureMonitor(String name, int displayId); 2820 } 2821 2822 /** 2823 * Callback interface implemented by WiredAccessoryObserver. 2824 */ 2825 public interface WiredAccessoryCallbacks { 2826 /** 2827 * Notifies WiredAccessoryObserver that input state for wired accessories has changed 2828 * @param whenNanos When the wired accessories changed 2829 * @param switchValues The state of the switches 2830 * @param switchMask The mask of switches that changed 2831 */ notifyWiredAccessoryChanged(long whenNanos, int switchValues, int switchMask)2832 void notifyWiredAccessoryChanged(long whenNanos, int switchValues, int switchMask); 2833 2834 /** 2835 * Notifies WiredAccessoryObserver that the system is now ready. 2836 */ systemReady()2837 void systemReady(); 2838 } 2839 2840 /** 2841 * Private handler for the input manager. 2842 */ 2843 private final class InputManagerHandler extends Handler { InputManagerHandler(Looper looper)2844 public InputManagerHandler(Looper looper) { 2845 super(looper, null, true /*async*/); 2846 } 2847 2848 @Override handleMessage(Message msg)2849 public void handleMessage(Message msg) { 2850 switch (msg.what) { 2851 case MSG_DELIVER_INPUT_DEVICES_CHANGED: 2852 deliverInputDevicesChanged((InputDevice[])msg.obj); 2853 break; 2854 case MSG_RELOAD_DEVICE_ALIASES: 2855 reloadDeviceAliases(); 2856 break; 2857 case MSG_DELIVER_TABLET_MODE_CHANGED: 2858 SomeArgs args = (SomeArgs) msg.obj; 2859 long whenNanos = (args.argi1 & 0xFFFFFFFFL) | ((long) args.argi2 << 32); 2860 boolean inTabletMode = (boolean) args.arg1; 2861 deliverTabletModeChanged(whenNanos, inTabletMode); 2862 break; 2863 } 2864 } 2865 } 2866 2867 /** 2868 * Hosting interface for input filters to call back into the input manager. 2869 */ 2870 private final class InputFilterHost extends IInputFilterHost.Stub { 2871 @GuardedBy("mInputFilterLock") 2872 private boolean mDisconnected; 2873 2874 @GuardedBy("mInputFilterLock") disconnectLocked()2875 public void disconnectLocked() { 2876 mDisconnected = true; 2877 } 2878 2879 @Override sendInputEvent(InputEvent event, int policyFlags)2880 public void sendInputEvent(InputEvent event, int policyFlags) { 2881 if (!checkCallingPermission(android.Manifest.permission.INJECT_EVENTS, 2882 "sendInputEvent()")) { 2883 throw new SecurityException( 2884 "The INJECT_EVENTS permission is required for injecting input events."); 2885 } 2886 Objects.requireNonNull(event, "event must not be null"); 2887 2888 synchronized (mInputFilterLock) { 2889 if (!mDisconnected) { 2890 mNative.injectInputEvent(event, false /* injectIntoUid */, -1 /* uid */, 2891 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC, 0 /* timeout */, 2892 policyFlags | WindowManagerPolicy.FLAG_FILTERED); 2893 } 2894 } 2895 } 2896 } 2897 2898 /** 2899 * Interface for the system to handle request from InputMonitors. 2900 */ 2901 private final class InputMonitorHost extends IInputMonitorHost.Stub { 2902 private final IBinder mInputChannelToken; 2903 InputMonitorHost(IBinder inputChannelToken)2904 InputMonitorHost(IBinder inputChannelToken) { 2905 mInputChannelToken = inputChannelToken; 2906 } 2907 2908 @Override pilferPointers()2909 public void pilferPointers() { 2910 mNative.pilferPointers(mInputChannelToken); 2911 } 2912 2913 @Override dispose()2914 public void dispose() { 2915 removeSpyWindowGestureMonitor(mInputChannelToken); 2916 } 2917 } 2918 2919 private final class InputDevicesChangedListenerRecord implements DeathRecipient { 2920 private final int mPid; 2921 private final IInputDevicesChangedListener mListener; 2922 InputDevicesChangedListenerRecord(int pid, IInputDevicesChangedListener listener)2923 public InputDevicesChangedListenerRecord(int pid, IInputDevicesChangedListener listener) { 2924 mPid = pid; 2925 mListener = listener; 2926 } 2927 2928 @Override binderDied()2929 public void binderDied() { 2930 if (DEBUG) { 2931 Slog.d(TAG, "Input devices changed listener for pid " + mPid + " died."); 2932 } 2933 onInputDevicesChangedListenerDied(mPid); 2934 } 2935 notifyInputDevicesChanged(int[] info)2936 public void notifyInputDevicesChanged(int[] info) { 2937 try { 2938 mListener.onInputDevicesChanged(info); 2939 } catch (RemoteException ex) { 2940 Slog.w(TAG, "Failed to notify process " 2941 + mPid + " that input devices changed, assuming it died.", ex); 2942 binderDied(); 2943 } 2944 } 2945 } 2946 2947 private final class TabletModeChangedListenerRecord implements DeathRecipient { 2948 private final int mPid; 2949 private final ITabletModeChangedListener mListener; 2950 TabletModeChangedListenerRecord(int pid, ITabletModeChangedListener listener)2951 public TabletModeChangedListenerRecord(int pid, ITabletModeChangedListener listener) { 2952 mPid = pid; 2953 mListener = listener; 2954 } 2955 2956 @Override binderDied()2957 public void binderDied() { 2958 if (DEBUG) { 2959 Slog.d(TAG, "Tablet mode changed listener for pid " + mPid + " died."); 2960 } 2961 onTabletModeChangedListenerDied(mPid); 2962 } 2963 notifyTabletModeChanged(long whenNanos, boolean inTabletMode)2964 public void notifyTabletModeChanged(long whenNanos, boolean inTabletMode) { 2965 try { 2966 mListener.onTabletModeChanged(whenNanos, inTabletMode); 2967 } catch (RemoteException ex) { 2968 Slog.w(TAG, "Failed to notify process " + mPid + 2969 " that tablet mode changed, assuming it died.", ex); 2970 binderDied(); 2971 } 2972 } 2973 } 2974 onSensorEventListenerDied(int pid)2975 private void onSensorEventListenerDied(int pid) { 2976 synchronized (mSensorEventLock) { 2977 mSensorEventListeners.remove(pid); 2978 } 2979 } 2980 2981 private final class SensorEventListenerRecord implements DeathRecipient { 2982 private final int mPid; 2983 private final IInputSensorEventListener mListener; 2984 SensorEventListenerRecord(int pid, IInputSensorEventListener listener)2985 SensorEventListenerRecord(int pid, IInputSensorEventListener listener) { 2986 mPid = pid; 2987 mListener = listener; 2988 } 2989 2990 @Override binderDied()2991 public void binderDied() { 2992 if (DEBUG) { 2993 Slog.d(TAG, "Sensor event listener for pid " + mPid + " died."); 2994 } 2995 onSensorEventListenerDied(mPid); 2996 } 2997 getListener()2998 public IInputSensorEventListener getListener() { 2999 return mListener; 3000 } 3001 notifySensorEvent(int deviceId, int sensorType, int accuracy, long timestamp, float[] values)3002 public void notifySensorEvent(int deviceId, int sensorType, int accuracy, long timestamp, 3003 float[] values) { 3004 try { 3005 mListener.onInputSensorChanged(deviceId, sensorType, accuracy, timestamp, 3006 values); 3007 } catch (RemoteException ex) { 3008 Slog.w(TAG, "Failed to notify process " + mPid 3009 + " that sensor event notified, assuming it died.", ex); 3010 binderDied(); 3011 } 3012 } 3013 notifySensorAccuracy(int deviceId, int sensorType, int accuracy)3014 public void notifySensorAccuracy(int deviceId, int sensorType, int accuracy) { 3015 try { 3016 mListener.onInputSensorAccuracyChanged(deviceId, sensorType, accuracy); 3017 } catch (RemoteException ex) { 3018 Slog.w(TAG, "Failed to notify process " + mPid 3019 + " that sensor accuracy notified, assuming it died.", ex); 3020 binderDied(); 3021 } 3022 } 3023 } 3024 3025 private final class VibratorToken implements DeathRecipient { 3026 public final int mDeviceId; 3027 public final IBinder mToken; 3028 public final int mTokenValue; 3029 3030 public boolean mVibrating; 3031 VibratorToken(int deviceId, IBinder token, int tokenValue)3032 public VibratorToken(int deviceId, IBinder token, int tokenValue) { 3033 mDeviceId = deviceId; 3034 mToken = token; 3035 mTokenValue = tokenValue; 3036 } 3037 3038 @Override binderDied()3039 public void binderDied() { 3040 if (DEBUG) { 3041 Slog.d(TAG, "Vibrator token died."); 3042 } 3043 onVibratorTokenDied(this); 3044 } 3045 } 3046 3047 private final class LocalService extends InputManagerInternal { 3048 @Override setDisplayViewports(List<DisplayViewport> viewports)3049 public void setDisplayViewports(List<DisplayViewport> viewports) { 3050 setDisplayViewportsInternal(viewports); 3051 } 3052 3053 @Override setInteractive(boolean interactive)3054 public void setInteractive(boolean interactive) { 3055 mNative.setInteractive(interactive); 3056 mBatteryController.onInteractiveChanged(interactive); 3057 mKeyboardBacklightController.onInteractiveChanged(interactive); 3058 } 3059 3060 @Override toggleCapsLock(int deviceId)3061 public void toggleCapsLock(int deviceId) { 3062 mNative.toggleCapsLock(deviceId); 3063 } 3064 3065 @Override setPulseGestureEnabled(boolean enabled)3066 public void setPulseGestureEnabled(boolean enabled) { 3067 if (mDoubleTouchGestureEnableFile != null) { 3068 FileWriter writer = null; 3069 try { 3070 writer = new FileWriter(mDoubleTouchGestureEnableFile); 3071 writer.write(enabled ? "1" : "0"); 3072 } catch (IOException e) { 3073 Log.wtf(TAG, "Unable to setPulseGestureEnabled", e); 3074 } finally { 3075 IoUtils.closeQuietly(writer); 3076 } 3077 } 3078 } 3079 3080 @Override transferTouchGesture(@onNull IBinder fromChannelToken, @NonNull IBinder toChannelToken)3081 public boolean transferTouchGesture(@NonNull IBinder fromChannelToken, 3082 @NonNull IBinder toChannelToken) { 3083 return InputManagerService.this.transferTouchGesture(fromChannelToken, toChannelToken); 3084 } 3085 3086 @Override getCursorPosition(int displayId)3087 public PointF getCursorPosition(int displayId) { 3088 final float[] p = mNative.getMouseCursorPosition(displayId); 3089 if (p == null || p.length != 2) { 3090 throw new IllegalStateException("Failed to get mouse cursor position"); 3091 } 3092 return new PointF(p[0], p[1]); 3093 } 3094 3095 @Override setMousePointerAccelerationEnabled(boolean enabled, int displayId)3096 public void setMousePointerAccelerationEnabled(boolean enabled, int displayId) { 3097 InputManagerService.this.setMousePointerAccelerationEnabled(enabled, displayId); 3098 } 3099 3100 @Override setDisplayEligibilityForPointerCapture(int displayId, boolean isEligible)3101 public void setDisplayEligibilityForPointerCapture(int displayId, boolean isEligible) { 3102 InputManagerService.this.setDisplayEligibilityForPointerCapture(displayId, isEligible); 3103 } 3104 3105 @Override setPointerIconVisible(boolean visible, int displayId)3106 public void setPointerIconVisible(boolean visible, int displayId) { 3107 InputManagerService.this.setPointerIconVisible(visible, displayId); 3108 } 3109 3110 @Override registerLidSwitchCallback(LidSwitchCallback callbacks)3111 public void registerLidSwitchCallback(LidSwitchCallback callbacks) { 3112 registerLidSwitchCallbackInternal(callbacks); 3113 } 3114 3115 @Override unregisterLidSwitchCallback(LidSwitchCallback callbacks)3116 public void unregisterLidSwitchCallback(LidSwitchCallback callbacks) { 3117 unregisterLidSwitchCallbackInternal(callbacks); 3118 } 3119 3120 @Override notifyInputMethodConnectionActive(boolean connectionIsActive)3121 public void notifyInputMethodConnectionActive(boolean connectionIsActive) { 3122 mNative.setInputMethodConnectionIsActive(connectionIsActive); 3123 } 3124 3125 @Override createInputChannel(String inputChannelName)3126 public InputChannel createInputChannel(String inputChannelName) { 3127 return InputManagerService.this.createInputChannel(inputChannelName); 3128 } 3129 3130 @Override pilferPointers(IBinder token)3131 public void pilferPointers(IBinder token) { 3132 mNative.pilferPointers(token); 3133 } 3134 3135 @Override onInputMethodSubtypeChangedForKeyboardLayoutMapping(@serIdInt int userId, @Nullable InputMethodSubtypeHandle subtypeHandle, @Nullable InputMethodSubtype subtype)3136 public void onInputMethodSubtypeChangedForKeyboardLayoutMapping(@UserIdInt int userId, 3137 @Nullable InputMethodSubtypeHandle subtypeHandle, 3138 @Nullable InputMethodSubtype subtype) { 3139 mKeyboardLayoutManager.onInputMethodSubtypeChanged(userId, subtypeHandle, subtype); 3140 } 3141 3142 @Override notifyUserActivity()3143 public void notifyUserActivity() { 3144 mKeyboardBacklightController.notifyUserActivity(); 3145 } 3146 3147 @Override incrementKeyboardBacklight(int deviceId)3148 public void incrementKeyboardBacklight(int deviceId) { 3149 mKeyboardBacklightController.incrementKeyboardBacklight(deviceId); 3150 } 3151 3152 @Override decrementKeyboardBacklight(int deviceId)3153 public void decrementKeyboardBacklight(int deviceId) { 3154 mKeyboardBacklightController.decrementKeyboardBacklight(deviceId); 3155 } 3156 3157 @Override setTypeAssociation(@onNull String inputPort, @NonNull String type)3158 public void setTypeAssociation(@NonNull String inputPort, @NonNull String type) { 3159 setTypeAssociationInternal(inputPort, type); 3160 } 3161 3162 @Override unsetTypeAssociation(@onNull String inputPort)3163 public void unsetTypeAssociation(@NonNull String inputPort) { 3164 unsetTypeAssociationInternal(inputPort); 3165 } 3166 3167 @Override addKeyboardLayoutAssociation(@onNull String inputPort, @NonNull String languageTag, @NonNull String layoutType)3168 public void addKeyboardLayoutAssociation(@NonNull String inputPort, 3169 @NonNull String languageTag, @NonNull String layoutType) { 3170 InputManagerService.this.addKeyboardLayoutAssociation(inputPort, 3171 languageTag, layoutType); 3172 } 3173 3174 @Override removeKeyboardLayoutAssociation(@onNull String inputPort)3175 public void removeKeyboardLayoutAssociation(@NonNull String inputPort) { 3176 InputManagerService.this.removeKeyboardLayoutAssociation(inputPort); 3177 } 3178 3179 @Override setStylusButtonMotionEventsEnabled(boolean enabled)3180 public void setStylusButtonMotionEventsEnabled(boolean enabled) { 3181 mNative.setStylusButtonMotionEventsEnabled(enabled); 3182 } 3183 3184 @Override getLastUsedInputDeviceId()3185 public int getLastUsedInputDeviceId() { 3186 return mNative.getLastUsedInputDeviceId(); 3187 } 3188 } 3189 3190 @Override onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)3191 public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, 3192 String[] args, ShellCallback callback, ResultReceiver resultReceiver) { 3193 new InputShellCommand().exec(this, in, out, err, args, callback, resultReceiver); 3194 } 3195 3196 private static class AdditionalDisplayInputProperties { 3197 3198 static final boolean DEFAULT_POINTER_ICON_VISIBLE = true; 3199 static final boolean DEFAULT_MOUSE_POINTER_ACCELERATION_ENABLED = true; 3200 3201 /** 3202 * Whether to enable mouse pointer acceleration on this display. Note that this only affects 3203 * pointer movements from mice (that is, pointing devices which send relative motions, 3204 * including trackballs and pointing sticks), not from other pointer devices such as 3205 * touchpads and styluses. 3206 */ 3207 public boolean mousePointerAccelerationEnabled; 3208 3209 // Whether the pointer icon should be visible or hidden on this display. 3210 public boolean pointerIconVisible; 3211 AdditionalDisplayInputProperties()3212 AdditionalDisplayInputProperties() { 3213 reset(); 3214 } 3215 allDefaults()3216 public boolean allDefaults() { 3217 return mousePointerAccelerationEnabled == DEFAULT_MOUSE_POINTER_ACCELERATION_ENABLED 3218 && pointerIconVisible == DEFAULT_POINTER_ICON_VISIBLE; 3219 } 3220 reset()3221 public void reset() { 3222 mousePointerAccelerationEnabled = DEFAULT_MOUSE_POINTER_ACCELERATION_ENABLED; 3223 pointerIconVisible = DEFAULT_POINTER_ICON_VISIBLE; 3224 } 3225 } 3226 updateAdditionalDisplayInputProperties(int displayId, Consumer<AdditionalDisplayInputProperties> updater)3227 private void updateAdditionalDisplayInputProperties(int displayId, 3228 Consumer<AdditionalDisplayInputProperties> updater) { 3229 synchronized (mAdditionalDisplayInputPropertiesLock) { 3230 AdditionalDisplayInputProperties properties = 3231 mAdditionalDisplayInputProperties.get(displayId); 3232 if (properties == null) { 3233 properties = new AdditionalDisplayInputProperties(); 3234 mAdditionalDisplayInputProperties.put(displayId, properties); 3235 } 3236 final boolean oldPointerIconVisible = properties.pointerIconVisible; 3237 final boolean oldMouseAccelerationEnabled = properties.mousePointerAccelerationEnabled; 3238 updater.accept(properties); 3239 if (oldPointerIconVisible != properties.pointerIconVisible) { 3240 mNative.setPointerIconVisibility(displayId, properties.pointerIconVisible); 3241 } 3242 if (oldMouseAccelerationEnabled != properties.mousePointerAccelerationEnabled) { 3243 mNative.setMousePointerAccelerationEnabled(displayId, 3244 properties.mousePointerAccelerationEnabled); 3245 } 3246 if (properties.allDefaults()) { 3247 mAdditionalDisplayInputProperties.remove(displayId); 3248 } 3249 } 3250 } 3251 updatePointerLocationEnabled(boolean enabled)3252 void updatePointerLocationEnabled(boolean enabled) { 3253 mWindowManagerCallbacks.notifyPointerLocationChanged(enabled); 3254 } 3255 updateShowKeyPresses(boolean enabled)3256 void updateShowKeyPresses(boolean enabled) { 3257 if (mShowKeyPresses == enabled) { 3258 return; 3259 } 3260 3261 mShowKeyPresses = enabled; 3262 updateFocusEventDebugViewEnabled(); 3263 3264 synchronized (mFocusEventDebugViewLock) { 3265 if (mFocusEventDebugView != null) { 3266 mFocusEventDebugView.updateShowKeyPresses(enabled); 3267 } 3268 } 3269 } 3270 updateShowRotaryInput(boolean enabled)3271 void updateShowRotaryInput(boolean enabled) { 3272 if (mShowRotaryInput == enabled) { 3273 return; 3274 } 3275 3276 mShowRotaryInput = enabled; 3277 updateFocusEventDebugViewEnabled(); 3278 3279 synchronized (mFocusEventDebugViewLock) { 3280 if (mFocusEventDebugView != null) { 3281 mFocusEventDebugView.updateShowRotaryInput(enabled); 3282 } 3283 } 3284 } 3285 updateFocusEventDebugViewEnabled()3286 private void updateFocusEventDebugViewEnabled() { 3287 boolean enabled = mShowKeyPresses || mShowRotaryInput; 3288 FocusEventDebugView view; 3289 synchronized (mFocusEventDebugViewLock) { 3290 if (enabled == (mFocusEventDebugView != null)) { 3291 return; 3292 } 3293 if (enabled) { 3294 mFocusEventDebugView = new FocusEventDebugView(mContext, this); 3295 view = mFocusEventDebugView; 3296 } else { 3297 view = mFocusEventDebugView; 3298 mFocusEventDebugView = null; 3299 } 3300 } 3301 Objects.requireNonNull(view); 3302 3303 // Interact with WM outside the lock, since the lock is part of the input hotpath. 3304 final WindowManager wm = 3305 Objects.requireNonNull(mContext.getSystemService(WindowManager.class)); 3306 if (!enabled) { 3307 wm.removeView(view); 3308 return; 3309 } 3310 3311 // TODO: Support multi display 3312 final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 3313 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 3314 lp.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE 3315 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 3316 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; 3317 lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS; 3318 lp.setFitInsetsTypes(0); 3319 lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; 3320 lp.format = PixelFormat.TRANSLUCENT; 3321 lp.setTitle("FocusEventDebugView - display " + mContext.getDisplayId()); 3322 lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL; 3323 wm.addView(view, lp); 3324 } 3325 3326 /** 3327 * Sets Accessibility bounce keys threshold in milliseconds. 3328 */ setAccessibilityBounceKeysThreshold(int thresholdTimeMs)3329 public void setAccessibilityBounceKeysThreshold(int thresholdTimeMs) { 3330 mNative.setAccessibilityBounceKeysThreshold(thresholdTimeMs); 3331 } 3332 3333 /** 3334 * Sets Accessibility slow keys threshold in milliseconds. 3335 */ setAccessibilitySlowKeysThreshold(int thresholdTimeMs)3336 public void setAccessibilitySlowKeysThreshold(int thresholdTimeMs) { 3337 mNative.setAccessibilitySlowKeysThreshold(thresholdTimeMs); 3338 } 3339 3340 /** 3341 * Sets whether Accessibility sticky keys is enabled. 3342 */ setAccessibilityStickyKeysEnabled(boolean enabled)3343 public void setAccessibilityStickyKeysEnabled(boolean enabled) { 3344 mNative.setAccessibilityStickyKeysEnabled(enabled); 3345 } 3346 setUseLargePointerIcons(boolean useLargeIcons)3347 void setUseLargePointerIcons(boolean useLargeIcons) { 3348 mPointerIconCache.setUseLargePointerIcons(useLargeIcons); 3349 } 3350 setPointerFillStyle(@ointerIcon.PointerIconVectorStyleFill int fillStyle)3351 void setPointerFillStyle(@PointerIcon.PointerIconVectorStyleFill int fillStyle) { 3352 mPointerIconCache.setPointerFillStyle(fillStyle); 3353 } 3354 setPointerScale(float scale)3355 void setPointerScale(float scale) { 3356 mPointerIconCache.setPointerScale(scale); 3357 } 3358 3359 interface KeyboardBacklightControllerInterface { incrementKeyboardBacklight(int deviceId)3360 default void incrementKeyboardBacklight(int deviceId) {} decrementKeyboardBacklight(int deviceId)3361 default void decrementKeyboardBacklight(int deviceId) {} registerKeyboardBacklightListener(IKeyboardBacklightListener l, int pid)3362 default void registerKeyboardBacklightListener(IKeyboardBacklightListener l, int pid) {} unregisterKeyboardBacklightListener(IKeyboardBacklightListener l, int pid)3363 default void unregisterKeyboardBacklightListener(IKeyboardBacklightListener l, int pid) {} onInteractiveChanged(boolean isInteractive)3364 default void onInteractiveChanged(boolean isInteractive) {} notifyUserActivity()3365 default void notifyUserActivity() {} systemRunning()3366 default void systemRunning() {} dump(PrintWriter pw)3367 default void dump(PrintWriter pw) {} 3368 } 3369 } 3370