InputReader_test.cpp revision b7198743ab3976b30d4655c1e065ca33e372b6af
1// 2// Copyright 2010 The Android Open Source Project 3// 4 5#include "../InputReader.h" 6 7#include <utils/List.h> 8#include <gtest/gtest.h> 9#include <math.h> 10 11namespace android { 12 13// An arbitrary time value. 14static const nsecs_t ARBITRARY_TIME = 1234; 15 16// Arbitrary display properties. 17static const int32_t DISPLAY_ID = 0; 18static const int32_t DISPLAY_WIDTH = 480; 19static const int32_t DISPLAY_HEIGHT = 800; 20 21// Error tolerance for floating point assertions. 22static const float EPSILON = 0.001f; 23 24template<typename T> 25static inline T min(T a, T b) { 26 return a < b ? a : b; 27} 28 29static inline float avg(float x, float y) { 30 return (x + y) / 2; 31} 32 33 34// --- FakePointerController --- 35 36class FakePointerController : public PointerControllerInterface { 37 bool mHaveBounds; 38 float mMinX, mMinY, mMaxX, mMaxY; 39 40protected: 41 virtual ~FakePointerController() { } 42 43public: 44 FakePointerController() : 45 mHaveBounds(false), mMinX(0), mMinY(0), mMaxX(0), mMaxY(0) { 46 } 47 48 void setBounds(float minX, float minY, float maxX, float maxY) { 49 mHaveBounds = true; 50 mMinX = minX; 51 mMinY = minY; 52 mMaxX = maxX; 53 mMaxY = maxY; 54 } 55 56private: 57 virtual bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const { 58 *outMinX = mMinX; 59 *outMinY = mMinY; 60 *outMaxX = mMaxX; 61 *outMaxY = mMaxY; 62 return mHaveBounds; 63 } 64 65 virtual void move(float deltaX, float deltaY) { 66 } 67 68 virtual void setButtonState(uint32_t buttonState) { 69 } 70 71 virtual uint32_t getButtonState() const { 72 return 0; 73 } 74 75 virtual void setPosition(float x, float y) { 76 } 77 78 virtual void getPosition(float* outX, float* outY) const { 79 *outX = 0; 80 *outY = 0; 81 } 82 83 virtual void fade() { 84 } 85 86 virtual void unfade() { 87 } 88}; 89 90 91// --- FakeInputReaderPolicy --- 92 93class FakeInputReaderPolicy : public InputReaderPolicyInterface { 94 struct DisplayInfo { 95 int32_t width; 96 int32_t height; 97 int32_t orientation; 98 }; 99 100 KeyedVector<int32_t, DisplayInfo> mDisplayInfos; 101 bool mFilterTouchEvents; 102 bool mFilterJumpyTouchEvents; 103 Vector<String8> mExcludedDeviceNames; 104 KeyedVector<int32_t, sp<FakePointerController> > mPointerControllers; 105 106protected: 107 virtual ~FakeInputReaderPolicy() { } 108 109public: 110 FakeInputReaderPolicy() : 111 mFilterTouchEvents(false), mFilterJumpyTouchEvents(false) { 112 } 113 114 void removeDisplayInfo(int32_t displayId) { 115 mDisplayInfos.removeItem(displayId); 116 } 117 118 void setDisplayInfo(int32_t displayId, int32_t width, int32_t height, int32_t orientation) { 119 removeDisplayInfo(displayId); 120 121 DisplayInfo info; 122 info.width = width; 123 info.height = height; 124 info.orientation = orientation; 125 mDisplayInfos.add(displayId, info); 126 } 127 128 void setFilterTouchEvents(bool enabled) { 129 mFilterTouchEvents = enabled; 130 } 131 132 void setFilterJumpyTouchEvents(bool enabled) { 133 mFilterJumpyTouchEvents = enabled; 134 } 135 136 virtual nsecs_t getVirtualKeyQuietTime() { 137 return 0; 138 } 139 140 void addExcludedDeviceName(const String8& deviceName) { 141 mExcludedDeviceNames.push(deviceName); 142 } 143 144 void setPointerController(int32_t deviceId, const sp<FakePointerController>& controller) { 145 mPointerControllers.add(deviceId, controller); 146 } 147 148private: 149 virtual bool getDisplayInfo(int32_t displayId, 150 int32_t* width, int32_t* height, int32_t* orientation) { 151 ssize_t index = mDisplayInfos.indexOfKey(displayId); 152 if (index >= 0) { 153 const DisplayInfo& info = mDisplayInfos.valueAt(index); 154 if (width) { 155 *width = info.width; 156 } 157 if (height) { 158 *height = info.height; 159 } 160 if (orientation) { 161 *orientation = info.orientation; 162 } 163 return true; 164 } 165 return false; 166 } 167 168 virtual bool filterTouchEvents() { 169 return mFilterTouchEvents; 170 } 171 172 virtual bool filterJumpyTouchEvents() { 173 return mFilterJumpyTouchEvents; 174 } 175 176 virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) { 177 outExcludedDeviceNames.appendVector(mExcludedDeviceNames); 178 } 179 180 virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId) { 181 return mPointerControllers.valueFor(deviceId); 182 } 183}; 184 185 186// --- FakeInputDispatcher --- 187 188class FakeInputDispatcher : public InputDispatcherInterface { 189public: 190 struct NotifyConfigurationChangedArgs { 191 NotifyConfigurationChangedArgs() : eventTime(0) { } 192 193 nsecs_t eventTime; 194 }; 195 196 struct NotifyKeyArgs { 197 nsecs_t eventTime; 198 int32_t deviceId; 199 uint32_t source; 200 uint32_t policyFlags; 201 int32_t action; 202 int32_t flags; 203 int32_t keyCode; 204 int32_t scanCode; 205 int32_t metaState; 206 nsecs_t downTime; 207 }; 208 209 struct NotifyMotionArgs { 210 nsecs_t eventTime; 211 int32_t deviceId; 212 uint32_t source; 213 uint32_t policyFlags; 214 int32_t action; 215 int32_t flags; 216 int32_t metaState; 217 int32_t edgeFlags; 218 uint32_t pointerCount; 219 Vector<int32_t> pointerIds; 220 Vector<PointerCoords> pointerCoords; 221 float xPrecision; 222 float yPrecision; 223 nsecs_t downTime; 224 }; 225 226 struct NotifySwitchArgs { 227 nsecs_t when; 228 int32_t switchCode; 229 int32_t switchValue; 230 uint32_t policyFlags; 231 }; 232 233private: 234 List<NotifyConfigurationChangedArgs> mNotifyConfigurationChangedArgs; 235 List<NotifyKeyArgs> mNotifyKeyArgs; 236 List<NotifyMotionArgs> mNotifyMotionArgs; 237 List<NotifySwitchArgs> mNotifySwitchArgs; 238 239protected: 240 virtual ~FakeInputDispatcher() { } 241 242public: 243 FakeInputDispatcher() { 244 } 245 246 void assertNotifyConfigurationChangedWasCalled(NotifyConfigurationChangedArgs* outArgs = NULL) { 247 ASSERT_FALSE(mNotifyConfigurationChangedArgs.empty()) 248 << "Expected notifyConfigurationChanged() to have been called."; 249 if (outArgs) { 250 *outArgs = *mNotifyConfigurationChangedArgs.begin(); 251 } 252 mNotifyConfigurationChangedArgs.erase(mNotifyConfigurationChangedArgs.begin()); 253 } 254 255 void assertNotifyKeyWasCalled(NotifyKeyArgs* outArgs = NULL) { 256 ASSERT_FALSE(mNotifyKeyArgs.empty()) 257 << "Expected notifyKey() to have been called."; 258 if (outArgs) { 259 *outArgs = *mNotifyKeyArgs.begin(); 260 } 261 mNotifyKeyArgs.erase(mNotifyKeyArgs.begin()); 262 } 263 264 void assertNotifyKeyWasNotCalled() { 265 ASSERT_TRUE(mNotifyKeyArgs.empty()) 266 << "Expected notifyKey() to not have been called."; 267 } 268 269 void assertNotifyMotionWasCalled(NotifyMotionArgs* outArgs = NULL) { 270 ASSERT_FALSE(mNotifyMotionArgs.empty()) 271 << "Expected notifyMotion() to have been called."; 272 if (outArgs) { 273 *outArgs = *mNotifyMotionArgs.begin(); 274 } 275 mNotifyMotionArgs.erase(mNotifyMotionArgs.begin()); 276 } 277 278 void assertNotifyMotionWasNotCalled() { 279 ASSERT_TRUE(mNotifyMotionArgs.empty()) 280 << "Expected notifyMotion() to not have been called."; 281 } 282 283 void assertNotifySwitchWasCalled(NotifySwitchArgs* outArgs = NULL) { 284 ASSERT_FALSE(mNotifySwitchArgs.empty()) 285 << "Expected notifySwitch() to have been called."; 286 if (outArgs) { 287 *outArgs = *mNotifySwitchArgs.begin(); 288 } 289 mNotifySwitchArgs.erase(mNotifySwitchArgs.begin()); 290 } 291 292private: 293 virtual void notifyConfigurationChanged(nsecs_t eventTime) { 294 NotifyConfigurationChangedArgs args; 295 args.eventTime = eventTime; 296 mNotifyConfigurationChangedArgs.push_back(args); 297 } 298 299 virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t source, 300 uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode, 301 int32_t scanCode, int32_t metaState, nsecs_t downTime) { 302 NotifyKeyArgs args; 303 args.eventTime = eventTime; 304 args.deviceId = deviceId; 305 args.source = source; 306 args.policyFlags = policyFlags; 307 args.action = action; 308 args.flags = flags; 309 args.keyCode = keyCode; 310 args.scanCode = scanCode; 311 args.metaState = metaState; 312 args.downTime = downTime; 313 mNotifyKeyArgs.push_back(args); 314 } 315 316 virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t source, 317 uint32_t policyFlags, int32_t action, int32_t flags, 318 int32_t metaState, int32_t edgeFlags, 319 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords, 320 float xPrecision, float yPrecision, nsecs_t downTime) { 321 NotifyMotionArgs args; 322 args.eventTime = eventTime; 323 args.deviceId = deviceId; 324 args.source = source; 325 args.policyFlags = policyFlags; 326 args.action = action; 327 args.flags = flags; 328 args.metaState = metaState; 329 args.edgeFlags = edgeFlags; 330 args.pointerCount = pointerCount; 331 args.pointerIds.clear(); 332 args.pointerIds.appendArray(pointerIds, pointerCount); 333 args.pointerCoords.clear(); 334 args.pointerCoords.appendArray(pointerCoords, pointerCount); 335 args.xPrecision = xPrecision; 336 args.yPrecision = yPrecision; 337 args.downTime = downTime; 338 mNotifyMotionArgs.push_back(args); 339 } 340 341 virtual void notifySwitch(nsecs_t when, 342 int32_t switchCode, int32_t switchValue, uint32_t policyFlags) { 343 NotifySwitchArgs args; 344 args.when = when; 345 args.switchCode = switchCode; 346 args.switchValue = switchValue; 347 args.policyFlags = policyFlags; 348 mNotifySwitchArgs.push_back(args); 349 } 350 351 virtual void dump(String8& dump) { 352 ADD_FAILURE() << "Should never be called by input reader."; 353 } 354 355 virtual void dispatchOnce() { 356 ADD_FAILURE() << "Should never be called by input reader."; 357 } 358 359 virtual int32_t injectInputEvent(const InputEvent* event, 360 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) { 361 ADD_FAILURE() << "Should never be called by input reader."; 362 return INPUT_EVENT_INJECTION_FAILED; 363 } 364 365 virtual void setInputWindows(const Vector<InputWindow>& inputWindows) { 366 ADD_FAILURE() << "Should never be called by input reader."; 367 } 368 369 virtual void setFocusedApplication(const InputApplication* inputApplication) { 370 ADD_FAILURE() << "Should never be called by input reader."; 371 } 372 373 virtual void setInputDispatchMode(bool enabled, bool frozen) { 374 ADD_FAILURE() << "Should never be called by input reader."; 375 } 376 377 virtual bool transferTouchFocus(const sp<InputChannel>& fromChannel, 378 const sp<InputChannel>& toChannel) { 379 ADD_FAILURE() << "Should never be called by input reader."; 380 return 0; 381 } 382 383 virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel, 384 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) { 385 ADD_FAILURE() << "Should never be called by input reader."; 386 return 0; 387 } 388 389 virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) { 390 ADD_FAILURE() << "Should never be called by input reader."; 391 return 0; 392 } 393}; 394 395 396// --- FakeEventHub --- 397 398class FakeEventHub : public EventHubInterface { 399 struct KeyInfo { 400 int32_t keyCode; 401 uint32_t flags; 402 }; 403 404 struct Device { 405 String8 name; 406 uint32_t classes; 407 PropertyMap configuration; 408 KeyedVector<int, RawAbsoluteAxisInfo> absoluteAxes; 409 KeyedVector<int, bool> relativeAxes; 410 KeyedVector<int32_t, int32_t> keyCodeStates; 411 KeyedVector<int32_t, int32_t> scanCodeStates; 412 KeyedVector<int32_t, int32_t> switchStates; 413 KeyedVector<int32_t, KeyInfo> keys; 414 KeyedVector<int32_t, bool> leds; 415 Vector<VirtualKeyDefinition> virtualKeys; 416 417 Device(const String8& name, uint32_t classes) : 418 name(name), classes(classes) { 419 } 420 }; 421 422 KeyedVector<int32_t, Device*> mDevices; 423 Vector<String8> mExcludedDevices; 424 List<RawEvent> mEvents; 425 426protected: 427 virtual ~FakeEventHub() { 428 for (size_t i = 0; i < mDevices.size(); i++) { 429 delete mDevices.valueAt(i); 430 } 431 } 432 433public: 434 FakeEventHub() { } 435 436 void addDevice(int32_t deviceId, const String8& name, uint32_t classes) { 437 Device* device = new Device(name, classes); 438 mDevices.add(deviceId, device); 439 440 enqueueEvent(ARBITRARY_TIME, deviceId, EventHubInterface::DEVICE_ADDED, 0, 0, 0, 0); 441 } 442 443 void removeDevice(int32_t deviceId) { 444 delete mDevices.valueFor(deviceId); 445 mDevices.removeItem(deviceId); 446 447 enqueueEvent(ARBITRARY_TIME, deviceId, EventHubInterface::DEVICE_REMOVED, 0, 0, 0, 0); 448 } 449 450 void finishDeviceScan() { 451 enqueueEvent(ARBITRARY_TIME, 0, EventHubInterface::FINISHED_DEVICE_SCAN, 0, 0, 0, 0); 452 } 453 454 void addConfigurationProperty(int32_t deviceId, const String8& key, const String8& value) { 455 Device* device = getDevice(deviceId); 456 device->configuration.addProperty(key, value); 457 } 458 459 void addConfigurationMap(int32_t deviceId, const PropertyMap* configuration) { 460 Device* device = getDevice(deviceId); 461 device->configuration.addAll(configuration); 462 } 463 464 void addAbsoluteAxis(int32_t deviceId, int axis, 465 int32_t minValue, int32_t maxValue, int flat, int fuzz) { 466 Device* device = getDevice(deviceId); 467 468 RawAbsoluteAxisInfo info; 469 info.valid = true; 470 info.minValue = minValue; 471 info.maxValue = maxValue; 472 info.flat = flat; 473 info.fuzz = fuzz; 474 device->absoluteAxes.add(axis, info); 475 } 476 477 void addRelativeAxis(int32_t deviceId, int32_t axis) { 478 Device* device = getDevice(deviceId); 479 device->relativeAxes.add(axis, true); 480 } 481 482 void setKeyCodeState(int32_t deviceId, int32_t keyCode, int32_t state) { 483 Device* device = getDevice(deviceId); 484 device->keyCodeStates.replaceValueFor(keyCode, state); 485 } 486 487 void setScanCodeState(int32_t deviceId, int32_t scanCode, int32_t state) { 488 Device* device = getDevice(deviceId); 489 device->scanCodeStates.replaceValueFor(scanCode, state); 490 } 491 492 void setSwitchState(int32_t deviceId, int32_t switchCode, int32_t state) { 493 Device* device = getDevice(deviceId); 494 device->switchStates.replaceValueFor(switchCode, state); 495 } 496 497 void addKey(int32_t deviceId, int32_t scanCode, int32_t keyCode, uint32_t flags) { 498 Device* device = getDevice(deviceId); 499 KeyInfo info; 500 info.keyCode = keyCode; 501 info.flags = flags; 502 device->keys.add(scanCode, info); 503 } 504 505 void addLed(int32_t deviceId, int32_t led, bool initialState) { 506 Device* device = getDevice(deviceId); 507 device->leds.add(led, initialState); 508 } 509 510 bool getLedState(int32_t deviceId, int32_t led) { 511 Device* device = getDevice(deviceId); 512 return device->leds.valueFor(led); 513 } 514 515 Vector<String8>& getExcludedDevices() { 516 return mExcludedDevices; 517 } 518 519 void addVirtualKeyDefinition(int32_t deviceId, const VirtualKeyDefinition& definition) { 520 Device* device = getDevice(deviceId); 521 device->virtualKeys.push(definition); 522 } 523 524 void enqueueEvent(nsecs_t when, int32_t deviceId, int32_t type, 525 int32_t scanCode, int32_t keyCode, int32_t value, uint32_t flags) { 526 RawEvent event; 527 event.when = when; 528 event.deviceId = deviceId; 529 event.type = type; 530 event.scanCode = scanCode; 531 event.keyCode = keyCode; 532 event.value = value; 533 event.flags = flags; 534 mEvents.push_back(event); 535 } 536 537 void assertQueueIsEmpty() { 538 ASSERT_EQ(size_t(0), mEvents.size()) 539 << "Expected the event queue to be empty (fully consumed)."; 540 } 541 542private: 543 Device* getDevice(int32_t deviceId) const { 544 ssize_t index = mDevices.indexOfKey(deviceId); 545 return index >= 0 ? mDevices.valueAt(index) : NULL; 546 } 547 548 virtual uint32_t getDeviceClasses(int32_t deviceId) const { 549 Device* device = getDevice(deviceId); 550 return device ? device->classes : 0; 551 } 552 553 virtual String8 getDeviceName(int32_t deviceId) const { 554 Device* device = getDevice(deviceId); 555 return device ? device->name : String8("unknown"); 556 } 557 558 virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const { 559 Device* device = getDevice(deviceId); 560 if (device) { 561 *outConfiguration = device->configuration; 562 } 563 } 564 565 virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis, 566 RawAbsoluteAxisInfo* outAxisInfo) const { 567 Device* device = getDevice(deviceId); 568 if (device) { 569 ssize_t index = device->absoluteAxes.indexOfKey(axis); 570 if (index >= 0) { 571 *outAxisInfo = device->absoluteAxes.valueAt(index); 572 return OK; 573 } 574 } 575 return -1; 576 } 577 578 virtual bool hasRelativeAxis(int32_t deviceId, int axis) const { 579 Device* device = getDevice(deviceId); 580 if (device) { 581 return device->relativeAxes.indexOfKey(axis) >= 0; 582 } 583 return false; 584 } 585 586 virtual status_t mapKey(int32_t deviceId, int scancode, 587 int32_t* outKeycode, uint32_t* outFlags) const { 588 Device* device = getDevice(deviceId); 589 if (device) { 590 ssize_t index = device->keys.indexOfKey(scancode); 591 if (index >= 0) { 592 if (outKeycode) { 593 *outKeycode = device->keys.valueAt(index).keyCode; 594 } 595 if (outFlags) { 596 *outFlags = device->keys.valueAt(index).flags; 597 } 598 return OK; 599 } 600 } 601 return NAME_NOT_FOUND; 602 } 603 604 virtual status_t mapAxis(int32_t deviceId, int scancode, 605 AxisInfo* outAxisInfo) const { 606 return NAME_NOT_FOUND; 607 } 608 609 virtual void addExcludedDevice(const char* deviceName) { 610 mExcludedDevices.add(String8(deviceName)); 611 } 612 613 virtual size_t getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) { 614 if (mEvents.empty()) { 615 return 0; 616 } 617 618 *buffer = *mEvents.begin(); 619 mEvents.erase(mEvents.begin()); 620 return 1; 621 } 622 623 virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const { 624 Device* device = getDevice(deviceId); 625 if (device) { 626 ssize_t index = device->scanCodeStates.indexOfKey(scanCode); 627 if (index >= 0) { 628 return device->scanCodeStates.valueAt(index); 629 } 630 } 631 return AKEY_STATE_UNKNOWN; 632 } 633 634 virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const { 635 Device* device = getDevice(deviceId); 636 if (device) { 637 ssize_t index = device->keyCodeStates.indexOfKey(keyCode); 638 if (index >= 0) { 639 return device->keyCodeStates.valueAt(index); 640 } 641 } 642 return AKEY_STATE_UNKNOWN; 643 } 644 645 virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const { 646 Device* device = getDevice(deviceId); 647 if (device) { 648 ssize_t index = device->switchStates.indexOfKey(sw); 649 if (index >= 0) { 650 return device->switchStates.valueAt(index); 651 } 652 } 653 return AKEY_STATE_UNKNOWN; 654 } 655 656 virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes, 657 uint8_t* outFlags) const { 658 bool result = false; 659 Device* device = getDevice(deviceId); 660 if (device) { 661 for (size_t i = 0; i < numCodes; i++) { 662 for (size_t j = 0; j < device->keys.size(); j++) { 663 if (keyCodes[i] == device->keys.valueAt(j).keyCode) { 664 outFlags[i] = 1; 665 result = true; 666 } 667 } 668 } 669 } 670 return result; 671 } 672 673 virtual bool hasLed(int32_t deviceId, int32_t led) const { 674 Device* device = getDevice(deviceId); 675 return device && device->leds.indexOfKey(led) >= 0; 676 } 677 678 virtual void setLedState(int32_t deviceId, int32_t led, bool on) { 679 Device* device = getDevice(deviceId); 680 if (device) { 681 ssize_t index = device->leds.indexOfKey(led); 682 if (index >= 0) { 683 device->leds.replaceValueAt(led, on); 684 } else { 685 ADD_FAILURE() 686 << "Attempted to set the state of an LED that the EventHub declared " 687 "was not present. led=" << led; 688 } 689 } 690 } 691 692 virtual void getVirtualKeyDefinitions(int32_t deviceId, 693 Vector<VirtualKeyDefinition>& outVirtualKeys) const { 694 outVirtualKeys.clear(); 695 696 Device* device = getDevice(deviceId); 697 if (device) { 698 outVirtualKeys.appendVector(device->virtualKeys); 699 } 700 } 701 702 virtual bool isExternal(int32_t deviceId) const { 703 return false; 704 } 705 706 virtual void dump(String8& dump) { 707 } 708}; 709 710 711// --- FakeInputReaderContext --- 712 713class FakeInputReaderContext : public InputReaderContext { 714 sp<EventHubInterface> mEventHub; 715 sp<InputReaderPolicyInterface> mPolicy; 716 sp<InputDispatcherInterface> mDispatcher; 717 int32_t mGlobalMetaState; 718 bool mUpdateGlobalMetaStateWasCalled; 719 720public: 721 FakeInputReaderContext(const sp<EventHubInterface>& eventHub, 722 const sp<InputReaderPolicyInterface>& policy, 723 const sp<InputDispatcherInterface>& dispatcher) : 724 mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher), 725 mGlobalMetaState(0) { 726 } 727 728 virtual ~FakeInputReaderContext() { } 729 730 void assertUpdateGlobalMetaStateWasCalled() { 731 ASSERT_TRUE(mUpdateGlobalMetaStateWasCalled) 732 << "Expected updateGlobalMetaState() to have been called."; 733 mUpdateGlobalMetaStateWasCalled = false; 734 } 735 736 void setGlobalMetaState(int32_t state) { 737 mGlobalMetaState = state; 738 } 739 740private: 741 virtual void updateGlobalMetaState() { 742 mUpdateGlobalMetaStateWasCalled = true; 743 } 744 745 virtual int32_t getGlobalMetaState() { 746 return mGlobalMetaState; 747 } 748 749 virtual EventHubInterface* getEventHub() { 750 return mEventHub.get(); 751 } 752 753 virtual InputReaderPolicyInterface* getPolicy() { 754 return mPolicy.get(); 755 } 756 757 virtual InputDispatcherInterface* getDispatcher() { 758 return mDispatcher.get(); 759 } 760 761 virtual void disableVirtualKeysUntil(nsecs_t time) { 762 } 763 764 virtual bool shouldDropVirtualKey(nsecs_t now, 765 InputDevice* device, int32_t keyCode, int32_t scanCode) { 766 return false; 767 } 768 769 virtual void fadePointer() { 770 } 771 772 virtual void requestTimeoutAtTime(nsecs_t when) { 773 } 774}; 775 776 777// --- FakeInputMapper --- 778 779class FakeInputMapper : public InputMapper { 780 uint32_t mSources; 781 int32_t mKeyboardType; 782 int32_t mMetaState; 783 KeyedVector<int32_t, int32_t> mKeyCodeStates; 784 KeyedVector<int32_t, int32_t> mScanCodeStates; 785 KeyedVector<int32_t, int32_t> mSwitchStates; 786 Vector<int32_t> mSupportedKeyCodes; 787 RawEvent mLastEvent; 788 789 bool mConfigureWasCalled; 790 bool mResetWasCalled; 791 bool mProcessWasCalled; 792 793public: 794 FakeInputMapper(InputDevice* device, uint32_t sources) : 795 InputMapper(device), 796 mSources(sources), mKeyboardType(AINPUT_KEYBOARD_TYPE_NONE), 797 mMetaState(0), 798 mConfigureWasCalled(false), mResetWasCalled(false), mProcessWasCalled(false) { 799 } 800 801 virtual ~FakeInputMapper() { } 802 803 void setKeyboardType(int32_t keyboardType) { 804 mKeyboardType = keyboardType; 805 } 806 807 void setMetaState(int32_t metaState) { 808 mMetaState = metaState; 809 } 810 811 void assertConfigureWasCalled() { 812 ASSERT_TRUE(mConfigureWasCalled) 813 << "Expected configure() to have been called."; 814 mConfigureWasCalled = false; 815 } 816 817 void assertResetWasCalled() { 818 ASSERT_TRUE(mResetWasCalled) 819 << "Expected reset() to have been called."; 820 mResetWasCalled = false; 821 } 822 823 void assertProcessWasCalled(RawEvent* outLastEvent = NULL) { 824 ASSERT_TRUE(mProcessWasCalled) 825 << "Expected process() to have been called."; 826 if (outLastEvent) { 827 *outLastEvent = mLastEvent; 828 } 829 mProcessWasCalled = false; 830 } 831 832 void setKeyCodeState(int32_t keyCode, int32_t state) { 833 mKeyCodeStates.replaceValueFor(keyCode, state); 834 } 835 836 void setScanCodeState(int32_t scanCode, int32_t state) { 837 mScanCodeStates.replaceValueFor(scanCode, state); 838 } 839 840 void setSwitchState(int32_t switchCode, int32_t state) { 841 mSwitchStates.replaceValueFor(switchCode, state); 842 } 843 844 void addSupportedKeyCode(int32_t keyCode) { 845 mSupportedKeyCodes.add(keyCode); 846 } 847 848private: 849 virtual uint32_t getSources() { 850 return mSources; 851 } 852 853 virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo) { 854 InputMapper::populateDeviceInfo(deviceInfo); 855 856 if (mKeyboardType != AINPUT_KEYBOARD_TYPE_NONE) { 857 deviceInfo->setKeyboardType(mKeyboardType); 858 } 859 } 860 861 virtual void configure() { 862 mConfigureWasCalled = true; 863 } 864 865 virtual void reset() { 866 mResetWasCalled = true; 867 } 868 869 virtual void process(const RawEvent* rawEvent) { 870 mLastEvent = *rawEvent; 871 mProcessWasCalled = true; 872 } 873 874 virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode) { 875 ssize_t index = mKeyCodeStates.indexOfKey(keyCode); 876 return index >= 0 ? mKeyCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN; 877 } 878 879 virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode) { 880 ssize_t index = mScanCodeStates.indexOfKey(scanCode); 881 return index >= 0 ? mScanCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN; 882 } 883 884 virtual int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode) { 885 ssize_t index = mSwitchStates.indexOfKey(switchCode); 886 return index >= 0 ? mSwitchStates.valueAt(index) : AKEY_STATE_UNKNOWN; 887 } 888 889 virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, 890 const int32_t* keyCodes, uint8_t* outFlags) { 891 bool result = false; 892 for (size_t i = 0; i < numCodes; i++) { 893 for (size_t j = 0; j < mSupportedKeyCodes.size(); j++) { 894 if (keyCodes[i] == mSupportedKeyCodes[j]) { 895 outFlags[i] = 1; 896 result = true; 897 } 898 } 899 } 900 return result; 901 } 902 903 virtual int32_t getMetaState() { 904 return mMetaState; 905 } 906 907 virtual void fadePointer() { 908 } 909}; 910 911 912// --- InstrumentedInputReader --- 913 914class InstrumentedInputReader : public InputReader { 915 InputDevice* mNextDevice; 916 917public: 918 InstrumentedInputReader(const sp<EventHubInterface>& eventHub, 919 const sp<InputReaderPolicyInterface>& policy, 920 const sp<InputDispatcherInterface>& dispatcher) : 921 InputReader(eventHub, policy, dispatcher), 922 mNextDevice(NULL) { 923 } 924 925 virtual ~InstrumentedInputReader() { 926 if (mNextDevice) { 927 delete mNextDevice; 928 } 929 } 930 931 void setNextDevice(InputDevice* device) { 932 mNextDevice = device; 933 } 934 935protected: 936 virtual InputDevice* createDevice(int32_t deviceId, const String8& name, uint32_t classes) { 937 if (mNextDevice) { 938 InputDevice* device = mNextDevice; 939 mNextDevice = NULL; 940 return device; 941 } 942 return InputReader::createDevice(deviceId, name, classes); 943 } 944 945 friend class InputReaderTest; 946}; 947 948 949// --- InputReaderTest --- 950 951class InputReaderTest : public testing::Test { 952protected: 953 sp<FakeInputDispatcher> mFakeDispatcher; 954 sp<FakeInputReaderPolicy> mFakePolicy; 955 sp<FakeEventHub> mFakeEventHub; 956 sp<InstrumentedInputReader> mReader; 957 958 virtual void SetUp() { 959 mFakeEventHub = new FakeEventHub(); 960 mFakePolicy = new FakeInputReaderPolicy(); 961 mFakeDispatcher = new FakeInputDispatcher(); 962 963 mReader = new InstrumentedInputReader(mFakeEventHub, mFakePolicy, mFakeDispatcher); 964 } 965 966 virtual void TearDown() { 967 mReader.clear(); 968 969 mFakeDispatcher.clear(); 970 mFakePolicy.clear(); 971 mFakeEventHub.clear(); 972 } 973 974 void addDevice(int32_t deviceId, const String8& name, uint32_t classes, 975 const PropertyMap* configuration) { 976 mFakeEventHub->addDevice(deviceId, name, classes); 977 if (configuration) { 978 mFakeEventHub->addConfigurationMap(deviceId, configuration); 979 } 980 mFakeEventHub->finishDeviceScan(); 981 mReader->loopOnce(); 982 mReader->loopOnce(); 983 mFakeEventHub->assertQueueIsEmpty(); 984 } 985 986 FakeInputMapper* addDeviceWithFakeInputMapper(int32_t deviceId, 987 const String8& name, uint32_t classes, uint32_t sources, 988 const PropertyMap* configuration) { 989 InputDevice* device = new InputDevice(mReader.get(), deviceId, name); 990 FakeInputMapper* mapper = new FakeInputMapper(device, sources); 991 device->addMapper(mapper); 992 mReader->setNextDevice(device); 993 addDevice(deviceId, name, classes, configuration); 994 return mapper; 995 } 996}; 997 998TEST_F(InputReaderTest, GetInputConfiguration_WhenNoDevices_ReturnsDefaults) { 999 InputConfiguration config; 1000 mReader->getInputConfiguration(&config); 1001 1002 ASSERT_EQ(InputConfiguration::KEYBOARD_NOKEYS, config.keyboard); 1003 ASSERT_EQ(InputConfiguration::NAVIGATION_NONAV, config.navigation); 1004 ASSERT_EQ(InputConfiguration::TOUCHSCREEN_NOTOUCH, config.touchScreen); 1005} 1006 1007TEST_F(InputReaderTest, GetInputConfiguration_WhenAlphabeticKeyboardPresent_ReturnsQwertyKeyboard) { 1008 ASSERT_NO_FATAL_FAILURE(addDevice(0, String8("keyboard"), 1009 INPUT_DEVICE_CLASS_KEYBOARD | INPUT_DEVICE_CLASS_ALPHAKEY, NULL)); 1010 1011 InputConfiguration config; 1012 mReader->getInputConfiguration(&config); 1013 1014 ASSERT_EQ(InputConfiguration::KEYBOARD_QWERTY, config.keyboard); 1015 ASSERT_EQ(InputConfiguration::NAVIGATION_NONAV, config.navigation); 1016 ASSERT_EQ(InputConfiguration::TOUCHSCREEN_NOTOUCH, config.touchScreen); 1017} 1018 1019TEST_F(InputReaderTest, GetInputConfiguration_WhenTouchScreenPresent_ReturnsFingerTouchScreen) { 1020 PropertyMap configuration; 1021 configuration.addProperty(String8("touch.deviceType"), String8("touchScreen")); 1022 ASSERT_NO_FATAL_FAILURE(addDevice(0, String8("touchscreen"), 1023 INPUT_DEVICE_CLASS_TOUCH, &configuration)); 1024 1025 InputConfiguration config; 1026 mReader->getInputConfiguration(&config); 1027 1028 ASSERT_EQ(InputConfiguration::KEYBOARD_NOKEYS, config.keyboard); 1029 ASSERT_EQ(InputConfiguration::NAVIGATION_NONAV, config.navigation); 1030 ASSERT_EQ(InputConfiguration::TOUCHSCREEN_FINGER, config.touchScreen); 1031} 1032 1033TEST_F(InputReaderTest, GetInputConfiguration_WhenTouchPadPresent_ReturnsFingerNoTouch) { 1034 ASSERT_NO_FATAL_FAILURE(addDevice(0, String8("touchpad"), 1035 INPUT_DEVICE_CLASS_TOUCH, NULL)); 1036 1037 InputConfiguration config; 1038 mReader->getInputConfiguration(&config); 1039 1040 ASSERT_EQ(InputConfiguration::KEYBOARD_NOKEYS, config.keyboard); 1041 ASSERT_EQ(InputConfiguration::NAVIGATION_NONAV, config.navigation); 1042 ASSERT_EQ(InputConfiguration::TOUCHSCREEN_NOTOUCH, config.touchScreen); 1043} 1044 1045TEST_F(InputReaderTest, GetInputConfiguration_WhenMousePresent_ReturnsNoNavigation) { 1046 sp<FakePointerController> controller = new FakePointerController(); 1047 mFakePolicy->setPointerController(0, controller); 1048 1049 PropertyMap configuration; 1050 configuration.addProperty(String8("cursor.mode"), String8("pointer")); 1051 ASSERT_NO_FATAL_FAILURE(addDevice(0, String8("mouse"), 1052 INPUT_DEVICE_CLASS_CURSOR, &configuration)); 1053 1054 InputConfiguration config; 1055 mReader->getInputConfiguration(&config); 1056 1057 ASSERT_EQ(InputConfiguration::KEYBOARD_NOKEYS, config.keyboard); 1058 ASSERT_EQ(InputConfiguration::NAVIGATION_NONAV, config.navigation); 1059 ASSERT_EQ(InputConfiguration::TOUCHSCREEN_NOTOUCH, config.touchScreen); 1060} 1061 1062TEST_F(InputReaderTest, GetInputConfiguration_WhenTrackballPresent_ReturnsTrackballNavigation) { 1063 PropertyMap configuration; 1064 configuration.addProperty(String8("cursor.mode"), String8("navigation")); 1065 ASSERT_NO_FATAL_FAILURE(addDevice(0, String8("trackball"), 1066 INPUT_DEVICE_CLASS_CURSOR, &configuration)); 1067 1068 InputConfiguration config; 1069 mReader->getInputConfiguration(&config); 1070 1071 ASSERT_EQ(InputConfiguration::KEYBOARD_NOKEYS, config.keyboard); 1072 ASSERT_EQ(InputConfiguration::NAVIGATION_TRACKBALL, config.navigation); 1073 ASSERT_EQ(InputConfiguration::TOUCHSCREEN_NOTOUCH, config.touchScreen); 1074} 1075 1076TEST_F(InputReaderTest, GetInputConfiguration_WhenDPadPresent_ReturnsDPadNavigation) { 1077 ASSERT_NO_FATAL_FAILURE(addDevice(0, String8("dpad"), 1078 INPUT_DEVICE_CLASS_DPAD, NULL)); 1079 1080 InputConfiguration config; 1081 mReader->getInputConfiguration(&config); 1082 1083 ASSERT_EQ(InputConfiguration::KEYBOARD_NOKEYS, config.keyboard); 1084 ASSERT_EQ(InputConfiguration::NAVIGATION_DPAD, config.navigation); 1085 ASSERT_EQ(InputConfiguration::TOUCHSCREEN_NOTOUCH, config.touchScreen); 1086} 1087 1088TEST_F(InputReaderTest, GetInputDeviceInfo_WhenDeviceIdIsValid) { 1089 ASSERT_NO_FATAL_FAILURE(addDevice(1, String8("keyboard"), 1090 INPUT_DEVICE_CLASS_KEYBOARD, NULL)); 1091 1092 InputDeviceInfo info; 1093 status_t result = mReader->getInputDeviceInfo(1, &info); 1094 1095 ASSERT_EQ(OK, result); 1096 ASSERT_EQ(1, info.getId()); 1097 ASSERT_STREQ("keyboard", info.getName().string()); 1098 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, info.getKeyboardType()); 1099 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, info.getSources()); 1100 ASSERT_EQ(size_t(0), info.getMotionRanges().size()); 1101} 1102 1103TEST_F(InputReaderTest, GetInputDeviceInfo_WhenDeviceIdIsInvalid) { 1104 InputDeviceInfo info; 1105 status_t result = mReader->getInputDeviceInfo(-1, &info); 1106 1107 ASSERT_EQ(NAME_NOT_FOUND, result); 1108} 1109 1110TEST_F(InputReaderTest, GetInputDeviceInfo_WhenDeviceIdIsIgnored) { 1111 addDevice(1, String8("ignored"), 0, NULL); // no classes so device will be ignored 1112 1113 InputDeviceInfo info; 1114 status_t result = mReader->getInputDeviceInfo(1, &info); 1115 1116 ASSERT_EQ(NAME_NOT_FOUND, result); 1117} 1118 1119TEST_F(InputReaderTest, GetInputDeviceIds) { 1120 sp<FakePointerController> controller = new FakePointerController(); 1121 mFakePolicy->setPointerController(2, controller); 1122 1123 ASSERT_NO_FATAL_FAILURE(addDevice(1, String8("keyboard"), 1124 INPUT_DEVICE_CLASS_KEYBOARD | INPUT_DEVICE_CLASS_ALPHAKEY, NULL)); 1125 ASSERT_NO_FATAL_FAILURE(addDevice(2, String8("mouse"), 1126 INPUT_DEVICE_CLASS_CURSOR, NULL)); 1127 1128 Vector<int32_t> ids; 1129 mReader->getInputDeviceIds(ids); 1130 1131 ASSERT_EQ(size_t(2), ids.size()); 1132 ASSERT_EQ(1, ids[0]); 1133 ASSERT_EQ(2, ids[1]); 1134} 1135 1136TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToMappers) { 1137 FakeInputMapper* mapper = NULL; 1138 ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"), 1139 INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL)); 1140 mapper->setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN); 1141 1142 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(0, 1143 AINPUT_SOURCE_ANY, AKEYCODE_A)) 1144 << "Should return unknown when the device id is >= 0 but unknown."; 1145 1146 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(1, 1147 AINPUT_SOURCE_TRACKBALL, AKEYCODE_A)) 1148 << "Should return unknown when the device id is valid but the sources are not supported by the device."; 1149 1150 ASSERT_EQ(AKEY_STATE_DOWN, mReader->getKeyCodeState(1, 1151 AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, AKEYCODE_A)) 1152 << "Should return value provided by mapper when device id is valid and the device supports some of the sources."; 1153 1154 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(-1, 1155 AINPUT_SOURCE_TRACKBALL, AKEYCODE_A)) 1156 << "Should return unknown when the device id is < 0 but the sources are not supported by any device."; 1157 1158 ASSERT_EQ(AKEY_STATE_DOWN, mReader->getKeyCodeState(-1, 1159 AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, AKEYCODE_A)) 1160 << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources."; 1161} 1162 1163TEST_F(InputReaderTest, GetScanCodeState_ForwardsRequestsToMappers) { 1164 FakeInputMapper* mapper = NULL; 1165 ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"), 1166 INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL)); 1167 mapper->setScanCodeState(KEY_A, AKEY_STATE_DOWN); 1168 1169 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(0, 1170 AINPUT_SOURCE_ANY, KEY_A)) 1171 << "Should return unknown when the device id is >= 0 but unknown."; 1172 1173 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(1, 1174 AINPUT_SOURCE_TRACKBALL, KEY_A)) 1175 << "Should return unknown when the device id is valid but the sources are not supported by the device."; 1176 1177 ASSERT_EQ(AKEY_STATE_DOWN, mReader->getScanCodeState(1, 1178 AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, KEY_A)) 1179 << "Should return value provided by mapper when device id is valid and the device supports some of the sources."; 1180 1181 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(-1, 1182 AINPUT_SOURCE_TRACKBALL, KEY_A)) 1183 << "Should return unknown when the device id is < 0 but the sources are not supported by any device."; 1184 1185 ASSERT_EQ(AKEY_STATE_DOWN, mReader->getScanCodeState(-1, 1186 AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, KEY_A)) 1187 << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources."; 1188} 1189 1190TEST_F(InputReaderTest, GetSwitchState_ForwardsRequestsToMappers) { 1191 FakeInputMapper* mapper = NULL; 1192 ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"), 1193 INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL)); 1194 mapper->setSwitchState(SW_LID, AKEY_STATE_DOWN); 1195 1196 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(0, 1197 AINPUT_SOURCE_ANY, SW_LID)) 1198 << "Should return unknown when the device id is >= 0 but unknown."; 1199 1200 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(1, 1201 AINPUT_SOURCE_TRACKBALL, SW_LID)) 1202 << "Should return unknown when the device id is valid but the sources are not supported by the device."; 1203 1204 ASSERT_EQ(AKEY_STATE_DOWN, mReader->getSwitchState(1, 1205 AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, SW_LID)) 1206 << "Should return value provided by mapper when device id is valid and the device supports some of the sources."; 1207 1208 ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(-1, 1209 AINPUT_SOURCE_TRACKBALL, SW_LID)) 1210 << "Should return unknown when the device id is < 0 but the sources are not supported by any device."; 1211 1212 ASSERT_EQ(AKEY_STATE_DOWN, mReader->getSwitchState(-1, 1213 AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, SW_LID)) 1214 << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources."; 1215} 1216 1217TEST_F(InputReaderTest, MarkSupportedKeyCodes_ForwardsRequestsToMappers) { 1218 FakeInputMapper* mapper = NULL; 1219 ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"), 1220 INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL)); 1221 mapper->addSupportedKeyCode(AKEYCODE_A); 1222 mapper->addSupportedKeyCode(AKEYCODE_B); 1223 1224 const int32_t keyCodes[4] = { AKEYCODE_A, AKEYCODE_B, AKEYCODE_1, AKEYCODE_2 }; 1225 uint8_t flags[4] = { 0, 0, 0, 1 }; 1226 1227 ASSERT_FALSE(mReader->hasKeys(0, AINPUT_SOURCE_ANY, 4, keyCodes, flags)) 1228 << "Should return false when device id is >= 0 but unknown."; 1229 ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]); 1230 1231 flags[3] = 1; 1232 ASSERT_FALSE(mReader->hasKeys(1, AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags)) 1233 << "Should return false when device id is valid but the sources are not supported by the device."; 1234 ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]); 1235 1236 flags[3] = 1; 1237 ASSERT_TRUE(mReader->hasKeys(1, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags)) 1238 << "Should return value provided by mapper when device id is valid and the device supports some of the sources."; 1239 ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]); 1240 1241 flags[3] = 1; 1242 ASSERT_FALSE(mReader->hasKeys(-1, AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags)) 1243 << "Should return false when the device id is < 0 but the sources are not supported by any device."; 1244 ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]); 1245 1246 flags[3] = 1; 1247 ASSERT_TRUE(mReader->hasKeys(-1, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags)) 1248 << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources."; 1249 ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]); 1250} 1251 1252TEST_F(InputReaderTest, LoopOnce_WhenDeviceScanFinished_SendsConfigurationChanged) { 1253 addDevice(1, String8("ignored"), INPUT_DEVICE_CLASS_KEYBOARD, NULL); 1254 1255 FakeInputDispatcher::NotifyConfigurationChangedArgs args; 1256 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyConfigurationChangedWasCalled(&args)); 1257 ASSERT_EQ(ARBITRARY_TIME, args.eventTime); 1258} 1259 1260TEST_F(InputReaderTest, LoopOnce_ForwardsRawEventsToMappers) { 1261 FakeInputMapper* mapper = NULL; 1262 ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"), 1263 INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL)); 1264 1265 mFakeEventHub->enqueueEvent(0, 1, EV_KEY, KEY_A, AKEYCODE_A, 1, POLICY_FLAG_WAKE); 1266 mReader->loopOnce(); 1267 ASSERT_NO_FATAL_FAILURE(mFakeEventHub->assertQueueIsEmpty()); 1268 1269 RawEvent event; 1270 ASSERT_NO_FATAL_FAILURE(mapper->assertProcessWasCalled(&event)); 1271 ASSERT_EQ(0, event.when); 1272 ASSERT_EQ(1, event.deviceId); 1273 ASSERT_EQ(EV_KEY, event.type); 1274 ASSERT_EQ(KEY_A, event.scanCode); 1275 ASSERT_EQ(AKEYCODE_A, event.keyCode); 1276 ASSERT_EQ(1, event.value); 1277 ASSERT_EQ(POLICY_FLAG_WAKE, event.flags); 1278} 1279 1280 1281// --- InputDeviceTest --- 1282 1283class InputDeviceTest : public testing::Test { 1284protected: 1285 static const char* DEVICE_NAME; 1286 static const int32_t DEVICE_ID; 1287 1288 sp<FakeEventHub> mFakeEventHub; 1289 sp<FakeInputReaderPolicy> mFakePolicy; 1290 sp<FakeInputDispatcher> mFakeDispatcher; 1291 FakeInputReaderContext* mFakeContext; 1292 1293 InputDevice* mDevice; 1294 1295 virtual void SetUp() { 1296 mFakeEventHub = new FakeEventHub(); 1297 mFakePolicy = new FakeInputReaderPolicy(); 1298 mFakeDispatcher = new FakeInputDispatcher(); 1299 mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeDispatcher); 1300 1301 mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0); 1302 mDevice = new InputDevice(mFakeContext, DEVICE_ID, String8(DEVICE_NAME)); 1303 } 1304 1305 virtual void TearDown() { 1306 delete mDevice; 1307 1308 delete mFakeContext; 1309 mFakeDispatcher.clear(); 1310 mFakePolicy.clear(); 1311 mFakeEventHub.clear(); 1312 } 1313}; 1314 1315const char* InputDeviceTest::DEVICE_NAME = "device"; 1316const int32_t InputDeviceTest::DEVICE_ID = 1; 1317 1318TEST_F(InputDeviceTest, ImmutableProperties) { 1319 ASSERT_EQ(DEVICE_ID, mDevice->getId()); 1320 ASSERT_STREQ(DEVICE_NAME, mDevice->getName()); 1321} 1322 1323TEST_F(InputDeviceTest, WhenNoMappersAreRegistered_DeviceIsIgnored) { 1324 // Configuration. 1325 mDevice->configure(); 1326 1327 // Metadata. 1328 ASSERT_TRUE(mDevice->isIgnored()); 1329 ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, mDevice->getSources()); 1330 1331 InputDeviceInfo info; 1332 mDevice->getDeviceInfo(&info); 1333 ASSERT_EQ(DEVICE_ID, info.getId()); 1334 ASSERT_STREQ(DEVICE_NAME, info.getName().string()); 1335 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NONE, info.getKeyboardType()); 1336 ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, info.getSources()); 1337 1338 // State queries. 1339 ASSERT_EQ(0, mDevice->getMetaState()); 1340 1341 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_KEYBOARD, 0)) 1342 << "Ignored device should return unknown key code state."; 1343 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getScanCodeState(AINPUT_SOURCE_KEYBOARD, 0)) 1344 << "Ignored device should return unknown scan code state."; 1345 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getSwitchState(AINPUT_SOURCE_KEYBOARD, 0)) 1346 << "Ignored device should return unknown switch state."; 1347 1348 const int32_t keyCodes[2] = { AKEYCODE_A, AKEYCODE_B }; 1349 uint8_t flags[2] = { 0, 1 }; 1350 ASSERT_FALSE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_KEYBOARD, 2, keyCodes, flags)) 1351 << "Ignored device should never mark any key codes."; 1352 ASSERT_EQ(0, flags[0]) << "Flag for unsupported key should be unchanged."; 1353 ASSERT_EQ(1, flags[1]) << "Flag for unsupported key should be unchanged."; 1354 1355 // Reset. 1356 mDevice->reset(); 1357} 1358 1359TEST_F(InputDeviceTest, WhenMappersAreRegistered_DeviceIsNotIgnoredAndForwardsRequestsToMappers) { 1360 // Configuration. 1361 mFakeEventHub->addConfigurationProperty(DEVICE_ID, String8("key"), String8("value")); 1362 1363 FakeInputMapper* mapper1 = new FakeInputMapper(mDevice, AINPUT_SOURCE_KEYBOARD); 1364 mapper1->setKeyboardType(AINPUT_KEYBOARD_TYPE_ALPHABETIC); 1365 mapper1->setMetaState(AMETA_ALT_ON); 1366 mapper1->addSupportedKeyCode(AKEYCODE_A); 1367 mapper1->addSupportedKeyCode(AKEYCODE_B); 1368 mapper1->setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN); 1369 mapper1->setKeyCodeState(AKEYCODE_B, AKEY_STATE_UP); 1370 mapper1->setScanCodeState(2, AKEY_STATE_DOWN); 1371 mapper1->setScanCodeState(3, AKEY_STATE_UP); 1372 mapper1->setSwitchState(4, AKEY_STATE_DOWN); 1373 mDevice->addMapper(mapper1); 1374 1375 FakeInputMapper* mapper2 = new FakeInputMapper(mDevice, AINPUT_SOURCE_TOUCHSCREEN); 1376 mapper2->setMetaState(AMETA_SHIFT_ON); 1377 mDevice->addMapper(mapper2); 1378 1379 mDevice->configure(); 1380 1381 String8 propertyValue; 1382 ASSERT_TRUE(mDevice->getConfiguration().tryGetProperty(String8("key"), propertyValue)) 1383 << "Device should have read configuration during configuration phase."; 1384 ASSERT_STREQ("value", propertyValue.string()); 1385 1386 ASSERT_NO_FATAL_FAILURE(mapper1->assertConfigureWasCalled()); 1387 ASSERT_NO_FATAL_FAILURE(mapper2->assertConfigureWasCalled()); 1388 1389 // Metadata. 1390 ASSERT_FALSE(mDevice->isIgnored()); 1391 ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), mDevice->getSources()); 1392 1393 InputDeviceInfo info; 1394 mDevice->getDeviceInfo(&info); 1395 ASSERT_EQ(DEVICE_ID, info.getId()); 1396 ASSERT_STREQ(DEVICE_NAME, info.getName().string()); 1397 ASSERT_EQ(AINPUT_KEYBOARD_TYPE_ALPHABETIC, info.getKeyboardType()); 1398 ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), info.getSources()); 1399 1400 // State queries. 1401 ASSERT_EQ(AMETA_ALT_ON | AMETA_SHIFT_ON, mDevice->getMetaState()) 1402 << "Should query mappers and combine meta states."; 1403 1404 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A)) 1405 << "Should return unknown key code state when source not supported."; 1406 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getScanCodeState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A)) 1407 << "Should return unknown scan code state when source not supported."; 1408 ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getSwitchState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A)) 1409 << "Should return unknown switch state when source not supported."; 1410 1411 ASSERT_EQ(AKEY_STATE_DOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_KEYBOARD, AKEYCODE_A)) 1412 << "Should query mapper when source is supported."; 1413 ASSERT_EQ(AKEY_STATE_UP, mDevice->getScanCodeState(AINPUT_SOURCE_KEYBOARD, 3)) 1414 << "Should query mapper when source is supported."; 1415 ASSERT_EQ(AKEY_STATE_DOWN, mDevice->getSwitchState(AINPUT_SOURCE_KEYBOARD, 4)) 1416 << "Should query mapper when source is supported."; 1417 1418 const int32_t keyCodes[4] = { AKEYCODE_A, AKEYCODE_B, AKEYCODE_1, AKEYCODE_2 }; 1419 uint8_t flags[4] = { 0, 0, 0, 1 }; 1420 ASSERT_FALSE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags)) 1421 << "Should do nothing when source is unsupported."; 1422 ASSERT_EQ(0, flags[0]) << "Flag should be unchanged when source is unsupported."; 1423 ASSERT_EQ(0, flags[1]) << "Flag should be unchanged when source is unsupported."; 1424 ASSERT_EQ(0, flags[2]) << "Flag should be unchanged when source is unsupported."; 1425 ASSERT_EQ(1, flags[3]) << "Flag should be unchanged when source is unsupported."; 1426 1427 ASSERT_TRUE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_KEYBOARD, 4, keyCodes, flags)) 1428 << "Should query mapper when source is supported."; 1429 ASSERT_EQ(1, flags[0]) << "Flag for supported key should be set."; 1430 ASSERT_EQ(1, flags[1]) << "Flag for supported key should be set."; 1431 ASSERT_EQ(0, flags[2]) << "Flag for unsupported key should be unchanged."; 1432 ASSERT_EQ(1, flags[3]) << "Flag for unsupported key should be unchanged."; 1433 1434 // Event handling. 1435 RawEvent event; 1436 mDevice->process(&event, 1); 1437 1438 ASSERT_NO_FATAL_FAILURE(mapper1->assertProcessWasCalled()); 1439 ASSERT_NO_FATAL_FAILURE(mapper2->assertProcessWasCalled()); 1440 1441 // Reset. 1442 mDevice->reset(); 1443 1444 ASSERT_NO_FATAL_FAILURE(mapper1->assertResetWasCalled()); 1445 ASSERT_NO_FATAL_FAILURE(mapper2->assertResetWasCalled()); 1446} 1447 1448 1449// --- InputMapperTest --- 1450 1451class InputMapperTest : public testing::Test { 1452protected: 1453 static const char* DEVICE_NAME; 1454 static const int32_t DEVICE_ID; 1455 1456 sp<FakeEventHub> mFakeEventHub; 1457 sp<FakeInputReaderPolicy> mFakePolicy; 1458 sp<FakeInputDispatcher> mFakeDispatcher; 1459 FakeInputReaderContext* mFakeContext; 1460 InputDevice* mDevice; 1461 1462 virtual void SetUp() { 1463 mFakeEventHub = new FakeEventHub(); 1464 mFakePolicy = new FakeInputReaderPolicy(); 1465 mFakeDispatcher = new FakeInputDispatcher(); 1466 mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeDispatcher); 1467 mDevice = new InputDevice(mFakeContext, DEVICE_ID, String8(DEVICE_NAME)); 1468 1469 mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0); 1470 } 1471 1472 virtual void TearDown() { 1473 delete mDevice; 1474 delete mFakeContext; 1475 mFakeDispatcher.clear(); 1476 mFakePolicy.clear(); 1477 mFakeEventHub.clear(); 1478 } 1479 1480 void addConfigurationProperty(const char* key, const char* value) { 1481 mFakeEventHub->addConfigurationProperty(DEVICE_ID, String8(key), String8(value)); 1482 } 1483 1484 void addMapperAndConfigure(InputMapper* mapper) { 1485 mDevice->addMapper(mapper); 1486 mDevice->configure(); 1487 } 1488 1489 static void process(InputMapper* mapper, nsecs_t when, int32_t deviceId, int32_t type, 1490 int32_t scanCode, int32_t keyCode, int32_t value, uint32_t flags) { 1491 RawEvent event; 1492 event.when = when; 1493 event.deviceId = deviceId; 1494 event.type = type; 1495 event.scanCode = scanCode; 1496 event.keyCode = keyCode; 1497 event.value = value; 1498 event.flags = flags; 1499 mapper->process(&event); 1500 } 1501 1502 static void assertMotionRange(const InputDeviceInfo& info, 1503 int32_t axis, uint32_t source, float min, float max, float flat, float fuzz) { 1504 const InputDeviceInfo::MotionRange* range = info.getMotionRange(axis, source); 1505 ASSERT_TRUE(range != NULL) << "Axis: " << axis << " Source: " << source; 1506 ASSERT_EQ(axis, range->axis) << "Axis: " << axis << " Source: " << source; 1507 ASSERT_EQ(source, range->source) << "Axis: " << axis << " Source: " << source; 1508 ASSERT_NEAR(min, range->min, EPSILON) << "Axis: " << axis << " Source: " << source; 1509 ASSERT_NEAR(max, range->max, EPSILON) << "Axis: " << axis << " Source: " << source; 1510 ASSERT_NEAR(flat, range->flat, EPSILON) << "Axis: " << axis << " Source: " << source; 1511 ASSERT_NEAR(fuzz, range->fuzz, EPSILON) << "Axis: " << axis << " Source: " << source; 1512 } 1513 1514 static void assertPointerCoords(const PointerCoords& coords, 1515 float x, float y, float pressure, float size, 1516 float touchMajor, float touchMinor, float toolMajor, float toolMinor, 1517 float orientation) { 1518 ASSERT_NEAR(x, coords.getAxisValue(AMOTION_EVENT_AXIS_X), 1); 1519 ASSERT_NEAR(y, coords.getAxisValue(AMOTION_EVENT_AXIS_Y), 1); 1520 ASSERT_NEAR(pressure, coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), EPSILON); 1521 ASSERT_NEAR(size, coords.getAxisValue(AMOTION_EVENT_AXIS_SIZE), EPSILON); 1522 ASSERT_NEAR(touchMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR), 1); 1523 ASSERT_NEAR(touchMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR), 1); 1524 ASSERT_NEAR(toolMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR), 1); 1525 ASSERT_NEAR(toolMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR), 1); 1526 ASSERT_NEAR(orientation, coords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION), EPSILON); 1527 } 1528}; 1529 1530const char* InputMapperTest::DEVICE_NAME = "device"; 1531const int32_t InputMapperTest::DEVICE_ID = 1; 1532 1533 1534// --- SwitchInputMapperTest --- 1535 1536class SwitchInputMapperTest : public InputMapperTest { 1537protected: 1538}; 1539 1540TEST_F(SwitchInputMapperTest, GetSources) { 1541 SwitchInputMapper* mapper = new SwitchInputMapper(mDevice); 1542 addMapperAndConfigure(mapper); 1543 1544 ASSERT_EQ(uint32_t(AINPUT_SOURCE_SWITCH), mapper->getSources()); 1545} 1546 1547TEST_F(SwitchInputMapperTest, GetSwitchState) { 1548 SwitchInputMapper* mapper = new SwitchInputMapper(mDevice); 1549 addMapperAndConfigure(mapper); 1550 1551 mFakeEventHub->setSwitchState(DEVICE_ID, SW_LID, 1); 1552 ASSERT_EQ(1, mapper->getSwitchState(AINPUT_SOURCE_ANY, SW_LID)); 1553 1554 mFakeEventHub->setSwitchState(DEVICE_ID, SW_LID, 0); 1555 ASSERT_EQ(0, mapper->getSwitchState(AINPUT_SOURCE_ANY, SW_LID)); 1556} 1557 1558TEST_F(SwitchInputMapperTest, Process) { 1559 SwitchInputMapper* mapper = new SwitchInputMapper(mDevice); 1560 addMapperAndConfigure(mapper); 1561 1562 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SW, SW_LID, 0, 1, 0); 1563 1564 FakeInputDispatcher::NotifySwitchArgs args; 1565 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifySwitchWasCalled(&args)); 1566 ASSERT_EQ(ARBITRARY_TIME, args.when); 1567 ASSERT_EQ(SW_LID, args.switchCode); 1568 ASSERT_EQ(1, args.switchValue); 1569 ASSERT_EQ(uint32_t(0), args.policyFlags); 1570} 1571 1572 1573// --- KeyboardInputMapperTest --- 1574 1575class KeyboardInputMapperTest : public InputMapperTest { 1576protected: 1577 void testDPadKeyRotation(KeyboardInputMapper* mapper, 1578 int32_t originalScanCode, int32_t originalKeyCode, int32_t rotatedKeyCode); 1579}; 1580 1581void KeyboardInputMapperTest::testDPadKeyRotation(KeyboardInputMapper* mapper, 1582 int32_t originalScanCode, int32_t originalKeyCode, int32_t rotatedKeyCode) { 1583 FakeInputDispatcher::NotifyKeyArgs args; 1584 1585 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, originalScanCode, originalKeyCode, 1, 0); 1586 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args)); 1587 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action); 1588 ASSERT_EQ(originalScanCode, args.scanCode); 1589 ASSERT_EQ(rotatedKeyCode, args.keyCode); 1590 1591 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, originalScanCode, originalKeyCode, 0, 0); 1592 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args)); 1593 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action); 1594 ASSERT_EQ(originalScanCode, args.scanCode); 1595 ASSERT_EQ(rotatedKeyCode, args.keyCode); 1596} 1597 1598 1599TEST_F(KeyboardInputMapperTest, GetSources) { 1600 KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, 1601 AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); 1602 addMapperAndConfigure(mapper); 1603 1604 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, mapper->getSources()); 1605} 1606 1607TEST_F(KeyboardInputMapperTest, Process_SimpleKeyPress) { 1608 KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, 1609 AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); 1610 addMapperAndConfigure(mapper); 1611 1612 // Key down. 1613 process(mapper, ARBITRARY_TIME, DEVICE_ID, 1614 EV_KEY, KEY_HOME, AKEYCODE_HOME, 1, POLICY_FLAG_WAKE); 1615 FakeInputDispatcher::NotifyKeyArgs args; 1616 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args)); 1617 ASSERT_EQ(DEVICE_ID, args.deviceId); 1618 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source); 1619 ASSERT_EQ(ARBITRARY_TIME, args.eventTime); 1620 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action); 1621 ASSERT_EQ(AKEYCODE_HOME, args.keyCode); 1622 ASSERT_EQ(KEY_HOME, args.scanCode); 1623 ASSERT_EQ(AMETA_NONE, args.metaState); 1624 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags); 1625 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags); 1626 ASSERT_EQ(ARBITRARY_TIME, args.downTime); 1627 1628 // Key up. 1629 process(mapper, ARBITRARY_TIME + 1, DEVICE_ID, 1630 EV_KEY, KEY_HOME, AKEYCODE_HOME, 0, POLICY_FLAG_WAKE); 1631 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args)); 1632 ASSERT_EQ(DEVICE_ID, args.deviceId); 1633 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source); 1634 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime); 1635 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action); 1636 ASSERT_EQ(AKEYCODE_HOME, args.keyCode); 1637 ASSERT_EQ(KEY_HOME, args.scanCode); 1638 ASSERT_EQ(AMETA_NONE, args.metaState); 1639 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags); 1640 ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags); 1641 ASSERT_EQ(ARBITRARY_TIME, args.downTime); 1642} 1643 1644TEST_F(KeyboardInputMapperTest, Reset_WhenKeysAreNotDown_DoesNotSynthesizeKeyUp) { 1645 KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, 1646 AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); 1647 addMapperAndConfigure(mapper); 1648 1649 // Key down. 1650 process(mapper, ARBITRARY_TIME, DEVICE_ID, 1651 EV_KEY, KEY_HOME, AKEYCODE_HOME, 1, POLICY_FLAG_WAKE); 1652 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled()); 1653 1654 // Key up. 1655 process(mapper, ARBITRARY_TIME, DEVICE_ID, 1656 EV_KEY, KEY_HOME, AKEYCODE_HOME, 0, POLICY_FLAG_WAKE); 1657 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled()); 1658 1659 // Reset. Since no keys still down, should not synthesize any key ups. 1660 mapper->reset(); 1661 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled()); 1662} 1663 1664TEST_F(KeyboardInputMapperTest, Reset_WhenKeysAreDown_SynthesizesKeyUps) { 1665 KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, 1666 AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); 1667 addMapperAndConfigure(mapper); 1668 1669 // Metakey down. 1670 process(mapper, ARBITRARY_TIME, DEVICE_ID, 1671 EV_KEY, KEY_LEFTSHIFT, AKEYCODE_SHIFT_LEFT, 1, 0); 1672 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled()); 1673 1674 // Key down. 1675 process(mapper, ARBITRARY_TIME + 1, DEVICE_ID, 1676 EV_KEY, KEY_A, AKEYCODE_A, 1, 0); 1677 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled()); 1678 1679 // Reset. Since two keys are still down, should synthesize two key ups in reverse order. 1680 mapper->reset(); 1681 1682 FakeInputDispatcher::NotifyKeyArgs args; 1683 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args)); 1684 ASSERT_EQ(DEVICE_ID, args.deviceId); 1685 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source); 1686 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action); 1687 ASSERT_EQ(AKEYCODE_A, args.keyCode); 1688 ASSERT_EQ(KEY_A, args.scanCode); 1689 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState); 1690 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags); 1691 ASSERT_EQ(uint32_t(0), args.policyFlags); 1692 ASSERT_EQ(ARBITRARY_TIME + 1, args.downTime); 1693 1694 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args)); 1695 ASSERT_EQ(DEVICE_ID, args.deviceId); 1696 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source); 1697 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action); 1698 ASSERT_EQ(AKEYCODE_SHIFT_LEFT, args.keyCode); 1699 ASSERT_EQ(KEY_LEFTSHIFT, args.scanCode); 1700 ASSERT_EQ(AMETA_NONE, args.metaState); 1701 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags); 1702 ASSERT_EQ(uint32_t(0), args.policyFlags); 1703 ASSERT_EQ(ARBITRARY_TIME + 1, args.downTime); 1704 1705 // And that's it. 1706 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled()); 1707} 1708 1709TEST_F(KeyboardInputMapperTest, Process_ShouldUpdateMetaState) { 1710 KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, 1711 AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); 1712 addMapperAndConfigure(mapper); 1713 1714 // Initial metastate. 1715 ASSERT_EQ(AMETA_NONE, mapper->getMetaState()); 1716 1717 // Metakey down. 1718 process(mapper, ARBITRARY_TIME, DEVICE_ID, 1719 EV_KEY, KEY_LEFTSHIFT, AKEYCODE_SHIFT_LEFT, 1, 0); 1720 FakeInputDispatcher::NotifyKeyArgs args; 1721 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args)); 1722 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState); 1723 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper->getMetaState()); 1724 ASSERT_NO_FATAL_FAILURE(mFakeContext->assertUpdateGlobalMetaStateWasCalled()); 1725 1726 // Key down. 1727 process(mapper, ARBITRARY_TIME + 1, DEVICE_ID, 1728 EV_KEY, KEY_A, AKEYCODE_A, 1, 0); 1729 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args)); 1730 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState); 1731 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper->getMetaState()); 1732 1733 // Key up. 1734 process(mapper, ARBITRARY_TIME + 2, DEVICE_ID, 1735 EV_KEY, KEY_A, AKEYCODE_A, 0, 0); 1736 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args)); 1737 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState); 1738 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper->getMetaState()); 1739 1740 // Metakey up. 1741 process(mapper, ARBITRARY_TIME + 3, DEVICE_ID, 1742 EV_KEY, KEY_LEFTSHIFT, AKEYCODE_SHIFT_LEFT, 0, 0); 1743 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args)); 1744 ASSERT_EQ(AMETA_NONE, args.metaState); 1745 ASSERT_EQ(AMETA_NONE, mapper->getMetaState()); 1746 ASSERT_NO_FATAL_FAILURE(mFakeContext->assertUpdateGlobalMetaStateWasCalled()); 1747} 1748 1749TEST_F(KeyboardInputMapperTest, Process_WhenNotOrientationAware_ShouldNotRotateDPad) { 1750 KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, 1751 AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); 1752 addMapperAndConfigure(mapper); 1753 1754 mFakePolicy->setDisplayInfo(DISPLAY_ID, 1755 DISPLAY_WIDTH, DISPLAY_HEIGHT, 1756 DISPLAY_ORIENTATION_90); 1757 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, 1758 KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP)); 1759 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, 1760 KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_RIGHT)); 1761 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, 1762 KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_DOWN)); 1763 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, 1764 KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_LEFT)); 1765} 1766 1767TEST_F(KeyboardInputMapperTest, Process_WhenOrientationAware_ShouldRotateDPad) { 1768 KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, 1769 AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); 1770 addConfigurationProperty("keyboard.orientationAware", "1"); 1771 addMapperAndConfigure(mapper); 1772 1773 mFakePolicy->setDisplayInfo(DISPLAY_ID, 1774 DISPLAY_WIDTH, DISPLAY_HEIGHT, 1775 DISPLAY_ORIENTATION_0); 1776 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, 1777 KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP)); 1778 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, 1779 KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_RIGHT)); 1780 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, 1781 KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_DOWN)); 1782 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, 1783 KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_LEFT)); 1784 1785 mFakePolicy->setDisplayInfo(DISPLAY_ID, 1786 DISPLAY_WIDTH, DISPLAY_HEIGHT, 1787 DISPLAY_ORIENTATION_90); 1788 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, 1789 KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT)); 1790 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, 1791 KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP)); 1792 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, 1793 KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT)); 1794 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, 1795 KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN)); 1796 1797 mFakePolicy->setDisplayInfo(DISPLAY_ID, 1798 DISPLAY_WIDTH, DISPLAY_HEIGHT, 1799 DISPLAY_ORIENTATION_180); 1800 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, 1801 KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_DOWN)); 1802 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, 1803 KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_LEFT)); 1804 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, 1805 KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_UP)); 1806 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, 1807 KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_RIGHT)); 1808 1809 mFakePolicy->setDisplayInfo(DISPLAY_ID, 1810 DISPLAY_WIDTH, DISPLAY_HEIGHT, 1811 DISPLAY_ORIENTATION_270); 1812 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, 1813 KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_RIGHT)); 1814 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, 1815 KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_DOWN)); 1816 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, 1817 KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_LEFT)); 1818 ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, 1819 KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_UP)); 1820 1821 // Special case: if orientation changes while key is down, we still emit the same keycode 1822 // in the key up as we did in the key down. 1823 FakeInputDispatcher::NotifyKeyArgs args; 1824 1825 mFakePolicy->setDisplayInfo(DISPLAY_ID, 1826 DISPLAY_WIDTH, DISPLAY_HEIGHT, 1827 DISPLAY_ORIENTATION_270); 1828 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, AKEYCODE_DPAD_UP, 1, 0); 1829 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args)); 1830 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action); 1831 ASSERT_EQ(KEY_UP, args.scanCode); 1832 ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode); 1833 1834 mFakePolicy->setDisplayInfo(DISPLAY_ID, 1835 DISPLAY_WIDTH, DISPLAY_HEIGHT, 1836 DISPLAY_ORIENTATION_180); 1837 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, AKEYCODE_DPAD_UP, 0, 0); 1838 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args)); 1839 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action); 1840 ASSERT_EQ(KEY_UP, args.scanCode); 1841 ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode); 1842} 1843 1844TEST_F(KeyboardInputMapperTest, GetKeyCodeState) { 1845 KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, 1846 AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); 1847 addMapperAndConfigure(mapper); 1848 1849 mFakeEventHub->setKeyCodeState(DEVICE_ID, AKEYCODE_A, 1); 1850 ASSERT_EQ(1, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A)); 1851 1852 mFakeEventHub->setKeyCodeState(DEVICE_ID, AKEYCODE_A, 0); 1853 ASSERT_EQ(0, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A)); 1854} 1855 1856TEST_F(KeyboardInputMapperTest, GetScanCodeState) { 1857 KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, 1858 AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); 1859 addMapperAndConfigure(mapper); 1860 1861 mFakeEventHub->setScanCodeState(DEVICE_ID, KEY_A, 1); 1862 ASSERT_EQ(1, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_A)); 1863 1864 mFakeEventHub->setScanCodeState(DEVICE_ID, KEY_A, 0); 1865 ASSERT_EQ(0, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_A)); 1866} 1867 1868TEST_F(KeyboardInputMapperTest, MarkSupportedKeyCodes) { 1869 KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, 1870 AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); 1871 addMapperAndConfigure(mapper); 1872 1873 mFakeEventHub->addKey(DEVICE_ID, KEY_A, AKEYCODE_A, 0); 1874 1875 const int32_t keyCodes[2] = { AKEYCODE_A, AKEYCODE_B }; 1876 uint8_t flags[2] = { 0, 0 }; 1877 ASSERT_TRUE(mapper->markSupportedKeyCodes(AINPUT_SOURCE_ANY, 1, keyCodes, flags)); 1878 ASSERT_TRUE(flags[0]); 1879 ASSERT_FALSE(flags[1]); 1880} 1881 1882TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleMetaStateAndLeds) { 1883 mFakeEventHub->addLed(DEVICE_ID, LED_CAPSL, true /*initially on*/); 1884 mFakeEventHub->addLed(DEVICE_ID, LED_NUML, false /*initially off*/); 1885 mFakeEventHub->addLed(DEVICE_ID, LED_SCROLLL, false /*initially off*/); 1886 1887 KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, 1888 AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); 1889 addMapperAndConfigure(mapper); 1890 1891 // Initialization should have turned all of the lights off. 1892 ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL)); 1893 ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML)); 1894 ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL)); 1895 1896 // Toggle caps lock on. 1897 process(mapper, ARBITRARY_TIME, DEVICE_ID, 1898 EV_KEY, KEY_CAPSLOCK, AKEYCODE_CAPS_LOCK, 1, 0); 1899 process(mapper, ARBITRARY_TIME, DEVICE_ID, 1900 EV_KEY, KEY_CAPSLOCK, AKEYCODE_CAPS_LOCK, 0, 0); 1901 ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL)); 1902 ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML)); 1903 ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL)); 1904 ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper->getMetaState()); 1905 1906 // Toggle num lock on. 1907 process(mapper, ARBITRARY_TIME, DEVICE_ID, 1908 EV_KEY, KEY_NUMLOCK, AKEYCODE_NUM_LOCK, 1, 0); 1909 process(mapper, ARBITRARY_TIME, DEVICE_ID, 1910 EV_KEY, KEY_NUMLOCK, AKEYCODE_NUM_LOCK, 0, 0); 1911 ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL)); 1912 ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML)); 1913 ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL)); 1914 ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON, mapper->getMetaState()); 1915 1916 // Toggle caps lock off. 1917 process(mapper, ARBITRARY_TIME, DEVICE_ID, 1918 EV_KEY, KEY_CAPSLOCK, AKEYCODE_CAPS_LOCK, 1, 0); 1919 process(mapper, ARBITRARY_TIME, DEVICE_ID, 1920 EV_KEY, KEY_CAPSLOCK, AKEYCODE_CAPS_LOCK, 0, 0); 1921 ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL)); 1922 ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML)); 1923 ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL)); 1924 ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper->getMetaState()); 1925 1926 // Toggle scroll lock on. 1927 process(mapper, ARBITRARY_TIME, DEVICE_ID, 1928 EV_KEY, KEY_SCROLLLOCK, AKEYCODE_SCROLL_LOCK, 1, 0); 1929 process(mapper, ARBITRARY_TIME, DEVICE_ID, 1930 EV_KEY, KEY_SCROLLLOCK, AKEYCODE_SCROLL_LOCK, 0, 0); 1931 ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL)); 1932 ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML)); 1933 ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL)); 1934 ASSERT_EQ(AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mapper->getMetaState()); 1935 1936 // Toggle num lock off. 1937 process(mapper, ARBITRARY_TIME, DEVICE_ID, 1938 EV_KEY, KEY_NUMLOCK, AKEYCODE_NUM_LOCK, 1, 0); 1939 process(mapper, ARBITRARY_TIME, DEVICE_ID, 1940 EV_KEY, KEY_NUMLOCK, AKEYCODE_NUM_LOCK, 0, 0); 1941 ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL)); 1942 ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML)); 1943 ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL)); 1944 ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper->getMetaState()); 1945 1946 // Toggle scroll lock off. 1947 process(mapper, ARBITRARY_TIME, DEVICE_ID, 1948 EV_KEY, KEY_SCROLLLOCK, AKEYCODE_SCROLL_LOCK, 1, 0); 1949 process(mapper, ARBITRARY_TIME, DEVICE_ID, 1950 EV_KEY, KEY_SCROLLLOCK, AKEYCODE_SCROLL_LOCK, 0, 0); 1951 ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL)); 1952 ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML)); 1953 ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL)); 1954 ASSERT_EQ(AMETA_NONE, mapper->getMetaState()); 1955} 1956 1957 1958// --- CursorInputMapperTest --- 1959 1960class CursorInputMapperTest : public InputMapperTest { 1961protected: 1962 static const int32_t TRACKBALL_MOVEMENT_THRESHOLD; 1963 1964 sp<FakePointerController> mFakePointerController; 1965 1966 virtual void SetUp() { 1967 InputMapperTest::SetUp(); 1968 1969 mFakePointerController = new FakePointerController(); 1970 mFakePolicy->setPointerController(DEVICE_ID, mFakePointerController); 1971 } 1972 1973 void testMotionRotation(CursorInputMapper* mapper, 1974 int32_t originalX, int32_t originalY, int32_t rotatedX, int32_t rotatedY); 1975}; 1976 1977const int32_t CursorInputMapperTest::TRACKBALL_MOVEMENT_THRESHOLD = 6; 1978 1979void CursorInputMapperTest::testMotionRotation(CursorInputMapper* mapper, 1980 int32_t originalX, int32_t originalY, int32_t rotatedX, int32_t rotatedY) { 1981 FakeInputDispatcher::NotifyMotionArgs args; 1982 1983 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 0, originalX, 0); 1984 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 0, originalY, 0); 1985 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0); 1986 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); 1987 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action); 1988 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 1989 float(rotatedX) / TRACKBALL_MOVEMENT_THRESHOLD, 1990 float(rotatedY) / TRACKBALL_MOVEMENT_THRESHOLD, 1991 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); 1992} 1993 1994TEST_F(CursorInputMapperTest, WhenModeIsPointer_GetSources_ReturnsMouse) { 1995 CursorInputMapper* mapper = new CursorInputMapper(mDevice); 1996 addConfigurationProperty("cursor.mode", "pointer"); 1997 addMapperAndConfigure(mapper); 1998 1999 ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper->getSources()); 2000} 2001 2002TEST_F(CursorInputMapperTest, WhenModeIsNavigation_GetSources_ReturnsTrackball) { 2003 CursorInputMapper* mapper = new CursorInputMapper(mDevice); 2004 addConfigurationProperty("cursor.mode", "navigation"); 2005 addMapperAndConfigure(mapper); 2006 2007 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, mapper->getSources()); 2008} 2009 2010TEST_F(CursorInputMapperTest, WhenModeIsPointer_PopulateDeviceInfo_ReturnsRangeFromPointerController) { 2011 CursorInputMapper* mapper = new CursorInputMapper(mDevice); 2012 addConfigurationProperty("cursor.mode", "pointer"); 2013 addMapperAndConfigure(mapper); 2014 2015 InputDeviceInfo info; 2016 mapper->populateDeviceInfo(&info); 2017 2018 // Initially there may not be a valid motion range. 2019 ASSERT_EQ(NULL, info.getMotionRange(AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE)); 2020 ASSERT_EQ(NULL, info.getMotionRange(AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_MOUSE)); 2021 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info, 2022 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_MOUSE, 0.0f, 1.0f, 0.0f, 0.0f)); 2023 2024 // When the bounds are set, then there should be a valid motion range. 2025 mFakePointerController->setBounds(1, 2, 800 - 1, 480 - 1); 2026 2027 InputDeviceInfo info2; 2028 mapper->populateDeviceInfo(&info2); 2029 2030 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2, 2031 AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE, 2032 1, 800 - 1, 0.0f, 0.0f)); 2033 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2, 2034 AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_MOUSE, 2035 2, 480 - 1, 0.0f, 0.0f)); 2036 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2, 2037 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_MOUSE, 2038 0.0f, 1.0f, 0.0f, 0.0f)); 2039} 2040 2041TEST_F(CursorInputMapperTest, WhenModeIsNavigation_PopulateDeviceInfo_ReturnsScaledRange) { 2042 CursorInputMapper* mapper = new CursorInputMapper(mDevice); 2043 addConfigurationProperty("cursor.mode", "navigation"); 2044 addMapperAndConfigure(mapper); 2045 2046 InputDeviceInfo info; 2047 mapper->populateDeviceInfo(&info); 2048 2049 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info, 2050 AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_TRACKBALL, 2051 -1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD)); 2052 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info, 2053 AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_TRACKBALL, 2054 -1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD)); 2055 ASSERT_NO_FATAL_FAILURE(assertMotionRange(info, 2056 AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_TRACKBALL, 2057 0.0f, 1.0f, 0.0f, 0.0f)); 2058} 2059 2060TEST_F(CursorInputMapperTest, Process_ShouldSetAllFieldsAndIncludeGlobalMetaState) { 2061 CursorInputMapper* mapper = new CursorInputMapper(mDevice); 2062 addConfigurationProperty("cursor.mode", "navigation"); 2063 addMapperAndConfigure(mapper); 2064 2065 mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON); 2066 2067 FakeInputDispatcher::NotifyMotionArgs args; 2068 2069 // Button press. 2070 // Mostly testing non x/y behavior here so we don't need to check again elsewhere. 2071 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 1, 0); 2072 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); 2073 ASSERT_EQ(ARBITRARY_TIME, args.eventTime); 2074 ASSERT_EQ(DEVICE_ID, args.deviceId); 2075 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source); 2076 ASSERT_EQ(uint32_t(0), args.policyFlags); 2077 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action); 2078 ASSERT_EQ(0, args.flags); 2079 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState); 2080 ASSERT_EQ(0, args.edgeFlags); 2081 ASSERT_EQ(uint32_t(1), args.pointerCount); 2082 ASSERT_EQ(0, args.pointerIds[0]); 2083 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 2084 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); 2085 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision); 2086 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision); 2087 ASSERT_EQ(ARBITRARY_TIME, args.downTime); 2088 2089 // Button release. Should have same down time. 2090 process(mapper, ARBITRARY_TIME + 1, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 0, 0); 2091 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); 2092 ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime); 2093 ASSERT_EQ(DEVICE_ID, args.deviceId); 2094 ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source); 2095 ASSERT_EQ(uint32_t(0), args.policyFlags); 2096 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action); 2097 ASSERT_EQ(0, args.flags); 2098 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState); 2099 ASSERT_EQ(0, args.edgeFlags); 2100 ASSERT_EQ(uint32_t(1), args.pointerCount); 2101 ASSERT_EQ(0, args.pointerIds[0]); 2102 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 2103 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); 2104 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision); 2105 ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision); 2106 ASSERT_EQ(ARBITRARY_TIME, args.downTime); 2107} 2108 2109TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentXYUpdates) { 2110 CursorInputMapper* mapper = new CursorInputMapper(mDevice); 2111 addConfigurationProperty("cursor.mode", "navigation"); 2112 addMapperAndConfigure(mapper); 2113 2114 FakeInputDispatcher::NotifyMotionArgs args; 2115 2116 // Motion in X but not Y. 2117 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 0, 1, 0); 2118 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0); 2119 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); 2120 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action); 2121 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 2122 1.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); 2123 2124 // Motion in Y but not X. 2125 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 0, -2, 0); 2126 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0); 2127 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); 2128 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action); 2129 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 2130 0.0f, -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); 2131} 2132 2133TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentButtonUpdates) { 2134 CursorInputMapper* mapper = new CursorInputMapper(mDevice); 2135 addConfigurationProperty("cursor.mode", "navigation"); 2136 addMapperAndConfigure(mapper); 2137 2138 FakeInputDispatcher::NotifyMotionArgs args; 2139 2140 // Button press without following sync. 2141 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 1, 0); 2142 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); 2143 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action); 2144 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 2145 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); 2146 2147 // Button release without following sync. 2148 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 0, 0); 2149 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); 2150 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action); 2151 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 2152 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); 2153} 2154 2155TEST_F(CursorInputMapperTest, Process_ShouldHandleCombinedXYAndButtonUpdates) { 2156 CursorInputMapper* mapper = new CursorInputMapper(mDevice); 2157 addConfigurationProperty("cursor.mode", "navigation"); 2158 addMapperAndConfigure(mapper); 2159 2160 FakeInputDispatcher::NotifyMotionArgs args; 2161 2162 // Combined X, Y and Button. 2163 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 0, 1, 0); 2164 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 0, -2, 0); 2165 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 1, 0); 2166 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0); 2167 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); 2168 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action); 2169 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 2170 1.0f / TRACKBALL_MOVEMENT_THRESHOLD, -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 2171 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); 2172 2173 // Move X, Y a bit while pressed. 2174 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 0, 2, 0); 2175 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 0, 1, 0); 2176 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0); 2177 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); 2178 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action); 2179 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 2180 2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD, 2181 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); 2182 2183 // Release Button. 2184 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 0, 0); 2185 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); 2186 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action); 2187 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 2188 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); 2189} 2190 2191TEST_F(CursorInputMapperTest, Reset_WhenButtonIsNotDown_ShouldNotSynthesizeButtonUp) { 2192 CursorInputMapper* mapper = new CursorInputMapper(mDevice); 2193 addConfigurationProperty("cursor.mode", "navigation"); 2194 addMapperAndConfigure(mapper); 2195 2196 FakeInputDispatcher::NotifyMotionArgs args; 2197 2198 // Button press. 2199 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 1, 0); 2200 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); 2201 2202 // Button release. 2203 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 0, 0); 2204 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); 2205 2206 // Reset. Should not synthesize button up since button is not pressed. 2207 mapper->reset(); 2208 2209 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled()); 2210} 2211 2212TEST_F(CursorInputMapperTest, Reset_WhenButtonIsDown_ShouldSynthesizeButtonUp) { 2213 CursorInputMapper* mapper = new CursorInputMapper(mDevice); 2214 addConfigurationProperty("cursor.mode", "navigation"); 2215 addMapperAndConfigure(mapper); 2216 2217 FakeInputDispatcher::NotifyMotionArgs args; 2218 2219 // Button press. 2220 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 1, 0); 2221 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); 2222 2223 // Reset. Should synthesize button up. 2224 mapper->reset(); 2225 2226 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); 2227 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action); 2228 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 2229 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); 2230} 2231 2232TEST_F(CursorInputMapperTest, Process_WhenNotOrientationAware_ShouldNotRotateMotions) { 2233 CursorInputMapper* mapper = new CursorInputMapper(mDevice); 2234 addConfigurationProperty("cursor.mode", "navigation"); 2235 addMapperAndConfigure(mapper); 2236 2237 mFakePolicy->setDisplayInfo(DISPLAY_ID, 2238 DISPLAY_WIDTH, DISPLAY_HEIGHT, 2239 DISPLAY_ORIENTATION_90); 2240 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 0, 1)); 2241 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, 1, 1)); 2242 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 1, 0)); 2243 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, 1, -1)); 2244 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 0, -1)); 2245 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, -1)); 2246 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, -1, 0)); 2247 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, 1)); 2248} 2249 2250TEST_F(CursorInputMapperTest, Process_WhenOrientationAware_ShouldRotateMotions) { 2251 CursorInputMapper* mapper = new CursorInputMapper(mDevice); 2252 addConfigurationProperty("cursor.mode", "navigation"); 2253 addConfigurationProperty("cursor.orientationAware", "1"); 2254 addMapperAndConfigure(mapper); 2255 2256 mFakePolicy->setDisplayInfo(DISPLAY_ID, 2257 DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_0); 2258 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 0, 1)); 2259 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, 1, 1)); 2260 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 1, 0)); 2261 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, 1, -1)); 2262 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 0, -1)); 2263 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, -1)); 2264 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, -1, 0)); 2265 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, 1)); 2266 2267 mFakePolicy->setDisplayInfo(DISPLAY_ID, 2268 DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_90); 2269 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 1, 0)); 2270 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, 1, -1)); 2271 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 0, -1)); 2272 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, -1, -1)); 2273 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, -1, 0)); 2274 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, 1)); 2275 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, 0, 1)); 2276 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, 1, 1)); 2277 2278 mFakePolicy->setDisplayInfo(DISPLAY_ID, 2279 DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_180); 2280 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 0, -1)); 2281 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, -1, -1)); 2282 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, -1, 0)); 2283 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, -1, 1)); 2284 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 0, 1)); 2285 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, 1, 1)); 2286 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, 1, 0)); 2287 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, 1, -1)); 2288 2289 mFakePolicy->setDisplayInfo(DISPLAY_ID, 2290 DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_270); 2291 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, -1, 0)); 2292 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, -1, 1)); 2293 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 0, 1)); 2294 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, 1, 1)); 2295 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 1, 0)); 2296 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, 1, -1)); 2297 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, 0, -1)); 2298 ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, -1)); 2299} 2300 2301 2302// --- TouchInputMapperTest --- 2303 2304class TouchInputMapperTest : public InputMapperTest { 2305protected: 2306 static const int32_t RAW_X_MIN; 2307 static const int32_t RAW_X_MAX; 2308 static const int32_t RAW_Y_MIN; 2309 static const int32_t RAW_Y_MAX; 2310 static const int32_t RAW_TOUCH_MIN; 2311 static const int32_t RAW_TOUCH_MAX; 2312 static const int32_t RAW_TOOL_MIN; 2313 static const int32_t RAW_TOOL_MAX; 2314 static const int32_t RAW_PRESSURE_MIN; 2315 static const int32_t RAW_PRESSURE_MAX; 2316 static const int32_t RAW_ORIENTATION_MIN; 2317 static const int32_t RAW_ORIENTATION_MAX; 2318 static const int32_t RAW_ID_MIN; 2319 static const int32_t RAW_ID_MAX; 2320 static const float X_PRECISION; 2321 static const float Y_PRECISION; 2322 2323 static const VirtualKeyDefinition VIRTUAL_KEYS[2]; 2324 2325 enum Axes { 2326 POSITION = 1 << 0, 2327 TOUCH = 1 << 1, 2328 TOOL = 1 << 2, 2329 PRESSURE = 1 << 3, 2330 ORIENTATION = 1 << 4, 2331 MINOR = 1 << 5, 2332 ID = 1 << 6, 2333 }; 2334 2335 void prepareDisplay(int32_t orientation); 2336 void prepareVirtualKeys(); 2337 int32_t toRawX(float displayX); 2338 int32_t toRawY(float displayY); 2339 float toDisplayX(int32_t rawX); 2340 float toDisplayY(int32_t rawY); 2341}; 2342 2343const int32_t TouchInputMapperTest::RAW_X_MIN = 25; 2344const int32_t TouchInputMapperTest::RAW_X_MAX = 1019; 2345const int32_t TouchInputMapperTest::RAW_Y_MIN = 30; 2346const int32_t TouchInputMapperTest::RAW_Y_MAX = 1009; 2347const int32_t TouchInputMapperTest::RAW_TOUCH_MIN = 0; 2348const int32_t TouchInputMapperTest::RAW_TOUCH_MAX = 31; 2349const int32_t TouchInputMapperTest::RAW_TOOL_MIN = 0; 2350const int32_t TouchInputMapperTest::RAW_TOOL_MAX = 15; 2351const int32_t TouchInputMapperTest::RAW_PRESSURE_MIN = RAW_TOUCH_MIN; 2352const int32_t TouchInputMapperTest::RAW_PRESSURE_MAX = RAW_TOUCH_MAX; 2353const int32_t TouchInputMapperTest::RAW_ORIENTATION_MIN = -7; 2354const int32_t TouchInputMapperTest::RAW_ORIENTATION_MAX = 7; 2355const int32_t TouchInputMapperTest::RAW_ID_MIN = 0; 2356const int32_t TouchInputMapperTest::RAW_ID_MAX = 9; 2357const float TouchInputMapperTest::X_PRECISION = float(RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH; 2358const float TouchInputMapperTest::Y_PRECISION = float(RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT; 2359 2360const VirtualKeyDefinition TouchInputMapperTest::VIRTUAL_KEYS[2] = { 2361 { KEY_HOME, 60, DISPLAY_HEIGHT + 15, 20, 20 }, 2362 { KEY_MENU, DISPLAY_HEIGHT - 60, DISPLAY_WIDTH + 15, 20, 20 }, 2363}; 2364 2365void TouchInputMapperTest::prepareDisplay(int32_t orientation) { 2366 mFakePolicy->setDisplayInfo(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation); 2367} 2368 2369void TouchInputMapperTest::prepareVirtualKeys() { 2370 mFakeEventHub->addVirtualKeyDefinition(DEVICE_ID, VIRTUAL_KEYS[0]); 2371 mFakeEventHub->addVirtualKeyDefinition(DEVICE_ID, VIRTUAL_KEYS[1]); 2372 mFakeEventHub->addKey(DEVICE_ID, KEY_HOME, AKEYCODE_HOME, POLICY_FLAG_WAKE); 2373 mFakeEventHub->addKey(DEVICE_ID, KEY_MENU, AKEYCODE_MENU, POLICY_FLAG_WAKE); 2374} 2375 2376int32_t TouchInputMapperTest::toRawX(float displayX) { 2377 return int32_t(displayX * (RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH + RAW_X_MIN); 2378} 2379 2380int32_t TouchInputMapperTest::toRawY(float displayY) { 2381 return int32_t(displayY * (RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT + RAW_Y_MIN); 2382} 2383 2384float TouchInputMapperTest::toDisplayX(int32_t rawX) { 2385 return float(rawX - RAW_X_MIN) * DISPLAY_WIDTH / (RAW_X_MAX - RAW_X_MIN + 1); 2386} 2387 2388float TouchInputMapperTest::toDisplayY(int32_t rawY) { 2389 return float(rawY - RAW_Y_MIN) * DISPLAY_HEIGHT / (RAW_Y_MAX - RAW_Y_MIN + 1); 2390} 2391 2392 2393// --- SingleTouchInputMapperTest --- 2394 2395class SingleTouchInputMapperTest : public TouchInputMapperTest { 2396protected: 2397 void prepareAxes(int axes); 2398 2399 void processDown(SingleTouchInputMapper* mapper, int32_t x, int32_t y); 2400 void processMove(SingleTouchInputMapper* mapper, int32_t x, int32_t y); 2401 void processUp(SingleTouchInputMapper* mappery); 2402 void processPressure(SingleTouchInputMapper* mapper, int32_t pressure); 2403 void processToolMajor(SingleTouchInputMapper* mapper, int32_t toolMajor); 2404 void processSync(SingleTouchInputMapper* mapper); 2405}; 2406 2407void SingleTouchInputMapperTest::prepareAxes(int axes) { 2408 if (axes & POSITION) { 2409 mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_X, 2410 RAW_X_MIN, RAW_X_MAX, 0, 0); 2411 mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_Y, 2412 RAW_Y_MIN, RAW_Y_MAX, 0, 0); 2413 } 2414 if (axes & PRESSURE) { 2415 mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_PRESSURE, 2416 RAW_PRESSURE_MIN, RAW_PRESSURE_MAX, 0, 0); 2417 } 2418 if (axes & TOOL) { 2419 mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_TOOL_WIDTH, 2420 RAW_TOOL_MIN, RAW_TOOL_MAX, 0, 0); 2421 } 2422} 2423 2424void SingleTouchInputMapperTest::processDown(SingleTouchInputMapper* mapper, int32_t x, int32_t y) { 2425 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_TOUCH, 0, 1, 0); 2426 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_X, 0, x, 0); 2427 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_Y, 0, y, 0); 2428} 2429 2430void SingleTouchInputMapperTest::processMove(SingleTouchInputMapper* mapper, int32_t x, int32_t y) { 2431 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_X, 0, x, 0); 2432 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_Y, 0, y, 0); 2433} 2434 2435void SingleTouchInputMapperTest::processUp(SingleTouchInputMapper* mapper) { 2436 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_TOUCH, 0, 0, 0); 2437} 2438 2439void SingleTouchInputMapperTest::processPressure( 2440 SingleTouchInputMapper* mapper, int32_t pressure) { 2441 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_PRESSURE, 0, pressure, 0); 2442} 2443 2444void SingleTouchInputMapperTest::processToolMajor( 2445 SingleTouchInputMapper* mapper, int32_t toolMajor) { 2446 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_TOOL_WIDTH, 0, toolMajor, 0); 2447} 2448 2449void SingleTouchInputMapperTest::processSync(SingleTouchInputMapper* mapper) { 2450 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0); 2451} 2452 2453 2454TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsNotSpecifiedAndNotACursor_ReturnsPointer) { 2455 SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); 2456 prepareAxes(POSITION); 2457 addMapperAndConfigure(mapper); 2458 2459 ASSERT_EQ(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, mapper->getSources()); 2460} 2461 2462TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsNotSpecifiedAndIsACursor_ReturnsTouchPad) { 2463 SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); 2464 mFakeEventHub->addRelativeAxis(DEVICE_ID, REL_X); 2465 mFakeEventHub->addRelativeAxis(DEVICE_ID, REL_Y); 2466 prepareAxes(POSITION); 2467 addMapperAndConfigure(mapper); 2468 2469 ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper->getSources()); 2470} 2471 2472TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsTouchPad_ReturnsTouchPad) { 2473 SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); 2474 prepareAxes(POSITION); 2475 addConfigurationProperty("touch.deviceType", "touchPad"); 2476 addMapperAndConfigure(mapper); 2477 2478 ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper->getSources()); 2479} 2480 2481TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsTouchScreen_ReturnsTouchScreen) { 2482 SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); 2483 prepareAxes(POSITION); 2484 addConfigurationProperty("touch.deviceType", "touchScreen"); 2485 addMapperAndConfigure(mapper); 2486 2487 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper->getSources()); 2488} 2489 2490TEST_F(SingleTouchInputMapperTest, GetKeyCodeState) { 2491 SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); 2492 addConfigurationProperty("touch.deviceType", "touchScreen"); 2493 prepareDisplay(DISPLAY_ORIENTATION_0); 2494 prepareAxes(POSITION); 2495 prepareVirtualKeys(); 2496 addMapperAndConfigure(mapper); 2497 2498 // Unknown key. 2499 ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A)); 2500 2501 // Virtual key is down. 2502 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX); 2503 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY); 2504 processDown(mapper, x, y); 2505 processSync(mapper); 2506 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled()); 2507 2508 ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME)); 2509 2510 // Virtual key is up. 2511 processUp(mapper); 2512 processSync(mapper); 2513 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled()); 2514 2515 ASSERT_EQ(AKEY_STATE_UP, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME)); 2516} 2517 2518TEST_F(SingleTouchInputMapperTest, GetScanCodeState) { 2519 SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); 2520 addConfigurationProperty("touch.deviceType", "touchScreen"); 2521 prepareDisplay(DISPLAY_ORIENTATION_0); 2522 prepareAxes(POSITION); 2523 prepareVirtualKeys(); 2524 addMapperAndConfigure(mapper); 2525 2526 // Unknown key. 2527 ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_A)); 2528 2529 // Virtual key is down. 2530 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX); 2531 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY); 2532 processDown(mapper, x, y); 2533 processSync(mapper); 2534 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled()); 2535 2536 ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME)); 2537 2538 // Virtual key is up. 2539 processUp(mapper); 2540 processSync(mapper); 2541 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled()); 2542 2543 ASSERT_EQ(AKEY_STATE_UP, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME)); 2544} 2545 2546TEST_F(SingleTouchInputMapperTest, MarkSupportedKeyCodes) { 2547 SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); 2548 addConfigurationProperty("touch.deviceType", "touchScreen"); 2549 prepareDisplay(DISPLAY_ORIENTATION_0); 2550 prepareAxes(POSITION); 2551 prepareVirtualKeys(); 2552 addMapperAndConfigure(mapper); 2553 2554 const int32_t keys[2] = { AKEYCODE_HOME, AKEYCODE_A }; 2555 uint8_t flags[2] = { 0, 0 }; 2556 ASSERT_TRUE(mapper->markSupportedKeyCodes(AINPUT_SOURCE_ANY, 2, keys, flags)); 2557 ASSERT_TRUE(flags[0]); 2558 ASSERT_FALSE(flags[1]); 2559} 2560 2561TEST_F(SingleTouchInputMapperTest, Reset_WhenVirtualKeysAreDown_SendsUp) { 2562 // Note: Ideally we should send cancels but the implementation is more straightforward 2563 // with up and this will only happen if a device is forcibly removed. 2564 SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); 2565 addConfigurationProperty("touch.deviceType", "touchScreen"); 2566 prepareDisplay(DISPLAY_ORIENTATION_0); 2567 prepareAxes(POSITION); 2568 prepareVirtualKeys(); 2569 addMapperAndConfigure(mapper); 2570 2571 mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON); 2572 2573 // Press virtual key. 2574 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX); 2575 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY); 2576 processDown(mapper, x, y); 2577 processSync(mapper); 2578 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled()); 2579 2580 // Reset. Since key is down, synthesize key up. 2581 mapper->reset(); 2582 2583 FakeInputDispatcher::NotifyKeyArgs args; 2584 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args)); 2585 //ASSERT_EQ(ARBITRARY_TIME, args.eventTime); 2586 ASSERT_EQ(DEVICE_ID, args.deviceId); 2587 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source); 2588 ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags); 2589 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action); 2590 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags); 2591 ASSERT_EQ(AKEYCODE_HOME, args.keyCode); 2592 ASSERT_EQ(KEY_HOME, args.scanCode); 2593 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState); 2594 ASSERT_EQ(ARBITRARY_TIME, args.downTime); 2595} 2596 2597TEST_F(SingleTouchInputMapperTest, Reset_WhenNothingIsPressed_NothingMuchHappens) { 2598 SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); 2599 addConfigurationProperty("touch.deviceType", "touchScreen"); 2600 prepareDisplay(DISPLAY_ORIENTATION_0); 2601 prepareAxes(POSITION); 2602 prepareVirtualKeys(); 2603 addMapperAndConfigure(mapper); 2604 2605 // Press virtual key. 2606 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX); 2607 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY); 2608 processDown(mapper, x, y); 2609 processSync(mapper); 2610 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled()); 2611 2612 // Release virtual key. 2613 processUp(mapper); 2614 processSync(mapper); 2615 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled()); 2616 2617 // Reset. Since no key is down, nothing happens. 2618 mapper->reset(); 2619 2620 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled()); 2621 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled()); 2622} 2623 2624TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndReleasedNormally_SendsKeyDownAndKeyUp) { 2625 SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); 2626 addConfigurationProperty("touch.deviceType", "touchScreen"); 2627 prepareDisplay(DISPLAY_ORIENTATION_0); 2628 prepareAxes(POSITION); 2629 prepareVirtualKeys(); 2630 addMapperAndConfigure(mapper); 2631 2632 mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON); 2633 2634 FakeInputDispatcher::NotifyKeyArgs args; 2635 2636 // Press virtual key. 2637 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX); 2638 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY); 2639 processDown(mapper, x, y); 2640 processSync(mapper); 2641 2642 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args)); 2643 ASSERT_EQ(ARBITRARY_TIME, args.eventTime); 2644 ASSERT_EQ(DEVICE_ID, args.deviceId); 2645 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source); 2646 ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags); 2647 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action); 2648 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags); 2649 ASSERT_EQ(AKEYCODE_HOME, args.keyCode); 2650 ASSERT_EQ(KEY_HOME, args.scanCode); 2651 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState); 2652 ASSERT_EQ(ARBITRARY_TIME, args.downTime); 2653 2654 // Release virtual key. 2655 processUp(mapper); 2656 processSync(mapper); 2657 2658 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args)); 2659 ASSERT_EQ(ARBITRARY_TIME, args.eventTime); 2660 ASSERT_EQ(DEVICE_ID, args.deviceId); 2661 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source); 2662 ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags); 2663 ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action); 2664 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags); 2665 ASSERT_EQ(AKEYCODE_HOME, args.keyCode); 2666 ASSERT_EQ(KEY_HOME, args.scanCode); 2667 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState); 2668 ASSERT_EQ(ARBITRARY_TIME, args.downTime); 2669 2670 // Should not have sent any motions. 2671 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled()); 2672} 2673 2674TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfBounds_SendsKeyDownAndKeyCancel) { 2675 SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); 2676 addConfigurationProperty("touch.deviceType", "touchScreen"); 2677 prepareDisplay(DISPLAY_ORIENTATION_0); 2678 prepareAxes(POSITION); 2679 prepareVirtualKeys(); 2680 addMapperAndConfigure(mapper); 2681 2682 mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON); 2683 2684 FakeInputDispatcher::NotifyKeyArgs keyArgs; 2685 2686 // Press virtual key. 2687 int32_t x = toRawX(VIRTUAL_KEYS[0].centerX); 2688 int32_t y = toRawY(VIRTUAL_KEYS[0].centerY); 2689 processDown(mapper, x, y); 2690 processSync(mapper); 2691 2692 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&keyArgs)); 2693 ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime); 2694 ASSERT_EQ(DEVICE_ID, keyArgs.deviceId); 2695 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source); 2696 ASSERT_EQ(POLICY_FLAG_VIRTUAL, keyArgs.policyFlags); 2697 ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action); 2698 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, keyArgs.flags); 2699 ASSERT_EQ(AKEYCODE_HOME, keyArgs.keyCode); 2700 ASSERT_EQ(KEY_HOME, keyArgs.scanCode); 2701 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState); 2702 ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime); 2703 2704 // Move out of bounds. This should generate a cancel and a pointer down since we moved 2705 // into the display area. 2706 y -= 100; 2707 processMove(mapper, x, y); 2708 processSync(mapper); 2709 2710 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&keyArgs)); 2711 ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime); 2712 ASSERT_EQ(DEVICE_ID, keyArgs.deviceId); 2713 ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source); 2714 ASSERT_EQ(POLICY_FLAG_VIRTUAL, keyArgs.policyFlags); 2715 ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action); 2716 ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY 2717 | AKEY_EVENT_FLAG_CANCELED, keyArgs.flags); 2718 ASSERT_EQ(AKEYCODE_HOME, keyArgs.keyCode); 2719 ASSERT_EQ(KEY_HOME, keyArgs.scanCode); 2720 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState); 2721 ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime); 2722 2723 FakeInputDispatcher::NotifyMotionArgs motionArgs; 2724 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 2725 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime); 2726 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId); 2727 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source); 2728 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags); 2729 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action); 2730 ASSERT_EQ(0, motionArgs.flags); 2731 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState); 2732 ASSERT_EQ(0, motionArgs.edgeFlags); 2733 ASSERT_EQ(size_t(1), motionArgs.pointerCount); 2734 ASSERT_EQ(0, motionArgs.pointerIds[0]); 2735 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 2736 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0)); 2737 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON); 2738 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON); 2739 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime); 2740 2741 // Keep moving out of bounds. Should generate a pointer move. 2742 y -= 50; 2743 processMove(mapper, x, y); 2744 processSync(mapper); 2745 2746 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 2747 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime); 2748 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId); 2749 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source); 2750 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags); 2751 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action); 2752 ASSERT_EQ(0, motionArgs.flags); 2753 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState); 2754 ASSERT_EQ(0, motionArgs.edgeFlags); 2755 ASSERT_EQ(size_t(1), motionArgs.pointerCount); 2756 ASSERT_EQ(0, motionArgs.pointerIds[0]); 2757 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 2758 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0)); 2759 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON); 2760 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON); 2761 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime); 2762 2763 // Release out of bounds. Should generate a pointer up. 2764 processUp(mapper); 2765 processSync(mapper); 2766 2767 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 2768 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime); 2769 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId); 2770 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source); 2771 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags); 2772 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action); 2773 ASSERT_EQ(0, motionArgs.flags); 2774 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState); 2775 ASSERT_EQ(0, motionArgs.edgeFlags); 2776 ASSERT_EQ(size_t(1), motionArgs.pointerCount); 2777 ASSERT_EQ(0, motionArgs.pointerIds[0]); 2778 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 2779 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0)); 2780 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON); 2781 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON); 2782 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime); 2783 2784 // Should not have sent any more keys or motions. 2785 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled()); 2786 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled()); 2787} 2788 2789TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMovesIn_SendsDownAsTouchEntersDisplay) { 2790 SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); 2791 addConfigurationProperty("touch.deviceType", "touchScreen"); 2792 prepareDisplay(DISPLAY_ORIENTATION_0); 2793 prepareAxes(POSITION); 2794 prepareVirtualKeys(); 2795 addMapperAndConfigure(mapper); 2796 2797 mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON); 2798 2799 FakeInputDispatcher::NotifyMotionArgs motionArgs; 2800 2801 // Initially go down out of bounds. 2802 int32_t x = -10; 2803 int32_t y = -10; 2804 processDown(mapper, x, y); 2805 processSync(mapper); 2806 2807 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled()); 2808 2809 // Move into the display area. Should generate a pointer down. 2810 x = 50; 2811 y = 75; 2812 processMove(mapper, x, y); 2813 processSync(mapper); 2814 2815 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 2816 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime); 2817 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId); 2818 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source); 2819 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags); 2820 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action); 2821 ASSERT_EQ(0, motionArgs.flags); 2822 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState); 2823 ASSERT_EQ(0, motionArgs.edgeFlags); 2824 ASSERT_EQ(size_t(1), motionArgs.pointerCount); 2825 ASSERT_EQ(0, motionArgs.pointerIds[0]); 2826 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 2827 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0)); 2828 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON); 2829 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON); 2830 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime); 2831 2832 // Release. Should generate a pointer up. 2833 processUp(mapper); 2834 processSync(mapper); 2835 2836 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 2837 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime); 2838 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId); 2839 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source); 2840 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags); 2841 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action); 2842 ASSERT_EQ(0, motionArgs.flags); 2843 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState); 2844 ASSERT_EQ(0, motionArgs.edgeFlags); 2845 ASSERT_EQ(size_t(1), motionArgs.pointerCount); 2846 ASSERT_EQ(0, motionArgs.pointerIds[0]); 2847 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 2848 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0)); 2849 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON); 2850 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON); 2851 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime); 2852 2853 // Should not have sent any more keys or motions. 2854 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled()); 2855 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled()); 2856} 2857 2858TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) { 2859 SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); 2860 addConfigurationProperty("touch.deviceType", "touchScreen"); 2861 prepareDisplay(DISPLAY_ORIENTATION_0); 2862 prepareAxes(POSITION); 2863 prepareVirtualKeys(); 2864 addMapperAndConfigure(mapper); 2865 2866 mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON); 2867 2868 FakeInputDispatcher::NotifyMotionArgs motionArgs; 2869 2870 // Down. 2871 int32_t x = 100; 2872 int32_t y = 125; 2873 processDown(mapper, x, y); 2874 processSync(mapper); 2875 2876 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 2877 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime); 2878 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId); 2879 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source); 2880 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags); 2881 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action); 2882 ASSERT_EQ(0, motionArgs.flags); 2883 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState); 2884 ASSERT_EQ(0, motionArgs.edgeFlags); 2885 ASSERT_EQ(size_t(1), motionArgs.pointerCount); 2886 ASSERT_EQ(0, motionArgs.pointerIds[0]); 2887 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 2888 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0)); 2889 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON); 2890 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON); 2891 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime); 2892 2893 // Move. 2894 x += 50; 2895 y += 75; 2896 processMove(mapper, x, y); 2897 processSync(mapper); 2898 2899 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 2900 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime); 2901 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId); 2902 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source); 2903 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags); 2904 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action); 2905 ASSERT_EQ(0, motionArgs.flags); 2906 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState); 2907 ASSERT_EQ(0, motionArgs.edgeFlags); 2908 ASSERT_EQ(size_t(1), motionArgs.pointerCount); 2909 ASSERT_EQ(0, motionArgs.pointerIds[0]); 2910 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 2911 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0)); 2912 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON); 2913 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON); 2914 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime); 2915 2916 // Up. 2917 processUp(mapper); 2918 processSync(mapper); 2919 2920 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 2921 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime); 2922 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId); 2923 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source); 2924 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags); 2925 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action); 2926 ASSERT_EQ(0, motionArgs.flags); 2927 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState); 2928 ASSERT_EQ(0, motionArgs.edgeFlags); 2929 ASSERT_EQ(size_t(1), motionArgs.pointerCount); 2930 ASSERT_EQ(0, motionArgs.pointerIds[0]); 2931 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 2932 toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0)); 2933 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON); 2934 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON); 2935 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime); 2936 2937 // Should not have sent any more keys or motions. 2938 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled()); 2939 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled()); 2940} 2941 2942TEST_F(SingleTouchInputMapperTest, Process_WhenNotOrientationAware_DoesNotRotateMotions) { 2943 SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); 2944 addConfigurationProperty("touch.deviceType", "touchScreen"); 2945 prepareAxes(POSITION); 2946 addConfigurationProperty("touch.orientationAware", "0"); 2947 addMapperAndConfigure(mapper); 2948 2949 FakeInputDispatcher::NotifyMotionArgs args; 2950 2951 // Rotation 90. 2952 prepareDisplay(DISPLAY_ORIENTATION_90); 2953 processDown(mapper, toRawX(50), toRawY(75)); 2954 processSync(mapper); 2955 2956 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); 2957 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1); 2958 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1); 2959 2960 processUp(mapper); 2961 processSync(mapper); 2962 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled()); 2963} 2964 2965TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_RotatesMotions) { 2966 SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); 2967 addConfigurationProperty("touch.deviceType", "touchScreen"); 2968 prepareAxes(POSITION); 2969 addMapperAndConfigure(mapper); 2970 2971 FakeInputDispatcher::NotifyMotionArgs args; 2972 2973 // Rotation 0. 2974 prepareDisplay(DISPLAY_ORIENTATION_0); 2975 processDown(mapper, toRawX(50), toRawY(75)); 2976 processSync(mapper); 2977 2978 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); 2979 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1); 2980 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1); 2981 2982 processUp(mapper); 2983 processSync(mapper); 2984 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled()); 2985 2986 // Rotation 90. 2987 prepareDisplay(DISPLAY_ORIENTATION_90); 2988 processDown(mapper, RAW_X_MAX - toRawX(75) + RAW_X_MIN, toRawY(50)); 2989 processSync(mapper); 2990 2991 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); 2992 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1); 2993 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1); 2994 2995 processUp(mapper); 2996 processSync(mapper); 2997 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled()); 2998 2999 // Rotation 180. 3000 prepareDisplay(DISPLAY_ORIENTATION_180); 3001 processDown(mapper, RAW_X_MAX - toRawX(50) + RAW_X_MIN, RAW_Y_MAX - toRawY(75) + RAW_Y_MIN); 3002 processSync(mapper); 3003 3004 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); 3005 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1); 3006 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1); 3007 3008 processUp(mapper); 3009 processSync(mapper); 3010 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled()); 3011 3012 // Rotation 270. 3013 prepareDisplay(DISPLAY_ORIENTATION_270); 3014 processDown(mapper, toRawX(75), RAW_Y_MAX - toRawY(50) + RAW_Y_MIN); 3015 processSync(mapper); 3016 3017 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); 3018 ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1); 3019 ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1); 3020 3021 processUp(mapper); 3022 processSync(mapper); 3023 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled()); 3024} 3025 3026TEST_F(SingleTouchInputMapperTest, Process_AllAxes_DefaultCalibration) { 3027 SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); 3028 addConfigurationProperty("touch.deviceType", "touchScreen"); 3029 prepareDisplay(DISPLAY_ORIENTATION_0); 3030 prepareAxes(POSITION | PRESSURE | TOOL); 3031 addMapperAndConfigure(mapper); 3032 3033 // These calculations are based on the input device calibration documentation. 3034 int32_t rawX = 100; 3035 int32_t rawY = 200; 3036 int32_t rawPressure = 10; 3037 int32_t rawToolMajor = 12; 3038 3039 float x = toDisplayX(rawX); 3040 float y = toDisplayY(rawY); 3041 float pressure = float(rawPressure) / RAW_PRESSURE_MAX; 3042 float size = float(rawToolMajor) / RAW_TOOL_MAX; 3043 float tool = min(DISPLAY_WIDTH, DISPLAY_HEIGHT) * size; 3044 float touch = min(tool * pressure, tool); 3045 3046 processDown(mapper, rawX, rawY); 3047 processPressure(mapper, rawPressure); 3048 processToolMajor(mapper, rawToolMajor); 3049 processSync(mapper); 3050 3051 FakeInputDispatcher::NotifyMotionArgs args; 3052 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); 3053 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 3054 x, y, pressure, size, touch, touch, tool, tool, 0)); 3055} 3056 3057 3058// --- MultiTouchInputMapperTest --- 3059 3060class MultiTouchInputMapperTest : public TouchInputMapperTest { 3061protected: 3062 void prepareAxes(int axes); 3063 3064 void processPosition(MultiTouchInputMapper* mapper, int32_t x, int32_t y); 3065 void processTouchMajor(MultiTouchInputMapper* mapper, int32_t touchMajor); 3066 void processTouchMinor(MultiTouchInputMapper* mapper, int32_t touchMinor); 3067 void processToolMajor(MultiTouchInputMapper* mapper, int32_t toolMajor); 3068 void processToolMinor(MultiTouchInputMapper* mapper, int32_t toolMinor); 3069 void processOrientation(MultiTouchInputMapper* mapper, int32_t orientation); 3070 void processPressure(MultiTouchInputMapper* mapper, int32_t pressure); 3071 void processId(MultiTouchInputMapper* mapper, int32_t id); 3072 void processMTSync(MultiTouchInputMapper* mapper); 3073 void processSync(MultiTouchInputMapper* mapper); 3074}; 3075 3076void MultiTouchInputMapperTest::prepareAxes(int axes) { 3077 if (axes & POSITION) { 3078 mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_POSITION_X, 3079 RAW_X_MIN, RAW_X_MAX, 0, 0); 3080 mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_POSITION_Y, 3081 RAW_Y_MIN, RAW_Y_MAX, 0, 0); 3082 } 3083 if (axes & TOUCH) { 3084 mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TOUCH_MAJOR, 3085 RAW_TOUCH_MIN, RAW_TOUCH_MAX, 0, 0); 3086 if (axes & MINOR) { 3087 mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TOUCH_MINOR, 3088 RAW_TOUCH_MIN, RAW_TOUCH_MAX, 0, 0); 3089 } 3090 } 3091 if (axes & TOOL) { 3092 mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_WIDTH_MAJOR, 3093 RAW_TOOL_MIN, RAW_TOOL_MAX, 0, 0); 3094 if (axes & MINOR) { 3095 mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_WIDTH_MINOR, 3096 RAW_TOOL_MAX, RAW_TOOL_MAX, 0, 0); 3097 } 3098 } 3099 if (axes & ORIENTATION) { 3100 mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_ORIENTATION, 3101 RAW_ORIENTATION_MIN, RAW_ORIENTATION_MAX, 0, 0); 3102 } 3103 if (axes & PRESSURE) { 3104 mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_PRESSURE, 3105 RAW_PRESSURE_MIN, RAW_PRESSURE_MAX, 0, 0); 3106 } 3107 if (axes & ID) { 3108 mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TRACKING_ID, 3109 RAW_ID_MIN, RAW_ID_MAX, 0, 0); 3110 } 3111} 3112 3113void MultiTouchInputMapperTest::processPosition( 3114 MultiTouchInputMapper* mapper, int32_t x, int32_t y) { 3115 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_POSITION_X, 0, x, 0); 3116 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_POSITION_Y, 0, y, 0); 3117} 3118 3119void MultiTouchInputMapperTest::processTouchMajor( 3120 MultiTouchInputMapper* mapper, int32_t touchMajor) { 3121 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TOUCH_MAJOR, 0, touchMajor, 0); 3122} 3123 3124void MultiTouchInputMapperTest::processTouchMinor( 3125 MultiTouchInputMapper* mapper, int32_t touchMinor) { 3126 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TOUCH_MINOR, 0, touchMinor, 0); 3127} 3128 3129void MultiTouchInputMapperTest::processToolMajor( 3130 MultiTouchInputMapper* mapper, int32_t toolMajor) { 3131 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_WIDTH_MAJOR, 0, toolMajor, 0); 3132} 3133 3134void MultiTouchInputMapperTest::processToolMinor( 3135 MultiTouchInputMapper* mapper, int32_t toolMinor) { 3136 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_WIDTH_MINOR, 0, toolMinor, 0); 3137} 3138 3139void MultiTouchInputMapperTest::processOrientation( 3140 MultiTouchInputMapper* mapper, int32_t orientation) { 3141 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_ORIENTATION, 0, orientation, 0); 3142} 3143 3144void MultiTouchInputMapperTest::processPressure( 3145 MultiTouchInputMapper* mapper, int32_t pressure) { 3146 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_PRESSURE, 0, pressure, 0); 3147} 3148 3149void MultiTouchInputMapperTest::processId( 3150 MultiTouchInputMapper* mapper, int32_t id) { 3151 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TRACKING_ID, 0, id, 0); 3152} 3153 3154void MultiTouchInputMapperTest::processMTSync(MultiTouchInputMapper* mapper) { 3155 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_MT_REPORT, 0, 0, 0); 3156} 3157 3158void MultiTouchInputMapperTest::processSync(MultiTouchInputMapper* mapper) { 3159 process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0); 3160} 3161 3162 3163TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackingIds) { 3164 MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); 3165 addConfigurationProperty("touch.deviceType", "touchScreen"); 3166 prepareDisplay(DISPLAY_ORIENTATION_0); 3167 prepareAxes(POSITION); 3168 prepareVirtualKeys(); 3169 addMapperAndConfigure(mapper); 3170 3171 mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON); 3172 3173 FakeInputDispatcher::NotifyMotionArgs motionArgs; 3174 3175 // Two fingers down at once. 3176 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500; 3177 processPosition(mapper, x1, y1); 3178 processMTSync(mapper); 3179 processPosition(mapper, x2, y2); 3180 processMTSync(mapper); 3181 processSync(mapper); 3182 3183 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 3184 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime); 3185 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId); 3186 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source); 3187 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags); 3188 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action); 3189 ASSERT_EQ(0, motionArgs.flags); 3190 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState); 3191 ASSERT_EQ(0, motionArgs.edgeFlags); 3192 ASSERT_EQ(size_t(1), motionArgs.pointerCount); 3193 ASSERT_EQ(0, motionArgs.pointerIds[0]); 3194 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 3195 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0)); 3196 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON); 3197 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON); 3198 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime); 3199 3200 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 3201 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime); 3202 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId); 3203 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source); 3204 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags); 3205 ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), 3206 motionArgs.action); 3207 ASSERT_EQ(0, motionArgs.flags); 3208 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState); 3209 ASSERT_EQ(0, motionArgs.edgeFlags); 3210 ASSERT_EQ(size_t(2), motionArgs.pointerCount); 3211 ASSERT_EQ(0, motionArgs.pointerIds[0]); 3212 ASSERT_EQ(1, motionArgs.pointerIds[1]); 3213 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 3214 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0)); 3215 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1], 3216 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0)); 3217 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON); 3218 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON); 3219 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime); 3220 3221 // Move. 3222 x1 += 10; y1 += 15; x2 += 5; y2 -= 10; 3223 processPosition(mapper, x1, y1); 3224 processMTSync(mapper); 3225 processPosition(mapper, x2, y2); 3226 processMTSync(mapper); 3227 processSync(mapper); 3228 3229 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 3230 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime); 3231 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId); 3232 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source); 3233 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags); 3234 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action); 3235 ASSERT_EQ(0, motionArgs.flags); 3236 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState); 3237 ASSERT_EQ(0, motionArgs.edgeFlags); 3238 ASSERT_EQ(size_t(2), motionArgs.pointerCount); 3239 ASSERT_EQ(0, motionArgs.pointerIds[0]); 3240 ASSERT_EQ(1, motionArgs.pointerIds[1]); 3241 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 3242 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0)); 3243 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1], 3244 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0)); 3245 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON); 3246 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON); 3247 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime); 3248 3249 // First finger up. 3250 x2 += 15; y2 -= 20; 3251 processPosition(mapper, x2, y2); 3252 processMTSync(mapper); 3253 processSync(mapper); 3254 3255 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 3256 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime); 3257 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId); 3258 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source); 3259 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags); 3260 ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), 3261 motionArgs.action); 3262 ASSERT_EQ(0, motionArgs.flags); 3263 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState); 3264 ASSERT_EQ(0, motionArgs.edgeFlags); 3265 ASSERT_EQ(size_t(2), motionArgs.pointerCount); 3266 ASSERT_EQ(0, motionArgs.pointerIds[0]); 3267 ASSERT_EQ(1, motionArgs.pointerIds[1]); 3268 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 3269 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0)); 3270 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1], 3271 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0)); 3272 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON); 3273 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON); 3274 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime); 3275 3276 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 3277 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime); 3278 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId); 3279 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source); 3280 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags); 3281 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action); 3282 ASSERT_EQ(0, motionArgs.flags); 3283 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState); 3284 ASSERT_EQ(0, motionArgs.edgeFlags); 3285 ASSERT_EQ(size_t(1), motionArgs.pointerCount); 3286 ASSERT_EQ(1, motionArgs.pointerIds[0]); 3287 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 3288 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0)); 3289 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON); 3290 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON); 3291 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime); 3292 3293 // Move. 3294 x2 += 20; y2 -= 25; 3295 processPosition(mapper, x2, y2); 3296 processMTSync(mapper); 3297 processSync(mapper); 3298 3299 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 3300 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime); 3301 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId); 3302 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source); 3303 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags); 3304 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action); 3305 ASSERT_EQ(0, motionArgs.flags); 3306 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState); 3307 ASSERT_EQ(0, motionArgs.edgeFlags); 3308 ASSERT_EQ(size_t(1), motionArgs.pointerCount); 3309 ASSERT_EQ(1, motionArgs.pointerIds[0]); 3310 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 3311 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0)); 3312 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON); 3313 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON); 3314 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime); 3315 3316 // New finger down. 3317 int32_t x3 = 700, y3 = 300; 3318 processPosition(mapper, x2, y2); 3319 processMTSync(mapper); 3320 processPosition(mapper, x3, y3); 3321 processMTSync(mapper); 3322 processSync(mapper); 3323 3324 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 3325 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime); 3326 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId); 3327 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source); 3328 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags); 3329 ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), 3330 motionArgs.action); 3331 ASSERT_EQ(0, motionArgs.flags); 3332 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState); 3333 ASSERT_EQ(0, motionArgs.edgeFlags); 3334 ASSERT_EQ(size_t(2), motionArgs.pointerCount); 3335 ASSERT_EQ(0, motionArgs.pointerIds[0]); 3336 ASSERT_EQ(1, motionArgs.pointerIds[1]); 3337 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 3338 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0)); 3339 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1], 3340 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0)); 3341 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON); 3342 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON); 3343 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime); 3344 3345 // Second finger up. 3346 x3 += 30; y3 -= 20; 3347 processPosition(mapper, x3, y3); 3348 processMTSync(mapper); 3349 processSync(mapper); 3350 3351 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 3352 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime); 3353 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId); 3354 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source); 3355 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags); 3356 ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), 3357 motionArgs.action); 3358 ASSERT_EQ(0, motionArgs.flags); 3359 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState); 3360 ASSERT_EQ(0, motionArgs.edgeFlags); 3361 ASSERT_EQ(size_t(2), motionArgs.pointerCount); 3362 ASSERT_EQ(0, motionArgs.pointerIds[0]); 3363 ASSERT_EQ(1, motionArgs.pointerIds[1]); 3364 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 3365 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0)); 3366 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1], 3367 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0)); 3368 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON); 3369 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON); 3370 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime); 3371 3372 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 3373 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime); 3374 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId); 3375 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source); 3376 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags); 3377 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action); 3378 ASSERT_EQ(0, motionArgs.flags); 3379 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState); 3380 ASSERT_EQ(0, motionArgs.edgeFlags); 3381 ASSERT_EQ(size_t(1), motionArgs.pointerCount); 3382 ASSERT_EQ(0, motionArgs.pointerIds[0]); 3383 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 3384 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0)); 3385 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON); 3386 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON); 3387 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime); 3388 3389 // Last finger up. 3390 processMTSync(mapper); 3391 processSync(mapper); 3392 3393 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 3394 ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime); 3395 ASSERT_EQ(DEVICE_ID, motionArgs.deviceId); 3396 ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source); 3397 ASSERT_EQ(uint32_t(0), motionArgs.policyFlags); 3398 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action); 3399 ASSERT_EQ(0, motionArgs.flags); 3400 ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState); 3401 ASSERT_EQ(0, motionArgs.edgeFlags); 3402 ASSERT_EQ(size_t(1), motionArgs.pointerCount); 3403 ASSERT_EQ(0, motionArgs.pointerIds[0]); 3404 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 3405 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0)); 3406 ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON); 3407 ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON); 3408 ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime); 3409 3410 // Should not have sent any more keys or motions. 3411 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled()); 3412 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled()); 3413} 3414 3415TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingIds) { 3416 MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); 3417 addConfigurationProperty("touch.deviceType", "touchScreen"); 3418 prepareDisplay(DISPLAY_ORIENTATION_0); 3419 prepareAxes(POSITION | ID); 3420 prepareVirtualKeys(); 3421 addMapperAndConfigure(mapper); 3422 3423 mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON); 3424 3425 FakeInputDispatcher::NotifyMotionArgs motionArgs; 3426 3427 // Two fingers down at once. 3428 int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500; 3429 processPosition(mapper, x1, y1); 3430 processId(mapper, 1); 3431 processMTSync(mapper); 3432 processPosition(mapper, x2, y2); 3433 processId(mapper, 2); 3434 processMTSync(mapper); 3435 processSync(mapper); 3436 3437 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 3438 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action); 3439 ASSERT_EQ(size_t(1), motionArgs.pointerCount); 3440 ASSERT_EQ(1, motionArgs.pointerIds[0]); 3441 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 3442 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0)); 3443 3444 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 3445 ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), 3446 motionArgs.action); 3447 ASSERT_EQ(size_t(2), motionArgs.pointerCount); 3448 ASSERT_EQ(1, motionArgs.pointerIds[0]); 3449 ASSERT_EQ(2, motionArgs.pointerIds[1]); 3450 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 3451 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0)); 3452 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1], 3453 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0)); 3454 3455 // Move. 3456 x1 += 10; y1 += 15; x2 += 5; y2 -= 10; 3457 processPosition(mapper, x1, y1); 3458 processId(mapper, 1); 3459 processMTSync(mapper); 3460 processPosition(mapper, x2, y2); 3461 processId(mapper, 2); 3462 processMTSync(mapper); 3463 processSync(mapper); 3464 3465 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 3466 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action); 3467 ASSERT_EQ(size_t(2), motionArgs.pointerCount); 3468 ASSERT_EQ(1, motionArgs.pointerIds[0]); 3469 ASSERT_EQ(2, motionArgs.pointerIds[1]); 3470 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 3471 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0)); 3472 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1], 3473 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0)); 3474 3475 // First finger up. 3476 x2 += 15; y2 -= 20; 3477 processPosition(mapper, x2, y2); 3478 processId(mapper, 2); 3479 processMTSync(mapper); 3480 processSync(mapper); 3481 3482 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 3483 ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), 3484 motionArgs.action); 3485 ASSERT_EQ(size_t(2), motionArgs.pointerCount); 3486 ASSERT_EQ(1, motionArgs.pointerIds[0]); 3487 ASSERT_EQ(2, motionArgs.pointerIds[1]); 3488 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 3489 toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0)); 3490 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1], 3491 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0)); 3492 3493 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 3494 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action); 3495 ASSERT_EQ(size_t(1), motionArgs.pointerCount); 3496 ASSERT_EQ(2, motionArgs.pointerIds[0]); 3497 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 3498 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0)); 3499 3500 // Move. 3501 x2 += 20; y2 -= 25; 3502 processPosition(mapper, x2, y2); 3503 processId(mapper, 2); 3504 processMTSync(mapper); 3505 processSync(mapper); 3506 3507 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 3508 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action); 3509 ASSERT_EQ(size_t(1), motionArgs.pointerCount); 3510 ASSERT_EQ(2, motionArgs.pointerIds[0]); 3511 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 3512 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0)); 3513 3514 // New finger down. 3515 int32_t x3 = 700, y3 = 300; 3516 processPosition(mapper, x2, y2); 3517 processId(mapper, 2); 3518 processMTSync(mapper); 3519 processPosition(mapper, x3, y3); 3520 processId(mapper, 3); 3521 processMTSync(mapper); 3522 processSync(mapper); 3523 3524 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 3525 ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), 3526 motionArgs.action); 3527 ASSERT_EQ(size_t(2), motionArgs.pointerCount); 3528 ASSERT_EQ(2, motionArgs.pointerIds[0]); 3529 ASSERT_EQ(3, motionArgs.pointerIds[1]); 3530 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 3531 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0)); 3532 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1], 3533 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0)); 3534 3535 // Second finger up. 3536 x3 += 30; y3 -= 20; 3537 processPosition(mapper, x3, y3); 3538 processId(mapper, 3); 3539 processMTSync(mapper); 3540 processSync(mapper); 3541 3542 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 3543 ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), 3544 motionArgs.action); 3545 ASSERT_EQ(size_t(2), motionArgs.pointerCount); 3546 ASSERT_EQ(2, motionArgs.pointerIds[0]); 3547 ASSERT_EQ(3, motionArgs.pointerIds[1]); 3548 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 3549 toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0)); 3550 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1], 3551 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0)); 3552 3553 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 3554 ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action); 3555 ASSERT_EQ(size_t(1), motionArgs.pointerCount); 3556 ASSERT_EQ(3, motionArgs.pointerIds[0]); 3557 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 3558 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0)); 3559 3560 // Last finger up. 3561 processMTSync(mapper); 3562 processSync(mapper); 3563 3564 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs)); 3565 ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action); 3566 ASSERT_EQ(size_t(1), motionArgs.pointerCount); 3567 ASSERT_EQ(3, motionArgs.pointerIds[0]); 3568 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 3569 toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0)); 3570 3571 // Should not have sent any more keys or motions. 3572 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled()); 3573 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled()); 3574} 3575 3576TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) { 3577 MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); 3578 addConfigurationProperty("touch.deviceType", "touchScreen"); 3579 prepareDisplay(DISPLAY_ORIENTATION_0); 3580 prepareAxes(POSITION | TOUCH | TOOL | PRESSURE | ORIENTATION | ID | MINOR); 3581 addMapperAndConfigure(mapper); 3582 3583 // These calculations are based on the input device calibration documentation. 3584 int32_t rawX = 100; 3585 int32_t rawY = 200; 3586 int32_t rawTouchMajor = 7; 3587 int32_t rawTouchMinor = 6; 3588 int32_t rawToolMajor = 9; 3589 int32_t rawToolMinor = 8; 3590 int32_t rawPressure = 11; 3591 int32_t rawOrientation = 3; 3592 int32_t id = 5; 3593 3594 float x = toDisplayX(rawX); 3595 float y = toDisplayY(rawY); 3596 float pressure = float(rawPressure) / RAW_PRESSURE_MAX; 3597 float size = avg(rawToolMajor, rawToolMinor) / RAW_TOOL_MAX; 3598 float toolMajor = float(min(DISPLAY_WIDTH, DISPLAY_HEIGHT)) * rawToolMajor / RAW_TOOL_MAX; 3599 float toolMinor = float(min(DISPLAY_WIDTH, DISPLAY_HEIGHT)) * rawToolMinor / RAW_TOOL_MAX; 3600 float touchMajor = min(toolMajor * pressure, toolMajor); 3601 float touchMinor = min(toolMinor * pressure, toolMinor); 3602 float orientation = float(rawOrientation) / RAW_ORIENTATION_MAX * M_PI_2; 3603 3604 processPosition(mapper, rawX, rawY); 3605 processTouchMajor(mapper, rawTouchMajor); 3606 processTouchMinor(mapper, rawTouchMinor); 3607 processToolMajor(mapper, rawToolMajor); 3608 processToolMinor(mapper, rawToolMinor); 3609 processPressure(mapper, rawPressure); 3610 processOrientation(mapper, rawOrientation); 3611 processId(mapper, id); 3612 processMTSync(mapper); 3613 processSync(mapper); 3614 3615 FakeInputDispatcher::NotifyMotionArgs args; 3616 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); 3617 ASSERT_EQ(id, args.pointerIds[0]); 3618 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 3619 x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor, orientation)); 3620} 3621 3622TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration) { 3623 MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); 3624 addConfigurationProperty("touch.deviceType", "touchScreen"); 3625 prepareDisplay(DISPLAY_ORIENTATION_0); 3626 prepareAxes(POSITION | TOUCH | TOOL | MINOR); 3627 addConfigurationProperty("touch.touchSize.calibration", "geometric"); 3628 addConfigurationProperty("touch.toolSize.calibration", "geometric"); 3629 addMapperAndConfigure(mapper); 3630 3631 // These calculations are based on the input device calibration documentation. 3632 int32_t rawX = 100; 3633 int32_t rawY = 200; 3634 int32_t rawTouchMajor = 140; 3635 int32_t rawTouchMinor = 120; 3636 int32_t rawToolMajor = 180; 3637 int32_t rawToolMinor = 160; 3638 3639 float x = toDisplayX(rawX); 3640 float y = toDisplayY(rawY); 3641 float pressure = float(rawTouchMajor) / RAW_TOUCH_MAX; 3642 float size = avg(rawToolMajor, rawToolMinor) / RAW_TOOL_MAX; 3643 float scale = avg(float(DISPLAY_WIDTH) / (RAW_X_MAX - RAW_X_MIN + 1), 3644 float(DISPLAY_HEIGHT) / (RAW_Y_MAX - RAW_Y_MIN + 1)); 3645 float toolMajor = float(rawToolMajor) * scale; 3646 float toolMinor = float(rawToolMinor) * scale; 3647 float touchMajor = min(float(rawTouchMajor) * scale, toolMajor); 3648 float touchMinor = min(float(rawTouchMinor) * scale, toolMinor); 3649 3650 processPosition(mapper, rawX, rawY); 3651 processTouchMajor(mapper, rawTouchMajor); 3652 processTouchMinor(mapper, rawTouchMinor); 3653 processToolMajor(mapper, rawToolMajor); 3654 processToolMinor(mapper, rawToolMinor); 3655 processMTSync(mapper); 3656 processSync(mapper); 3657 3658 FakeInputDispatcher::NotifyMotionArgs args; 3659 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); 3660 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 3661 x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor, 0)); 3662} 3663 3664TEST_F(MultiTouchInputMapperTest, Process_TouchToolPressureSizeAxes_SummedLinearCalibration) { 3665 MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); 3666 addConfigurationProperty("touch.deviceType", "touchScreen"); 3667 prepareDisplay(DISPLAY_ORIENTATION_0); 3668 prepareAxes(POSITION | TOUCH | TOOL); 3669 addConfigurationProperty("touch.touchSize.calibration", "pressure"); 3670 addConfigurationProperty("touch.toolSize.calibration", "linear"); 3671 addConfigurationProperty("touch.toolSize.linearScale", "10"); 3672 addConfigurationProperty("touch.toolSize.linearBias", "160"); 3673 addConfigurationProperty("touch.toolSize.isSummed", "1"); 3674 addConfigurationProperty("touch.pressure.calibration", "amplitude"); 3675 addConfigurationProperty("touch.pressure.source", "touch"); 3676 addConfigurationProperty("touch.pressure.scale", "0.01"); 3677 addMapperAndConfigure(mapper); 3678 3679 // These calculations are based on the input device calibration documentation. 3680 // Note: We only provide a single common touch/tool value because the device is assumed 3681 // not to emit separate values for each pointer (isSummed = 1). 3682 int32_t rawX = 100; 3683 int32_t rawY = 200; 3684 int32_t rawX2 = 150; 3685 int32_t rawY2 = 250; 3686 int32_t rawTouchMajor = 60; 3687 int32_t rawToolMajor = 5; 3688 3689 float x = toDisplayX(rawX); 3690 float y = toDisplayY(rawY); 3691 float x2 = toDisplayX(rawX2); 3692 float y2 = toDisplayY(rawY2); 3693 float pressure = float(rawTouchMajor) * 0.01f; 3694 float size = float(rawToolMajor) / RAW_TOOL_MAX; 3695 float tool = (float(rawToolMajor) * 10.0f + 160.0f) / 2; 3696 float touch = min(tool * pressure, tool); 3697 3698 processPosition(mapper, rawX, rawY); 3699 processTouchMajor(mapper, rawTouchMajor); 3700 processToolMajor(mapper, rawToolMajor); 3701 processMTSync(mapper); 3702 processPosition(mapper, rawX2, rawY2); 3703 processTouchMajor(mapper, rawTouchMajor); 3704 processToolMajor(mapper, rawToolMajor); 3705 processMTSync(mapper); 3706 processSync(mapper); 3707 3708 FakeInputDispatcher::NotifyMotionArgs args; 3709 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); 3710 ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action); 3711 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); 3712 ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), 3713 args.action); 3714 ASSERT_EQ(size_t(2), args.pointerCount); 3715 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 3716 x, y, pressure, size, touch, touch, tool, tool, 0)); 3717 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[1], 3718 x2, y2, pressure, size, touch, touch, tool, tool, 0)); 3719} 3720 3721TEST_F(MultiTouchInputMapperTest, Process_TouchToolPressureSizeAxes_AreaCalibration) { 3722 MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); 3723 addConfigurationProperty("touch.deviceType", "touchScreen"); 3724 prepareDisplay(DISPLAY_ORIENTATION_0); 3725 prepareAxes(POSITION | TOUCH | TOOL); 3726 addConfigurationProperty("touch.touchSize.calibration", "pressure"); 3727 addConfigurationProperty("touch.toolSize.calibration", "area"); 3728 addConfigurationProperty("touch.toolSize.areaScale", "22"); 3729 addConfigurationProperty("touch.toolSize.areaBias", "1"); 3730 addConfigurationProperty("touch.toolSize.linearScale", "9.2"); 3731 addConfigurationProperty("touch.toolSize.linearBias", "3"); 3732 addConfigurationProperty("touch.pressure.calibration", "amplitude"); 3733 addConfigurationProperty("touch.pressure.source", "touch"); 3734 addConfigurationProperty("touch.pressure.scale", "0.01"); 3735 addMapperAndConfigure(mapper); 3736 3737 // These calculations are based on the input device calibration documentation. 3738 int32_t rawX = 100; 3739 int32_t rawY = 200; 3740 int32_t rawTouchMajor = 60; 3741 int32_t rawToolMajor = 5; 3742 3743 float x = toDisplayX(rawX); 3744 float y = toDisplayY(rawY); 3745 float pressure = float(rawTouchMajor) * 0.01f; 3746 float size = float(rawToolMajor) / RAW_TOOL_MAX; 3747 float tool = sqrtf(float(rawToolMajor) * 22.0f + 1.0f) * 9.2f + 3.0f; 3748 float touch = min(tool * pressure, tool); 3749 3750 processPosition(mapper, rawX, rawY); 3751 processTouchMajor(mapper, rawTouchMajor); 3752 processToolMajor(mapper, rawToolMajor); 3753 processMTSync(mapper); 3754 processSync(mapper); 3755 3756 FakeInputDispatcher::NotifyMotionArgs args; 3757 ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); 3758 ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 3759 x, y, pressure, size, touch, touch, tool, tool, 0)); 3760} 3761 3762} // namespace android 3763