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