Input.h revision 5b2b4d9c0a56c4b5e869c828a6c36a1b9e27d61b
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#ifndef _UI_INPUT_H 18#define _UI_INPUT_H 19 20/** 21 * Native input event structures. 22 */ 23 24#include <android/input.h> 25#include <utils/Vector.h> 26#include <utils/KeyedVector.h> 27#include <utils/Timers.h> 28#include <utils/RefBase.h> 29#include <utils/String8.h> 30#include <utils/BitSet.h> 31 32#ifdef HAVE_ANDROID_OS 33class SkMatrix; 34#endif 35 36/* 37 * Additional private constants not defined in ndk/ui/input.h. 38 */ 39enum { 40 /* 41 * Private control to determine when an app is tracking a key sequence. 42 */ 43 AKEY_EVENT_FLAG_START_TRACKING = 0x40000000 44}; 45 46enum { 47 /* 48 * Indicates that an input device has switches. 49 * This input source flag is hidden from the API because switches are only used by the system 50 * and applications have no way to interact with them. 51 */ 52 AINPUT_SOURCE_SWITCH = 0x80000000, 53}; 54 55/* 56 * SystemUiVisibility constants from View. 57 */ 58enum { 59 ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE = 0, 60 ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN = 0x00000001, 61}; 62 63/* 64 * Maximum number of pointers supported per motion event. 65 * Smallest number of pointers is 1. 66 * (We want at least 10 but some touch controllers obstensibly configured for 10 pointers 67 * will occasionally emit 11. There is not much harm making this constant bigger.) 68 */ 69#define MAX_POINTERS 16 70 71/* 72 * Maximum pointer id value supported in a motion event. 73 * Smallest pointer id is 0. 74 * (This is limited by our use of BitSet32 to track pointer assignments.) 75 */ 76#define MAX_POINTER_ID 31 77 78/* 79 * Declare a concrete type for the NDK's input event forward declaration. 80 */ 81struct AInputEvent { 82 virtual ~AInputEvent() { } 83}; 84 85/* 86 * Declare a concrete type for the NDK's input device forward declaration. 87 */ 88struct AInputDevice { 89 virtual ~AInputDevice() { } 90}; 91 92 93namespace android { 94 95#ifdef HAVE_ANDROID_OS 96class Parcel; 97#endif 98 99/* 100 * Flags that flow alongside events in the input dispatch system to help with certain 101 * policy decisions such as waking from device sleep. 102 * 103 * These flags are also defined in frameworks/base/core/java/android/view/WindowManagerPolicy.java. 104 */ 105enum { 106 /* These flags originate in RawEvents and are generally set in the key map. 107 * NOTE: If you edit these flags, also edit labels in KeycodeLabels.h. */ 108 109 POLICY_FLAG_WAKE = 0x00000001, 110 POLICY_FLAG_WAKE_DROPPED = 0x00000002, 111 POLICY_FLAG_SHIFT = 0x00000004, 112 POLICY_FLAG_CAPS_LOCK = 0x00000008, 113 POLICY_FLAG_ALT = 0x00000010, 114 POLICY_FLAG_ALT_GR = 0x00000020, 115 POLICY_FLAG_MENU = 0x00000040, 116 POLICY_FLAG_LAUNCHER = 0x00000080, 117 POLICY_FLAG_VIRTUAL = 0x00000100, 118 POLICY_FLAG_FUNCTION = 0x00000200, 119 120 POLICY_FLAG_RAW_MASK = 0x0000ffff, 121 122 /* These flags are set by the input dispatcher. */ 123 124 // Indicates that the input event was injected. 125 POLICY_FLAG_INJECTED = 0x01000000, 126 127 // Indicates that the input event is from a trusted source such as a directly attached 128 // input device or an application with system-wide event injection permission. 129 POLICY_FLAG_TRUSTED = 0x02000000, 130 131 /* These flags are set by the input reader policy as it intercepts each event. */ 132 133 // Indicates that the screen was off when the event was received and the event 134 // should wake the device. 135 POLICY_FLAG_WOKE_HERE = 0x10000000, 136 137 // Indicates that the screen was dim when the event was received and the event 138 // should brighten the device. 139 POLICY_FLAG_BRIGHT_HERE = 0x20000000, 140 141 // Indicates that the event should be dispatched to applications. 142 // The input event should still be sent to the InputDispatcher so that it can see all 143 // input events received include those that it will not deliver. 144 POLICY_FLAG_PASS_TO_USER = 0x40000000, 145}; 146 147/* 148 * Button state. 149 */ 150enum { 151 // Primary button pressed (left mouse button). 152 BUTTON_STATE_PRIMARY = 1 << 0, 153}; 154 155/* 156 * Describes the basic configuration of input devices that are present. 157 */ 158struct InputConfiguration { 159 enum { 160 TOUCHSCREEN_UNDEFINED = 0, 161 TOUCHSCREEN_NOTOUCH = 1, 162 TOUCHSCREEN_STYLUS = 2, 163 TOUCHSCREEN_FINGER = 3 164 }; 165 166 enum { 167 KEYBOARD_UNDEFINED = 0, 168 KEYBOARD_NOKEYS = 1, 169 KEYBOARD_QWERTY = 2, 170 KEYBOARD_12KEY = 3 171 }; 172 173 enum { 174 NAVIGATION_UNDEFINED = 0, 175 NAVIGATION_NONAV = 1, 176 NAVIGATION_DPAD = 2, 177 NAVIGATION_TRACKBALL = 3, 178 NAVIGATION_WHEEL = 4 179 }; 180 181 int32_t touchScreen; 182 int32_t keyboard; 183 int32_t navigation; 184}; 185 186/* 187 * Pointer coordinate data. 188 */ 189struct PointerCoords { 190 enum { MAX_AXES = 14 }; // 14 so that sizeof(PointerCoords) == 64 191 192 // Bitfield of axes that are present in this structure. 193 uint64_t bits; 194 195 // Values of axes that are stored in this structure packed in order by axis id 196 // for each axis that is present in the structure according to 'bits'. 197 float values[MAX_AXES]; 198 199 inline void clear() { 200 bits = 0; 201 } 202 203 float getAxisValue(int32_t axis) const; 204 status_t setAxisValue(int32_t axis, float value); 205 float* editAxisValue(int32_t axis); 206 207 void scale(float scale); 208 209#ifdef HAVE_ANDROID_OS 210 status_t readFromParcel(Parcel* parcel); 211 status_t writeToParcel(Parcel* parcel) const; 212#endif 213 214 bool operator==(const PointerCoords& other) const; 215 inline bool operator!=(const PointerCoords& other) const { 216 return !(*this == other); 217 } 218 219 void copyFrom(const PointerCoords& other); 220 221private: 222 void tooManyAxes(int axis); 223}; 224 225/* 226 * Input events. 227 */ 228class InputEvent : public AInputEvent { 229public: 230 virtual ~InputEvent() { } 231 232 virtual int32_t getType() const = 0; 233 234 inline int32_t getDeviceId() const { return mDeviceId; } 235 236 inline int32_t getSource() const { return mSource; } 237 238 inline void setSource(int32_t source) { mSource = source; } 239 240protected: 241 void initialize(int32_t deviceId, int32_t source); 242 void initialize(const InputEvent& from); 243 244 int32_t mDeviceId; 245 int32_t mSource; 246}; 247 248/* 249 * Key events. 250 */ 251class KeyEvent : public InputEvent { 252public: 253 virtual ~KeyEvent() { } 254 255 virtual int32_t getType() const { return AINPUT_EVENT_TYPE_KEY; } 256 257 inline int32_t getAction() const { return mAction; } 258 259 inline int32_t getFlags() const { return mFlags; } 260 261 inline int32_t getKeyCode() const { return mKeyCode; } 262 263 inline int32_t getScanCode() const { return mScanCode; } 264 265 inline int32_t getMetaState() const { return mMetaState; } 266 267 inline int32_t getRepeatCount() const { return mRepeatCount; } 268 269 inline nsecs_t getDownTime() const { return mDownTime; } 270 271 inline nsecs_t getEventTime() const { return mEventTime; } 272 273 // Return true if this event may have a default action implementation. 274 static bool hasDefaultAction(int32_t keyCode); 275 bool hasDefaultAction() const; 276 277 // Return true if this event represents a system key. 278 static bool isSystemKey(int32_t keyCode); 279 bool isSystemKey() const; 280 281 void initialize( 282 int32_t deviceId, 283 int32_t source, 284 int32_t action, 285 int32_t flags, 286 int32_t keyCode, 287 int32_t scanCode, 288 int32_t metaState, 289 int32_t repeatCount, 290 nsecs_t downTime, 291 nsecs_t eventTime); 292 void initialize(const KeyEvent& from); 293 294protected: 295 int32_t mAction; 296 int32_t mFlags; 297 int32_t mKeyCode; 298 int32_t mScanCode; 299 int32_t mMetaState; 300 int32_t mRepeatCount; 301 nsecs_t mDownTime; 302 nsecs_t mEventTime; 303}; 304 305/* 306 * Motion events. 307 */ 308class MotionEvent : public InputEvent { 309public: 310 virtual ~MotionEvent() { } 311 312 virtual int32_t getType() const { return AINPUT_EVENT_TYPE_MOTION; } 313 314 inline int32_t getAction() const { return mAction; } 315 316 inline int32_t getActionMasked() const { return mAction & AMOTION_EVENT_ACTION_MASK; } 317 318 inline int32_t getActionIndex() const { 319 return (mAction & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) 320 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; 321 } 322 323 inline void setAction(int32_t action) { mAction = action; } 324 325 inline int32_t getFlags() const { return mFlags; } 326 327 inline int32_t getEdgeFlags() const { return mEdgeFlags; } 328 329 inline void setEdgeFlags(int32_t edgeFlags) { mEdgeFlags = edgeFlags; } 330 331 inline int32_t getMetaState() const { return mMetaState; } 332 333 inline void setMetaState(int32_t metaState) { mMetaState = metaState; } 334 335 inline float getXOffset() const { return mXOffset; } 336 337 inline float getYOffset() const { return mYOffset; } 338 339 inline float getXPrecision() const { return mXPrecision; } 340 341 inline float getYPrecision() const { return mYPrecision; } 342 343 inline nsecs_t getDownTime() const { return mDownTime; } 344 345 inline size_t getPointerCount() const { return mPointerIds.size(); } 346 347 inline int32_t getPointerId(size_t pointerIndex) const { return mPointerIds[pointerIndex]; } 348 349 inline nsecs_t getEventTime() const { return mSampleEventTimes[getHistorySize()]; } 350 351 const PointerCoords* getRawPointerCoords(size_t pointerIndex) const; 352 353 float getRawAxisValue(int32_t axis, size_t pointerIndex) const; 354 355 inline float getRawX(size_t pointerIndex) const { 356 return getRawAxisValue(AMOTION_EVENT_AXIS_X, pointerIndex); 357 } 358 359 inline float getRawY(size_t pointerIndex) const { 360 return getRawAxisValue(AMOTION_EVENT_AXIS_Y, pointerIndex); 361 } 362 363 float getAxisValue(int32_t axis, size_t pointerIndex) const; 364 365 inline float getX(size_t pointerIndex) const { 366 return getAxisValue(AMOTION_EVENT_AXIS_X, pointerIndex); 367 } 368 369 inline float getY(size_t pointerIndex) const { 370 return getAxisValue(AMOTION_EVENT_AXIS_Y, pointerIndex); 371 } 372 373 inline float getPressure(size_t pointerIndex) const { 374 return getAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pointerIndex); 375 } 376 377 inline float getSize(size_t pointerIndex) const { 378 return getAxisValue(AMOTION_EVENT_AXIS_SIZE, pointerIndex); 379 } 380 381 inline float getTouchMajor(size_t pointerIndex) const { 382 return getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, pointerIndex); 383 } 384 385 inline float getTouchMinor(size_t pointerIndex) const { 386 return getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, pointerIndex); 387 } 388 389 inline float getToolMajor(size_t pointerIndex) const { 390 return getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, pointerIndex); 391 } 392 393 inline float getToolMinor(size_t pointerIndex) const { 394 return getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, pointerIndex); 395 } 396 397 inline float getOrientation(size_t pointerIndex) const { 398 return getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex); 399 } 400 401 inline size_t getHistorySize() const { return mSampleEventTimes.size() - 1; } 402 403 inline nsecs_t getHistoricalEventTime(size_t historicalIndex) const { 404 return mSampleEventTimes[historicalIndex]; 405 } 406 407 const PointerCoords* getHistoricalRawPointerCoords( 408 size_t pointerIndex, size_t historicalIndex) const; 409 410 float getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex, 411 size_t historicalIndex) const; 412 413 inline float getHistoricalRawX(size_t pointerIndex, size_t historicalIndex) const { 414 return getHistoricalRawAxisValue( 415 AMOTION_EVENT_AXIS_X, pointerIndex, historicalIndex); 416 } 417 418 inline float getHistoricalRawY(size_t pointerIndex, size_t historicalIndex) const { 419 return getHistoricalRawAxisValue( 420 AMOTION_EVENT_AXIS_Y, pointerIndex, historicalIndex); 421 } 422 423 float getHistoricalAxisValue(int32_t axis, size_t pointerIndex, size_t historicalIndex) const; 424 425 inline float getHistoricalX(size_t pointerIndex, size_t historicalIndex) const { 426 return getHistoricalAxisValue( 427 AMOTION_EVENT_AXIS_X, pointerIndex, historicalIndex); 428 } 429 430 inline float getHistoricalY(size_t pointerIndex, size_t historicalIndex) const { 431 return getHistoricalAxisValue( 432 AMOTION_EVENT_AXIS_Y, pointerIndex, historicalIndex); 433 } 434 435 inline float getHistoricalPressure(size_t pointerIndex, size_t historicalIndex) const { 436 return getHistoricalAxisValue( 437 AMOTION_EVENT_AXIS_PRESSURE, pointerIndex, historicalIndex); 438 } 439 440 inline float getHistoricalSize(size_t pointerIndex, size_t historicalIndex) const { 441 return getHistoricalAxisValue( 442 AMOTION_EVENT_AXIS_SIZE, pointerIndex, historicalIndex); 443 } 444 445 inline float getHistoricalTouchMajor(size_t pointerIndex, size_t historicalIndex) const { 446 return getHistoricalAxisValue( 447 AMOTION_EVENT_AXIS_TOUCH_MAJOR, pointerIndex, historicalIndex); 448 } 449 450 inline float getHistoricalTouchMinor(size_t pointerIndex, size_t historicalIndex) const { 451 return getHistoricalAxisValue( 452 AMOTION_EVENT_AXIS_TOUCH_MINOR, pointerIndex, historicalIndex); 453 } 454 455 inline float getHistoricalToolMajor(size_t pointerIndex, size_t historicalIndex) const { 456 return getHistoricalAxisValue( 457 AMOTION_EVENT_AXIS_TOOL_MAJOR, pointerIndex, historicalIndex); 458 } 459 460 inline float getHistoricalToolMinor(size_t pointerIndex, size_t historicalIndex) const { 461 return getHistoricalAxisValue( 462 AMOTION_EVENT_AXIS_TOOL_MINOR, pointerIndex, historicalIndex); 463 } 464 465 inline float getHistoricalOrientation(size_t pointerIndex, size_t historicalIndex) const { 466 return getHistoricalAxisValue( 467 AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex, historicalIndex); 468 } 469 470 ssize_t findPointerIndex(int32_t pointerId) const; 471 472 void initialize( 473 int32_t deviceId, 474 int32_t source, 475 int32_t action, 476 int32_t flags, 477 int32_t edgeFlags, 478 int32_t metaState, 479 float xOffset, 480 float yOffset, 481 float xPrecision, 482 float yPrecision, 483 nsecs_t downTime, 484 nsecs_t eventTime, 485 size_t pointerCount, 486 const int32_t* pointerIds, 487 const PointerCoords* pointerCoords); 488 489 void copyFrom(const MotionEvent* other, bool keepHistory); 490 491 void addSample( 492 nsecs_t eventTime, 493 const PointerCoords* pointerCoords); 494 495 void offsetLocation(float xOffset, float yOffset); 496 497 void scale(float scaleFactor); 498 499#ifdef HAVE_ANDROID_OS 500 void transform(const SkMatrix* matrix); 501 502 status_t readFromParcel(Parcel* parcel); 503 status_t writeToParcel(Parcel* parcel) const; 504#endif 505 506 static bool isTouchEvent(int32_t source, int32_t action); 507 inline bool isTouchEvent() const { 508 return isTouchEvent(mSource, mAction); 509 } 510 511 // Low-level accessors. 512 inline const int32_t* getPointerIds() const { return mPointerIds.array(); } 513 inline const nsecs_t* getSampleEventTimes() const { return mSampleEventTimes.array(); } 514 inline const PointerCoords* getSamplePointerCoords() const { 515 return mSamplePointerCoords.array(); 516 } 517 518protected: 519 int32_t mAction; 520 int32_t mFlags; 521 int32_t mEdgeFlags; 522 int32_t mMetaState; 523 float mXOffset; 524 float mYOffset; 525 float mXPrecision; 526 float mYPrecision; 527 nsecs_t mDownTime; 528 Vector<int32_t> mPointerIds; 529 Vector<nsecs_t> mSampleEventTimes; 530 Vector<PointerCoords> mSamplePointerCoords; 531}; 532 533/* 534 * Input event factory. 535 */ 536class InputEventFactoryInterface { 537protected: 538 virtual ~InputEventFactoryInterface() { } 539 540public: 541 InputEventFactoryInterface() { } 542 543 virtual KeyEvent* createKeyEvent() = 0; 544 virtual MotionEvent* createMotionEvent() = 0; 545}; 546 547/* 548 * A simple input event factory implementation that uses a single preallocated instance 549 * of each type of input event that are reused for each request. 550 */ 551class PreallocatedInputEventFactory : public InputEventFactoryInterface { 552public: 553 PreallocatedInputEventFactory() { } 554 virtual ~PreallocatedInputEventFactory() { } 555 556 virtual KeyEvent* createKeyEvent() { return & mKeyEvent; } 557 virtual MotionEvent* createMotionEvent() { return & mMotionEvent; } 558 559private: 560 KeyEvent mKeyEvent; 561 MotionEvent mMotionEvent; 562}; 563 564/* 565 * Calculates the velocity of pointer movements over time. 566 */ 567class VelocityTracker { 568public: 569 struct Position { 570 float x, y; 571 }; 572 573 VelocityTracker(); 574 575 // Resets the velocity tracker state. 576 void clear(); 577 578 // Resets the velocity tracker state for specific pointers. 579 // Call this method when some pointers have changed and may be reusing 580 // an id that was assigned to a different pointer earlier. 581 void clearPointers(BitSet32 idBits); 582 583 // Adds movement information for a set of pointers. 584 // The idBits bitfield specifies the pointer ids of the pointers whose positions 585 // are included in the movement. 586 // The positions array contains position information for each pointer in order by 587 // increasing id. Its size should be equal to the number of one bits in idBits. 588 void addMovement(nsecs_t eventTime, BitSet32 idBits, const Position* positions); 589 590 // Adds movement information for all pointers in a MotionEvent, including historical samples. 591 void addMovement(const MotionEvent* event); 592 593 // Gets the velocity of the specified pointer id in position units per second. 594 // Returns false and sets the velocity components to zero if there is no movement 595 // information for the pointer. 596 bool getVelocity(uint32_t id, float* outVx, float* outVy) const; 597 598 // Gets the active pointer id, or -1 if none. 599 inline int32_t getActivePointerId() const { return mActivePointerId; } 600 601 // Gets a bitset containing all pointer ids from the most recent movement. 602 inline BitSet32 getCurrentPointerIdBits() const { return mMovements[mIndex].idBits; } 603 604private: 605 // Number of samples to keep. 606 static const uint32_t HISTORY_SIZE = 10; 607 608 // Oldest sample to consider when calculating the velocity. 609 static const nsecs_t MAX_AGE = 200 * 1000000; // 200 ms 610 611 // The minimum duration between samples when estimating velocity. 612 static const nsecs_t MIN_DURATION = 10 * 1000000; // 10 ms 613 614 struct Movement { 615 nsecs_t eventTime; 616 BitSet32 idBits; 617 Position positions[MAX_POINTERS]; 618 }; 619 620 uint32_t mIndex; 621 Movement mMovements[HISTORY_SIZE]; 622 int32_t mActivePointerId; 623}; 624 625/* 626 * Describes the characteristics and capabilities of an input device. 627 */ 628class InputDeviceInfo { 629public: 630 InputDeviceInfo(); 631 InputDeviceInfo(const InputDeviceInfo& other); 632 ~InputDeviceInfo(); 633 634 struct MotionRange { 635 int32_t axis; 636 uint32_t source; 637 float min; 638 float max; 639 float flat; 640 float fuzz; 641 }; 642 643 void initialize(int32_t id, const String8& name); 644 645 inline int32_t getId() const { return mId; } 646 inline const String8 getName() const { return mName; } 647 inline uint32_t getSources() const { return mSources; } 648 649 const MotionRange* getMotionRange(int32_t axis, uint32_t source) const; 650 651 void addSource(uint32_t source); 652 void addMotionRange(int32_t axis, uint32_t source, 653 float min, float max, float flat, float fuzz); 654 void addMotionRange(const MotionRange& range); 655 656 inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; } 657 inline int32_t getKeyboardType() const { return mKeyboardType; } 658 659 inline const Vector<MotionRange>& getMotionRanges() const { 660 return mMotionRanges; 661 } 662 663private: 664 int32_t mId; 665 String8 mName; 666 uint32_t mSources; 667 int32_t mKeyboardType; 668 669 Vector<MotionRange> mMotionRanges; 670}; 671 672/* 673 * Identifies a device. 674 */ 675struct InputDeviceIdentifier { 676 inline InputDeviceIdentifier() : 677 bus(0), vendor(0), product(0), version(0) { 678 } 679 680 String8 name; 681 String8 location; 682 String8 uniqueId; 683 uint16_t bus; 684 uint16_t vendor; 685 uint16_t product; 686 uint16_t version; 687}; 688 689/* Types of input device configuration files. */ 690enum InputDeviceConfigurationFileType { 691 INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION = 0, /* .idc file */ 692 INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT = 1, /* .kl file */ 693 INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP = 2, /* .kcm file */ 694}; 695 696/* 697 * Gets the path of an input device configuration file, if one is available. 698 * Considers both system provided and user installed configuration files. 699 * 700 * The device identifier is used to construct several default configuration file 701 * names to try based on the device name, vendor, product, and version. 702 * 703 * Returns an empty string if not found. 704 */ 705extern String8 getInputDeviceConfigurationFilePathByDeviceIdentifier( 706 const InputDeviceIdentifier& deviceIdentifier, 707 InputDeviceConfigurationFileType type); 708 709/* 710 * Gets the path of an input device configuration file, if one is available. 711 * Considers both system provided and user installed configuration files. 712 * 713 * The name is case-sensitive and is used to construct the filename to resolve. 714 * All characters except 'a'-'z', 'A'-'Z', '0'-'9', '-', and '_' are replaced by underscores. 715 * 716 * Returns an empty string if not found. 717 */ 718extern String8 getInputDeviceConfigurationFilePathByName( 719 const String8& name, InputDeviceConfigurationFileType type); 720 721} // namespace android 722 723#endif // _UI_INPUT_H 724