PageRenderTime 68ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 2ms

/services/input/InputReader.cpp

https://github.com/aizuzi/platform_frameworks_base
C++ | 6530 lines | 5241 code | 841 blank | 448 comment | 1189 complexity | 19fa9db18105ec4a4b7b381c61b853b7 MD5 | raw file
  1. /*
  2. * Copyright (C) 2010 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #define LOG_TAG "InputReader"
  17. //#define LOG_NDEBUG 0
  18. // Log debug messages for each raw event received from the EventHub.
  19. #define DEBUG_RAW_EVENTS 0
  20. // Log debug messages about touch screen filtering hacks.
  21. #define DEBUG_HACKS 0
  22. // Log debug messages about virtual key processing.
  23. #define DEBUG_VIRTUAL_KEYS 0
  24. // Log debug messages about pointers.
  25. #define DEBUG_POINTERS 0
  26. // Log debug messages about pointer assignment calculations.
  27. #define DEBUG_POINTER_ASSIGNMENT 0
  28. // Log debug messages about gesture detection.
  29. #define DEBUG_GESTURES 0
  30. // Log debug messages about the vibrator.
  31. #define DEBUG_VIBRATOR 0
  32. #include "InputReader.h"
  33. #include <cutils/log.h>
  34. #include <input/Keyboard.h>
  35. #include <input/VirtualKeyMap.h>
  36. #include <stddef.h>
  37. #include <stdlib.h>
  38. #include <unistd.h>
  39. #include <errno.h>
  40. #include <limits.h>
  41. #include <math.h>
  42. #define INDENT " "
  43. #define INDENT2 " "
  44. #define INDENT3 " "
  45. #define INDENT4 " "
  46. #define INDENT5 " "
  47. namespace android {
  48. // --- Constants ---
  49. // Maximum number of slots supported when using the slot-based Multitouch Protocol B.
  50. static const size_t MAX_SLOTS = 32;
  51. // --- Static Functions ---
  52. template<typename T>
  53. inline static T abs(const T& value) {
  54. return value < 0 ? - value : value;
  55. }
  56. template<typename T>
  57. inline static T min(const T& a, const T& b) {
  58. return a < b ? a : b;
  59. }
  60. template<typename T>
  61. inline static void swap(T& a, T& b) {
  62. T temp = a;
  63. a = b;
  64. b = temp;
  65. }
  66. inline static float avg(float x, float y) {
  67. return (x + y) / 2;
  68. }
  69. inline static float distance(float x1, float y1, float x2, float y2) {
  70. return hypotf(x1 - x2, y1 - y2);
  71. }
  72. inline static int32_t signExtendNybble(int32_t value) {
  73. return value >= 8 ? value - 16 : value;
  74. }
  75. static inline const char* toString(bool value) {
  76. return value ? "true" : "false";
  77. }
  78. static int32_t rotateValueUsingRotationMap(int32_t value, int32_t orientation,
  79. const int32_t map[][4], size_t mapSize) {
  80. if (orientation != DISPLAY_ORIENTATION_0) {
  81. for (size_t i = 0; i < mapSize; i++) {
  82. if (value == map[i][0]) {
  83. return map[i][orientation];
  84. }
  85. }
  86. }
  87. return value;
  88. }
  89. static const int32_t keyCodeRotationMap[][4] = {
  90. // key codes enumerated counter-clockwise with the original (unrotated) key first
  91. // no rotation, 90 degree rotation, 180 degree rotation, 270 degree rotation
  92. { AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT },
  93. { AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN },
  94. { AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT },
  95. { AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP },
  96. };
  97. static const size_t keyCodeRotationMapSize =
  98. sizeof(keyCodeRotationMap) / sizeof(keyCodeRotationMap[0]);
  99. static int32_t rotateKeyCode(int32_t keyCode, int32_t orientation) {
  100. return rotateValueUsingRotationMap(keyCode, orientation,
  101. keyCodeRotationMap, keyCodeRotationMapSize);
  102. }
  103. static void rotateDelta(int32_t orientation, float* deltaX, float* deltaY) {
  104. float temp;
  105. switch (orientation) {
  106. case DISPLAY_ORIENTATION_90:
  107. temp = *deltaX;
  108. *deltaX = *deltaY;
  109. *deltaY = -temp;
  110. break;
  111. case DISPLAY_ORIENTATION_180:
  112. *deltaX = -*deltaX;
  113. *deltaY = -*deltaY;
  114. break;
  115. case DISPLAY_ORIENTATION_270:
  116. temp = *deltaX;
  117. *deltaX = -*deltaY;
  118. *deltaY = temp;
  119. break;
  120. }
  121. }
  122. static inline bool sourcesMatchMask(uint32_t sources, uint32_t sourceMask) {
  123. return (sources & sourceMask & ~ AINPUT_SOURCE_CLASS_MASK) != 0;
  124. }
  125. // Returns true if the pointer should be reported as being down given the specified
  126. // button states. This determines whether the event is reported as a touch event.
  127. static bool isPointerDown(int32_t buttonState) {
  128. return buttonState &
  129. (AMOTION_EVENT_BUTTON_PRIMARY | AMOTION_EVENT_BUTTON_SECONDARY
  130. | AMOTION_EVENT_BUTTON_TERTIARY);
  131. }
  132. static float calculateCommonVector(float a, float b) {
  133. if (a > 0 && b > 0) {
  134. return a < b ? a : b;
  135. } else if (a < 0 && b < 0) {
  136. return a > b ? a : b;
  137. } else {
  138. return 0;
  139. }
  140. }
  141. static void synthesizeButtonKey(InputReaderContext* context, int32_t action,
  142. nsecs_t when, int32_t deviceId, uint32_t source,
  143. uint32_t policyFlags, int32_t lastButtonState, int32_t currentButtonState,
  144. int32_t buttonState, int32_t keyCode) {
  145. if (
  146. (action == AKEY_EVENT_ACTION_DOWN
  147. && !(lastButtonState & buttonState)
  148. && (currentButtonState & buttonState))
  149. || (action == AKEY_EVENT_ACTION_UP
  150. && (lastButtonState & buttonState)
  151. && !(currentButtonState & buttonState))) {
  152. NotifyKeyArgs args(when, deviceId, source, policyFlags,
  153. action, 0, keyCode, 0, context->getGlobalMetaState(), when);
  154. context->getListener()->notifyKey(&args);
  155. }
  156. }
  157. static void synthesizeButtonKeys(InputReaderContext* context, int32_t action,
  158. nsecs_t when, int32_t deviceId, uint32_t source,
  159. uint32_t policyFlags, int32_t lastButtonState, int32_t currentButtonState) {
  160. synthesizeButtonKey(context, action, when, deviceId, source, policyFlags,
  161. lastButtonState, currentButtonState,
  162. AMOTION_EVENT_BUTTON_BACK, AKEYCODE_BACK);
  163. synthesizeButtonKey(context, action, when, deviceId, source, policyFlags,
  164. lastButtonState, currentButtonState,
  165. AMOTION_EVENT_BUTTON_FORWARD, AKEYCODE_FORWARD);
  166. }
  167. // --- InputReaderConfiguration ---
  168. bool InputReaderConfiguration::getDisplayInfo(bool external, DisplayViewport* outViewport) const {
  169. const DisplayViewport& viewport = external ? mExternalDisplay : mInternalDisplay;
  170. if (viewport.displayId >= 0) {
  171. *outViewport = viewport;
  172. return true;
  173. }
  174. return false;
  175. }
  176. void InputReaderConfiguration::setDisplayInfo(bool external, const DisplayViewport& viewport) {
  177. DisplayViewport& v = external ? mExternalDisplay : mInternalDisplay;
  178. v = viewport;
  179. }
  180. // --- InputReader ---
  181. InputReader::InputReader(const sp<EventHubInterface>& eventHub,
  182. const sp<InputReaderPolicyInterface>& policy,
  183. const sp<InputListenerInterface>& listener) :
  184. mContext(this), mEventHub(eventHub), mPolicy(policy),
  185. mGlobalMetaState(0), mGeneration(1),
  186. mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
  187. mConfigurationChangesToRefresh(0) {
  188. mQueuedListener = new QueuedInputListener(listener);
  189. { // acquire lock
  190. AutoMutex _l(mLock);
  191. refreshConfigurationLocked(0);
  192. updateGlobalMetaStateLocked();
  193. } // release lock
  194. }
  195. InputReader::~InputReader() {
  196. for (size_t i = 0; i < mDevices.size(); i++) {
  197. delete mDevices.valueAt(i);
  198. }
  199. }
  200. void InputReader::loopOnce() {
  201. int32_t oldGeneration;
  202. int32_t timeoutMillis;
  203. bool inputDevicesChanged = false;
  204. Vector<InputDeviceInfo> inputDevices;
  205. { // acquire lock
  206. AutoMutex _l(mLock);
  207. oldGeneration = mGeneration;
  208. timeoutMillis = -1;
  209. uint32_t changes = mConfigurationChangesToRefresh;
  210. if (changes) {
  211. mConfigurationChangesToRefresh = 0;
  212. timeoutMillis = 0;
  213. refreshConfigurationLocked(changes);
  214. } else if (mNextTimeout != LLONG_MAX) {
  215. nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
  216. timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
  217. }
  218. } // release lock
  219. size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
  220. { // acquire lock
  221. AutoMutex _l(mLock);
  222. mReaderIsAliveCondition.broadcast();
  223. if (count) {
  224. processEventsLocked(mEventBuffer, count);
  225. }
  226. if (mNextTimeout != LLONG_MAX) {
  227. nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
  228. if (now >= mNextTimeout) {
  229. #if DEBUG_RAW_EVENTS
  230. ALOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
  231. #endif
  232. mNextTimeout = LLONG_MAX;
  233. timeoutExpiredLocked(now);
  234. }
  235. }
  236. if (oldGeneration != mGeneration) {
  237. inputDevicesChanged = true;
  238. getInputDevicesLocked(inputDevices);
  239. }
  240. } // release lock
  241. // Send out a message that the describes the changed input devices.
  242. if (inputDevicesChanged) {
  243. mPolicy->notifyInputDevicesChanged(inputDevices);
  244. }
  245. // Flush queued events out to the listener.
  246. // This must happen outside of the lock because the listener could potentially call
  247. // back into the InputReader's methods, such as getScanCodeState, or become blocked
  248. // on another thread similarly waiting to acquire the InputReader lock thereby
  249. // resulting in a deadlock. This situation is actually quite plausible because the
  250. // listener is actually the input dispatcher, which calls into the window manager,
  251. // which occasionally calls into the input reader.
  252. mQueuedListener->flush();
  253. }
  254. void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
  255. for (const RawEvent* rawEvent = rawEvents; count;) {
  256. int32_t type = rawEvent->type;
  257. size_t batchSize = 1;
  258. if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
  259. int32_t deviceId = rawEvent->deviceId;
  260. while (batchSize < count) {
  261. if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT
  262. || rawEvent[batchSize].deviceId != deviceId) {
  263. break;
  264. }
  265. batchSize += 1;
  266. }
  267. #if DEBUG_RAW_EVENTS
  268. ALOGD("BatchSize: %d Count: %d", batchSize, count);
  269. #endif
  270. processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
  271. } else {
  272. switch (rawEvent->type) {
  273. case EventHubInterface::DEVICE_ADDED:
  274. addDeviceLocked(rawEvent->when, rawEvent->deviceId);
  275. break;
  276. case EventHubInterface::DEVICE_REMOVED:
  277. removeDeviceLocked(rawEvent->when, rawEvent->deviceId);
  278. break;
  279. case EventHubInterface::FINISHED_DEVICE_SCAN:
  280. handleConfigurationChangedLocked(rawEvent->when);
  281. break;
  282. default:
  283. ALOG_ASSERT(false); // can't happen
  284. break;
  285. }
  286. }
  287. count -= batchSize;
  288. rawEvent += batchSize;
  289. }
  290. }
  291. void InputReader::addDeviceLocked(nsecs_t when, int32_t deviceId) {
  292. ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
  293. if (deviceIndex >= 0) {
  294. ALOGW("Ignoring spurious device added event for deviceId %d.", deviceId);
  295. return;
  296. }
  297. InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceId);
  298. uint32_t classes = mEventHub->getDeviceClasses(deviceId);
  299. int32_t controllerNumber = mEventHub->getDeviceControllerNumber(deviceId);
  300. InputDevice* device = createDeviceLocked(deviceId, controllerNumber, identifier, classes);
  301. device->configure(when, &mConfig, 0);
  302. device->reset(when);
  303. if (device->isIgnored()) {
  304. ALOGI("Device added: id=%d, name='%s' (ignored non-input device)", deviceId,
  305. identifier.name.string());
  306. } else {
  307. ALOGI("Device added: id=%d, name='%s', sources=0x%08x", deviceId,
  308. identifier.name.string(), device->getSources());
  309. }
  310. mDevices.add(deviceId, device);
  311. bumpGenerationLocked();
  312. }
  313. void InputReader::removeDeviceLocked(nsecs_t when, int32_t deviceId) {
  314. InputDevice* device = NULL;
  315. ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
  316. if (deviceIndex < 0) {
  317. ALOGW("Ignoring spurious device removed event for deviceId %d.", deviceId);
  318. return;
  319. }
  320. device = mDevices.valueAt(deviceIndex);
  321. mDevices.removeItemsAt(deviceIndex, 1);
  322. bumpGenerationLocked();
  323. if (device->isIgnored()) {
  324. ALOGI("Device removed: id=%d, name='%s' (ignored non-input device)",
  325. device->getId(), device->getName().string());
  326. } else {
  327. ALOGI("Device removed: id=%d, name='%s', sources=0x%08x",
  328. device->getId(), device->getName().string(), device->getSources());
  329. }
  330. device->reset(when);
  331. delete device;
  332. }
  333. InputDevice* InputReader::createDeviceLocked(int32_t deviceId, int32_t controllerNumber,
  334. const InputDeviceIdentifier& identifier, uint32_t classes) {
  335. InputDevice* device = new InputDevice(&mContext, deviceId, bumpGenerationLocked(),
  336. controllerNumber, identifier, classes);
  337. // External devices.
  338. if (classes & INPUT_DEVICE_CLASS_EXTERNAL) {
  339. device->setExternal(true);
  340. }
  341. // Switch-like devices.
  342. if (classes & INPUT_DEVICE_CLASS_SWITCH) {
  343. device->addMapper(new SwitchInputMapper(device));
  344. }
  345. // Vibrator-like devices.
  346. if (classes & INPUT_DEVICE_CLASS_VIBRATOR) {
  347. device->addMapper(new VibratorInputMapper(device));
  348. }
  349. // Keyboard-like devices.
  350. uint32_t keyboardSource = 0;
  351. int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
  352. if (classes & INPUT_DEVICE_CLASS_KEYBOARD) {
  353. keyboardSource |= AINPUT_SOURCE_KEYBOARD;
  354. }
  355. if (classes & INPUT_DEVICE_CLASS_ALPHAKEY) {
  356. keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC;
  357. }
  358. if (classes & INPUT_DEVICE_CLASS_DPAD) {
  359. keyboardSource |= AINPUT_SOURCE_DPAD;
  360. }
  361. if (classes & INPUT_DEVICE_CLASS_GAMEPAD) {
  362. keyboardSource |= AINPUT_SOURCE_GAMEPAD;
  363. }
  364. if (keyboardSource != 0) {
  365. device->addMapper(new KeyboardInputMapper(device, keyboardSource, keyboardType));
  366. }
  367. // Cursor-like devices.
  368. if (classes & INPUT_DEVICE_CLASS_CURSOR) {
  369. device->addMapper(new CursorInputMapper(device));
  370. }
  371. // Touchscreens and touchpad devices.
  372. if (classes & INPUT_DEVICE_CLASS_TOUCH_MT) {
  373. device->addMapper(new MultiTouchInputMapper(device));
  374. } else if (classes & INPUT_DEVICE_CLASS_TOUCH) {
  375. device->addMapper(new SingleTouchInputMapper(device));
  376. }
  377. // Joystick-like devices.
  378. if (classes & INPUT_DEVICE_CLASS_JOYSTICK) {
  379. device->addMapper(new JoystickInputMapper(device));
  380. }
  381. return device;
  382. }
  383. void InputReader::processEventsForDeviceLocked(int32_t deviceId,
  384. const RawEvent* rawEvents, size_t count) {
  385. ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
  386. if (deviceIndex < 0) {
  387. ALOGW("Discarding event for unknown deviceId %d.", deviceId);
  388. return;
  389. }
  390. InputDevice* device = mDevices.valueAt(deviceIndex);
  391. if (device->isIgnored()) {
  392. //ALOGD("Discarding event for ignored deviceId %d.", deviceId);
  393. return;
  394. }
  395. device->process(rawEvents, count);
  396. }
  397. void InputReader::timeoutExpiredLocked(nsecs_t when) {
  398. for (size_t i = 0; i < mDevices.size(); i++) {
  399. InputDevice* device = mDevices.valueAt(i);
  400. if (!device->isIgnored()) {
  401. device->timeoutExpired(when);
  402. }
  403. }
  404. }
  405. void InputReader::handleConfigurationChangedLocked(nsecs_t when) {
  406. // Reset global meta state because it depends on the list of all configured devices.
  407. updateGlobalMetaStateLocked();
  408. // Enqueue configuration changed.
  409. NotifyConfigurationChangedArgs args(when);
  410. mQueuedListener->notifyConfigurationChanged(&args);
  411. }
  412. void InputReader::refreshConfigurationLocked(uint32_t changes) {
  413. mPolicy->getReaderConfiguration(&mConfig);
  414. mEventHub->setExcludedDevices(mConfig.excludedDeviceNames);
  415. if (changes) {
  416. ALOGI("Reconfiguring input devices. changes=0x%08x", changes);
  417. nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
  418. if (changes & InputReaderConfiguration::CHANGE_MUST_REOPEN) {
  419. mEventHub->requestReopenDevices();
  420. } else {
  421. for (size_t i = 0; i < mDevices.size(); i++) {
  422. InputDevice* device = mDevices.valueAt(i);
  423. device->configure(now, &mConfig, changes);
  424. }
  425. }
  426. }
  427. }
  428. void InputReader::updateGlobalMetaStateLocked() {
  429. mGlobalMetaState = 0;
  430. for (size_t i = 0; i < mDevices.size(); i++) {
  431. InputDevice* device = mDevices.valueAt(i);
  432. mGlobalMetaState |= device->getMetaState();
  433. }
  434. }
  435. int32_t InputReader::getGlobalMetaStateLocked() {
  436. return mGlobalMetaState;
  437. }
  438. void InputReader::disableVirtualKeysUntilLocked(nsecs_t time) {
  439. mDisableVirtualKeysTimeout = time;
  440. }
  441. bool InputReader::shouldDropVirtualKeyLocked(nsecs_t now,
  442. InputDevice* device, int32_t keyCode, int32_t scanCode) {
  443. if (now < mDisableVirtualKeysTimeout) {
  444. ALOGI("Dropping virtual key from device %s because virtual keys are "
  445. "temporarily disabled for the next %0.3fms. keyCode=%d, scanCode=%d",
  446. device->getName().string(),
  447. (mDisableVirtualKeysTimeout - now) * 0.000001,
  448. keyCode, scanCode);
  449. return true;
  450. } else {
  451. return false;
  452. }
  453. }
  454. void InputReader::fadePointerLocked() {
  455. for (size_t i = 0; i < mDevices.size(); i++) {
  456. InputDevice* device = mDevices.valueAt(i);
  457. device->fadePointer();
  458. }
  459. }
  460. void InputReader::requestTimeoutAtTimeLocked(nsecs_t when) {
  461. if (when < mNextTimeout) {
  462. mNextTimeout = when;
  463. mEventHub->wake();
  464. }
  465. }
  466. int32_t InputReader::bumpGenerationLocked() {
  467. return ++mGeneration;
  468. }
  469. void InputReader::getInputDevices(Vector<InputDeviceInfo>& outInputDevices) {
  470. AutoMutex _l(mLock);
  471. getInputDevicesLocked(outInputDevices);
  472. }
  473. void InputReader::getInputDevicesLocked(Vector<InputDeviceInfo>& outInputDevices) {
  474. outInputDevices.clear();
  475. size_t numDevices = mDevices.size();
  476. for (size_t i = 0; i < numDevices; i++) {
  477. InputDevice* device = mDevices.valueAt(i);
  478. if (!device->isIgnored()) {
  479. outInputDevices.push();
  480. device->getDeviceInfo(&outInputDevices.editTop());
  481. }
  482. }
  483. }
  484. int32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
  485. int32_t keyCode) {
  486. AutoMutex _l(mLock);
  487. return getStateLocked(deviceId, sourceMask, keyCode, &InputDevice::getKeyCodeState);
  488. }
  489. int32_t InputReader::getScanCodeState(int32_t deviceId, uint32_t sourceMask,
  490. int32_t scanCode) {
  491. AutoMutex _l(mLock);
  492. return getStateLocked(deviceId, sourceMask, scanCode, &InputDevice::getScanCodeState);
  493. }
  494. int32_t InputReader::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t switchCode) {
  495. AutoMutex _l(mLock);
  496. return getStateLocked(deviceId, sourceMask, switchCode, &InputDevice::getSwitchState);
  497. }
  498. int32_t InputReader::getStateLocked(int32_t deviceId, uint32_t sourceMask, int32_t code,
  499. GetStateFunc getStateFunc) {
  500. int32_t result = AKEY_STATE_UNKNOWN;
  501. if (deviceId >= 0) {
  502. ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
  503. if (deviceIndex >= 0) {
  504. InputDevice* device = mDevices.valueAt(deviceIndex);
  505. if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
  506. result = (device->*getStateFunc)(sourceMask, code);
  507. }
  508. }
  509. } else {
  510. size_t numDevices = mDevices.size();
  511. for (size_t i = 0; i < numDevices; i++) {
  512. InputDevice* device = mDevices.valueAt(i);
  513. if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
  514. // If any device reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
  515. // value. Otherwise, return AKEY_STATE_UP as long as one device reports it.
  516. int32_t currentResult = (device->*getStateFunc)(sourceMask, code);
  517. if (currentResult >= AKEY_STATE_DOWN) {
  518. return currentResult;
  519. } else if (currentResult == AKEY_STATE_UP) {
  520. result = currentResult;
  521. }
  522. }
  523. }
  524. }
  525. return result;
  526. }
  527. bool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask,
  528. size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
  529. AutoMutex _l(mLock);
  530. memset(outFlags, 0, numCodes);
  531. return markSupportedKeyCodesLocked(deviceId, sourceMask, numCodes, keyCodes, outFlags);
  532. }
  533. bool InputReader::markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask,
  534. size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
  535. bool result = false;
  536. if (deviceId >= 0) {
  537. ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
  538. if (deviceIndex >= 0) {
  539. InputDevice* device = mDevices.valueAt(deviceIndex);
  540. if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
  541. result = device->markSupportedKeyCodes(sourceMask,
  542. numCodes, keyCodes, outFlags);
  543. }
  544. }
  545. } else {
  546. size_t numDevices = mDevices.size();
  547. for (size_t i = 0; i < numDevices; i++) {
  548. InputDevice* device = mDevices.valueAt(i);
  549. if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
  550. result |= device->markSupportedKeyCodes(sourceMask,
  551. numCodes, keyCodes, outFlags);
  552. }
  553. }
  554. }
  555. return result;
  556. }
  557. void InputReader::requestRefreshConfiguration(uint32_t changes) {
  558. AutoMutex _l(mLock);
  559. if (changes) {
  560. bool needWake = !mConfigurationChangesToRefresh;
  561. mConfigurationChangesToRefresh |= changes;
  562. if (needWake) {
  563. mEventHub->wake();
  564. }
  565. }
  566. }
  567. void InputReader::vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
  568. ssize_t repeat, int32_t token) {
  569. AutoMutex _l(mLock);
  570. ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
  571. if (deviceIndex >= 0) {
  572. InputDevice* device = mDevices.valueAt(deviceIndex);
  573. device->vibrate(pattern, patternSize, repeat, token);
  574. }
  575. }
  576. void InputReader::cancelVibrate(int32_t deviceId, int32_t token) {
  577. AutoMutex _l(mLock);
  578. ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
  579. if (deviceIndex >= 0) {
  580. InputDevice* device = mDevices.valueAt(deviceIndex);
  581. device->cancelVibrate(token);
  582. }
  583. }
  584. void InputReader::dump(String8& dump) {
  585. AutoMutex _l(mLock);
  586. mEventHub->dump(dump);
  587. dump.append("\n");
  588. dump.append("Input Reader State:\n");
  589. for (size_t i = 0; i < mDevices.size(); i++) {
  590. mDevices.valueAt(i)->dump(dump);
  591. }
  592. dump.append(INDENT "Configuration:\n");
  593. dump.append(INDENT2 "ExcludedDeviceNames: [");
  594. for (size_t i = 0; i < mConfig.excludedDeviceNames.size(); i++) {
  595. if (i != 0) {
  596. dump.append(", ");
  597. }
  598. dump.append(mConfig.excludedDeviceNames.itemAt(i).string());
  599. }
  600. dump.append("]\n");
  601. dump.appendFormat(INDENT2 "VirtualKeyQuietTime: %0.1fms\n",
  602. mConfig.virtualKeyQuietTime * 0.000001f);
  603. dump.appendFormat(INDENT2 "PointerVelocityControlParameters: "
  604. "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, acceleration=%0.3f\n",
  605. mConfig.pointerVelocityControlParameters.scale,
  606. mConfig.pointerVelocityControlParameters.lowThreshold,
  607. mConfig.pointerVelocityControlParameters.highThreshold,
  608. mConfig.pointerVelocityControlParameters.acceleration);
  609. dump.appendFormat(INDENT2 "WheelVelocityControlParameters: "
  610. "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, acceleration=%0.3f\n",
  611. mConfig.wheelVelocityControlParameters.scale,
  612. mConfig.wheelVelocityControlParameters.lowThreshold,
  613. mConfig.wheelVelocityControlParameters.highThreshold,
  614. mConfig.wheelVelocityControlParameters.acceleration);
  615. dump.appendFormat(INDENT2 "PointerGesture:\n");
  616. dump.appendFormat(INDENT3 "Enabled: %s\n",
  617. toString(mConfig.pointerGesturesEnabled));
  618. dump.appendFormat(INDENT3 "QuietInterval: %0.1fms\n",
  619. mConfig.pointerGestureQuietInterval * 0.000001f);
  620. dump.appendFormat(INDENT3 "DragMinSwitchSpeed: %0.1fpx/s\n",
  621. mConfig.pointerGestureDragMinSwitchSpeed);
  622. dump.appendFormat(INDENT3 "TapInterval: %0.1fms\n",
  623. mConfig.pointerGestureTapInterval * 0.000001f);
  624. dump.appendFormat(INDENT3 "TapDragInterval: %0.1fms\n",
  625. mConfig.pointerGestureTapDragInterval * 0.000001f);
  626. dump.appendFormat(INDENT3 "TapSlop: %0.1fpx\n",
  627. mConfig.pointerGestureTapSlop);
  628. dump.appendFormat(INDENT3 "MultitouchSettleInterval: %0.1fms\n",
  629. mConfig.pointerGestureMultitouchSettleInterval * 0.000001f);
  630. dump.appendFormat(INDENT3 "MultitouchMinDistance: %0.1fpx\n",
  631. mConfig.pointerGestureMultitouchMinDistance);
  632. dump.appendFormat(INDENT3 "SwipeTransitionAngleCosine: %0.1f\n",
  633. mConfig.pointerGestureSwipeTransitionAngleCosine);
  634. dump.appendFormat(INDENT3 "SwipeMaxWidthRatio: %0.1f\n",
  635. mConfig.pointerGestureSwipeMaxWidthRatio);
  636. dump.appendFormat(INDENT3 "MovementSpeedRatio: %0.1f\n",
  637. mConfig.pointerGestureMovementSpeedRatio);
  638. dump.appendFormat(INDENT3 "ZoomSpeedRatio: %0.1f\n",
  639. mConfig.pointerGestureZoomSpeedRatio);
  640. }
  641. void InputReader::monitor() {
  642. // Acquire and release the lock to ensure that the reader has not deadlocked.
  643. mLock.lock();
  644. mEventHub->wake();
  645. mReaderIsAliveCondition.wait(mLock);
  646. mLock.unlock();
  647. // Check the EventHub
  648. mEventHub->monitor();
  649. }
  650. // --- InputReader::ContextImpl ---
  651. InputReader::ContextImpl::ContextImpl(InputReader* reader) :
  652. mReader(reader) {
  653. }
  654. void InputReader::ContextImpl::updateGlobalMetaState() {
  655. // lock is already held by the input loop
  656. mReader->updateGlobalMetaStateLocked();
  657. }
  658. int32_t InputReader::ContextImpl::getGlobalMetaState() {
  659. // lock is already held by the input loop
  660. return mReader->getGlobalMetaStateLocked();
  661. }
  662. void InputReader::ContextImpl::disableVirtualKeysUntil(nsecs_t time) {
  663. // lock is already held by the input loop
  664. mReader->disableVirtualKeysUntilLocked(time);
  665. }
  666. bool InputReader::ContextImpl::shouldDropVirtualKey(nsecs_t now,
  667. InputDevice* device, int32_t keyCode, int32_t scanCode) {
  668. // lock is already held by the input loop
  669. return mReader->shouldDropVirtualKeyLocked(now, device, keyCode, scanCode);
  670. }
  671. void InputReader::ContextImpl::fadePointer() {
  672. // lock is already held by the input loop
  673. mReader->fadePointerLocked();
  674. }
  675. void InputReader::ContextImpl::requestTimeoutAtTime(nsecs_t when) {
  676. // lock is already held by the input loop
  677. mReader->requestTimeoutAtTimeLocked(when);
  678. }
  679. int32_t InputReader::ContextImpl::bumpGeneration() {
  680. // lock is already held by the input loop
  681. return mReader->bumpGenerationLocked();
  682. }
  683. InputReaderPolicyInterface* InputReader::ContextImpl::getPolicy() {
  684. return mReader->mPolicy.get();
  685. }
  686. InputListenerInterface* InputReader::ContextImpl::getListener() {
  687. return mReader->mQueuedListener.get();
  688. }
  689. EventHubInterface* InputReader::ContextImpl::getEventHub() {
  690. return mReader->mEventHub.get();
  691. }
  692. // --- InputReaderThread ---
  693. InputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) :
  694. Thread(/*canCallJava*/ true), mReader(reader) {
  695. }
  696. InputReaderThread::~InputReaderThread() {
  697. }
  698. bool InputReaderThread::threadLoop() {
  699. mReader->loopOnce();
  700. return true;
  701. }
  702. // --- InputDevice ---
  703. InputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
  704. int32_t controllerNumber, const InputDeviceIdentifier& identifier, uint32_t classes) :
  705. mContext(context), mId(id), mGeneration(generation), mControllerNumber(controllerNumber),
  706. mIdentifier(identifier), mClasses(classes),
  707. mSources(0), mIsExternal(false), mDropUntilNextSync(false) {
  708. }
  709. InputDevice::~InputDevice() {
  710. size_t numMappers = mMappers.size();
  711. for (size_t i = 0; i < numMappers; i++) {
  712. delete mMappers[i];
  713. }
  714. mMappers.clear();
  715. }
  716. void InputDevice::dump(String8& dump) {
  717. InputDeviceInfo deviceInfo;
  718. getDeviceInfo(& deviceInfo);
  719. dump.appendFormat(INDENT "Device %d: %s\n", deviceInfo.getId(),
  720. deviceInfo.getDisplayName().string());
  721. dump.appendFormat(INDENT2 "Generation: %d\n", mGeneration);
  722. dump.appendFormat(INDENT2 "IsExternal: %s\n", toString(mIsExternal));
  723. dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
  724. dump.appendFormat(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
  725. const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
  726. if (!ranges.isEmpty()) {
  727. dump.append(INDENT2 "Motion Ranges:\n");
  728. for (size_t i = 0; i < ranges.size(); i++) {
  729. const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
  730. const char* label = getAxisLabel(range.axis);
  731. char name[32];
  732. if (label) {
  733. strncpy(name, label, sizeof(name));
  734. name[sizeof(name) - 1] = '\0';
  735. } else {
  736. snprintf(name, sizeof(name), "%d", range.axis);
  737. }
  738. dump.appendFormat(INDENT3 "%s: source=0x%08x, "
  739. "min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f, resolution=%0.3f\n",
  740. name, range.source, range.min, range.max, range.flat, range.fuzz,
  741. range.resolution);
  742. }
  743. }
  744. size_t numMappers = mMappers.size();
  745. for (size_t i = 0; i < numMappers; i++) {
  746. InputMapper* mapper = mMappers[i];
  747. mapper->dump(dump);
  748. }
  749. }
  750. void InputDevice::addMapper(InputMapper* mapper) {
  751. mMappers.add(mapper);
  752. }
  753. void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes) {
  754. mSources = 0;
  755. if (!isIgnored()) {
  756. if (!changes) { // first time only
  757. mContext->getEventHub()->getConfiguration(mId, &mConfiguration);
  758. }
  759. if (!changes || (changes & InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS)) {
  760. if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
  761. sp<KeyCharacterMap> keyboardLayout =
  762. mContext->getPolicy()->getKeyboardLayoutOverlay(mIdentifier.descriptor);
  763. if (mContext->getEventHub()->setKeyboardLayoutOverlay(mId, keyboardLayout)) {
  764. bumpGeneration();
  765. }
  766. }
  767. }
  768. if (!changes || (changes & InputReaderConfiguration::CHANGE_DEVICE_ALIAS)) {
  769. if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
  770. String8 alias = mContext->getPolicy()->getDeviceAlias(mIdentifier);
  771. if (mAlias != alias) {
  772. mAlias = alias;
  773. bumpGeneration();
  774. }
  775. }
  776. }
  777. size_t numMappers = mMappers.size();
  778. for (size_t i = 0; i < numMappers; i++) {
  779. InputMapper* mapper = mMappers[i];
  780. mapper->configure(when, config, changes);
  781. mSources |= mapper->getSources();
  782. }
  783. }
  784. }
  785. void InputDevice::reset(nsecs_t when) {
  786. size_t numMappers = mMappers.size();
  787. for (size_t i = 0; i < numMappers; i++) {
  788. InputMapper* mapper = mMappers[i];
  789. mapper->reset(when);
  790. }
  791. mContext->updateGlobalMetaState();
  792. notifyReset(when);
  793. }
  794. void InputDevice::process(const RawEvent* rawEvents, size_t count) {
  795. // Process all of the events in order for each mapper.
  796. // We cannot simply ask each mapper to process them in bulk because mappers may
  797. // have side-effects that must be interleaved. For example, joystick movement events and
  798. // gamepad button presses are handled by different mappers but they should be dispatched
  799. // in the order received.
  800. size_t numMappers = mMappers.size();
  801. for (const RawEvent* rawEvent = rawEvents; count--; rawEvent++) {
  802. #if DEBUG_RAW_EVENTS
  803. ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%lld",
  804. rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value,
  805. rawEvent->when);
  806. #endif
  807. if (mDropUntilNextSync) {
  808. if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
  809. mDropUntilNextSync = false;
  810. #if DEBUG_RAW_EVENTS
  811. ALOGD("Recovered from input event buffer overrun.");
  812. #endif
  813. } else {
  814. #if DEBUG_RAW_EVENTS
  815. ALOGD("Dropped input event while waiting for next input sync.");
  816. #endif
  817. }
  818. } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
  819. ALOGI("Detected input event buffer overrun for device %s.", getName().string());
  820. mDropUntilNextSync = true;
  821. reset(rawEvent->when);
  822. } else {
  823. for (size_t i = 0; i < numMappers; i++) {
  824. InputMapper* mapper = mMappers[i];
  825. mapper->process(rawEvent);
  826. }
  827. }
  828. }
  829. }
  830. void InputDevice::timeoutExpired(nsecs_t when) {
  831. size_t numMappers = mMappers.size();
  832. for (size_t i = 0; i < numMappers; i++) {
  833. InputMapper* mapper = mMappers[i];
  834. mapper->timeoutExpired(when);
  835. }
  836. }
  837. void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
  838. outDeviceInfo->initialize(mId, mGeneration, mControllerNumber, mIdentifier, mAlias,
  839. mIsExternal);
  840. size_t numMappers = mMappers.size();
  841. for (size_t i = 0; i < numMappers; i++) {
  842. InputMapper* mapper = mMappers[i];
  843. mapper->populateDeviceInfo(outDeviceInfo);
  844. }
  845. }
  846. int32_t InputDevice::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
  847. return getState(sourceMask, keyCode, & InputMapper::getKeyCodeState);
  848. }
  849. int32_t InputDevice::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
  850. return getState(sourceMask, scanCode, & InputMapper::getScanCodeState);
  851. }
  852. int32_t InputDevice::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
  853. return getState(sourceMask, switchCode, & InputMapper::getSwitchState);
  854. }
  855. int32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) {
  856. int32_t result = AKEY_STATE_UNKNOWN;
  857. size_t numMappers = mMappers.size();
  858. for (size_t i = 0; i < numMappers; i++) {
  859. InputMapper* mapper = mMappers[i];
  860. if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
  861. // If any mapper reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
  862. // value. Otherwise, return AKEY_STATE_UP as long as one mapper reports it.
  863. int32_t currentResult = (mapper->*getStateFunc)(sourceMask, code);
  864. if (currentResult >= AKEY_STATE_DOWN) {
  865. return currentResult;
  866. } else if (currentResult == AKEY_STATE_UP) {
  867. result = currentResult;
  868. }
  869. }
  870. }
  871. return result;
  872. }
  873. bool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
  874. const int32_t* keyCodes, uint8_t* outFlags) {
  875. bool result = false;
  876. size_t numMappers = mMappers.size();
  877. for (size_t i = 0; i < numMappers; i++) {
  878. InputMapper* mapper = mMappers[i];
  879. if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
  880. result |= mapper->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
  881. }
  882. }
  883. return result;
  884. }
  885. void InputDevice::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
  886. int32_t token) {
  887. size_t numMappers = mMappers.size();
  888. for (size_t i = 0; i < numMappers; i++) {
  889. InputMapper* mapper = mMappers[i];
  890. mapper->vibrate(pattern, patternSize, repeat, token);
  891. }
  892. }
  893. void InputDevice::cancelVibrate(int32_t token) {
  894. size_t numMappers = mMappers.size();
  895. for (size_t i = 0; i < numMappers; i++) {
  896. InputMapper* mapper = mMappers[i];
  897. mapper->cancelVibrate(token);
  898. }
  899. }
  900. int32_t InputDevice::getMetaState() {
  901. int32_t result = 0;
  902. size_t numMappers = mMappers.size();
  903. for (size_t i = 0; i < numMappers; i++) {
  904. InputMapper* mapper = mMappers[i];
  905. result |= mapper->getMetaState();
  906. }
  907. return result;
  908. }
  909. void InputDevice::fadePointer() {
  910. size_t numMappers = mMappers.size();
  911. for (size_t i = 0; i < numMappers; i++) {
  912. InputMapper* mapper = mMappers[i];
  913. mapper->fadePointer();
  914. }
  915. }
  916. void InputDevice::bumpGeneration() {
  917. mGeneration = mContext->bumpGeneration();
  918. }
  919. void InputDevice::notifyReset(nsecs_t when) {
  920. NotifyDeviceResetArgs args(when, mId);
  921. mContext->getListener()->notifyDeviceReset(&args);
  922. }
  923. // --- CursorButtonAccumulator ---
  924. CursorButtonAccumulator::CursorButtonAccumulator() {
  925. clearButtons();
  926. }
  927. void CursorButtonAccumulator::reset(InputDevice* device) {
  928. mBtnLeft = device->isKeyPressed(BTN_LEFT);
  929. mBtnRight = device->isKeyPressed(BTN_RIGHT);
  930. mBtnMiddle = device->isKeyPressed(BTN_MIDDLE);
  931. mBtnBack = device->isKeyPressed(BTN_BACK);
  932. mBtnSide = device->isKeyPressed(BTN_SIDE);
  933. mBtnForward = device->isKeyPressed(BTN_FORWARD);
  934. mBtnExtra = device->isKeyPressed(BTN_EXTRA);
  935. mBtnTask = device->isKeyPressed(BTN_TASK);
  936. }
  937. void CursorButtonAccumulator::clearButtons() {
  938. mBtnLeft = 0;
  939. mBtnRight = 0;
  940. mBtnMiddle = 0;
  941. mBtnBack = 0;
  942. mBtnSide = 0;
  943. mBtnForward = 0;
  944. mBtnExtra = 0;
  945. mBtnTask = 0;
  946. }
  947. void CursorButtonAccumulator::process(const RawEvent* rawEvent) {
  948. if (rawEvent->type == EV_KEY) {
  949. switch (rawEvent->code) {
  950. case BTN_LEFT:
  951. mBtnLeft = rawEvent->value;
  952. break;
  953. case BTN_RIGHT:
  954. mBtnRight = rawEvent->value;
  955. break;
  956. case BTN_MIDDLE:
  957. mBtnMiddle = rawEvent->value;
  958. break;
  959. case BTN_BACK:
  960. mBtnBack = rawEvent->value;
  961. break;
  962. case BTN_SIDE:
  963. mBtnSide = rawEvent->value;
  964. break;
  965. case BTN_FORWARD:
  966. mBtnForward = rawEvent->value;
  967. break;
  968. case BTN_EXTRA:
  969. mBtnExtra = rawEvent->value;
  970. break;
  971. case BTN_TASK:
  972. mBtnTask = rawEvent->value;
  973. break;
  974. }
  975. }
  976. }
  977. uint32_t CursorButtonAccumulator::getButtonState() const {
  978. uint32_t result = 0;
  979. if (mBtnLeft) {
  980. result |= AMOTION_EVENT_BUTTON_PRIMARY;
  981. }
  982. if (mBtnRight) {
  983. result |= AMOTION_EVENT_BUTTON_SECONDARY;
  984. }
  985. if (mBtnMiddle) {
  986. result |= AMOTION_EVENT_BUTTON_TERTIARY;
  987. }
  988. if (mBtnBack || mBtnSide) {
  989. result |= AMOTION_EVENT_BUTTON_BACK;
  990. }
  991. if (mBtnForward || mBtnExtra) {
  992. result |= AMOTION_EVENT_BUTTON_FORWARD;
  993. }
  994. return result;
  995. }
  996. // --- CursorMotionAccumulator ---
  997. CursorMotionAccumulator::CursorMotionAccumulator() {
  998. clearRelativeAxes();
  999. }
  1000. void CursorMotionAccumulator::reset(InputDevice* device) {
  1001. clearRelativeAxes();
  1002. }
  1003. void CursorMotionAccumulator::clearRelativeAxes() {
  1004. mRelX = 0;
  1005. mRelY = 0;
  1006. }
  1007. void CursorMotionAccumulator::process(const RawEvent* rawEvent) {
  1008. if (rawEvent->type == EV_REL) {
  1009. switch (rawEvent->code) {
  1010. case REL_X:
  1011. mRelX = rawEvent->value;
  1012. break;
  1013. case REL_Y:
  1014. mRelY = rawEvent->value;
  1015. break;
  1016. }
  1017. }
  1018. }
  1019. void CursorMotionAccumulator::finishSync() {
  1020. clearRelativeAxes();
  1021. }
  1022. // --- CursorScrollAccumulator ---
  1023. CursorScrollAccumulator::CursorScrollAccumulator() :
  1024. mHaveRelWheel(false), mHaveRelHWheel(false) {
  1025. clearRelativeAxes();
  1026. }
  1027. void CursorScrollAccumulator::configure(InputDevice* device) {
  1028. mHaveRelWheel = device->getEventHub()->hasRelativeAxis(device->getId(), REL_WHEEL);
  1029. mHaveRelHWheel = device->getEventHub()->hasRelativeAxis(device->getId(), REL_HWHEEL);
  1030. }
  1031. void CursorScrollAccumulator::reset(InputDevice* device) {
  1032. clearRelativeAxes();
  1033. }
  1034. void CursorScrollAccumulator::clearRelativeAxes() {
  1035. mRelWheel = 0;
  1036. mRelHWheel = 0;
  1037. }
  1038. void CursorScrollAccumulator::process(const RawEvent* rawEvent) {
  1039. if (rawEvent->type == EV_REL) {
  1040. switch (rawEvent->code) {
  1041. case REL_WHEEL:
  1042. mRelWheel = rawEvent->value;
  1043. break;
  1044. case REL_HWHEEL:
  1045. mRelHWheel = rawEvent->value;
  1046. break;
  1047. }
  1048. }
  1049. }
  1050. void CursorScrollAccumulator::finishSync() {
  1051. clearRelativeAxes();
  1052. }
  1053. // --- TouchButtonAccumulator ---
  1054. TouchButtonAccumulator::TouchButtonAccumulator() :
  1055. mHaveBtnTouch(false), mHaveStylus(false) {
  1056. clearButtons();
  1057. }
  1058. void TouchButtonAccumulator::configure(InputDevice* device) {
  1059. mHaveBtnTouch = device->hasKey(BTN_TOUCH);
  1060. mHaveStylus = device->hasKey(BTN_TOOL_PEN)
  1061. || device->hasKey(BTN_TOOL_RUBBER)
  1062. || device->hasKey(BTN_TOOL_BRUSH)
  1063. || device->hasKey(BTN_TOOL_PENCIL)
  1064. || device->hasKey(BTN_TOOL_AIRBRUSH);
  1065. }
  1066. void TouchButtonAccumulator::reset(InputDevice* device) {
  1067. mBtnTouch = device->isKeyPressed(BTN_TOUCH);
  1068. mBtnStylus = device->isKeyPressed(BTN_STYLUS);
  1069. mBtnStylus2 = device->isKeyPressed(BTN_STYLUS);
  1070. mBtnToolFinger = device->isKeyPressed(BTN_TOOL_FINGER);
  1071. mBtnToolPen = device->isKeyPressed(BTN_TOOL_PEN);
  1072. mBtnToolRubber = device->isKeyPressed(BTN_TOOL_RUBBER);
  1073. mBtnToolBrush = device->isKeyPressed(BTN_TOOL_BRUSH);
  1074. mBtnToolPencil = device->isKeyPressed(BTN_TOOL_PENCIL);
  1075. mBtnToolAirbrush = device->isKeyPressed(BTN_TOOL_AIRBRUSH);
  1076. mBtnToolMouse = device->isKeyPressed(BTN_TOOL_MOUSE);
  1077. mBtnToolLens = device->isKeyPressed(BTN_TOOL_LENS);
  1078. mBtnToolDoubleTap = device->isKeyPressed(BTN_TOOL_DOUBLETAP);
  1079. mBtnToolTripleTap = device->isKeyPressed(BTN_TOOL_TRIPLETAP);
  1080. mBtnToolQuadTap = device->isKeyPressed(BTN_TOOL_QUADTAP);
  1081. }
  1082. void TouchButtonAccumulator::clearButtons() {
  1083. mBtnTouch = 0;
  1084. mBtnStylus = 0;
  1085. mBtnStylus2 = 0;
  1086. mBtnToolFinger = 0;
  1087. mBtnToolPen = 0;
  1088. mBtnToolRubber = 0;
  1089. mBtnToolBrush = 0;
  1090. mBtnToolPencil = 0;
  1091. mBtnToolAirbrush = 0;
  1092. mBtnToolMouse = 0;
  1093. mBtnToolLens = 0;
  1094. mBtnToolDoubleTap = 0;
  1095. mBtnToolTripleTap = 0;
  1096. mBtnToolQuadTap = 0;
  1097. }
  1098. void TouchButtonAccumulator::process(const RawEvent* rawEvent) {
  1099. if (rawEvent->type == EV_KEY) {
  1100. switch (rawEvent->code) {
  1101. case BTN_TOUCH:
  1102. mBtnTouch = rawEvent->value;
  1103. break;
  1104. case BTN_STYLUS:
  1105. mBtnStylus = rawEvent->value;
  1106. break;
  1107. case BTN_STYLUS2:
  1108. mBtnStylus2 = rawEvent->value;
  1109. break;
  1110. case BTN_TOOL_FINGER:
  1111. mBtnToolFinger = rawEvent->value;
  1112. break;
  1113. case BTN_TOOL_PEN:
  1114. mBtnToolPen = rawEvent->value;
  1115. break;
  1116. case BTN_TOOL_RUBBER:
  1117. mBtnToolRubber = rawEvent->value;
  1118. break;
  1119. case BTN_TOOL_BRUSH:
  1120. mBtnToolBrush = rawEvent->value;
  1121. break;
  1122. case BTN_TOOL_PENCIL:
  1123. mBtnToolPencil = rawEvent->value;
  1124. break;
  1125. case BTN_TOOL_AIRBRUSH:
  1126. mBtnToolAirbrush = rawEvent->value;
  1127. break;
  1128. case BTN_TOOL_MOUSE:
  1129. mBtnToolMouse = rawEvent->value;
  1130. break;
  1131. case BTN_TOOL_LENS:
  1132. mBtnToolLens = rawEvent->value;
  1133. break;
  1134. case BTN_TOOL_DOUBLETAP:
  1135. mBtnToolDoubleTap = rawEvent->value;
  1136. break;
  1137. case BTN_TOOL_TRIPLETAP:
  1138. mBtnToolTripleTap = rawEvent->value;
  1139. break;
  1140. case BTN_TOOL_QUADTAP:
  1141. mBtnToolQuadTap = rawEvent->value;
  1142. break;
  1143. }
  1144. }
  1145. }
  1146. uint32_t TouchButtonAccumulator::getButtonState() const {
  1147. uint32_t result = 0;
  1148. if (mBtnStylus) {
  1149. result |= AMOTION_EVENT_BUTTON_SECONDARY;
  1150. }
  1151. if (mBtnStylus2) {
  1152. result |= AMOTION_EVENT_BUTTON_TERTIARY;
  1153. }
  1154. return result;
  1155. }
  1156. int32_t TouchButtonAccumulator::getToolType() const {
  1157. if (mBtnToolMouse || mBtnToolLens) {
  1158. return AMOTION_EVENT_TOOL_TYPE_MOUSE;
  1159. }
  1160. if (mBtnToolRubber) {
  1161. return AMOTION_EVENT_TOOL_TYPE_ERASER;
  1162. }
  1163. if (mBtnToolPen || mBtnToolBrush || mBtnToolPencil || mBtnToolAirbrush) {
  1164. return AMOTION_EVENT_TOOL_TYPE_STYLUS;
  1165. }
  1166. if (mBtnToolFinger || mBtnToolDoubleTap || mBtnToolTripleTap || mBtnToolQuadTap) {
  1167. return AMOTION_EVENT_TOOL_TYPE_FINGER;
  1168. }
  1169. return AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
  1170. }
  1171. bool TouchButtonAccumulator::isToolActive() const {
  1172. return mBtnTouch || mBtnToolFinger || mBtnToolPen || mBtnToolRubber
  1173. || mBtnToolBrush || mBtnToolPencil || mBtnToolAirbrush
  1174. || mBtnToolMouse || mBtnToolLens
  1175. || mBtnToolDoubleTap || mBtnToolTripleTap || mBtnToolQuadTap;
  1176. }
  1177. bool TouchButtonAccumulator::isHovering() const {
  1178. return mHaveBtnTouch && !mBtnTouch;
  1179. }
  1180. bool TouchButtonAccumulator::hasStylus() const {
  1181. return mHaveStylus;
  1182. }
  1183. // --- RawPointerAxes ---
  1184. RawPointerAxes::RawPointerAxes() {
  1185. clear();
  1186. }
  1187. void RawPointerAxes::clear() {
  1188. x.clear();
  1189. y.clear();
  1190. pressure.clear();
  1191. touchMajor.clear();
  1192. touchMinor.clear();
  1193. toolMajor.clear();
  1194. toolMinor.clear();
  1195. orientation.clear();
  1196. distance.clear();
  1197. tiltX.clear();
  1198. tiltY.clear();
  1199. trackingId.clear();
  1200. slot.clear();
  1201. }
  1202. // --- RawPointerData ---
  1203. RawPointerData::RawPointerData() {
  1204. clear();
  1205. }
  1206. void RawPointerData::clear() {
  1207. pointerCount = 0;
  1208. clearIdBits();
  1209. }
  1210. void RawPointerData::copyFrom(const RawPointerData& other) {
  1211. pointerCount = other.pointerCount;
  1212. hoveringIdBits = other.hoveringIdBits;
  1213. touchingIdBits = other.touchingIdBits;
  1214. for (uint32_t i = 0; i < pointerCount; i++) {
  1215. pointers[i] = other.pointers[i];
  1216. int id = pointers[i].id;
  1217. idToIndex[id] = other.idToIndex[id];
  1218. }
  1219. }
  1220. void RawPointerData::getCentroidOfTouchingPointers(float* outX, float* outY) const {
  1221. float x = 0, y = 0;
  1222. uint32_t count = touchingIdBits.count();
  1223. if (count) {
  1224. for (BitSet32 idBits(touchingIdBits); !idBits.isEmpty(); ) {
  1225. uint32_t id = idBits.clearFirstMarkedBit();
  1226. const Pointer& pointer = pointerForId(id);
  1227. x += pointer.x;
  1228. y += pointer.y;
  1229. }
  1230. x /= count;
  1231. y /= count;
  1232. }
  1233. *outX = x;
  1234. *outY = y;
  1235. }
  1236. // --- CookedPointerData ---
  1237. CookedPointerData::CookedPointerData() {
  1238. clear();
  1239. }
  1240. void CookedPointerData::clear() {
  1241. pointerCount = 0;
  1242. hoveringIdBits.clear();
  1243. touchingIdBits.clear();
  1244. }
  1245. void CookedPointerData::copyFrom(const CookedPointerData& other) {
  1246. pointerCount = other.pointerCount;
  1247. hoveringIdBits = other.hoveringIdBits;
  1248. touchingIdBits = other.touchingIdBits;
  1249. for (uint32_t i = 0; i < pointerCount; i++) {
  1250. pointerProperties[i].copyFrom(other.pointerProperties[i]);
  1251. pointerCoords[i].copyFrom(other.pointerCoords[i]);
  1252. int id = pointerProperties[i].id;
  1253. idToIndex[id] = other.idToIndex[id];
  1254. }
  1255. }
  1256. // --- SingleTouchMotionAccumulator ---
  1257. SingleTouchMotionAccumulator::SingleTouchMotionAccumulator() {
  1258. clearAbsoluteAxes();
  1259. }
  1260. void SingleTouchMotionAccumulator::reset(InputDevice* device) {
  1261. mAbsX = device->getAbsoluteAxisValue(ABS_X);
  1262. mAbsY = device->getAbsoluteAxisValue(ABS_Y);
  1263. mAbsPressure = device->getAbsoluteAxisValue(ABS_PRESSURE);
  1264. mAbsToolWidth = device->getAbsoluteAxisValue(ABS_TOOL_WIDTH);
  1265. mAbsDistance = device->getAbsoluteAxisValue(ABS_DISTANCE);
  1266. mAbsTiltX = device->getAbsoluteAxisValue(ABS_TILT_X);
  1267. mAbsTiltY = device->getAbsoluteAxisValue(ABS_TILT_Y);
  1268. }
  1269. void SingleTouchMotionAccumulator::clearAbsoluteAxes() {
  1270. mAbsX = 0;
  1271. mAbsY = 0;
  1272. mAbsPressure = 0;
  1273. mAbsToolWidth = 0;
  1274. mAbsDistance = 0;
  1275. mAbsTiltX = 0;
  1276. mAbsTiltY = 0;
  1277. }
  1278. void SingleTouchMotionAccumulator::process(const RawEvent* rawEvent) {
  1279. if (rawEvent->type == EV_ABS) {
  1280. switch (rawEvent->code) {
  1281. case ABS_X:
  1282. mAbsX = rawEvent->value;
  1283. break;
  1284. case ABS_Y:
  1285. mAbsY = rawEvent->value;
  1286. break;
  1287. case ABS_PRESSURE:
  1288. mAbsPressure = rawEvent->value;
  1289. break;
  1290. case ABS_TOOL_WIDTH:
  1291. mAbsToolWidth = rawEvent->value;
  1292. break;
  1293. case ABS_DISTANCE:
  1294. mAbsDistance = rawEvent->value;
  1295. break;
  1296. case ABS_TILT_X:
  1297. mAbsTiltX = rawEvent->value;
  1298. break;
  1299. case ABS_TILT_Y:
  1300. mAbsTiltY = rawEvent->value;
  1301. break;
  1302. }
  1303. }
  1304. }
  1305. // --- MultiTouchMotionAccumulator ---
  1306. MultiTouchMotionAccumulator::MultiTouchMotionAccumulator() :
  1307. mCurrentSlot(-1), mSlots(NULL), mSlotCount(0), mUsingSlotsProtocol(false),
  1308. mHaveStylus(false) {
  1309. }
  1310. MultiTouchMotionAccumulator::~MultiTouchMotionAccumulator() {
  1311. delete[] mSlots;
  1312. }
  1313. void MultiTouchMotionAccumulator::configure(InputDevice* device,
  1314. size_t slotCount, bool usingSlotsProtocol) {
  1315. mSlotCount = slotCount;
  1316. mUsingSlotsProtocol = usingSlotsProtocol;
  1317. mHaveStylus = device->hasAbsoluteAxis(ABS_MT_TOOL_TYPE);
  1318. delete[] mSlots;
  1319. mSlots = new Slot[slotCount];
  1320. }
  1321. void MultiTouchMotionAccumulator::reset(InputDevice* device) {
  1322. // Unfortunately there is no way to read the initial contents of the slots.
  1323. // So when we reset the accumulator, we must assume they are all zeroes.
  1324. if (mUsingSlotsProtocol) {
  1325. // Query the driver for the current slot index and use it as the initial slot
  1326. // before we start reading events from the device. It is possible that the
  1327. // current slot index will not be the same as it was when the first event was
  1328. // written into the evdev buffer, which means the input mapper could start
  1329. // out of sync with the initial state of the events in the evdev buffer.
  1330. // In the extremely unlikely case that this happens, the data from
  1331. // two slots will be confused until the next ABS_MT_SLOT event is received.
  1332. // This can cause the touch point to "jump", but at least there will be
  1333. // no stuck touches.
  1334. int32_t initialSlot;
  1335. status_t status = device->getEventHub()->getAbsoluteAxisValue(device->getId(),
  1336. ABS_MT_SLOT, &initialSlot);
  1337. if (status) {
  1338. ALOGD("Could not retrieve current multitouch slot index. status=%d", status);
  1339. initialSlot = -1;
  1340. }
  1341. clearSlots(initialSlot);
  1342. } else {
  1343. clearSlots(-1);
  1344. }
  1345. }
  1346. void MultiTouchMotionAccumulator::clearSlots(int32_t initialSlot) {
  1347. if (mSlots) {
  1348. for (size_t i = 0; i < mSlotCount; i++) {
  1349. mSlots[i].clear();
  1350. }
  1351. }
  1352. mCurrentSlot = initialSlot;
  1353. }
  1354. void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
  1355. if (rawEvent->type == EV_ABS) {
  1356. bool newSlot = false;
  1357. if (mUsingSlotsProtocol) {
  1358. if (rawEvent->code == ABS_MT_SLOT) {
  1359. mCurrentSlot = rawEvent->value;
  1360. newSlot = true;
  1361. }
  1362. } else if (mCurrentSlot < 0) {
  1363. mCurrentSlot = 0;
  1364. }
  1365. if (mCurrentSlot < 0 || size_t(mCurrentSlot) >= mSlotCount) {
  1366. #if DEBUG_POINTERS
  1367. if (newSlot) {
  1368. ALOGW("MultiTouch device emitted invalid slot index %d but it "
  1369. "should be between 0 and %d; ignoring this slot.",
  1370. mCurrentSlot, mSlotCount - 1);
  1371. }
  1372. #endif
  1373. } else {
  1374. Slot* slot = &mSlots[mCurrentSlot];
  1375. switch (rawEvent->code) {
  1376. case ABS_MT_POSITION_X:
  1377. slot->mInUse = true;
  1378. slot->mAbsMTPositionX = rawEvent->value;
  1379. break;
  1380. case ABS_MT_POSITION_Y:
  1381. slot->mInUse = true;
  1382. slot->mAbsMTPositionY = rawEvent->value;
  1383. break;
  1384. case ABS_MT_TOUCH_MAJOR:
  1385. slot->mInUse = true;
  1386. slot->mAbsMTTouchMajor = rawEvent->value;
  1387. break;
  1388. case ABS_MT_TOUCH_MINOR:
  1389. slot->mInUse = true;
  1390. slot->mAbsMTTouchMinor = rawEvent->value;
  1391. slot->mHaveAbsMTTouchMinor = true;
  1392. break;
  1393. case ABS_MT_WIDTH_MAJOR:
  1394. slot->mInUse = true;
  1395. slot->mAbsMTWidthMajor = rawEvent->value;
  1396. break;
  1397. case ABS_MT_WIDTH_MINOR:
  1398. slot->mInUse = true;
  1399. slot->mAbsMTWidthMinor = rawEvent->value;
  1400. slot->mHaveAbsMTWidthMinor = true;
  1401. break;
  1402. case ABS_MT_ORIENTATION:
  1403. slot->mInUse = true;
  1404. slot->mAbsMTOrientation = rawEvent->value;
  1405. break;
  1406. case ABS_MT_TRACKING_ID:
  1407. if (mUsingSlotsProtocol && rawEvent->value < 0) {
  1408. // The slot is no longer in use but it retains its previous contents,
  1409. // which may be reused for subsequent touches.
  1410. slot->mInUse = false;
  1411. } else {
  1412. slot->mInUse = true;
  1413. slot->mAbsMTTrackingId = rawEvent->value;
  1414. }
  1415. break;
  1416. case ABS_MT_PRESSURE:
  1417. slot->mInUse = true;
  1418. slot->mAbsMTPressure = rawEvent->value;
  1419. break;
  1420. case ABS_MT_DISTANCE:
  1421. slot->mInUse = true;
  1422. slot->mAbsMTDistance = rawEvent->value;
  1423. break;
  1424. case ABS_MT_TOOL_TYPE:
  1425. slot->mInUse = true;
  1426. slot->mAbsMTToolType = rawEvent->value;
  1427. slot->mHaveAbsMTToolType = true;
  1428. break;
  1429. }
  1430. }
  1431. } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_MT_REPORT) {
  1432. // MultiTouch Sync: The driver has returned all data for *one* of the pointers.
  1433. mCurrentSlot += 1;
  1434. }
  1435. }
  1436. void MultiTouchMotionAccumulator::finishSync() {
  1437. if (!mUsingSlotsProtocol) {
  1438. clearSlots(-1);
  1439. }
  1440. }
  1441. bool MultiTouchMotionAccumulator::hasStylus() const {
  1442. return mHaveStylus;
  1443. }
  1444. // --- MultiTouchMotionAccumulator::Slot ---
  1445. MultiTouchMotionAccumulator::Slot::Slot() {
  1446. clear();
  1447. }
  1448. void MultiTouchMotionAccumulator::Slot::clear() {
  1449. mInUse = false;
  1450. mHaveAbsMTTouchMinor = false;
  1451. mHaveAbsMTWidthMinor = false;
  1452. mHaveAbsMTToolType = false;
  1453. mAbsMTPositionX = 0;
  1454. mAbsMTPositionY = 0;
  1455. mAbsMTTouchMajor = 0;
  1456. mAbsMTTouchMinor = 0;
  1457. mAbsMTWidthMajor = 0;
  1458. mAbsMTWidthMinor = 0;
  1459. mAbsMTOrientation = 0;
  1460. mAbsMTTrackingId = -1;
  1461. mAbsMTPressure = 0;
  1462. mAbsMTDistance = 0;
  1463. mAbsMTToolType = 0;
  1464. }
  1465. int32_t MultiTouchMotionAccumulator::Slot::getToolType() const {
  1466. if (mHaveAbsMTToolType) {
  1467. switch (mAbsMTToolType) {
  1468. case MT_TOOL_FINGER:
  1469. return AMOTION_EVENT_TOOL_TYPE_FINGER;
  1470. case MT_TOOL_PEN:
  1471. return AMOTION_EVENT_TOOL_TYPE_STYLUS;
  1472. }
  1473. }
  1474. return AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
  1475. }
  1476. // --- InputMapper ---
  1477. InputMapper::InputMapper(InputDevice* device) :
  1478. mDevice(device), mContext(device->getContext()) {
  1479. }
  1480. InputMapper::~InputMapper() {
  1481. }
  1482. void InputMapper::populateDeviceInfo(InputDeviceInfo* info) {
  1483. info->addSource(getSources());
  1484. }
  1485. void InputMapper::dump(String8& dump) {
  1486. }
  1487. void InputMapper::configure(nsecs_t when,
  1488. const InputReaderConfiguration* config, uint32_t changes) {
  1489. }
  1490. void InputMapper::reset(nsecs_t when) {
  1491. }
  1492. void InputMapper::timeoutExpired(nsecs_t when) {
  1493. }
  1494. int32_t InputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
  1495. return AKEY_STATE_UNKNOWN;
  1496. }
  1497. int32_t InputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
  1498. return AKEY_STATE_UNKNOWN;
  1499. }
  1500. int32_t InputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
  1501. return AKEY_STATE_UNKNOWN;
  1502. }
  1503. bool InputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
  1504. const int32_t* keyCodes, uint8_t* outFlags) {
  1505. return false;
  1506. }
  1507. void InputMapper::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
  1508. int32_t token) {
  1509. }
  1510. void InputMapper::cancelVibrate(int32_t token) {
  1511. }
  1512. int32_t InputMapper::getMetaState() {
  1513. return 0;
  1514. }
  1515. void InputMapper::fadePointer() {
  1516. }
  1517. status_t InputMapper::getAbsoluteAxisInfo(int32_t axis, RawAbsoluteAxisInfo* axisInfo) {
  1518. return getEventHub()->getAbsoluteAxisInfo(getDeviceId(), axis, axisInfo);
  1519. }
  1520. void InputMapper::bumpGeneration() {
  1521. mDevice->bumpGeneration();
  1522. }
  1523. void InputMapper::dumpRawAbsoluteAxisInfo(String8& dump,
  1524. const RawAbsoluteAxisInfo& axis, const char* name) {
  1525. if (axis.valid) {
  1526. dump.appendFormat(INDENT4 "%s: min=%d, max=%d, flat=%d, fuzz=%d, resolution=%d\n",
  1527. name, axis.minValue, axis.maxValue, axis.flat, axis.fuzz, axis.resolution);
  1528. } else {
  1529. dump.appendFormat(INDENT4 "%s: unknown range\n", name);
  1530. }
  1531. }
  1532. // --- SwitchInputMapper ---
  1533. SwitchInputMapper::SwitchInputMapper(InputDevice* device) :
  1534. InputMapper(device), mUpdatedSwitchValues(0), mUpdatedSwitchMask(0) {
  1535. }
  1536. SwitchInputMapper::~SwitchInputMapper() {
  1537. }
  1538. uint32_t SwitchInputMapper::getSources() {
  1539. return AINPUT_SOURCE_SWITCH;
  1540. }
  1541. void SwitchInputMapper::process(const RawEvent* rawEvent) {
  1542. switch (rawEvent->type) {
  1543. case EV_SW:
  1544. processSwitch(rawEvent->code, rawEvent->value);
  1545. break;
  1546. case EV_SYN:
  1547. if (rawEvent->code == SYN_REPORT) {
  1548. sync(rawEvent->when);
  1549. }
  1550. }
  1551. }
  1552. void SwitchInputMapper::processSwitch(int32_t switchCode, int32_t switchValue) {
  1553. if (switchCode >= 0 && switchCode < 32) {
  1554. if (switchValue) {
  1555. mUpdatedSwitchValues |= 1 << switchCode;
  1556. }
  1557. mUpdatedSwitchMask |= 1 << switchCode;
  1558. }
  1559. }
  1560. void SwitchInputMapper::sync(nsecs_t when) {
  1561. if (mUpdatedSwitchMask) {
  1562. NotifySwitchArgs args(when, 0, mUpdatedSwitchValues, mUpdatedSwitchMask);
  1563. getListener()->notifySwitch(&args);
  1564. mUpdatedSwitchValues = 0;
  1565. mUpdatedSwitchMask = 0;
  1566. }
  1567. }
  1568. int32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
  1569. return getEventHub()->getSwitchState(getDeviceId(), switchCode);
  1570. }
  1571. // --- VibratorInputMapper ---
  1572. VibratorInputMapper::VibratorInputMapper(InputDevice* device) :
  1573. InputMapper(device), mVibrating(false) {
  1574. }
  1575. VibratorInputMapper::~VibratorInputMapper() {
  1576. }
  1577. uint32_t VibratorInputMapper::getSources() {
  1578. return 0;
  1579. }
  1580. void VibratorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
  1581. InputMapper::populateDeviceInfo(info);
  1582. info->setVibrator(true);
  1583. }
  1584. void VibratorInputMapper::process(const RawEvent* rawEvent) {
  1585. // TODO: Handle FF_STATUS, although it does not seem to be widely supported.
  1586. }
  1587. void VibratorInputMapper::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
  1588. int32_t token) {
  1589. #if DEBUG_VIBRATOR
  1590. String8 patternStr;
  1591. for (size_t i = 0; i < patternSize; i++) {
  1592. if (i != 0) {
  1593. patternStr.append(", ");
  1594. }
  1595. patternStr.appendFormat("%lld", pattern[i]);
  1596. }
  1597. ALOGD("vibrate: deviceId=%d, pattern=[%s], repeat=%ld, token=%d",
  1598. getDeviceId(), patternStr.string(), repeat, token);
  1599. #endif
  1600. mVibrating = true;
  1601. memcpy(mPattern, pattern, patternSize * sizeof(nsecs_t));
  1602. mPatternSize = patternSize;
  1603. mRepeat = repeat;
  1604. mToken = token;
  1605. mIndex = -1;
  1606. nextStep();
  1607. }
  1608. void VibratorInputMapper::cancelVibrate(int32_t token) {
  1609. #if DEBUG_VIBRATOR
  1610. ALOGD("cancelVibrate: deviceId=%d, token=%d", getDeviceId(), token);
  1611. #endif
  1612. if (mVibrating && mToken == token) {
  1613. stopVibrating();
  1614. }
  1615. }
  1616. void VibratorInputMapper::timeoutExpired(nsecs_t when) {
  1617. if (mVibrating) {
  1618. if (when >= mNextStepTime) {
  1619. nextStep();
  1620. } else {
  1621. getContext()->requestTimeoutAtTime(mNextStepTime);
  1622. }
  1623. }
  1624. }
  1625. void VibratorInputMapper::nextStep() {
  1626. mIndex += 1;
  1627. if (size_t(mIndex) >= mPatternSize) {
  1628. if (mRepeat < 0) {
  1629. // We are done.
  1630. stopVibrating();
  1631. return;
  1632. }
  1633. mIndex = mRepeat;
  1634. }
  1635. bool vibratorOn = mIndex & 1;
  1636. nsecs_t duration = mPattern[mIndex];
  1637. if (vibratorOn) {
  1638. #if DEBUG_VIBRATOR
  1639. ALOGD("nextStep: sending vibrate deviceId=%d, duration=%lld",
  1640. getDeviceId(), duration);
  1641. #endif
  1642. getEventHub()->vibrate(getDeviceId(), duration);
  1643. } else {
  1644. #if DEBUG_VIBRATOR
  1645. ALOGD("nextStep: sending cancel vibrate deviceId=%d", getDeviceId());
  1646. #endif
  1647. getEventHub()->cancelVibrate(getDeviceId());
  1648. }
  1649. nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
  1650. mNextStepTime = now + duration;
  1651. getContext()->requestTimeoutAtTime(mNextStepTime);
  1652. #if DEBUG_VIBRATOR
  1653. ALOGD("nextStep: scheduled timeout in %0.3fms", duration * 0.000001f);
  1654. #endif
  1655. }
  1656. void VibratorInputMapper::stopVibrating() {
  1657. mVibrating = false;
  1658. #if DEBUG_VIBRATOR
  1659. ALOGD("stopVibrating: sending cancel vibrate deviceId=%d", getDeviceId());
  1660. #endif
  1661. getEventHub()->cancelVibrate(getDeviceId());
  1662. }
  1663. void VibratorInputMapper::dump(String8& dump) {
  1664. dump.append(INDENT2 "Vibrator Input Mapper:\n");
  1665. dump.appendFormat(INDENT3 "Vibrating: %s\n", toString(mVibrating));
  1666. }
  1667. // --- KeyboardInputMapper ---
  1668. KeyboardInputMapper::KeyboardInputMapper(InputDevice* device,
  1669. uint32_t source, int32_t keyboardType) :
  1670. InputMapper(device), mSource(source),
  1671. mKeyboardType(keyboardType) {
  1672. }
  1673. KeyboardInputMapper::~KeyboardInputMapper() {
  1674. }
  1675. uint32_t KeyboardInputMapper::getSources() {
  1676. return mSource;
  1677. }
  1678. void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
  1679. InputMapper::populateDeviceInfo(info);
  1680. info->setKeyboardType(mKeyboardType);
  1681. info->setKeyCharacterMap(getEventHub()->getKeyCharacterMap(getDeviceId()));
  1682. }
  1683. void KeyboardInputMapper::dump(String8& dump) {
  1684. dump.append(INDENT2 "Keyboard Input Mapper:\n");
  1685. dumpParameters(dump);
  1686. dump.appendFormat(INDENT3 "KeyboardType: %d\n", mKeyboardType);
  1687. dump.appendFormat(INDENT3 "Orientation: %d\n", mOrientation);
  1688. dump.appendFormat(INDENT3 "KeyDowns: %zu keys currently down\n", mKeyDowns.size());
  1689. dump.appendFormat(INDENT3 "MetaState: 0x%0x\n", mMetaState);
  1690. dump.appendFormat(INDENT3 "DownTime: %lld\n", mDownTime);
  1691. }
  1692. void KeyboardInputMapper::configure(nsecs_t when,
  1693. const InputReaderConfiguration* config, uint32_t changes) {
  1694. InputMapper::configure(when, config, changes);
  1695. if (!changes) { // first time only
  1696. // Configure basic parameters.
  1697. configureParameters();
  1698. }
  1699. if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
  1700. if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
  1701. DisplayViewport v;
  1702. if (config->getDisplayInfo(false /*external*/, &v)) {
  1703. mOrientation = v.orientation;
  1704. } else {
  1705. mOrientation = DISPLAY_ORIENTATION_0;
  1706. }
  1707. } else {
  1708. mOrientation = DISPLAY_ORIENTATION_0;
  1709. }
  1710. }
  1711. }
  1712. void KeyboardInputMapper::configureParameters() {
  1713. mParameters.orientationAware = false;
  1714. getDevice()->getConfiguration().tryGetProperty(String8("keyboard.orientationAware"),
  1715. mParameters.orientationAware);
  1716. mParameters.hasAssociatedDisplay = false;
  1717. if (mParameters.orientationAware) {
  1718. mParameters.hasAssociatedDisplay = true;
  1719. }
  1720. }
  1721. void KeyboardInputMapper::dumpParameters(String8& dump) {
  1722. dump.append(INDENT3 "Parameters:\n");
  1723. dump.appendFormat(INDENT4 "HasAssociatedDisplay: %s\n",
  1724. toString(mParameters.hasAssociatedDisplay));
  1725. dump.appendFormat(INDENT4 "OrientationAware: %s\n",
  1726. toString(mParameters.orientationAware));
  1727. }
  1728. void KeyboardInputMapper::reset(nsecs_t when) {
  1729. mMetaState = AMETA_NONE;
  1730. mDownTime = 0;
  1731. mKeyDowns.clear();
  1732. mCurrentHidUsage = 0;
  1733. resetLedState();
  1734. InputMapper::reset(when);
  1735. }
  1736. void KeyboardInputMapper::process(const RawEvent* rawEvent) {
  1737. switch (rawEvent->type) {
  1738. case EV_KEY: {
  1739. int32_t scanCode = rawEvent->code;
  1740. int32_t usageCode = mCurrentHidUsage;
  1741. mCurrentHidUsage = 0;
  1742. if (isKeyboardOrGamepadKey(scanCode)) {
  1743. int32_t keyCode;
  1744. uint32_t flags;
  1745. if (getEventHub()->mapKey(getDeviceId(), scanCode, usageCode, &keyCode, &flags)) {
  1746. keyCode = AKEYCODE_UNKNOWN;
  1747. flags = 0;
  1748. }
  1749. processKey(rawEvent->when, rawEvent->value != 0, keyCode, scanCode, flags);
  1750. }
  1751. break;
  1752. }
  1753. case EV_MSC: {
  1754. if (rawEvent->code == MSC_SCAN) {
  1755. mCurrentHidUsage = rawEvent->value;
  1756. }
  1757. break;
  1758. }
  1759. case EV_SYN: {
  1760. if (rawEvent->code == SYN_REPORT) {
  1761. mCurrentHidUsage = 0;
  1762. }
  1763. }
  1764. }
  1765. }
  1766. bool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) {
  1767. return scanCode < BTN_MOUSE
  1768. || scanCode >= KEY_OK
  1769. || (scanCode >= BTN_MISC && scanCode < BTN_MOUSE)
  1770. || (scanCode >= BTN_JOYSTICK && scanCode < BTN_DIGI);
  1771. }
  1772. void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
  1773. int32_t scanCode, uint32_t policyFlags) {
  1774. if (down) {
  1775. // Rotate key codes according to orientation if needed.
  1776. if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
  1777. keyCode = rotateKeyCode(keyCode, mOrientation);
  1778. }
  1779. // Add key down.
  1780. ssize_t keyDownIndex = findKeyDown(scanCode);
  1781. if (keyDownIndex >= 0) {
  1782. // key repeat, be sure to use same keycode as before in case of rotation
  1783. keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
  1784. } else {
  1785. // key down
  1786. if ((policyFlags & POLICY_FLAG_VIRTUAL)
  1787. && mContext->shouldDropVirtualKey(when,
  1788. getDevice(), keyCode, scanCode)) {
  1789. return;
  1790. }
  1791. mKeyDowns.push();
  1792. KeyDown& keyDown = mKeyDowns.editTop();
  1793. keyDown.keyCode = keyCode;
  1794. keyDown.scanCode = scanCode;
  1795. }
  1796. mDownTime = when;
  1797. } else {
  1798. // Remove key down.
  1799. ssize_t keyDownIndex = findKeyDown(scanCode);
  1800. if (keyDownIndex >= 0) {
  1801. // key up, be sure to use same keycode as before in case of rotation
  1802. keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
  1803. mKeyDowns.removeAt(size_t(keyDownIndex));
  1804. } else {
  1805. // key was not actually down
  1806. ALOGI("Dropping key up from device %s because the key was not down. "
  1807. "keyCode=%d, scanCode=%d",
  1808. getDeviceName().string(), keyCode, scanCode);
  1809. return;
  1810. }
  1811. }
  1812. int32_t oldMetaState = mMetaState;
  1813. int32_t newMetaState = updateMetaState(keyCode, down, oldMetaState);
  1814. bool metaStateChanged = oldMetaState != newMetaState;
  1815. if (metaStateChanged) {
  1816. mMetaState = newMetaState;
  1817. updateLedState(false);
  1818. }
  1819. nsecs_t downTime = mDownTime;
  1820. // Key down on external an keyboard should wake the device.
  1821. // We don't do this for internal keyboards to prevent them from waking up in your pocket.
  1822. // For internal keyboards, the key layout file should specify the policy flags for
  1823. // each wake key individually.
  1824. // TODO: Use the input device configuration to control this behavior more finely.
  1825. if (down && getDevice()->isExternal()
  1826. && !(policyFlags & (POLICY_FLAG_WAKE | POLICY_FLAG_WAKE_DROPPED))) {
  1827. policyFlags |= POLICY_FLAG_WAKE_DROPPED;
  1828. }
  1829. if (metaStateChanged) {
  1830. getContext()->updateGlobalMetaState();
  1831. }
  1832. if (down && !isMetaKey(keyCode)) {
  1833. getContext()->fadePointer();
  1834. }
  1835. NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
  1836. down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
  1837. AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
  1838. getListener()->notifyKey(&args);
  1839. }
  1840. ssize_t KeyboardInputMapper::findKeyDown(int32_t scanCode) {
  1841. size_t n = mKeyDowns.size();
  1842. for (size_t i = 0; i < n; i++) {
  1843. if (mKeyDowns[i].scanCode == scanCode) {
  1844. return i;
  1845. }
  1846. }
  1847. return -1;
  1848. }
  1849. int32_t KeyboardInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
  1850. return getEventHub()->getKeyCodeState(getDeviceId(), keyCode);
  1851. }
  1852. int32_t KeyboardInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
  1853. return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
  1854. }
  1855. bool KeyboardInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
  1856. const int32_t* keyCodes, uint8_t* outFlags) {
  1857. return getEventHub()->markSupportedKeyCodes(getDeviceId(), numCodes, keyCodes, outFlags);
  1858. }
  1859. int32_t KeyboardInputMapper::getMetaState() {
  1860. return mMetaState;
  1861. }
  1862. void KeyboardInputMapper::resetLedState() {
  1863. initializeLedState(mCapsLockLedState, LED_CAPSL);
  1864. initializeLedState(mNumLockLedState, LED_NUML);
  1865. initializeLedState(mScrollLockLedState, LED_SCROLLL);
  1866. updateLedState(true);
  1867. }
  1868. void KeyboardInputMapper::initializeLedState(LedState& ledState, int32_t led) {
  1869. ledState.avail = getEventHub()->hasLed(getDeviceId(), led);
  1870. ledState.on = false;
  1871. }
  1872. void KeyboardInputMapper::updateLedState(bool reset) {
  1873. updateLedStateForModifier(mCapsLockLedState, LED_CAPSL,
  1874. AMETA_CAPS_LOCK_ON, reset);
  1875. updateLedStateForModifier(mNumLockLedState, LED_NUML,
  1876. AMETA_NUM_LOCK_ON, reset);
  1877. updateLedStateForModifier(mScrollLockLedState, LED_SCROLLL,
  1878. AMETA_SCROLL_LOCK_ON, reset);
  1879. }
  1880. void KeyboardInputMapper::updateLedStateForModifier(LedState& ledState,
  1881. int32_t led, int32_t modifier, bool reset) {
  1882. if (ledState.avail) {
  1883. bool desiredState = (mMetaState & modifier) != 0;
  1884. if (reset || ledState.on != desiredState) {
  1885. getEventHub()->setLedState(getDeviceId(), led, desiredState);
  1886. ledState.on = desiredState;
  1887. }
  1888. }
  1889. }
  1890. // --- CursorInputMapper ---
  1891. CursorInputMapper::CursorInputMapper(InputDevice* device) :
  1892. InputMapper(device) {
  1893. }
  1894. CursorInputMapper::~CursorInputMapper() {
  1895. }
  1896. uint32_t CursorInputMapper::getSources() {
  1897. return mSource;
  1898. }
  1899. void CursorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
  1900. InputMapper::populateDeviceInfo(info);
  1901. if (mParameters.mode == Parameters::MODE_POINTER) {
  1902. float minX, minY, maxX, maxY;
  1903. if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
  1904. info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, minX, maxX, 0.0f, 0.0f, 0.0f);
  1905. info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, minY, maxY, 0.0f, 0.0f, 0.0f);
  1906. }
  1907. } else {
  1908. info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, -1.0f, 1.0f, 0.0f, mXScale, 0.0f);
  1909. info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, -1.0f, 1.0f, 0.0f, mYScale, 0.0f);
  1910. }
  1911. info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mSource, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
  1912. if (mCursorScrollAccumulator.haveRelativeVWheel()) {
  1913. info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
  1914. }
  1915. if (mCursorScrollAccumulator.haveRelativeHWheel()) {
  1916. info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
  1917. }
  1918. }
  1919. void CursorInputMapper::dump(String8& dump) {
  1920. dump.append(INDENT2 "Cursor Input Mapper:\n");
  1921. dumpParameters(dump);
  1922. dump.appendFormat(INDENT3 "XScale: %0.3f\n", mXScale);
  1923. dump.appendFormat(INDENT3 "YScale: %0.3f\n", mYScale);
  1924. dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision);
  1925. dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision);
  1926. dump.appendFormat(INDENT3 "HaveVWheel: %s\n",
  1927. toString(mCursorScrollAccumulator.haveRelativeVWheel()));
  1928. dump.appendFormat(INDENT3 "HaveHWheel: %s\n",
  1929. toString(mCursorScrollAccumulator.haveRelativeHWheel()));
  1930. dump.appendFormat(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale);
  1931. dump.appendFormat(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale);
  1932. dump.appendFormat(INDENT3 "Orientation: %d\n", mOrientation);
  1933. dump.appendFormat(INDENT3 "ButtonState: 0x%08x\n", mButtonState);
  1934. dump.appendFormat(INDENT3 "Down: %s\n", toString(isPointerDown(mButtonState)));
  1935. dump.appendFormat(INDENT3 "DownTime: %lld\n", mDownTime);
  1936. }
  1937. void CursorInputMapper::configure(nsecs_t when,
  1938. const InputReaderConfiguration* config, uint32_t changes) {
  1939. InputMapper::configure(when, config, changes);
  1940. if (!changes) { // first time only
  1941. mCursorScrollAccumulator.configure(getDevice());
  1942. // Configure basic parameters.
  1943. configureParameters();
  1944. // Configure device mode.
  1945. switch (mParameters.mode) {
  1946. case Parameters::MODE_POINTER:
  1947. mSource = AINPUT_SOURCE_MOUSE;
  1948. mXPrecision = 1.0f;
  1949. mYPrecision = 1.0f;
  1950. mXScale = 1.0f;
  1951. mYScale = 1.0f;
  1952. mPointerController = getPolicy()->obtainPointerController(getDeviceId());
  1953. break;
  1954. case Parameters::MODE_NAVIGATION:
  1955. mSource = AINPUT_SOURCE_TRACKBALL;
  1956. mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
  1957. mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
  1958. mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
  1959. mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
  1960. break;
  1961. }
  1962. mVWheelScale = 1.0f;
  1963. mHWheelScale = 1.0f;
  1964. }
  1965. if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
  1966. mPointerVelocityControl.setParameters(config->pointerVelocityControlParameters);
  1967. mWheelXVelocityControl.setParameters(config->wheelVelocityControlParameters);
  1968. mWheelYVelocityControl.setParameters(config->wheelVelocityControlParameters);
  1969. }
  1970. if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
  1971. if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
  1972. DisplayViewport v;
  1973. if (config->getDisplayInfo(false /*external*/, &v)) {
  1974. mOrientation = v.orientation;
  1975. } else {
  1976. mOrientation = DISPLAY_ORIENTATION_0;
  1977. }
  1978. } else {
  1979. mOrientation = DISPLAY_ORIENTATION_0;
  1980. }
  1981. bumpGeneration();
  1982. }
  1983. }
  1984. void CursorInputMapper::configureParameters() {
  1985. mParameters.mode = Parameters::MODE_POINTER;
  1986. String8 cursorModeString;
  1987. if (getDevice()->getConfiguration().tryGetProperty(String8("cursor.mode"), cursorModeString)) {
  1988. if (cursorModeString == "navigation") {
  1989. mParameters.mode = Parameters::MODE_NAVIGATION;
  1990. } else if (cursorModeString != "pointer" && cursorModeString != "default") {
  1991. ALOGW("Invalid value for cursor.mode: '%s'", cursorModeString.string());
  1992. }
  1993. }
  1994. mParameters.orientationAware = false;
  1995. getDevice()->getConfiguration().tryGetProperty(String8("cursor.orientationAware"),
  1996. mParameters.orientationAware);
  1997. mParameters.hasAssociatedDisplay = false;
  1998. if (mParameters.mode == Parameters::MODE_POINTER || mParameters.orientationAware) {
  1999. mParameters.hasAssociatedDisplay = true;
  2000. }
  2001. }
  2002. void CursorInputMapper::dumpParameters(String8& dump) {
  2003. dump.append(INDENT3 "Parameters:\n");
  2004. dump.appendFormat(INDENT4 "HasAssociatedDisplay: %s\n",
  2005. toString(mParameters.hasAssociatedDisplay));
  2006. switch (mParameters.mode) {
  2007. case Parameters::MODE_POINTER:
  2008. dump.append(INDENT4 "Mode: pointer\n");
  2009. break;
  2010. case Parameters::MODE_NAVIGATION:
  2011. dump.append(INDENT4 "Mode: navigation\n");
  2012. break;
  2013. default:
  2014. ALOG_ASSERT(false);
  2015. }
  2016. dump.appendFormat(INDENT4 "OrientationAware: %s\n",
  2017. toString(mParameters.orientationAware));
  2018. }
  2019. void CursorInputMapper::reset(nsecs_t when) {
  2020. mButtonState = 0;
  2021. mDownTime = 0;
  2022. mPointerVelocityControl.reset();
  2023. mWheelXVelocityControl.reset();
  2024. mWheelYVelocityControl.reset();
  2025. mCursorButtonAccumulator.reset(getDevice());
  2026. mCursorMotionAccumulator.reset(getDevice());
  2027. mCursorScrollAccumulator.reset(getDevice());
  2028. InputMapper::reset(when);
  2029. }
  2030. void CursorInputMapper::process(const RawEvent* rawEvent) {
  2031. mCursorButtonAccumulator.process(rawEvent);
  2032. mCursorMotionAccumulator.process(rawEvent);
  2033. mCursorScrollAccumulator.process(rawEvent);
  2034. if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
  2035. sync(rawEvent->when);
  2036. }
  2037. }
  2038. void CursorInputMapper::sync(nsecs_t when) {
  2039. int32_t lastButtonState = mButtonState;
  2040. int32_t currentButtonState = mCursorButtonAccumulator.getButtonState();
  2041. mButtonState = currentButtonState;
  2042. bool wasDown = isPointerDown(lastButtonState);
  2043. bool down = isPointerDown(currentButtonState);
  2044. bool downChanged;
  2045. if (!wasDown && down) {
  2046. mDownTime = when;
  2047. downChanged = true;
  2048. } else if (wasDown && !down) {
  2049. downChanged = true;
  2050. } else {
  2051. downChanged = false;
  2052. }
  2053. nsecs_t downTime = mDownTime;
  2054. bool buttonsChanged = currentButtonState != lastButtonState;
  2055. bool buttonsPressed = currentButtonState & ~lastButtonState;
  2056. float deltaX = mCursorMotionAccumulator.getRelativeX() * mXScale;
  2057. float deltaY = mCursorMotionAccumulator.getRelativeY() * mYScale;
  2058. bool moved = deltaX != 0 || deltaY != 0;
  2059. // Rotate delta according to orientation if needed.
  2060. if (mParameters.orientationAware && mParameters.hasAssociatedDisplay
  2061. && (deltaX != 0.0f || deltaY != 0.0f)) {
  2062. rotateDelta(mOrientation, &deltaX, &deltaY);
  2063. }
  2064. // Move the pointer.
  2065. PointerProperties pointerProperties;
  2066. pointerProperties.clear();
  2067. pointerProperties.id = 0;
  2068. pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;
  2069. PointerCoords pointerCoords;
  2070. pointerCoords.clear();
  2071. float vscroll = mCursorScrollAccumulator.getRelativeVWheel();
  2072. float hscroll = mCursorScrollAccumulator.getRelativeHWheel();
  2073. bool scrolled = vscroll != 0 || hscroll != 0;
  2074. mWheelYVelocityControl.move(when, NULL, &vscroll);
  2075. mWheelXVelocityControl.move(when, &hscroll, NULL);
  2076. mPointerVelocityControl.move(when, &deltaX, &deltaY);
  2077. int32_t displayId;
  2078. if (mPointerController != NULL) {
  2079. if (moved || scrolled || buttonsChanged) {
  2080. mPointerController->setPresentation(
  2081. PointerControllerInterface::PRESENTATION_POINTER);
  2082. if (moved) {
  2083. mPointerController->move(deltaX, deltaY);
  2084. }
  2085. if (buttonsChanged) {
  2086. mPointerController->setButtonState(currentButtonState);
  2087. }
  2088. mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
  2089. }
  2090. float x, y;
  2091. mPointerController->getPosition(&x, &y);
  2092. pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
  2093. pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
  2094. displayId = ADISPLAY_ID_DEFAULT;
  2095. } else {
  2096. pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
  2097. pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
  2098. displayId = ADISPLAY_ID_NONE;
  2099. }
  2100. pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);
  2101. // Moving an external trackball or mouse should wake the device.
  2102. // We don't do this for internal cursor devices to prevent them from waking up
  2103. // the device in your pocket.
  2104. // TODO: Use the input device configuration to control this behavior more finely.
  2105. uint32_t policyFlags = 0;
  2106. if ((buttonsPressed || moved || scrolled) && getDevice()->isExternal()) {
  2107. policyFlags |= POLICY_FLAG_WAKE_DROPPED;
  2108. }
  2109. // Synthesize key down from buttons if needed.
  2110. synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mSource,
  2111. policyFlags, lastButtonState, currentButtonState);
  2112. // Send motion event.
  2113. if (downChanged || moved || scrolled || buttonsChanged) {
  2114. int32_t metaState = mContext->getGlobalMetaState();
  2115. int32_t motionEventAction;
  2116. if (downChanged) {
  2117. motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
  2118. } else if (down || mPointerController == NULL) {
  2119. motionEventAction = AMOTION_EVENT_ACTION_MOVE;
  2120. } else {
  2121. motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
  2122. }
  2123. NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
  2124. motionEventAction, 0, metaState, currentButtonState, 0,
  2125. displayId, 1, &pointerProperties, &pointerCoords,
  2126. mXPrecision, mYPrecision, downTime);
  2127. getListener()->notifyMotion(&args);
  2128. // Send hover move after UP to tell the application that the mouse is hovering now.
  2129. if (motionEventAction == AMOTION_EVENT_ACTION_UP
  2130. && mPointerController != NULL) {
  2131. NotifyMotionArgs hoverArgs(when, getDeviceId(), mSource, policyFlags,
  2132. AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
  2133. metaState, currentButtonState, AMOTION_EVENT_EDGE_FLAG_NONE,
  2134. displayId, 1, &pointerProperties, &pointerCoords,
  2135. mXPrecision, mYPrecision, downTime);
  2136. getListener()->notifyMotion(&hoverArgs);
  2137. }
  2138. // Send scroll events.
  2139. if (scrolled) {
  2140. pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
  2141. pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
  2142. NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, policyFlags,
  2143. AMOTION_EVENT_ACTION_SCROLL, 0, metaState, currentButtonState,
  2144. AMOTION_EVENT_EDGE_FLAG_NONE,
  2145. displayId, 1, &pointerProperties, &pointerCoords,
  2146. mXPrecision, mYPrecision, downTime);
  2147. getListener()->notifyMotion(&scrollArgs);
  2148. }
  2149. }
  2150. // Synthesize key up from buttons if needed.
  2151. synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mSource,
  2152. policyFlags, lastButtonState, currentButtonState);
  2153. mCursorMotionAccumulator.finishSync();
  2154. mCursorScrollAccumulator.finishSync();
  2155. }
  2156. int32_t CursorInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
  2157. if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) {
  2158. return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
  2159. } else {
  2160. return AKEY_STATE_UNKNOWN;
  2161. }
  2162. }
  2163. void CursorInputMapper::fadePointer() {
  2164. if (mPointerController != NULL) {
  2165. mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
  2166. }
  2167. }
  2168. // --- TouchInputMapper ---
  2169. TouchInputMapper::TouchInputMapper(InputDevice* device) :
  2170. InputMapper(device),
  2171. mSource(0), mDeviceMode(DEVICE_MODE_DISABLED),
  2172. mSurfaceWidth(-1), mSurfaceHeight(-1), mSurfaceLeft(0), mSurfaceTop(0),
  2173. mSurfaceOrientation(DISPLAY_ORIENTATION_0) {
  2174. }
  2175. TouchInputMapper::~TouchInputMapper() {
  2176. }
  2177. uint32_t TouchInputMapper::getSources() {
  2178. return mSource;
  2179. }
  2180. void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
  2181. InputMapper::populateDeviceInfo(info);
  2182. if (mDeviceMode != DEVICE_MODE_DISABLED) {
  2183. info->addMotionRange(mOrientedRanges.x);
  2184. info->addMotionRange(mOrientedRanges.y);
  2185. info->addMotionRange(mOrientedRanges.pressure);
  2186. if (mOrientedRanges.haveSize) {
  2187. info->addMotionRange(mOrientedRanges.size);
  2188. }
  2189. if (mOrientedRanges.haveTouchSize) {
  2190. info->addMotionRange(mOrientedRanges.touchMajor);
  2191. info->addMotionRange(mOrientedRanges.touchMinor);
  2192. }
  2193. if (mOrientedRanges.haveToolSize) {
  2194. info->addMotionRange(mOrientedRanges.toolMajor);
  2195. info->addMotionRange(mOrientedRanges.toolMinor);
  2196. }
  2197. if (mOrientedRanges.haveOrientation) {
  2198. info->addMotionRange(mOrientedRanges.orientation);
  2199. }
  2200. if (mOrientedRanges.haveDistance) {
  2201. info->addMotionRange(mOrientedRanges.distance);
  2202. }
  2203. if (mOrientedRanges.haveTilt) {
  2204. info->addMotionRange(mOrientedRanges.tilt);
  2205. }
  2206. if (mCursorScrollAccumulator.haveRelativeVWheel()) {
  2207. info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f,
  2208. 0.0f);
  2209. }
  2210. if (mCursorScrollAccumulator.haveRelativeHWheel()) {
  2211. info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f,
  2212. 0.0f);
  2213. }
  2214. if (mCalibration.coverageCalibration == Calibration::COVERAGE_CALIBRATION_BOX) {
  2215. const InputDeviceInfo::MotionRange& x = mOrientedRanges.x;
  2216. const InputDeviceInfo::MotionRange& y = mOrientedRanges.y;
  2217. info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_1, mSource, x.min, x.max, x.flat,
  2218. x.fuzz, x.resolution);
  2219. info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_2, mSource, y.min, y.max, y.flat,
  2220. y.fuzz, y.resolution);
  2221. info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_3, mSource, x.min, x.max, x.flat,
  2222. x.fuzz, x.resolution);
  2223. info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_4, mSource, y.min, y.max, y.flat,
  2224. y.fuzz, y.resolution);
  2225. }
  2226. info->setButtonUnderPad(mParameters.hasButtonUnderPad);
  2227. }
  2228. }
  2229. void TouchInputMapper::dump(String8& dump) {
  2230. dump.append(INDENT2 "Touch Input Mapper:\n");
  2231. dumpParameters(dump);
  2232. dumpVirtualKeys(dump);
  2233. dumpRawPointerAxes(dump);
  2234. dumpCalibration(dump);
  2235. dumpSurface(dump);
  2236. dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n");
  2237. dump.appendFormat(INDENT4 "XTranslate: %0.3f\n", mXTranslate);
  2238. dump.appendFormat(INDENT4 "YTranslate: %0.3f\n", mYTranslate);
  2239. dump.appendFormat(INDENT4 "XScale: %0.3f\n", mXScale);
  2240. dump.appendFormat(INDENT4 "YScale: %0.3f\n", mYScale);
  2241. dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mXPrecision);
  2242. dump.appendFormat(INDENT4 "YPrecision: %0.3f\n", mYPrecision);
  2243. dump.appendFormat(INDENT4 "GeometricScale: %0.3f\n", mGeometricScale);
  2244. dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mPressureScale);
  2245. dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mSizeScale);
  2246. dump.appendFormat(INDENT4 "OrientationScale: %0.3f\n", mOrientationScale);
  2247. dump.appendFormat(INDENT4 "DistanceScale: %0.3f\n", mDistanceScale);
  2248. dump.appendFormat(INDENT4 "HaveTilt: %s\n", toString(mHaveTilt));
  2249. dump.appendFormat(INDENT4 "TiltXCenter: %0.3f\n", mTiltXCenter);
  2250. dump.appendFormat(INDENT4 "TiltXScale: %0.3f\n", mTiltXScale);
  2251. dump.appendFormat(INDENT4 "TiltYCenter: %0.3f\n", mTiltYCenter);
  2252. dump.appendFormat(INDENT4 "TiltYScale: %0.3f\n", mTiltYScale);
  2253. dump.appendFormat(INDENT3 "Last Button State: 0x%08x\n", mLastButtonState);
  2254. dump.appendFormat(INDENT3 "Last Raw Touch: pointerCount=%d\n",
  2255. mLastRawPointerData.pointerCount);
  2256. for (uint32_t i = 0; i < mLastRawPointerData.pointerCount; i++) {
  2257. const RawPointerData::Pointer& pointer = mLastRawPointerData.pointers[i];
  2258. dump.appendFormat(INDENT4 "[%d]: id=%d, x=%d, y=%d, pressure=%d, "
  2259. "touchMajor=%d, touchMinor=%d, toolMajor=%d, toolMinor=%d, "
  2260. "orientation=%d, tiltX=%d, tiltY=%d, distance=%d, "
  2261. "toolType=%d, isHovering=%s\n", i,
  2262. pointer.id, pointer.x, pointer.y, pointer.pressure,
  2263. pointer.touchMajor, pointer.touchMinor,
  2264. pointer.toolMajor, pointer.toolMinor,
  2265. pointer.orientation, pointer.tiltX, pointer.tiltY, pointer.distance,
  2266. pointer.toolType, toString(pointer.isHovering));
  2267. }
  2268. dump.appendFormat(INDENT3 "Last Cooked Touch: pointerCount=%d\n",
  2269. mLastCookedPointerData.pointerCount);
  2270. for (uint32_t i = 0; i < mLastCookedPointerData.pointerCount; i++) {
  2271. const PointerProperties& pointerProperties = mLastCookedPointerData.pointerProperties[i];
  2272. const PointerCoords& pointerCoords = mLastCookedPointerData.pointerCoords[i];
  2273. dump.appendFormat(INDENT4 "[%d]: id=%d, x=%0.3f, y=%0.3f, pressure=%0.3f, "
  2274. "touchMajor=%0.3f, touchMinor=%0.3f, toolMajor=%0.3f, toolMinor=%0.3f, "
  2275. "orientation=%0.3f, tilt=%0.3f, distance=%0.3f, "
  2276. "toolType=%d, isHovering=%s\n", i,
  2277. pointerProperties.id,
  2278. pointerCoords.getX(),
  2279. pointerCoords.getY(),
  2280. pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
  2281. pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
  2282. pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
  2283. pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
  2284. pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
  2285. pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
  2286. pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TILT),
  2287. pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE),
  2288. pointerProperties.toolType,
  2289. toString(mLastCookedPointerData.isHovering(i)));
  2290. }
  2291. if (mDeviceMode == DEVICE_MODE_POINTER) {
  2292. dump.appendFormat(INDENT3 "Pointer Gesture Detector:\n");
  2293. dump.appendFormat(INDENT4 "XMovementScale: %0.3f\n",
  2294. mPointerXMovementScale);
  2295. dump.appendFormat(INDENT4 "YMovementScale: %0.3f\n",
  2296. mPointerYMovementScale);
  2297. dump.appendFormat(INDENT4 "XZoomScale: %0.3f\n",
  2298. mPointerXZoomScale);
  2299. dump.appendFormat(INDENT4 "YZoomScale: %0.3f\n",
  2300. mPointerYZoomScale);
  2301. dump.appendFormat(INDENT4 "MaxSwipeWidth: %f\n",
  2302. mPointerGestureMaxSwipeWidth);
  2303. }
  2304. }
  2305. void TouchInputMapper::configure(nsecs_t when,
  2306. const InputReaderConfiguration* config, uint32_t changes) {
  2307. InputMapper::configure(when, config, changes);
  2308. mConfig = *config;
  2309. if (!changes) { // first time only
  2310. // Configure basic parameters.
  2311. configureParameters();
  2312. // Configure common accumulators.
  2313. mCursorScrollAccumulator.configure(getDevice());
  2314. mTouchButtonAccumulator.configure(getDevice());
  2315. // Configure absolute axis information.
  2316. configureRawPointerAxes();
  2317. // Prepare input device calibration.
  2318. parseCalibration();
  2319. resolveCalibration();
  2320. }
  2321. if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
  2322. // Update pointer speed.
  2323. mPointerVelocityControl.setParameters(mConfig.pointerVelocityControlParameters);
  2324. mWheelXVelocityControl.setParameters(mConfig.wheelVelocityControlParameters);
  2325. mWheelYVelocityControl.setParameters(mConfig.wheelVelocityControlParameters);
  2326. }
  2327. bool resetNeeded = false;
  2328. if (!changes || (changes & (InputReaderConfiguration::CHANGE_DISPLAY_INFO
  2329. | InputReaderConfiguration::CHANGE_POINTER_GESTURE_ENABLEMENT
  2330. | InputReaderConfiguration::CHANGE_SHOW_TOUCHES))) {
  2331. // Configure device sources, surface dimensions, orientation and
  2332. // scaling factors.
  2333. configureSurface(when, &resetNeeded);
  2334. }
  2335. if (changes && resetNeeded) {
  2336. // Send reset, unless this is the first time the device has been configured,
  2337. // in which case the reader will call reset itself after all mappers are ready.
  2338. getDevice()->notifyReset(when);
  2339. }
  2340. }
  2341. void TouchInputMapper::configureParameters() {
  2342. // Use the pointer presentation mode for devices that do not support distinct
  2343. // multitouch. The spot-based presentation relies on being able to accurately
  2344. // locate two or more fingers on the touch pad.
  2345. mParameters.gestureMode = getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_SEMI_MT)
  2346. ? Parameters::GESTURE_MODE_POINTER : Parameters::GESTURE_MODE_SPOTS;
  2347. String8 gestureModeString;
  2348. if (getDevice()->getConfiguration().tryGetProperty(String8("touch.gestureMode"),
  2349. gestureModeString)) {
  2350. if (gestureModeString == "pointer") {
  2351. mParameters.gestureMode = Parameters::GESTURE_MODE_POINTER;
  2352. } else if (gestureModeString == "spots") {
  2353. mParameters.gestureMode = Parameters::GESTURE_MODE_SPOTS;
  2354. } else if (gestureModeString != "default") {
  2355. ALOGW("Invalid value for touch.gestureMode: '%s'", gestureModeString.string());
  2356. }
  2357. }
  2358. if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_DIRECT)) {
  2359. // The device is a touch screen.
  2360. mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
  2361. } else if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_POINTER)) {
  2362. // The device is a pointing device like a track pad.
  2363. mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
  2364. } else if (getEventHub()->hasRelativeAxis(getDeviceId(), REL_X)
  2365. || getEventHub()->hasRelativeAxis(getDeviceId(), REL_Y)) {
  2366. // The device is a cursor device with a touch pad attached.
  2367. // By default don't use the touch pad to move the pointer.
  2368. mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
  2369. } else {
  2370. // The device is a touch pad of unknown purpose.
  2371. mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
  2372. }
  2373. mParameters.hasButtonUnderPad=
  2374. getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_BUTTONPAD);
  2375. String8 deviceTypeString;
  2376. if (getDevice()->getConfiguration().tryGetProperty(String8("touch.deviceType"),
  2377. deviceTypeString)) {
  2378. if (deviceTypeString == "touchScreen") {
  2379. mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
  2380. } else if (deviceTypeString == "touchPad") {
  2381. mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
  2382. } else if (deviceTypeString == "touchNavigation") {
  2383. mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_NAVIGATION;
  2384. } else if (deviceTypeString == "pointer") {
  2385. mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
  2386. } else if (deviceTypeString != "default") {
  2387. ALOGW("Invalid value for touch.deviceType: '%s'", deviceTypeString.string());
  2388. }
  2389. }
  2390. mParameters.orientationAware = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN;
  2391. getDevice()->getConfiguration().tryGetProperty(String8("touch.orientationAware"),
  2392. mParameters.orientationAware);
  2393. mParameters.hasAssociatedDisplay = false;
  2394. mParameters.associatedDisplayIsExternal = false;
  2395. if (mParameters.orientationAware
  2396. || mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
  2397. || mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) {
  2398. mParameters.hasAssociatedDisplay = true;
  2399. mParameters.associatedDisplayIsExternal =
  2400. mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
  2401. && getDevice()->isExternal();
  2402. }
  2403. }
  2404. void TouchInputMapper::dumpParameters(String8& dump) {
  2405. dump.append(INDENT3 "Parameters:\n");
  2406. switch (mParameters.gestureMode) {
  2407. case Parameters::GESTURE_MODE_POINTER:
  2408. dump.append(INDENT4 "GestureMode: pointer\n");
  2409. break;
  2410. case Parameters::GESTURE_MODE_SPOTS:
  2411. dump.append(INDENT4 "GestureMode: spots\n");
  2412. break;
  2413. default:
  2414. assert(false);
  2415. }
  2416. switch (mParameters.deviceType) {
  2417. case Parameters::DEVICE_TYPE_TOUCH_SCREEN:
  2418. dump.append(INDENT4 "DeviceType: touchScreen\n");
  2419. break;
  2420. case Parameters::DEVICE_TYPE_TOUCH_PAD:
  2421. dump.append(INDENT4 "DeviceType: touchPad\n");
  2422. break;
  2423. case Parameters::DEVICE_TYPE_TOUCH_NAVIGATION:
  2424. dump.append(INDENT4 "DeviceType: touchNavigation\n");
  2425. break;
  2426. case Parameters::DEVICE_TYPE_POINTER:
  2427. dump.append(INDENT4 "DeviceType: pointer\n");
  2428. break;
  2429. default:
  2430. ALOG_ASSERT(false);
  2431. }
  2432. dump.appendFormat(INDENT4 "AssociatedDisplay: hasAssociatedDisplay=%s, isExternal=%s\n",
  2433. toString(mParameters.hasAssociatedDisplay),
  2434. toString(mParameters.associatedDisplayIsExternal));
  2435. dump.appendFormat(INDENT4 "OrientationAware: %s\n",
  2436. toString(mParameters.orientationAware));
  2437. }
  2438. void TouchInputMapper::configureRawPointerAxes() {
  2439. mRawPointerAxes.clear();
  2440. }
  2441. void TouchInputMapper::dumpRawPointerAxes(String8& dump) {
  2442. dump.append(INDENT3 "Raw Touch Axes:\n");
  2443. dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.x, "X");
  2444. dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.y, "Y");
  2445. dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.pressure, "Pressure");
  2446. dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.touchMajor, "TouchMajor");
  2447. dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.touchMinor, "TouchMinor");
  2448. dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.toolMajor, "ToolMajor");
  2449. dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.toolMinor, "ToolMinor");
  2450. dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.orientation, "Orientation");
  2451. dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.distance, "Distance");
  2452. dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.tiltX, "TiltX");
  2453. dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.tiltY, "TiltY");
  2454. dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.trackingId, "TrackingId");
  2455. dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.slot, "Slot");
  2456. }
  2457. void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
  2458. int32_t oldDeviceMode = mDeviceMode;
  2459. // Determine device mode.
  2460. if (mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER
  2461. && mConfig.pointerGesturesEnabled) {
  2462. mSource = AINPUT_SOURCE_MOUSE;
  2463. mDeviceMode = DEVICE_MODE_POINTER;
  2464. if (hasStylus()) {
  2465. mSource |= AINPUT_SOURCE_STYLUS;
  2466. }
  2467. } else if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
  2468. && mParameters.hasAssociatedDisplay) {
  2469. mSource = AINPUT_SOURCE_TOUCHSCREEN;
  2470. mDeviceMode = DEVICE_MODE_DIRECT;
  2471. if (hasStylus()) {
  2472. mSource |= AINPUT_SOURCE_STYLUS;
  2473. }
  2474. } else if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_NAVIGATION) {
  2475. mSource = AINPUT_SOURCE_TOUCH_NAVIGATION;
  2476. mDeviceMode = DEVICE_MODE_NAVIGATION;
  2477. } else {
  2478. mSource = AINPUT_SOURCE_TOUCHPAD;
  2479. mDeviceMode = DEVICE_MODE_UNSCALED;
  2480. }
  2481. // Ensure we have valid X and Y axes.
  2482. if (!mRawPointerAxes.x.valid || !mRawPointerAxes.y.valid) {
  2483. ALOGW(INDENT "Touch device '%s' did not report support for X or Y axis! "
  2484. "The device will be inoperable.", getDeviceName().string());
  2485. mDeviceMode = DEVICE_MODE_DISABLED;
  2486. return;
  2487. }
  2488. // Raw width and height in the natural orientation.
  2489. int32_t rawWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
  2490. int32_t rawHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
  2491. // Get associated display dimensions.
  2492. DisplayViewport newViewport;
  2493. if (mParameters.hasAssociatedDisplay) {
  2494. if (!mConfig.getDisplayInfo(mParameters.associatedDisplayIsExternal, &newViewport)) {
  2495. ALOGI(INDENT "Touch device '%s' could not query the properties of its associated "
  2496. "display. The device will be inoperable until the display size "
  2497. "becomes available.",
  2498. getDeviceName().string());
  2499. mDeviceMode = DEVICE_MODE_DISABLED;
  2500. return;
  2501. }
  2502. } else {
  2503. newViewport.setNonDisplayViewport(rawWidth, rawHeight);
  2504. }
  2505. bool viewportChanged = mViewport != newViewport;
  2506. if (viewportChanged) {
  2507. mViewport = newViewport;
  2508. if (mDeviceMode == DEVICE_MODE_DIRECT || mDeviceMode == DEVICE_MODE_POINTER) {
  2509. // Convert rotated viewport to natural surface coordinates.
  2510. int32_t naturalLogicalWidth, naturalLogicalHeight;
  2511. int32_t naturalPhysicalWidth, naturalPhysicalHeight;
  2512. int32_t naturalPhysicalLeft, naturalPhysicalTop;
  2513. int32_t naturalDeviceWidth, naturalDeviceHeight;
  2514. switch (mViewport.orientation) {
  2515. case DISPLAY_ORIENTATION_90:
  2516. naturalLogicalWidth = mViewport.logicalBottom - mViewport.logicalTop;
  2517. naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
  2518. naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
  2519. naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
  2520. naturalPhysicalLeft = mViewport.deviceHeight - mViewport.physicalBottom;
  2521. naturalPhysicalTop = mViewport.physicalLeft;
  2522. naturalDeviceWidth = mViewport.deviceHeight;
  2523. naturalDeviceHeight = mViewport.deviceWidth;
  2524. break;
  2525. case DISPLAY_ORIENTATION_180:
  2526. naturalLogicalWidth = mViewport.logicalRight - mViewport.logicalLeft;
  2527. naturalLogicalHeight = mViewport.logicalBottom - mViewport.logicalTop;
  2528. naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft;
  2529. naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop;
  2530. naturalPhysicalLeft = mViewport.deviceWidth - mViewport.physicalRight;
  2531. naturalPhysicalTop = mViewport.deviceHeight - mViewport.physicalBottom;
  2532. naturalDeviceWidth = mViewport.deviceWidth;
  2533. naturalDeviceHeight = mViewport.deviceHeight;
  2534. break;
  2535. case DISPLAY_ORIENTATION_270:
  2536. naturalLogicalWidth = mViewport.logicalBottom - mViewport.logicalTop;
  2537. naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
  2538. naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
  2539. naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
  2540. naturalPhysicalLeft = mViewport.physicalTop;
  2541. naturalPhysicalTop = mViewport.deviceWidth - mViewport.physicalRight;
  2542. naturalDeviceWidth = mViewport.deviceHeight;
  2543. naturalDeviceHeight = mViewport.deviceWidth;
  2544. break;
  2545. case DISPLAY_ORIENTATION_0:
  2546. default:
  2547. naturalLogicalWidth = mViewport.logicalRight - mViewport.logicalLeft;
  2548. naturalLogicalHeight = mViewport.logicalBottom - mViewport.logicalTop;
  2549. naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft;
  2550. naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop;
  2551. naturalPhysicalLeft = mViewport.physicalLeft;
  2552. naturalPhysicalTop = mViewport.physicalTop;
  2553. naturalDeviceWidth = mViewport.deviceWidth;
  2554. naturalDeviceHeight = mViewport.deviceHeight;
  2555. break;
  2556. }
  2557. mSurfaceWidth = naturalLogicalWidth * naturalDeviceWidth / naturalPhysicalWidth;
  2558. mSurfaceHeight = naturalLogicalHeight * naturalDeviceHeight / naturalPhysicalHeight;
  2559. mSurfaceLeft = naturalPhysicalLeft * naturalLogicalWidth / naturalPhysicalWidth;
  2560. mSurfaceTop = naturalPhysicalTop * naturalLogicalHeight / naturalPhysicalHeight;
  2561. mSurfaceOrientation = mParameters.orientationAware ?
  2562. mViewport.orientation : DISPLAY_ORIENTATION_0;
  2563. } else {
  2564. mSurfaceWidth = rawWidth;
  2565. mSurfaceHeight = rawHeight;
  2566. mSurfaceLeft = 0;
  2567. mSurfaceTop = 0;
  2568. mSurfaceOrientation = DISPLAY_ORIENTATION_0;
  2569. }
  2570. }
  2571. // If moving between pointer modes, need to reset some state.
  2572. bool deviceModeChanged = mDeviceMode != oldDeviceMode;
  2573. if (deviceModeChanged) {
  2574. mOrientedRanges.clear();
  2575. }
  2576. // Create pointer controller if needed.
  2577. if (mDeviceMode == DEVICE_MODE_POINTER ||
  2578. (mDeviceMode == DEVICE_MODE_DIRECT && mConfig.showTouches)) {
  2579. if (mPointerController == NULL) {
  2580. mPointerController = getPolicy()->obtainPointerController(getDeviceId());
  2581. }
  2582. } else {
  2583. mPointerController.clear();
  2584. }
  2585. if (viewportChanged || deviceModeChanged) {
  2586. ALOGI("Device reconfigured: id=%d, name='%s', size %dx%d, orientation %d, mode %d, "
  2587. "display id %d",
  2588. getDeviceId(), getDeviceName().string(), mSurfaceWidth, mSurfaceHeight,
  2589. mSurfaceOrientation, mDeviceMode, mViewport.displayId);
  2590. // Configure X and Y factors.
  2591. mXScale = float(mSurfaceWidth) / rawWidth;
  2592. mYScale = float(mSurfaceHeight) / rawHeight;
  2593. mXTranslate = -mSurfaceLeft;
  2594. mYTranslate = -mSurfaceTop;
  2595. mXPrecision = 1.0f / mXScale;
  2596. mYPrecision = 1.0f / mYScale;
  2597. mOrientedRanges.x.axis = AMOTION_EVENT_AXIS_X;
  2598. mOrientedRanges.x.source = mSource;
  2599. mOrientedRanges.y.axis = AMOTION_EVENT_AXIS_Y;
  2600. mOrientedRanges.y.source = mSource;
  2601. configureVirtualKeys();
  2602. // Scale factor for terms that are not oriented in a particular axis.
  2603. // If the pixels are square then xScale == yScale otherwise we fake it
  2604. // by choosing an average.
  2605. mGeometricScale = avg(mXScale, mYScale);
  2606. // Size of diagonal axis.
  2607. float diagonalSize = hypotf(mSurfaceWidth, mSurfaceHeight);
  2608. // Size factors.
  2609. if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) {
  2610. if (mRawPointerAxes.touchMajor.valid
  2611. && mRawPointerAxes.touchMajor.maxValue != 0) {
  2612. mSizeScale = 1.0f / mRawPointerAxes.touchMajor.maxValue;
  2613. } else if (mRawPointerAxes.toolMajor.valid
  2614. && mRawPointerAxes.toolMajor.maxValue != 0) {
  2615. mSizeScale = 1.0f / mRawPointerAxes.toolMajor.maxValue;
  2616. } else {
  2617. mSizeScale = 0.0f;
  2618. }
  2619. mOrientedRanges.haveTouchSize = true;
  2620. mOrientedRanges.haveToolSize = true;
  2621. mOrientedRanges.haveSize = true;
  2622. mOrientedRanges.touchMajor.axis = AMOTION_EVENT_AXIS_TOUCH_MAJOR;
  2623. mOrientedRanges.touchMajor.source = mSource;
  2624. mOrientedRanges.touchMajor.min = 0;
  2625. mOrientedRanges.touchMajor.max = diagonalSize;
  2626. mOrientedRanges.touchMajor.flat = 0;
  2627. mOrientedRanges.touchMajor.fuzz = 0;
  2628. mOrientedRanges.touchMajor.resolution = 0;
  2629. mOrientedRanges.touchMinor = mOrientedRanges.touchMajor;
  2630. mOrientedRanges.touchMinor.axis = AMOTION_EVENT_AXIS_TOUCH_MINOR;
  2631. mOrientedRanges.toolMajor.axis = AMOTION_EVENT_AXIS_TOOL_MAJOR;
  2632. mOrientedRanges.toolMajor.source = mSource;
  2633. mOrientedRanges.toolMajor.min = 0;
  2634. mOrientedRanges.toolMajor.max = diagonalSize;
  2635. mOrientedRanges.toolMajor.flat = 0;
  2636. mOrientedRanges.toolMajor.fuzz = 0;
  2637. mOrientedRanges.toolMajor.resolution = 0;
  2638. mOrientedRanges.toolMinor = mOrientedRanges.toolMajor;
  2639. mOrientedRanges.toolMinor.axis = AMOTION_EVENT_AXIS_TOOL_MINOR;
  2640. mOrientedRanges.size.axis = AMOTION_EVENT_AXIS_SIZE;
  2641. mOrientedRanges.size.source = mSource;
  2642. mOrientedRanges.size.min = 0;
  2643. mOrientedRanges.size.max = 1.0;
  2644. mOrientedRanges.size.flat = 0;
  2645. mOrientedRanges.size.fuzz = 0;
  2646. mOrientedRanges.size.resolution = 0;
  2647. } else {
  2648. mSizeScale = 0.0f;
  2649. }
  2650. // Pressure factors.
  2651. mPressureScale = 0;
  2652. if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_PHYSICAL
  2653. || mCalibration.pressureCalibration
  2654. == Calibration::PRESSURE_CALIBRATION_AMPLITUDE) {
  2655. if (mCalibration.havePressureScale) {
  2656. mPressureScale = mCalibration.pressureScale;
  2657. } else if (mRawPointerAxes.pressure.valid
  2658. && mRawPointerAxes.pressure.maxValue != 0) {
  2659. mPressureScale = 1.0f / mRawPointerAxes.pressure.maxValue;
  2660. }
  2661. }
  2662. mOrientedRanges.pressure.axis = AMOTION_EVENT_AXIS_PRESSURE;
  2663. mOrientedRanges.pressure.source = mSource;
  2664. mOrientedRanges.pressure.min = 0;
  2665. mOrientedRanges.pressure.max = 1.0;
  2666. mOrientedRanges.pressure.flat = 0;
  2667. mOrientedRanges.pressure.fuzz = 0;
  2668. mOrientedRanges.pressure.resolution = 0;
  2669. // Tilt
  2670. mTiltXCenter = 0;
  2671. mTiltXScale = 0;
  2672. mTiltYCenter = 0;
  2673. mTiltYScale = 0;
  2674. mHaveTilt = mRawPointerAxes.tiltX.valid && mRawPointerAxes.tiltY.valid;
  2675. if (mHaveTilt) {
  2676. mTiltXCenter = avg(mRawPointerAxes.tiltX.minValue,
  2677. mRawPointerAxes.tiltX.maxValue);
  2678. mTiltYCenter = avg(mRawPointerAxes.tiltY.minValue,
  2679. mRawPointerAxes.tiltY.maxValue);
  2680. mTiltXScale = M_PI / 180;
  2681. mTiltYScale = M_PI / 180;
  2682. mOrientedRanges.haveTilt = true;
  2683. mOrientedRanges.tilt.axis = AMOTION_EVENT_AXIS_TILT;
  2684. mOrientedRanges.tilt.source = mSource;
  2685. mOrientedRanges.tilt.min = 0;
  2686. mOrientedRanges.tilt.max = M_PI_2;
  2687. mOrientedRanges.tilt.flat = 0;
  2688. mOrientedRanges.tilt.fuzz = 0;
  2689. mOrientedRanges.tilt.resolution = 0;
  2690. }
  2691. // Orientation
  2692. mOrientationScale = 0;
  2693. if (mHaveTilt) {
  2694. mOrientedRanges.haveOrientation = true;
  2695. mOrientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
  2696. mOrientedRanges.orientation.source = mSource;
  2697. mOrientedRanges.orientation.min = -M_PI;
  2698. mOrientedRanges.orientation.max = M_PI;
  2699. mOrientedRanges.orientation.flat = 0;
  2700. mOrientedRanges.orientation.fuzz = 0;
  2701. mOrientedRanges.orientation.resolution = 0;
  2702. } else if (mCalibration.orientationCalibration !=
  2703. Calibration::ORIENTATION_CALIBRATION_NONE) {
  2704. if (mCalibration.orientationCalibration
  2705. == Calibration::ORIENTATION_CALIBRATION_INTERPOLATED) {
  2706. if (mRawPointerAxes.orientation.valid) {
  2707. if (mRawPointerAxes.orientation.maxValue > 0) {
  2708. mOrientationScale = M_PI_2 / mRawPointerAxes.orientation.maxValue;
  2709. } else if (mRawPointerAxes.orientation.minValue < 0) {
  2710. mOrientationScale = -M_PI_2 / mRawPointerAxes.orientation.minValue;
  2711. } else {
  2712. mOrientationScale = 0;
  2713. }
  2714. }
  2715. }
  2716. mOrientedRanges.haveOrientation = true;
  2717. mOrientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
  2718. mOrientedRanges.orientation.source = mSource;
  2719. mOrientedRanges.orientation.min = -M_PI_2;
  2720. mOrientedRanges.orientation.max = M_PI_2;
  2721. mOrientedRanges.orientation.flat = 0;
  2722. mOrientedRanges.orientation.fuzz = 0;
  2723. mOrientedRanges.orientation.resolution = 0;
  2724. }
  2725. // Distance
  2726. mDistanceScale = 0;
  2727. if (mCalibration.distanceCalibration != Calibration::DISTANCE_CALIBRATION_NONE) {
  2728. if (mCalibration.distanceCalibration
  2729. == Calibration::DISTANCE_CALIBRATION_SCALED) {
  2730. if (mCalibration.haveDistanceScale) {
  2731. mDistanceScale = mCalibration.distanceScale;
  2732. } else {
  2733. mDistanceScale = 1.0f;
  2734. }
  2735. }
  2736. mOrientedRanges.haveDistance = true;
  2737. mOrientedRanges.distance.axis = AMOTION_EVENT_AXIS_DISTANCE;
  2738. mOrientedRanges.distance.source = mSource;
  2739. mOrientedRanges.distance.min =
  2740. mRawPointerAxes.distance.minValue * mDistanceScale;
  2741. mOrientedRanges.distance.max =
  2742. mRawPointerAxes.distance.maxValue * mDistanceScale;
  2743. mOrientedRanges.distance.flat = 0;
  2744. mOrientedRanges.distance.fuzz =
  2745. mRawPointerAxes.distance.fuzz * mDistanceScale;
  2746. mOrientedRanges.distance.resolution = 0;
  2747. }
  2748. // Compute oriented precision, scales and ranges.
  2749. // Note that the maximum value reported is an inclusive maximum value so it is one
  2750. // unit less than the total width or height of surface.
  2751. switch (mSurfaceOrientation) {
  2752. case DISPLAY_ORIENTATION_90:
  2753. case DISPLAY_ORIENTATION_270:
  2754. mOrientedXPrecision = mYPrecision;
  2755. mOrientedYPrecision = mXPrecision;
  2756. mOrientedRanges.x.min = mYTranslate;
  2757. mOrientedRanges.x.max = mSurfaceHeight + mYTranslate - 1;
  2758. mOrientedRanges.x.flat = 0;
  2759. mOrientedRanges.x.fuzz = 0;
  2760. mOrientedRanges.x.resolution = mRawPointerAxes.y.resolution * mYScale;
  2761. mOrientedRanges.y.min = mXTranslate;
  2762. mOrientedRanges.y.max = mSurfaceWidth + mXTranslate - 1;
  2763. mOrientedRanges.y.flat = 0;
  2764. mOrientedRanges.y.fuzz = 0;
  2765. mOrientedRanges.y.resolution = mRawPointerAxes.x.resolution * mXScale;
  2766. break;
  2767. default:
  2768. mOrientedXPrecision = mXPrecision;
  2769. mOrientedYPrecision = mYPrecision;
  2770. mOrientedRanges.x.min = mXTranslate;
  2771. mOrientedRanges.x.max = mSurfaceWidth + mXTranslate - 1;
  2772. mOrientedRanges.x.flat = 0;
  2773. mOrientedRanges.x.fuzz = 0;
  2774. mOrientedRanges.x.resolution = mRawPointerAxes.x.resolution * mXScale;
  2775. mOrientedRanges.y.min = mYTranslate;
  2776. mOrientedRanges.y.max = mSurfaceHeight + mYTranslate - 1;
  2777. mOrientedRanges.y.flat = 0;
  2778. mOrientedRanges.y.fuzz = 0;
  2779. mOrientedRanges.y.resolution = mRawPointerAxes.y.resolution * mYScale;
  2780. break;
  2781. }
  2782. if (mDeviceMode == DEVICE_MODE_POINTER) {
  2783. // Compute pointer gesture detection parameters.
  2784. float rawDiagonal = hypotf(rawWidth, rawHeight);
  2785. float displayDiagonal = hypotf(mSurfaceWidth, mSurfaceHeight);
  2786. // Scale movements such that one whole swipe of the touch pad covers a
  2787. // given area relative to the diagonal size of the display when no acceleration
  2788. // is applied.
  2789. // Assume that the touch pad has a square aspect ratio such that movements in
  2790. // X and Y of the same number of raw units cover the same physical distance.
  2791. mPointerXMovementScale = mConfig.pointerGestureMovementSpeedRatio
  2792. * displayDiagonal / rawDiagonal;
  2793. mPointerYMovementScale = mPointerXMovementScale;
  2794. // Scale zooms to cover a smaller range of the display than movements do.
  2795. // This value determines the area around the pointer that is affected by freeform
  2796. // pointer gestures.
  2797. mPointerXZoomScale = mConfig.pointerGestureZoomSpeedRatio
  2798. * displayDiagonal / rawDiagonal;
  2799. mPointerYZoomScale = mPointerXZoomScale;
  2800. // Max width between pointers to detect a swipe gesture is more than some fraction
  2801. // of the diagonal axis of the touch pad. Touches that are wider than this are
  2802. // translated into freeform gestures.
  2803. mPointerGestureMaxSwipeWidth =
  2804. mConfig.pointerGestureSwipeMaxWidthRatio * rawDiagonal;
  2805. // Abort current pointer usages because the state has changed.
  2806. abortPointerUsage(when, 0 /*policyFlags*/);
  2807. }
  2808. // Inform the dispatcher about the changes.
  2809. *outResetNeeded = true;
  2810. bumpGeneration();
  2811. }
  2812. }
  2813. void TouchInputMapper::dumpSurface(String8& dump) {
  2814. dump.appendFormat(INDENT3 "Viewport: displayId=%d, orientation=%d, "
  2815. "logicalFrame=[%d, %d, %d, %d], "
  2816. "physicalFrame=[%d, %d, %d, %d], "
  2817. "deviceSize=[%d, %d]\n",
  2818. mViewport.displayId, mViewport.orientation,
  2819. mViewport.logicalLeft, mViewport.logicalTop,
  2820. mViewport.logicalRight, mViewport.logicalBottom,
  2821. mViewport.physicalLeft, mViewport.physicalTop,
  2822. mViewport.physicalRight, mViewport.physicalBottom,
  2823. mViewport.deviceWidth, mViewport.deviceHeight);
  2824. dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mSurfaceWidth);
  2825. dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mSurfaceHeight);
  2826. dump.appendFormat(INDENT3 "SurfaceLeft: %d\n", mSurfaceLeft);
  2827. dump.appendFormat(INDENT3 "SurfaceTop: %d\n", mSurfaceTop);
  2828. dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mSurfaceOrientation);
  2829. }
  2830. void TouchInputMapper::configureVirtualKeys() {
  2831. Vector<VirtualKeyDefinition> virtualKeyDefinitions;
  2832. getEventHub()->getVirtualKeyDefinitions(getDeviceId(), virtualKeyDefinitions);
  2833. mVirtualKeys.clear();
  2834. if (virtualKeyDefinitions.size() == 0) {
  2835. return;
  2836. }
  2837. mVirtualKeys.setCapacity(virtualKeyDefinitions.size());
  2838. int32_t touchScreenLeft = mRawPointerAxes.x.minValue;
  2839. int32_t touchScreenTop = mRawPointerAxes.y.minValue;
  2840. int32_t touchScreenWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
  2841. int32_t touchScreenHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
  2842. for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
  2843. const VirtualKeyDefinition& virtualKeyDefinition =
  2844. virtualKeyDefinitions[i];
  2845. mVirtualKeys.add();
  2846. VirtualKey& virtualKey = mVirtualKeys.editTop();
  2847. virtualKey.scanCode = virtualKeyDefinition.scanCode;
  2848. int32_t keyCode;
  2849. uint32_t flags;
  2850. if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode, 0, &keyCode, &flags)) {
  2851. ALOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring",
  2852. virtualKey.scanCode);
  2853. mVirtualKeys.pop(); // drop the key
  2854. continue;
  2855. }
  2856. virtualKey.keyCode = keyCode;
  2857. virtualKey.flags = flags;
  2858. // convert the key definition's display coordinates into touch coordinates for a hit box
  2859. int32_t halfWidth = virtualKeyDefinition.width / 2;
  2860. int32_t halfHeight = virtualKeyDefinition.height / 2;
  2861. virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth)
  2862. * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
  2863. virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth)
  2864. * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
  2865. virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight)
  2866. * touchScreenHeight / mSurfaceHeight + touchScreenTop;
  2867. virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
  2868. * touchScreenHeight / mSurfaceHeight + touchScreenTop;
  2869. }
  2870. }
  2871. void TouchInputMapper::dumpVirtualKeys(String8& dump) {
  2872. if (!mVirtualKeys.isEmpty()) {
  2873. dump.append(INDENT3 "Virtual Keys:\n");
  2874. for (size_t i = 0; i < mVirtualKeys.size(); i++) {
  2875. const VirtualKey& virtualKey = mVirtualKeys.itemAt(i);
  2876. dump.appendFormat(INDENT4 "%zu: scanCode=%d, keyCode=%d, "
  2877. "hitLeft=%d, hitRight=%d, hitTop=%d, hitBottom=%d\n",
  2878. i, virtualKey.scanCode, virtualKey.keyCode,
  2879. virtualKey.hitLeft, virtualKey.hitRight,
  2880. virtualKey.hitTop, virtualKey.hitBottom);
  2881. }
  2882. }
  2883. }
  2884. void TouchInputMapper::parseCalibration() {
  2885. const PropertyMap& in = getDevice()->getConfiguration();
  2886. Calibration& out = mCalibration;
  2887. // Size
  2888. out.sizeCalibration = Calibration::SIZE_CALIBRATION_DEFAULT;
  2889. String8 sizeCalibrationString;
  2890. if (in.tryGetProperty(String8("touch.size.calibration"), sizeCalibrationString)) {
  2891. if (sizeCalibrationString == "none") {
  2892. out.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
  2893. } else if (sizeCalibrationString == "geometric") {
  2894. out.sizeCalibration = Calibration::SIZE_CALIBRATION_GEOMETRIC;
  2895. } else if (sizeCalibrationString == "diameter") {
  2896. out.sizeCalibration = Calibration::SIZE_CALIBRATION_DIAMETER;
  2897. } else if (sizeCalibrationString == "box") {
  2898. out.sizeCalibration = Calibration::SIZE_CALIBRATION_BOX;
  2899. } else if (sizeCalibrationString == "area") {
  2900. out.sizeCalibration = Calibration::SIZE_CALIBRATION_AREA;
  2901. } else if (sizeCalibrationString != "default") {
  2902. ALOGW("Invalid value for touch.size.calibration: '%s'",
  2903. sizeCalibrationString.string());
  2904. }
  2905. }
  2906. out.haveSizeScale = in.tryGetProperty(String8("touch.size.scale"),
  2907. out.sizeScale);
  2908. out.haveSizeBias = in.tryGetProperty(String8("touch.size.bias"),
  2909. out.sizeBias);
  2910. out.haveSizeIsSummed = in.tryGetProperty(String8("touch.size.isSummed"),
  2911. out.sizeIsSummed);
  2912. // Pressure
  2913. out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_DEFAULT;
  2914. String8 pressureCalibrationString;
  2915. if (in.tryGetProperty(String8("touch.pressure.calibration"), pressureCalibrationString)) {
  2916. if (pressureCalibrationString == "none") {
  2917. out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
  2918. } else if (pressureCalibrationString == "physical") {
  2919. out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
  2920. } else if (pressureCalibrationString == "amplitude") {
  2921. out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE;
  2922. } else if (pressureCalibrationString != "default") {
  2923. ALOGW("Invalid value for touch.pressure.calibration: '%s'",
  2924. pressureCalibrationString.string());
  2925. }
  2926. }
  2927. out.havePressureScale = in.tryGetProperty(String8("touch.pressure.scale"),
  2928. out.pressureScale);
  2929. // Orientation
  2930. out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_DEFAULT;
  2931. String8 orientationCalibrationString;
  2932. if (in.tryGetProperty(String8("touch.orientation.calibration"), orientationCalibrationString)) {
  2933. if (orientationCalibrationString == "none") {
  2934. out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
  2935. } else if (orientationCalibrationString == "interpolated") {
  2936. out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
  2937. } else if (orientationCalibrationString == "vector") {
  2938. out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_VECTOR;
  2939. } else if (orientationCalibrationString != "default") {
  2940. ALOGW("Invalid value for touch.orientation.calibration: '%s'",
  2941. orientationCalibrationString.string());
  2942. }
  2943. }
  2944. // Distance
  2945. out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_DEFAULT;
  2946. String8 distanceCalibrationString;
  2947. if (in.tryGetProperty(String8("touch.distance.calibration"), distanceCalibrationString)) {
  2948. if (distanceCalibrationString == "none") {
  2949. out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE;
  2950. } else if (distanceCalibrationString == "scaled") {
  2951. out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_SCALED;
  2952. } else if (distanceCalibrationString != "default") {
  2953. ALOGW("Invalid value for touch.distance.calibration: '%s'",
  2954. distanceCalibrationString.string());
  2955. }
  2956. }
  2957. out.haveDistanceScale = in.tryGetProperty(String8("touch.distance.scale"),
  2958. out.distanceScale);
  2959. out.coverageCalibration = Calibration::COVERAGE_CALIBRATION_DEFAULT;
  2960. String8 coverageCalibrationString;
  2961. if (in.tryGetProperty(String8("touch.coverage.calibration"), coverageCalibrationString)) {
  2962. if (coverageCalibrationString == "none") {
  2963. out.coverageCalibration = Calibration::COVERAGE_CALIBRATION_NONE;
  2964. } else if (coverageCalibrationString == "box") {
  2965. out.coverageCalibration = Calibration::COVERAGE_CALIBRATION_BOX;
  2966. } else if (coverageCalibrationString != "default") {
  2967. ALOGW("Invalid value for touch.coverage.calibration: '%s'",
  2968. coverageCalibrationString.string());
  2969. }
  2970. }
  2971. }
  2972. void TouchInputMapper::resolveCalibration() {
  2973. // Size
  2974. if (mRawPointerAxes.touchMajor.valid || mRawPointerAxes.toolMajor.valid) {
  2975. if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_DEFAULT) {
  2976. mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_GEOMETRIC;
  2977. }
  2978. } else {
  2979. mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
  2980. }
  2981. // Pressure
  2982. if (mRawPointerAxes.pressure.valid) {
  2983. if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_DEFAULT) {
  2984. mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
  2985. }
  2986. } else {
  2987. mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
  2988. }
  2989. // Orientation
  2990. if (mRawPointerAxes.orientation.valid) {
  2991. if (mCalibration.orientationCalibration == Calibration::ORIENTATION_CALIBRATION_DEFAULT) {
  2992. mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
  2993. }
  2994. } else {
  2995. mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
  2996. }
  2997. // Distance
  2998. if (mRawPointerAxes.distance.valid) {
  2999. if (mCalibration.distanceCalibration == Calibration::DISTANCE_CALIBRATION_DEFAULT) {
  3000. mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_SCALED;
  3001. }
  3002. } else {
  3003. mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE;
  3004. }
  3005. // Coverage
  3006. if (mCalibration.coverageCalibration == Calibration::COVERAGE_CALIBRATION_DEFAULT) {
  3007. mCalibration.coverageCalibration = Calibration::COVERAGE_CALIBRATION_NONE;
  3008. }
  3009. }
  3010. void TouchInputMapper::dumpCalibration(String8& dump) {
  3011. dump.append(INDENT3 "Calibration:\n");
  3012. // Size
  3013. switch (mCalibration.sizeCalibration) {
  3014. case Calibration::SIZE_CALIBRATION_NONE:
  3015. dump.append(INDENT4 "touch.size.calibration: none\n");
  3016. break;
  3017. case Calibration::SIZE_CALIBRATION_GEOMETRIC:
  3018. dump.append(INDENT4 "touch.size.calibration: geometric\n");
  3019. break;
  3020. case Calibration::SIZE_CALIBRATION_DIAMETER:
  3021. dump.append(INDENT4 "touch.size.calibration: diameter\n");
  3022. break;
  3023. case Calibration::SIZE_CALIBRATION_BOX:
  3024. dump.append(INDENT4 "touch.size.calibration: box\n");
  3025. break;
  3026. case Calibration::SIZE_CALIBRATION_AREA:
  3027. dump.append(INDENT4 "touch.size.calibration: area\n");
  3028. break;
  3029. default:
  3030. ALOG_ASSERT(false);
  3031. }
  3032. if (mCalibration.haveSizeScale) {
  3033. dump.appendFormat(INDENT4 "touch.size.scale: %0.3f\n",
  3034. mCalibration.sizeScale);
  3035. }
  3036. if (mCalibration.haveSizeBias) {
  3037. dump.appendFormat(INDENT4 "touch.size.bias: %0.3f\n",
  3038. mCalibration.sizeBias);
  3039. }
  3040. if (mCalibration.haveSizeIsSummed) {
  3041. dump.appendFormat(INDENT4 "touch.size.isSummed: %s\n",
  3042. toString(mCalibration.sizeIsSummed));
  3043. }
  3044. // Pressure
  3045. switch (mCalibration.pressureCalibration) {
  3046. case Calibration::PRESSURE_CALIBRATION_NONE:
  3047. dump.append(INDENT4 "touch.pressure.calibration: none\n");
  3048. break;
  3049. case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
  3050. dump.append(INDENT4 "touch.pressure.calibration: physical\n");
  3051. break;
  3052. case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
  3053. dump.append(INDENT4 "touch.pressure.calibration: amplitude\n");
  3054. break;
  3055. default:
  3056. ALOG_ASSERT(false);
  3057. }
  3058. if (mCalibration.havePressureScale) {
  3059. dump.appendFormat(INDENT4 "touch.pressure.scale: %0.3f\n",
  3060. mCalibration.pressureScale);
  3061. }
  3062. // Orientation
  3063. switch (mCalibration.orientationCalibration) {
  3064. case Calibration::ORIENTATION_CALIBRATION_NONE:
  3065. dump.append(INDENT4 "touch.orientation.calibration: none\n");
  3066. break;
  3067. case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
  3068. dump.append(INDENT4 "touch.orientation.calibration: interpolated\n");
  3069. break;
  3070. case Calibration::ORIENTATION_CALIBRATION_VECTOR:
  3071. dump.append(INDENT4 "touch.orientation.calibration: vector\n");
  3072. break;
  3073. default:
  3074. ALOG_ASSERT(false);
  3075. }
  3076. // Distance
  3077. switch (mCalibration.distanceCalibration) {
  3078. case Calibration::DISTANCE_CALIBRATION_NONE:
  3079. dump.append(INDENT4 "touch.distance.calibration: none\n");
  3080. break;
  3081. case Calibration::DISTANCE_CALIBRATION_SCALED:
  3082. dump.append(INDENT4 "touch.distance.calibration: scaled\n");
  3083. break;
  3084. default:
  3085. ALOG_ASSERT(false);
  3086. }
  3087. if (mCalibration.haveDistanceScale) {
  3088. dump.appendFormat(INDENT4 "touch.distance.scale: %0.3f\n",
  3089. mCalibration.distanceScale);
  3090. }
  3091. switch (mCalibration.coverageCalibration) {
  3092. case Calibration::COVERAGE_CALIBRATION_NONE:
  3093. dump.append(INDENT4 "touch.coverage.calibration: none\n");
  3094. break;
  3095. case Calibration::COVERAGE_CALIBRATION_BOX:
  3096. dump.append(INDENT4 "touch.coverage.calibration: box\n");
  3097. break;
  3098. default:
  3099. ALOG_ASSERT(false);
  3100. }
  3101. }
  3102. void TouchInputMapper::reset(nsecs_t when) {
  3103. mCursorButtonAccumulator.reset(getDevice());
  3104. mCursorScrollAccumulator.reset(getDevice());
  3105. mTouchButtonAccumulator.reset(getDevice());
  3106. mPointerVelocityControl.reset();
  3107. mWheelXVelocityControl.reset();
  3108. mWheelYVelocityControl.reset();
  3109. mCurrentRawPointerData.clear();
  3110. mLastRawPointerData.clear();
  3111. mCurrentCookedPointerData.clear();
  3112. mLastCookedPointerData.clear();
  3113. mCurrentButtonState = 0;
  3114. mLastButtonState = 0;
  3115. mCurrentRawVScroll = 0;
  3116. mCurrentRawHScroll = 0;
  3117. mCurrentFingerIdBits.clear();
  3118. mLastFingerIdBits.clear();
  3119. mCurrentStylusIdBits.clear();
  3120. mLastStylusIdBits.clear();
  3121. mCurrentMouseIdBits.clear();
  3122. mLastMouseIdBits.clear();
  3123. mPointerUsage = POINTER_USAGE_NONE;
  3124. mSentHoverEnter = false;
  3125. mDownTime = 0;
  3126. mCurrentVirtualKey.down = false;
  3127. mPointerGesture.reset();
  3128. mPointerSimple.reset();
  3129. if (mPointerController != NULL) {
  3130. mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
  3131. mPointerController->clearSpots();
  3132. }
  3133. InputMapper::reset(when);
  3134. }
  3135. void TouchInputMapper::process(const RawEvent* rawEvent) {
  3136. mCursorButtonAccumulator.process(rawEvent);
  3137. mCursorScrollAccumulator.process(rawEvent);
  3138. mTouchButtonAccumulator.process(rawEvent);
  3139. if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
  3140. sync(rawEvent->when);
  3141. }
  3142. }
  3143. void TouchInputMapper::sync(nsecs_t when) {
  3144. // Sync button state.
  3145. mCurrentButtonState = mTouchButtonAccumulator.getButtonState()
  3146. | mCursorButtonAccumulator.getButtonState();
  3147. // Sync scroll state.
  3148. mCurrentRawVScroll = mCursorScrollAccumulator.getRelativeVWheel();
  3149. mCurrentRawHScroll = mCursorScrollAccumulator.getRelativeHWheel();
  3150. mCursorScrollAccumulator.finishSync();
  3151. // Sync touch state.
  3152. bool havePointerIds = true;
  3153. mCurrentRawPointerData.clear();
  3154. syncTouch(when, &havePointerIds);
  3155. #if DEBUG_RAW_EVENTS
  3156. if (!havePointerIds) {
  3157. ALOGD("syncTouch: pointerCount %d -> %d, no pointer ids",
  3158. mLastRawPointerData.pointerCount,
  3159. mCurrentRawPointerData.pointerCount);
  3160. } else {
  3161. ALOGD("syncTouch: pointerCount %d -> %d, touching ids 0x%08x -> 0x%08x, "
  3162. "hovering ids 0x%08x -> 0x%08x",
  3163. mLastRawPointerData.pointerCount,
  3164. mCurrentRawPointerData.pointerCount,
  3165. mLastRawPointerData.touchingIdBits.value,
  3166. mCurrentRawPointerData.touchingIdBits.value,
  3167. mLastRawPointerData.hoveringIdBits.value,
  3168. mCurrentRawPointerData.hoveringIdBits.value);
  3169. }
  3170. #endif
  3171. // Reset state that we will compute below.
  3172. mCurrentFingerIdBits.clear();
  3173. mCurrentStylusIdBits.clear();
  3174. mCurrentMouseIdBits.clear();
  3175. mCurrentCookedPointerData.clear();
  3176. if (mDeviceMode == DEVICE_MODE_DISABLED) {
  3177. // Drop all input if the device is disabled.
  3178. mCurrentRawPointerData.clear();
  3179. mCurrentButtonState = 0;
  3180. } else {
  3181. // Preprocess pointer data.
  3182. if (!havePointerIds) {
  3183. assignPointerIds();
  3184. }
  3185. // Handle policy on initial down or hover events.
  3186. uint32_t policyFlags = 0;
  3187. bool initialDown = mLastRawPointerData.pointerCount == 0
  3188. && mCurrentRawPointerData.pointerCount != 0;
  3189. bool buttonsPressed = mCurrentButtonState & ~mLastButtonState;
  3190. if (initialDown || buttonsPressed) {
  3191. // If this is a touch screen, hide the pointer on an initial down.
  3192. if (mDeviceMode == DEVICE_MODE_DIRECT) {
  3193. getContext()->fadePointer();
  3194. }
  3195. // Initial downs on external touch devices should wake the device.
  3196. // We don't do this for internal touch screens to prevent them from waking
  3197. // up in your pocket.
  3198. // TODO: Use the input device configuration to control this behavior more finely.
  3199. if (getDevice()->isExternal()) {
  3200. policyFlags |= POLICY_FLAG_WAKE_DROPPED;
  3201. }
  3202. }
  3203. // Synthesize key down from raw buttons if needed.
  3204. synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mSource,
  3205. policyFlags, mLastButtonState, mCurrentButtonState);
  3206. // Consume raw off-screen touches before cooking pointer data.
  3207. // If touches are consumed, subsequent code will not receive any pointer data.
  3208. if (consumeRawTouches(when, policyFlags)) {
  3209. mCurrentRawPointerData.clear();
  3210. }
  3211. // Cook pointer data. This call populates the mCurrentCookedPointerData structure
  3212. // with cooked pointer data that has the same ids and indices as the raw data.
  3213. // The following code can use either the raw or cooked data, as needed.
  3214. cookPointerData();
  3215. // Dispatch the touches either directly or by translation through a pointer on screen.
  3216. if (mDeviceMode == DEVICE_MODE_POINTER) {
  3217. for (BitSet32 idBits(mCurrentRawPointerData.touchingIdBits); !idBits.isEmpty(); ) {
  3218. uint32_t id = idBits.clearFirstMarkedBit();
  3219. const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
  3220. if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS
  3221. || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_ERASER) {
  3222. mCurrentStylusIdBits.markBit(id);
  3223. } else if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_FINGER
  3224. || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
  3225. mCurrentFingerIdBits.markBit(id);
  3226. } else if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_MOUSE) {
  3227. mCurrentMouseIdBits.markBit(id);
  3228. }
  3229. }
  3230. for (BitSet32 idBits(mCurrentRawPointerData.hoveringIdBits); !idBits.isEmpty(); ) {
  3231. uint32_t id = idBits.clearFirstMarkedBit();
  3232. const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
  3233. if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS
  3234. || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_ERASER) {
  3235. mCurrentStylusIdBits.markBit(id);
  3236. }
  3237. }
  3238. // Stylus takes precedence over all tools, then mouse, then finger.
  3239. PointerUsage pointerUsage = mPointerUsage;
  3240. if (!mCurrentStylusIdBits.isEmpty()) {
  3241. mCurrentMouseIdBits.clear();
  3242. mCurrentFingerIdBits.clear();
  3243. pointerUsage = POINTER_USAGE_STYLUS;
  3244. } else if (!mCurrentMouseIdBits.isEmpty()) {
  3245. mCurrentFingerIdBits.clear();
  3246. pointerUsage = POINTER_USAGE_MOUSE;
  3247. } else if (!mCurrentFingerIdBits.isEmpty() || isPointerDown(mCurrentButtonState)) {
  3248. pointerUsage = POINTER_USAGE_GESTURES;
  3249. }
  3250. dispatchPointerUsage(when, policyFlags, pointerUsage);
  3251. } else {
  3252. if (mDeviceMode == DEVICE_MODE_DIRECT
  3253. && mConfig.showTouches && mPointerController != NULL) {
  3254. mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_SPOT);
  3255. mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
  3256. mPointerController->setButtonState(mCurrentButtonState);
  3257. mPointerController->setSpots(mCurrentCookedPointerData.pointerCoords,
  3258. mCurrentCookedPointerData.idToIndex,
  3259. mCurrentCookedPointerData.touchingIdBits);
  3260. }
  3261. dispatchHoverExit(when, policyFlags);
  3262. dispatchTouches(when, policyFlags);
  3263. dispatchHoverEnterAndMove(when, policyFlags);
  3264. }
  3265. // Synthesize key up from raw buttons if needed.
  3266. synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mSource,
  3267. policyFlags, mLastButtonState, mCurrentButtonState);
  3268. }
  3269. // Copy current touch to last touch in preparation for the next cycle.
  3270. mLastRawPointerData.copyFrom(mCurrentRawPointerData);
  3271. mLastCookedPointerData.copyFrom(mCurrentCookedPointerData);
  3272. mLastButtonState = mCurrentButtonState;
  3273. mLastFingerIdBits = mCurrentFingerIdBits;
  3274. mLastStylusIdBits = mCurrentStylusIdBits;
  3275. mLastMouseIdBits = mCurrentMouseIdBits;
  3276. // Clear some transient state.
  3277. mCurrentRawVScroll = 0;
  3278. mCurrentRawHScroll = 0;
  3279. }
  3280. void TouchInputMapper::timeoutExpired(nsecs_t when) {
  3281. if (mDeviceMode == DEVICE_MODE_POINTER) {
  3282. if (mPointerUsage == POINTER_USAGE_GESTURES) {
  3283. dispatchPointerGestures(when, 0 /*policyFlags*/, true /*isTimeout*/);
  3284. }
  3285. }
  3286. }
  3287. bool TouchInputMapper::consumeRawTouches(nsecs_t when, uint32_t policyFlags) {
  3288. // Check for release of a virtual key.
  3289. if (mCurrentVirtualKey.down) {
  3290. if (mCurrentRawPointerData.touchingIdBits.isEmpty()) {
  3291. // Pointer went up while virtual key was down.
  3292. mCurrentVirtualKey.down = false;
  3293. if (!mCurrentVirtualKey.ignored) {
  3294. #if DEBUG_VIRTUAL_KEYS
  3295. ALOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
  3296. mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
  3297. #endif
  3298. dispatchVirtualKey(when, policyFlags,
  3299. AKEY_EVENT_ACTION_UP,
  3300. AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
  3301. }
  3302. return true;
  3303. }
  3304. if (mCurrentRawPointerData.touchingIdBits.count() == 1) {
  3305. uint32_t id = mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
  3306. const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
  3307. const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
  3308. if (virtualKey && virtualKey->keyCode == mCurrentVirtualKey.keyCode) {
  3309. // Pointer is still within the space of the virtual key.
  3310. return true;
  3311. }
  3312. }
  3313. // Pointer left virtual key area or another pointer also went down.
  3314. // Send key cancellation but do not consume the touch yet.
  3315. // This is useful when the user swipes through from the virtual key area
  3316. // into the main display surface.
  3317. mCurrentVirtualKey.down = false;
  3318. if (!mCurrentVirtualKey.ignored) {
  3319. #if DEBUG_VIRTUAL_KEYS
  3320. ALOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
  3321. mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
  3322. #endif
  3323. dispatchVirtualKey(when, policyFlags,
  3324. AKEY_EVENT_ACTION_UP,
  3325. AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
  3326. | AKEY_EVENT_FLAG_CANCELED);
  3327. }
  3328. }
  3329. if (mLastRawPointerData.touchingIdBits.isEmpty()
  3330. && !mCurrentRawPointerData.touchingIdBits.isEmpty()) {
  3331. // Pointer just went down. Check for virtual key press or off-screen touches.
  3332. uint32_t id = mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
  3333. const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
  3334. if (!isPointInsideSurface(pointer.x, pointer.y)) {
  3335. // If exactly one pointer went down, check for virtual key hit.
  3336. // Otherwise we will drop the entire stroke.
  3337. if (mCurrentRawPointerData.touchingIdBits.count() == 1) {
  3338. const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
  3339. if (virtualKey) {
  3340. mCurrentVirtualKey.down = true;
  3341. mCurrentVirtualKey.downTime = when;
  3342. mCurrentVirtualKey.keyCode = virtualKey->keyCode;
  3343. mCurrentVirtualKey.scanCode = virtualKey->scanCode;
  3344. mCurrentVirtualKey.ignored = mContext->shouldDropVirtualKey(
  3345. when, getDevice(), virtualKey->keyCode, virtualKey->scanCode);
  3346. if (!mCurrentVirtualKey.ignored) {
  3347. #if DEBUG_VIRTUAL_KEYS
  3348. ALOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
  3349. mCurrentVirtualKey.keyCode,
  3350. mCurrentVirtualKey.scanCode);
  3351. #endif
  3352. dispatchVirtualKey(when, policyFlags,
  3353. AKEY_EVENT_ACTION_DOWN,
  3354. AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
  3355. }
  3356. }
  3357. }
  3358. return true;
  3359. }
  3360. }
  3361. // Disable all virtual key touches that happen within a short time interval of the
  3362. // most recent touch within the screen area. The idea is to filter out stray
  3363. // virtual key presses when interacting with the touch screen.
  3364. //
  3365. // Problems we're trying to solve:
  3366. //
  3367. // 1. While scrolling a list or dragging the window shade, the user swipes down into a
  3368. // virtual key area that is implemented by a separate touch panel and accidentally
  3369. // triggers a virtual key.
  3370. //
  3371. // 2. While typing in the on screen keyboard, the user taps slightly outside the screen
  3372. // area and accidentally triggers a virtual key. This often happens when virtual keys
  3373. // are layed out below the screen near to where the on screen keyboard's space bar
  3374. // is displayed.
  3375. if (mConfig.virtualKeyQuietTime > 0 && !mCurrentRawPointerData.touchingIdBits.isEmpty()) {
  3376. mContext->disableVirtualKeysUntil(when + mConfig.virtualKeyQuietTime);
  3377. }
  3378. return false;
  3379. }
  3380. void TouchInputMapper::dispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
  3381. int32_t keyEventAction, int32_t keyEventFlags) {
  3382. int32_t keyCode = mCurrentVirtualKey.keyCode;
  3383. int32_t scanCode = mCurrentVirtualKey.scanCode;
  3384. nsecs_t downTime = mCurrentVirtualKey.downTime;
  3385. int32_t metaState = mContext->getGlobalMetaState();
  3386. policyFlags |= POLICY_FLAG_VIRTUAL;
  3387. NotifyKeyArgs args(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
  3388. keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
  3389. getListener()->notifyKey(&args);
  3390. }
  3391. void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
  3392. BitSet32 currentIdBits = mCurrentCookedPointerData.touchingIdBits;
  3393. BitSet32 lastIdBits = mLastCookedPointerData.touchingIdBits;
  3394. int32_t metaState = getContext()->getGlobalMetaState();
  3395. int32_t buttonState = mCurrentButtonState;
  3396. if (currentIdBits == lastIdBits) {
  3397. if (!currentIdBits.isEmpty()) {
  3398. // No pointer id changes so this is a move event.
  3399. // The listener takes care of batching moves so we don't have to deal with that here.
  3400. dispatchMotion(when, policyFlags, mSource,
  3401. AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState,
  3402. AMOTION_EVENT_EDGE_FLAG_NONE,
  3403. mCurrentCookedPointerData.pointerProperties,
  3404. mCurrentCookedPointerData.pointerCoords,
  3405. mCurrentCookedPointerData.idToIndex,
  3406. currentIdBits, -1,
  3407. mOrientedXPrecision, mOrientedYPrecision, mDownTime);
  3408. }
  3409. } else {
  3410. // There may be pointers going up and pointers going down and pointers moving
  3411. // all at the same time.
  3412. BitSet32 upIdBits(lastIdBits.value & ~currentIdBits.value);
  3413. BitSet32 downIdBits(currentIdBits.value & ~lastIdBits.value);
  3414. BitSet32 moveIdBits(lastIdBits.value & currentIdBits.value);
  3415. BitSet32 dispatchedIdBits(lastIdBits.value);
  3416. // Update last coordinates of pointers that have moved so that we observe the new
  3417. // pointer positions at the same time as other pointers that have just gone up.
  3418. bool moveNeeded = updateMovedPointers(
  3419. mCurrentCookedPointerData.pointerProperties,
  3420. mCurrentCookedPointerData.pointerCoords,
  3421. mCurrentCookedPointerData.idToIndex,
  3422. mLastCookedPointerData.pointerProperties,
  3423. mLastCookedPointerData.pointerCoords,
  3424. mLastCookedPointerData.idToIndex,
  3425. moveIdBits);
  3426. if (buttonState != mLastButtonState) {
  3427. moveNeeded = true;
  3428. }
  3429. // Dispatch pointer up events.
  3430. while (!upIdBits.isEmpty()) {
  3431. uint32_t upId = upIdBits.clearFirstMarkedBit();
  3432. dispatchMotion(when, policyFlags, mSource,
  3433. AMOTION_EVENT_ACTION_POINTER_UP, 0, metaState, buttonState, 0,
  3434. mLastCookedPointerData.pointerProperties,
  3435. mLastCookedPointerData.pointerCoords,
  3436. mLastCookedPointerData.idToIndex,
  3437. dispatchedIdBits, upId,
  3438. mOrientedXPrecision, mOrientedYPrecision, mDownTime);
  3439. dispatchedIdBits.clearBit(upId);
  3440. }
  3441. // Dispatch move events if any of the remaining pointers moved from their old locations.
  3442. // Although applications receive new locations as part of individual pointer up
  3443. // events, they do not generally handle them except when presented in a move event.
  3444. if (moveNeeded) {
  3445. ALOG_ASSERT(moveIdBits.value == dispatchedIdBits.value);
  3446. dispatchMotion(when, policyFlags, mSource,
  3447. AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, 0,
  3448. mCurrentCookedPointerData.pointerProperties,
  3449. mCurrentCookedPointerData.pointerCoords,
  3450. mCurrentCookedPointerData.idToIndex,
  3451. dispatchedIdBits, -1,
  3452. mOrientedXPrecision, mOrientedYPrecision, mDownTime);
  3453. }
  3454. // Dispatch pointer down events using the new pointer locations.
  3455. while (!downIdBits.isEmpty()) {
  3456. uint32_t downId = downIdBits.clearFirstMarkedBit();
  3457. dispatchedIdBits.markBit(downId);
  3458. if (dispatchedIdBits.count() == 1) {
  3459. // First pointer is going down. Set down time.
  3460. mDownTime = when;
  3461. }
  3462. dispatchMotion(when, policyFlags, mSource,
  3463. AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, 0,
  3464. mCurrentCookedPointerData.pointerProperties,
  3465. mCurrentCookedPointerData.pointerCoords,
  3466. mCurrentCookedPointerData.idToIndex,
  3467. dispatchedIdBits, downId,
  3468. mOrientedXPrecision, mOrientedYPrecision, mDownTime);
  3469. }
  3470. }
  3471. }
  3472. void TouchInputMapper::dispatchHoverExit(nsecs_t when, uint32_t policyFlags) {
  3473. if (mSentHoverEnter &&
  3474. (mCurrentCookedPointerData.hoveringIdBits.isEmpty()
  3475. || !mCurrentCookedPointerData.touchingIdBits.isEmpty())) {
  3476. int32_t metaState = getContext()->getGlobalMetaState();
  3477. dispatchMotion(when, policyFlags, mSource,
  3478. AMOTION_EVENT_ACTION_HOVER_EXIT, 0, metaState, mLastButtonState, 0,
  3479. mLastCookedPointerData.pointerProperties,
  3480. mLastCookedPointerData.pointerCoords,
  3481. mLastCookedPointerData.idToIndex,
  3482. mLastCookedPointerData.hoveringIdBits, -1,
  3483. mOrientedXPrecision, mOrientedYPrecision, mDownTime);
  3484. mSentHoverEnter = false;
  3485. }
  3486. }
  3487. void TouchInputMapper::dispatchHoverEnterAndMove(nsecs_t when, uint32_t policyFlags) {
  3488. if (mCurrentCookedPointerData.touchingIdBits.isEmpty()
  3489. && !mCurrentCookedPointerData.hoveringIdBits.isEmpty()) {
  3490. int32_t metaState = getContext()->getGlobalMetaState();
  3491. if (!mSentHoverEnter) {
  3492. dispatchMotion(when, policyFlags, mSource,
  3493. AMOTION_EVENT_ACTION_HOVER_ENTER, 0, metaState, mCurrentButtonState, 0,
  3494. mCurrentCookedPointerData.pointerProperties,
  3495. mCurrentCookedPointerData.pointerCoords,
  3496. mCurrentCookedPointerData.idToIndex,
  3497. mCurrentCookedPointerData.hoveringIdBits, -1,
  3498. mOrientedXPrecision, mOrientedYPrecision, mDownTime);
  3499. mSentHoverEnter = true;
  3500. }
  3501. dispatchMotion(when, policyFlags, mSource,
  3502. AMOTION_EVENT_ACTION_HOVER_MOVE, 0, metaState, mCurrentButtonState, 0,
  3503. mCurrentCookedPointerData.pointerProperties,
  3504. mCurrentCookedPointerData.pointerCoords,
  3505. mCurrentCookedPointerData.idToIndex,
  3506. mCurrentCookedPointerData.hoveringIdBits, -1,
  3507. mOrientedXPrecision, mOrientedYPrecision, mDownTime);
  3508. }
  3509. }
  3510. void TouchInputMapper::cookPointerData() {
  3511. uint32_t currentPointerCount = mCurrentRawPointerData.pointerCount;
  3512. mCurrentCookedPointerData.clear();
  3513. mCurrentCookedPointerData.pointerCount = currentPointerCount;
  3514. mCurrentCookedPointerData.hoveringIdBits = mCurrentRawPointerData.hoveringIdBits;
  3515. mCurrentCookedPointerData.touchingIdBits = mCurrentRawPointerData.touchingIdBits;
  3516. // Walk through the the active pointers and map device coordinates onto
  3517. // surface coordinates and adjust for display orientation.
  3518. for (uint32_t i = 0; i < currentPointerCount; i++) {
  3519. const RawPointerData::Pointer& in = mCurrentRawPointerData.pointers[i];
  3520. // Size
  3521. float touchMajor, touchMinor, toolMajor, toolMinor, size;
  3522. switch (mCalibration.sizeCalibration) {
  3523. case Calibration::SIZE_CALIBRATION_GEOMETRIC:
  3524. case Calibration::SIZE_CALIBRATION_DIAMETER:
  3525. case Calibration::SIZE_CALIBRATION_BOX:
  3526. case Calibration::SIZE_CALIBRATION_AREA:
  3527. if (mRawPointerAxes.touchMajor.valid && mRawPointerAxes.toolMajor.valid) {
  3528. touchMajor = in.touchMajor;
  3529. touchMinor = mRawPointerAxes.touchMinor.valid ? in.touchMinor : in.touchMajor;
  3530. toolMajor = in.toolMajor;
  3531. toolMinor = mRawPointerAxes.toolMinor.valid ? in.toolMinor : in.toolMajor;
  3532. size = mRawPointerAxes.touchMinor.valid
  3533. ? avg(in.touchMajor, in.touchMinor) : in.touchMajor;
  3534. } else if (mRawPointerAxes.touchMajor.valid) {
  3535. toolMajor = touchMajor = in.touchMajor;
  3536. toolMinor = touchMinor = mRawPointerAxes.touchMinor.valid
  3537. ? in.touchMinor : in.touchMajor;
  3538. size = mRawPointerAxes.touchMinor.valid
  3539. ? avg(in.touchMajor, in.touchMinor) : in.touchMajor;
  3540. } else if (mRawPointerAxes.toolMajor.valid) {
  3541. touchMajor = toolMajor = in.toolMajor;
  3542. touchMinor = toolMinor = mRawPointerAxes.toolMinor.valid
  3543. ? in.toolMinor : in.toolMajor;
  3544. size = mRawPointerAxes.toolMinor.valid
  3545. ? avg(in.toolMajor, in.toolMinor) : in.toolMajor;
  3546. } else {
  3547. ALOG_ASSERT(false, "No touch or tool axes. "
  3548. "Size calibration should have been resolved to NONE.");
  3549. touchMajor = 0;
  3550. touchMinor = 0;
  3551. toolMajor = 0;
  3552. toolMinor = 0;
  3553. size = 0;
  3554. }
  3555. if (mCalibration.haveSizeIsSummed && mCalibration.sizeIsSummed) {
  3556. uint32_t touchingCount = mCurrentRawPointerData.touchingIdBits.count();
  3557. if (touchingCount > 1) {
  3558. touchMajor /= touchingCount;
  3559. touchMinor /= touchingCount;
  3560. toolMajor /= touchingCount;
  3561. toolMinor /= touchingCount;
  3562. size /= touchingCount;
  3563. }
  3564. }
  3565. if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_GEOMETRIC) {
  3566. touchMajor *= mGeometricScale;
  3567. touchMinor *= mGeometricScale;
  3568. toolMajor *= mGeometricScale;
  3569. toolMinor *= mGeometricScale;
  3570. } else if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_AREA) {
  3571. touchMajor = touchMajor > 0 ? sqrtf(touchMajor) : 0;
  3572. touchMinor = touchMajor;
  3573. toolMajor = toolMajor > 0 ? sqrtf(toolMajor) : 0;
  3574. toolMinor = toolMajor;
  3575. } else if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_DIAMETER) {
  3576. touchMinor = touchMajor;
  3577. toolMinor = toolMajor;
  3578. }
  3579. mCalibration.applySizeScaleAndBias(&touchMajor);
  3580. mCalibration.applySizeScaleAndBias(&touchMinor);
  3581. mCalibration.applySizeScaleAndBias(&toolMajor);
  3582. mCalibration.applySizeScaleAndBias(&toolMinor);
  3583. size *= mSizeScale;
  3584. break;
  3585. default:
  3586. touchMajor = 0;
  3587. touchMinor = 0;
  3588. toolMajor = 0;
  3589. toolMinor = 0;
  3590. size = 0;
  3591. break;
  3592. }
  3593. // Pressure
  3594. float pressure;
  3595. switch (mCalibration.pressureCalibration) {
  3596. case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
  3597. case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
  3598. pressure = in.pressure * mPressureScale;
  3599. break;
  3600. default:
  3601. pressure = in.isHovering ? 0 : 1;
  3602. break;
  3603. }
  3604. // Tilt and Orientation
  3605. float tilt;
  3606. float orientation;
  3607. if (mHaveTilt) {
  3608. float tiltXAngle = (in.tiltX - mTiltXCenter) * mTiltXScale;
  3609. float tiltYAngle = (in.tiltY - mTiltYCenter) * mTiltYScale;
  3610. orientation = atan2f(-sinf(tiltXAngle), sinf(tiltYAngle));
  3611. tilt = acosf(cosf(tiltXAngle) * cosf(tiltYAngle));
  3612. } else {
  3613. tilt = 0;
  3614. switch (mCalibration.orientationCalibration) {
  3615. case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
  3616. orientation = in.orientation * mOrientationScale;
  3617. break;
  3618. case Calibration::ORIENTATION_CALIBRATION_VECTOR: {
  3619. int32_t c1 = signExtendNybble((in.orientation & 0xf0) >> 4);
  3620. int32_t c2 = signExtendNybble(in.orientation & 0x0f);
  3621. if (c1 != 0 || c2 != 0) {
  3622. orientation = atan2f(c1, c2) * 0.5f;
  3623. float confidence = hypotf(c1, c2);
  3624. float scale = 1.0f + confidence / 16.0f;
  3625. touchMajor *= scale;
  3626. touchMinor /= scale;
  3627. toolMajor *= scale;
  3628. toolMinor /= scale;
  3629. } else {
  3630. orientation = 0;
  3631. }
  3632. break;
  3633. }
  3634. default:
  3635. orientation = 0;
  3636. }
  3637. }
  3638. // Distance
  3639. float distance;
  3640. switch (mCalibration.distanceCalibration) {
  3641. case Calibration::DISTANCE_CALIBRATION_SCALED:
  3642. distance = in.distance * mDistanceScale;
  3643. break;
  3644. default:
  3645. distance = 0;
  3646. }
  3647. // Coverage
  3648. int32_t rawLeft, rawTop, rawRight, rawBottom;
  3649. switch (mCalibration.coverageCalibration) {
  3650. case Calibration::COVERAGE_CALIBRATION_BOX:
  3651. rawLeft = (in.toolMinor & 0xffff0000) >> 16;
  3652. rawRight = in.toolMinor & 0x0000ffff;
  3653. rawBottom = in.toolMajor & 0x0000ffff;
  3654. rawTop = (in.toolMajor & 0xffff0000) >> 16;
  3655. break;
  3656. default:
  3657. rawLeft = rawTop = rawRight = rawBottom = 0;
  3658. break;
  3659. }
  3660. // X, Y, and the bounding box for coverage information
  3661. // Adjust coords for surface orientation.
  3662. float x, y, left, top, right, bottom;
  3663. switch (mSurfaceOrientation) {
  3664. case DISPLAY_ORIENTATION_90:
  3665. x = float(in.y - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
  3666. y = float(mRawPointerAxes.x.maxValue - in.x) * mXScale + mXTranslate;
  3667. left = float(rawTop - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
  3668. right = float(rawBottom- mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
  3669. bottom = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
  3670. top = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale + mXTranslate;
  3671. orientation -= M_PI_2;
  3672. if (orientation < mOrientedRanges.orientation.min) {
  3673. orientation += (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
  3674. }
  3675. break;
  3676. case DISPLAY_ORIENTATION_180:
  3677. x = float(mRawPointerAxes.x.maxValue - in.x) * mXScale + mXTranslate;
  3678. y = float(mRawPointerAxes.y.maxValue - in.y) * mYScale + mYTranslate;
  3679. left = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale + mXTranslate;
  3680. right = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
  3681. bottom = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
  3682. top = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale + mYTranslate;
  3683. orientation -= M_PI;
  3684. if (orientation < mOrientedRanges.orientation.min) {
  3685. orientation += (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
  3686. }
  3687. break;
  3688. case DISPLAY_ORIENTATION_270:
  3689. x = float(mRawPointerAxes.y.maxValue - in.y) * mYScale + mYTranslate;
  3690. y = float(in.x - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
  3691. left = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale + mYTranslate;
  3692. right = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
  3693. bottom = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
  3694. top = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
  3695. orientation += M_PI_2;
  3696. if (orientation > mOrientedRanges.orientation.max) {
  3697. orientation -= (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
  3698. }
  3699. break;
  3700. default:
  3701. x = float(in.x - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
  3702. y = float(in.y - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
  3703. left = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
  3704. right = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
  3705. bottom = float(rawBottom - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
  3706. top = float(rawTop - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
  3707. break;
  3708. }
  3709. // Write output coords.
  3710. PointerCoords& out = mCurrentCookedPointerData.pointerCoords[i];
  3711. out.clear();
  3712. out.setAxisValue(AMOTION_EVENT_AXIS_X, x);
  3713. out.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
  3714. out.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure);
  3715. out.setAxisValue(AMOTION_EVENT_AXIS_SIZE, size);
  3716. out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, touchMajor);
  3717. out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, touchMinor);
  3718. out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, orientation);
  3719. out.setAxisValue(AMOTION_EVENT_AXIS_TILT, tilt);
  3720. out.setAxisValue(AMOTION_EVENT_AXIS_DISTANCE, distance);
  3721. if (mCalibration.coverageCalibration == Calibration::COVERAGE_CALIBRATION_BOX) {
  3722. out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_1, left);
  3723. out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_2, top);
  3724. out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_3, right);
  3725. out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_4, bottom);
  3726. } else {
  3727. out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, toolMajor);
  3728. out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, toolMinor);
  3729. }
  3730. // Write output properties.
  3731. PointerProperties& properties = mCurrentCookedPointerData.pointerProperties[i];
  3732. uint32_t id = in.id;
  3733. properties.clear();
  3734. properties.id = id;
  3735. properties.toolType = in.toolType;
  3736. // Write id index.
  3737. mCurrentCookedPointerData.idToIndex[id] = i;
  3738. }
  3739. }
  3740. void TouchInputMapper::dispatchPointerUsage(nsecs_t when, uint32_t policyFlags,
  3741. PointerUsage pointerUsage) {
  3742. if (pointerUsage != mPointerUsage) {
  3743. abortPointerUsage(when, policyFlags);
  3744. mPointerUsage = pointerUsage;
  3745. }
  3746. switch (mPointerUsage) {
  3747. case POINTER_USAGE_GESTURES:
  3748. dispatchPointerGestures(when, policyFlags, false /*isTimeout*/);
  3749. break;
  3750. case POINTER_USAGE_STYLUS:
  3751. dispatchPointerStylus(when, policyFlags);
  3752. break;
  3753. case POINTER_USAGE_MOUSE:
  3754. dispatchPointerMouse(when, policyFlags);
  3755. break;
  3756. default:
  3757. break;
  3758. }
  3759. }
  3760. void TouchInputMapper::abortPointerUsage(nsecs_t when, uint32_t policyFlags) {
  3761. switch (mPointerUsage) {
  3762. case POINTER_USAGE_GESTURES:
  3763. abortPointerGestures(when, policyFlags);
  3764. break;
  3765. case POINTER_USAGE_STYLUS:
  3766. abortPointerStylus(when, policyFlags);
  3767. break;
  3768. case POINTER_USAGE_MOUSE:
  3769. abortPointerMouse(when, policyFlags);
  3770. break;
  3771. default:
  3772. break;
  3773. }
  3774. mPointerUsage = POINTER_USAGE_NONE;
  3775. }
  3776. void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlags,
  3777. bool isTimeout) {
  3778. // Update current gesture coordinates.
  3779. bool cancelPreviousGesture, finishPreviousGesture;
  3780. bool sendEvents = preparePointerGestures(when,
  3781. &cancelPreviousGesture, &finishPreviousGesture, isTimeout);
  3782. if (!sendEvents) {
  3783. return;
  3784. }
  3785. if (finishPreviousGesture) {
  3786. cancelPreviousGesture = false;
  3787. }
  3788. // Update the pointer presentation and spots.
  3789. if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
  3790. mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_SPOT);
  3791. if (finishPreviousGesture || cancelPreviousGesture) {
  3792. mPointerController->clearSpots();
  3793. }
  3794. mPointerController->setSpots(mPointerGesture.currentGestureCoords,
  3795. mPointerGesture.currentGestureIdToIndex,
  3796. mPointerGesture.currentGestureIdBits);
  3797. } else {
  3798. mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
  3799. }
  3800. // Show or hide the pointer if needed.
  3801. switch (mPointerGesture.currentGestureMode) {
  3802. case PointerGesture::NEUTRAL:
  3803. case PointerGesture::QUIET:
  3804. if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS
  3805. && (mPointerGesture.lastGestureMode == PointerGesture::SWIPE
  3806. || mPointerGesture.lastGestureMode == PointerGesture::FREEFORM)) {
  3807. // Remind the user of where the pointer is after finishing a gesture with spots.
  3808. mPointerController->unfade(PointerControllerInterface::TRANSITION_GRADUAL);
  3809. }
  3810. break;
  3811. case PointerGesture::TAP:
  3812. case PointerGesture::TAP_DRAG:
  3813. case PointerGesture::BUTTON_CLICK_OR_DRAG:
  3814. case PointerGesture::HOVER:
  3815. case PointerGesture::PRESS:
  3816. // Unfade the pointer when the current gesture manipulates the
  3817. // area directly under the pointer.
  3818. mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
  3819. break;
  3820. case PointerGesture::SWIPE:
  3821. case PointerGesture::FREEFORM:
  3822. // Fade the pointer when the current gesture manipulates a different
  3823. // area and there are spots to guide the user experience.
  3824. if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
  3825. mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
  3826. } else {
  3827. mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
  3828. }
  3829. break;
  3830. }
  3831. // Send events!
  3832. int32_t metaState = getContext()->getGlobalMetaState();
  3833. int32_t buttonState = mCurrentButtonState;
  3834. // Update last coordinates of pointers that have moved so that we observe the new
  3835. // pointer positions at the same time as other pointers that have just gone up.
  3836. bool down = mPointerGesture.currentGestureMode == PointerGesture::TAP
  3837. || mPointerGesture.currentGestureMode == PointerGesture::TAP_DRAG
  3838. || mPointerGesture.currentGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG
  3839. || mPointerGesture.currentGestureMode == PointerGesture::PRESS
  3840. || mPointerGesture.currentGestureMode == PointerGesture::SWIPE
  3841. || mPointerGesture.currentGestureMode == PointerGesture::FREEFORM;
  3842. bool moveNeeded = false;
  3843. if (down && !cancelPreviousGesture && !finishPreviousGesture
  3844. && !mPointerGesture.lastGestureIdBits.isEmpty()
  3845. && !mPointerGesture.currentGestureIdBits.isEmpty()) {
  3846. BitSet32 movedGestureIdBits(mPointerGesture.currentGestureIdBits.value
  3847. & mPointerGesture.lastGestureIdBits.value);
  3848. moveNeeded = updateMovedPointers(mPointerGesture.currentGestureProperties,
  3849. mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
  3850. mPointerGesture.lastGestureProperties,
  3851. mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
  3852. movedGestureIdBits);
  3853. if (buttonState != mLastButtonState) {
  3854. moveNeeded = true;
  3855. }
  3856. }
  3857. // Send motion events for all pointers that went up or were canceled.
  3858. BitSet32 dispatchedGestureIdBits(mPointerGesture.lastGestureIdBits);
  3859. if (!dispatchedGestureIdBits.isEmpty()) {
  3860. if (cancelPreviousGesture) {
  3861. dispatchMotion(when, policyFlags, mSource,
  3862. AMOTION_EVENT_ACTION_CANCEL, 0, metaState, buttonState,
  3863. AMOTION_EVENT_EDGE_FLAG_NONE,
  3864. mPointerGesture.lastGestureProperties,
  3865. mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
  3866. dispatchedGestureIdBits, -1,
  3867. 0, 0, mPointerGesture.downTime);
  3868. dispatchedGestureIdBits.clear();
  3869. } else {
  3870. BitSet32 upGestureIdBits;
  3871. if (finishPreviousGesture) {
  3872. upGestureIdBits = dispatchedGestureIdBits;
  3873. } else {
  3874. upGestureIdBits.value = dispatchedGestureIdBits.value
  3875. & ~mPointerGesture.currentGestureIdBits.value;
  3876. }
  3877. while (!upGestureIdBits.isEmpty()) {
  3878. uint32_t id = upGestureIdBits.clearFirstMarkedBit();
  3879. dispatchMotion(when, policyFlags, mSource,
  3880. AMOTION_EVENT_ACTION_POINTER_UP, 0,
  3881. metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
  3882. mPointerGesture.lastGestureProperties,
  3883. mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
  3884. dispatchedGestureIdBits, id,
  3885. 0, 0, mPointerGesture.downTime);
  3886. dispatchedGestureIdBits.clearBit(id);
  3887. }
  3888. }
  3889. }
  3890. // Send motion events for all pointers that moved.
  3891. if (moveNeeded) {
  3892. dispatchMotion(when, policyFlags, mSource,
  3893. AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
  3894. mPointerGesture.currentGestureProperties,
  3895. mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
  3896. dispatchedGestureIdBits, -1,
  3897. 0, 0, mPointerGesture.downTime);
  3898. }
  3899. // Send motion events for all pointers that went down.
  3900. if (down) {
  3901. BitSet32 downGestureIdBits(mPointerGesture.currentGestureIdBits.value
  3902. & ~dispatchedGestureIdBits.value);
  3903. while (!downGestureIdBits.isEmpty()) {
  3904. uint32_t id = downGestureIdBits.clearFirstMarkedBit();
  3905. dispatchedGestureIdBits.markBit(id);
  3906. if (dispatchedGestureIdBits.count() == 1) {
  3907. mPointerGesture.downTime = when;
  3908. }
  3909. dispatchMotion(when, policyFlags, mSource,
  3910. AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, 0,
  3911. mPointerGesture.currentGestureProperties,
  3912. mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
  3913. dispatchedGestureIdBits, id,
  3914. 0, 0, mPointerGesture.downTime);
  3915. }
  3916. }
  3917. // Send motion events for hover.
  3918. if (mPointerGesture.currentGestureMode == PointerGesture::HOVER) {
  3919. dispatchMotion(when, policyFlags, mSource,
  3920. AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
  3921. metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
  3922. mPointerGesture.currentGestureProperties,
  3923. mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
  3924. mPointerGesture.currentGestureIdBits, -1,
  3925. 0, 0, mPointerGesture.downTime);
  3926. } else if (dispatchedGestureIdBits.isEmpty()
  3927. && !mPointerGesture.lastGestureIdBits.isEmpty()) {
  3928. // Synthesize a hover move event after all pointers go up to indicate that
  3929. // the pointer is hovering again even if the user is not currently touching
  3930. // the touch pad. This ensures that a view will receive a fresh hover enter
  3931. // event after a tap.
  3932. float x, y;
  3933. mPointerController->getPosition(&x, &y);
  3934. PointerProperties pointerProperties;
  3935. pointerProperties.clear();
  3936. pointerProperties.id = 0;
  3937. pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
  3938. PointerCoords pointerCoords;
  3939. pointerCoords.clear();
  3940. pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
  3941. pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
  3942. NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
  3943. AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
  3944. metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
  3945. mViewport.displayId, 1, &pointerProperties, &pointerCoords,
  3946. 0, 0, mPointerGesture.downTime);
  3947. getListener()->notifyMotion(&args);
  3948. }
  3949. // Update state.
  3950. mPointerGesture.lastGestureMode = mPointerGesture.currentGestureMode;
  3951. if (!down) {
  3952. mPointerGesture.lastGestureIdBits.clear();
  3953. } else {
  3954. mPointerGesture.lastGestureIdBits = mPointerGesture.currentGestureIdBits;
  3955. for (BitSet32 idBits(mPointerGesture.currentGestureIdBits); !idBits.isEmpty(); ) {
  3956. uint32_t id = idBits.clearFirstMarkedBit();
  3957. uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
  3958. mPointerGesture.lastGestureProperties[index].copyFrom(
  3959. mPointerGesture.currentGestureProperties[index]);
  3960. mPointerGesture.lastGestureCoords[index].copyFrom(
  3961. mPointerGesture.currentGestureCoords[index]);
  3962. mPointerGesture.lastGestureIdToIndex[id] = index;
  3963. }
  3964. }
  3965. }
  3966. void TouchInputMapper::abortPointerGestures(nsecs_t when, uint32_t policyFlags) {
  3967. // Cancel previously dispatches pointers.
  3968. if (!mPointerGesture.lastGestureIdBits.isEmpty()) {
  3969. int32_t metaState = getContext()->getGlobalMetaState();
  3970. int32_t buttonState = mCurrentButtonState;
  3971. dispatchMotion(when, policyFlags, mSource,
  3972. AMOTION_EVENT_ACTION_CANCEL, 0, metaState, buttonState,
  3973. AMOTION_EVENT_EDGE_FLAG_NONE,
  3974. mPointerGesture.lastGestureProperties,
  3975. mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
  3976. mPointerGesture.lastGestureIdBits, -1,
  3977. 0, 0, mPointerGesture.downTime);
  3978. }
  3979. // Reset the current pointer gesture.
  3980. mPointerGesture.reset();
  3981. mPointerVelocityControl.reset();
  3982. // Remove any current spots.
  3983. if (mPointerController != NULL) {
  3984. mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
  3985. mPointerController->clearSpots();
  3986. }
  3987. }
  3988. bool TouchInputMapper::preparePointerGestures(nsecs_t when,
  3989. bool* outCancelPreviousGesture, bool* outFinishPreviousGesture, bool isTimeout) {
  3990. *outCancelPreviousGesture = false;
  3991. *outFinishPreviousGesture = false;
  3992. // Handle TAP timeout.
  3993. if (isTimeout) {
  3994. #if DEBUG_GESTURES
  3995. ALOGD("Gestures: Processing timeout");
  3996. #endif
  3997. if (mPointerGesture.lastGestureMode == PointerGesture::TAP) {
  3998. if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) {
  3999. // The tap/drag timeout has not yet expired.
  4000. getContext()->requestTimeoutAtTime(mPointerGesture.tapUpTime
  4001. + mConfig.pointerGestureTapDragInterval);
  4002. } else {
  4003. // The tap is finished.
  4004. #if DEBUG_GESTURES
  4005. ALOGD("Gestures: TAP finished");
  4006. #endif
  4007. *outFinishPreviousGesture = true;
  4008. mPointerGesture.activeGestureId = -1;
  4009. mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
  4010. mPointerGesture.currentGestureIdBits.clear();
  4011. mPointerVelocityControl.reset();
  4012. return true;
  4013. }
  4014. }
  4015. // We did not handle this timeout.
  4016. return false;
  4017. }
  4018. const uint32_t currentFingerCount = mCurrentFingerIdBits.count();
  4019. const uint32_t lastFingerCount = mLastFingerIdBits.count();
  4020. // Update the velocity tracker.
  4021. {
  4022. VelocityTracker::Position positions[MAX_POINTERS];
  4023. uint32_t count = 0;
  4024. for (BitSet32 idBits(mCurrentFingerIdBits); !idBits.isEmpty(); count++) {
  4025. uint32_t id = idBits.clearFirstMarkedBit();
  4026. const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
  4027. positions[count].x = pointer.x * mPointerXMovementScale;
  4028. positions[count].y = pointer.y * mPointerYMovementScale;
  4029. }
  4030. mPointerGesture.velocityTracker.addMovement(when,
  4031. mCurrentFingerIdBits, positions);
  4032. }
  4033. // If the gesture ever enters a mode other than TAP, HOVER or TAP_DRAG, without first returning
  4034. // to NEUTRAL, then we should not generate tap event.
  4035. if (mPointerGesture.lastGestureMode != PointerGesture::HOVER
  4036. && mPointerGesture.lastGestureMode != PointerGesture::TAP
  4037. && mPointerGesture.lastGestureMode != PointerGesture::TAP_DRAG) {
  4038. mPointerGesture.resetTap();
  4039. }
  4040. // Pick a new active touch id if needed.
  4041. // Choose an arbitrary pointer that just went down, if there is one.
  4042. // Otherwise choose an arbitrary remaining pointer.
  4043. // This guarantees we always have an active touch id when there is at least one pointer.
  4044. // We keep the same active touch id for as long as possible.
  4045. bool activeTouchChanged = false;
  4046. int32_t lastActiveTouchId = mPointerGesture.activeTouchId;
  4047. int32_t activeTouchId = lastActiveTouchId;
  4048. if (activeTouchId < 0) {
  4049. if (!mCurrentFingerIdBits.isEmpty()) {
  4050. activeTouchChanged = true;
  4051. activeTouchId = mPointerGesture.activeTouchId =
  4052. mCurrentFingerIdBits.firstMarkedBit();
  4053. mPointerGesture.firstTouchTime = when;
  4054. }
  4055. } else if (!mCurrentFingerIdBits.hasBit(activeTouchId)) {
  4056. activeTouchChanged = true;
  4057. if (!mCurrentFingerIdBits.isEmpty()) {
  4058. activeTouchId = mPointerGesture.activeTouchId =
  4059. mCurrentFingerIdBits.firstMarkedBit();
  4060. } else {
  4061. activeTouchId = mPointerGesture.activeTouchId = -1;
  4062. }
  4063. }
  4064. // Determine whether we are in quiet time.
  4065. bool isQuietTime = false;
  4066. if (activeTouchId < 0) {
  4067. mPointerGesture.resetQuietTime();
  4068. } else {
  4069. isQuietTime = when < mPointerGesture.quietTime + mConfig.pointerGestureQuietInterval;
  4070. if (!isQuietTime) {
  4071. if ((mPointerGesture.lastGestureMode == PointerGesture::PRESS
  4072. || mPointerGesture.lastGestureMode == PointerGesture::SWIPE
  4073. || mPointerGesture.lastGestureMode == PointerGesture::FREEFORM)
  4074. && currentFingerCount < 2) {
  4075. // Enter quiet time when exiting swipe or freeform state.
  4076. // This is to prevent accidentally entering the hover state and flinging the
  4077. // pointer when finishing a swipe and there is still one pointer left onscreen.
  4078. isQuietTime = true;
  4079. } else if (mPointerGesture.lastGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG
  4080. && currentFingerCount >= 2
  4081. && !isPointerDown(mCurrentButtonState)) {
  4082. // Enter quiet time when releasing the button and there are still two or more
  4083. // fingers down. This may indicate that one finger was used to press the button
  4084. // but it has not gone up yet.
  4085. isQuietTime = true;
  4086. }
  4087. if (isQuietTime) {
  4088. mPointerGesture.quietTime = when;
  4089. }
  4090. }
  4091. }
  4092. // Switch states based on button and pointer state.
  4093. if (isQuietTime) {
  4094. // Case 1: Quiet time. (QUIET)
  4095. #if DEBUG_GESTURES
  4096. ALOGD("Gestures: QUIET for next %0.3fms", (mPointerGesture.quietTime
  4097. + mConfig.pointerGestureQuietInterval - when) * 0.000001f);
  4098. #endif
  4099. if (mPointerGesture.lastGestureMode != PointerGesture::QUIET) {
  4100. *outFinishPreviousGesture = true;
  4101. }
  4102. mPointerGesture.activeGestureId = -1;
  4103. mPointerGesture.currentGestureMode = PointerGesture::QUIET;
  4104. mPointerGesture.currentGestureIdBits.clear();
  4105. mPointerVelocityControl.reset();
  4106. } else if (isPointerDown(mCurrentButtonState)) {
  4107. // Case 2: Button is pressed. (BUTTON_CLICK_OR_DRAG)
  4108. // The pointer follows the active touch point.
  4109. // Emit DOWN, MOVE, UP events at the pointer location.
  4110. //
  4111. // Only the active touch matters; other fingers are ignored. This policy helps
  4112. // to handle the case where the user places a second finger on the touch pad
  4113. // to apply the necessary force to depress an integrated button below the surface.
  4114. // We don't want the second finger to be delivered to applications.
  4115. //
  4116. // For this to work well, we need to make sure to track the pointer that is really
  4117. // active. If the user first puts one finger down to click then adds another
  4118. // finger to drag then the active pointer should switch to the finger that is
  4119. // being dragged.
  4120. #if DEBUG_GESTURES
  4121. ALOGD("Gestures: BUTTON_CLICK_OR_DRAG activeTouchId=%d, "
  4122. "currentFingerCount=%d", activeTouchId, currentFingerCount);
  4123. #endif
  4124. // Reset state when just starting.
  4125. if (mPointerGesture.lastGestureMode != PointerGesture::BUTTON_CLICK_OR_DRAG) {
  4126. *outFinishPreviousGesture = true;
  4127. mPointerGesture.activeGestureId = 0;
  4128. }
  4129. // Switch pointers if needed.
  4130. // Find the fastest pointer and follow it.
  4131. if (activeTouchId >= 0 && currentFingerCount > 1) {
  4132. int32_t bestId = -1;
  4133. float bestSpeed = mConfig.pointerGestureDragMinSwitchSpeed;
  4134. for (BitSet32 idBits(mCurrentFingerIdBits); !idBits.isEmpty(); ) {
  4135. uint32_t id = idBits.clearFirstMarkedBit();
  4136. float vx, vy;
  4137. if (mPointerGesture.velocityTracker.getVelocity(id, &vx, &vy)) {
  4138. float speed = hypotf(vx, vy);
  4139. if (speed > bestSpeed) {
  4140. bestId = id;
  4141. bestSpeed = speed;
  4142. }
  4143. }
  4144. }
  4145. if (bestId >= 0 && bestId != activeTouchId) {
  4146. mPointerGesture.activeTouchId = activeTouchId = bestId;
  4147. activeTouchChanged = true;
  4148. #if DEBUG_GESTURES
  4149. ALOGD("Gestures: BUTTON_CLICK_OR_DRAG switched pointers, "
  4150. "bestId=%d, bestSpeed=%0.3f", bestId, bestSpeed);
  4151. #endif
  4152. }
  4153. }
  4154. if (activeTouchId >= 0 && mLastFingerIdBits.hasBit(activeTouchId)) {
  4155. const RawPointerData::Pointer& currentPointer =
  4156. mCurrentRawPointerData.pointerForId(activeTouchId);
  4157. const RawPointerData::Pointer& lastPointer =
  4158. mLastRawPointerData.pointerForId(activeTouchId);
  4159. float deltaX = (currentPointer.x - lastPointer.x) * mPointerXMovementScale;
  4160. float deltaY = (currentPointer.y - lastPointer.y) * mPointerYMovementScale;
  4161. rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
  4162. mPointerVelocityControl.move(when, &deltaX, &deltaY);
  4163. // Move the pointer using a relative motion.
  4164. // When using spots, the click will occur at the position of the anchor
  4165. // spot and all other spots will move there.
  4166. mPointerController->move(deltaX, deltaY);
  4167. } else {
  4168. mPointerVelocityControl.reset();
  4169. }
  4170. float x, y;
  4171. mPointerController->getPosition(&x, &y);
  4172. mPointerGesture.currentGestureMode = PointerGesture::BUTTON_CLICK_OR_DRAG;
  4173. mPointerGesture.currentGestureIdBits.clear();
  4174. mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
  4175. mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
  4176. mPointerGesture.currentGestureProperties[0].clear();
  4177. mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
  4178. mPointerGesture.currentGestureProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
  4179. mPointerGesture.currentGestureCoords[0].clear();
  4180. mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
  4181. mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
  4182. mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
  4183. } else if (currentFingerCount == 0) {
  4184. // Case 3. No fingers down and button is not pressed. (NEUTRAL)
  4185. if (mPointerGesture.lastGestureMode != PointerGesture::NEUTRAL) {
  4186. *outFinishPreviousGesture = true;
  4187. }
  4188. // Watch for taps coming out of HOVER or TAP_DRAG mode.
  4189. // Checking for taps after TAP_DRAG allows us to detect double-taps.
  4190. bool tapped = false;
  4191. if ((mPointerGesture.lastGestureMode == PointerGesture::HOVER
  4192. || mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG)
  4193. && lastFingerCount == 1) {
  4194. if (when <= mPointerGesture.tapDownTime + mConfig.pointerGestureTapInterval) {
  4195. float x, y;
  4196. mPointerController->getPosition(&x, &y);
  4197. if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop
  4198. && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) {
  4199. #if DEBUG_GESTURES
  4200. ALOGD("Gestures: TAP");
  4201. #endif
  4202. mPointerGesture.tapUpTime = when;
  4203. getContext()->requestTimeoutAtTime(when
  4204. + mConfig.pointerGestureTapDragInterval);
  4205. mPointerGesture.activeGestureId = 0;
  4206. mPointerGesture.currentGestureMode = PointerGesture::TAP;
  4207. mPointerGesture.currentGestureIdBits.clear();
  4208. mPointerGesture.currentGestureIdBits.markBit(
  4209. mPointerGesture.activeGestureId);
  4210. mPointerGesture.currentGestureIdToIndex[
  4211. mPointerGesture.activeGestureId] = 0;
  4212. mPointerGesture.currentGestureProperties[0].clear();
  4213. mPointerGesture.currentGestureProperties[0].id =
  4214. mPointerGesture.activeGestureId;
  4215. mPointerGesture.currentGestureProperties[0].toolType =
  4216. AMOTION_EVENT_TOOL_TYPE_FINGER;
  4217. mPointerGesture.currentGestureCoords[0].clear();
  4218. mPointerGesture.currentGestureCoords[0].setAxisValue(
  4219. AMOTION_EVENT_AXIS_X, mPointerGesture.tapX);
  4220. mPointerGesture.currentGestureCoords[0].setAxisValue(
  4221. AMOTION_EVENT_AXIS_Y, mPointerGesture.tapY);
  4222. mPointerGesture.currentGestureCoords[0].setAxisValue(
  4223. AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
  4224. tapped = true;
  4225. } else {
  4226. #if DEBUG_GESTURES
  4227. ALOGD("Gestures: Not a TAP, deltaX=%f, deltaY=%f",
  4228. x - mPointerGesture.tapX,
  4229. y - mPointerGesture.tapY);
  4230. #endif
  4231. }
  4232. } else {
  4233. #if DEBUG_GESTURES
  4234. if (mPointerGesture.tapDownTime != LLONG_MIN) {
  4235. ALOGD("Gestures: Not a TAP, %0.3fms since down",
  4236. (when - mPointerGesture.tapDownTime) * 0.000001f);
  4237. } else {
  4238. ALOGD("Gestures: Not a TAP, incompatible mode transitions");
  4239. }
  4240. #endif
  4241. }
  4242. }
  4243. mPointerVelocityControl.reset();
  4244. if (!tapped) {
  4245. #if DEBUG_GESTURES
  4246. ALOGD("Gestures: NEUTRAL");
  4247. #endif
  4248. mPointerGesture.activeGestureId = -1;
  4249. mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
  4250. mPointerGesture.currentGestureIdBits.clear();
  4251. }
  4252. } else if (currentFingerCount == 1) {
  4253. // Case 4. Exactly one finger down, button is not pressed. (HOVER or TAP_DRAG)
  4254. // The pointer follows the active touch point.
  4255. // When in HOVER, emit HOVER_MOVE events at the pointer location.
  4256. // When in TAP_DRAG, emit MOVE events at the pointer location.
  4257. ALOG_ASSERT(activeTouchId >= 0);
  4258. mPointerGesture.currentGestureMode = PointerGesture::HOVER;
  4259. if (mPointerGesture.lastGestureMode == PointerGesture::TAP) {
  4260. if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) {
  4261. float x, y;
  4262. mPointerController->getPosition(&x, &y);
  4263. if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop
  4264. && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) {
  4265. mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG;
  4266. } else {
  4267. #if DEBUG_GESTURES
  4268. ALOGD("Gestures: Not a TAP_DRAG, deltaX=%f, deltaY=%f",
  4269. x - mPointerGesture.tapX,
  4270. y - mPointerGesture.tapY);
  4271. #endif
  4272. }
  4273. } else {
  4274. #if DEBUG_GESTURES
  4275. ALOGD("Gestures: Not a TAP_DRAG, %0.3fms time since up",
  4276. (when - mPointerGesture.tapUpTime) * 0.000001f);
  4277. #endif
  4278. }
  4279. } else if (mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG) {
  4280. mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG;
  4281. }
  4282. if (mLastFingerIdBits.hasBit(activeTouchId)) {
  4283. const RawPointerData::Pointer& currentPointer =
  4284. mCurrentRawPointerData.pointerForId(activeTouchId);
  4285. const RawPointerData::Pointer& lastPointer =
  4286. mLastRawPointerData.pointerForId(activeTouchId);
  4287. float deltaX = (currentPointer.x - lastPointer.x)
  4288. * mPointerXMovementScale;
  4289. float deltaY = (currentPointer.y - lastPointer.y)
  4290. * mPointerYMovementScale;
  4291. rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
  4292. mPointerVelocityControl.move(when, &deltaX, &deltaY);
  4293. // Move the pointer using a relative motion.
  4294. // When using spots, the hover or drag will occur at the position of the anchor spot.
  4295. mPointerController->move(deltaX, deltaY);
  4296. } else {
  4297. mPointerVelocityControl.reset();
  4298. }
  4299. bool down;
  4300. if (mPointerGesture.currentGestureMode == PointerGesture::TAP_DRAG) {
  4301. #if DEBUG_GESTURES
  4302. ALOGD("Gestures: TAP_DRAG");
  4303. #endif
  4304. down = true;
  4305. } else {
  4306. #if DEBUG_GESTURES
  4307. ALOGD("Gestures: HOVER");
  4308. #endif
  4309. if (mPointerGesture.lastGestureMode != PointerGesture::HOVER) {
  4310. *outFinishPreviousGesture = true;
  4311. }
  4312. mPointerGesture.activeGestureId = 0;
  4313. down = false;
  4314. }
  4315. float x, y;
  4316. mPointerController->getPosition(&x, &y);
  4317. mPointerGesture.currentGestureIdBits.clear();
  4318. mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
  4319. mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
  4320. mPointerGesture.currentGestureProperties[0].clear();
  4321. mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
  4322. mPointerGesture.currentGestureProperties[0].toolType =
  4323. AMOTION_EVENT_TOOL_TYPE_FINGER;
  4324. mPointerGesture.currentGestureCoords[0].clear();
  4325. mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
  4326. mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
  4327. mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
  4328. down ? 1.0f : 0.0f);
  4329. if (lastFingerCount == 0 && currentFingerCount != 0) {
  4330. mPointerGesture.resetTap();
  4331. mPointerGesture.tapDownTime = when;
  4332. mPointerGesture.tapX = x;
  4333. mPointerGesture.tapY = y;
  4334. }
  4335. } else {
  4336. // Case 5. At least two fingers down, button is not pressed. (PRESS, SWIPE or FREEFORM)
  4337. // We need to provide feedback for each finger that goes down so we cannot wait
  4338. // for the fingers to move before deciding what to do.
  4339. //
  4340. // The ambiguous case is deciding what to do when there are two fingers down but they
  4341. // have not moved enough to determine whether they are part of a drag or part of a
  4342. // freeform gesture, or just a press or long-press at the pointer location.
  4343. //
  4344. // When there are two fingers we start with the PRESS hypothesis and we generate a
  4345. // down at the pointer location.
  4346. //
  4347. // When the two fingers move enough or when additional fingers are added, we make
  4348. // a decision to transition into SWIPE or FREEFORM mode accordingly.
  4349. ALOG_ASSERT(activeTouchId >= 0);
  4350. bool settled = when >= mPointerGesture.firstTouchTime
  4351. + mConfig.pointerGestureMultitouchSettleInterval;
  4352. if (mPointerGesture.lastGestureMode != PointerGesture::PRESS
  4353. && mPointerGesture.lastGestureMode != PointerGesture::SWIPE
  4354. && mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) {
  4355. *outFinishPreviousGesture = true;
  4356. } else if (!settled && currentFingerCount > lastFingerCount) {
  4357. // Additional pointers have gone down but not yet settled.
  4358. // Reset the gesture.
  4359. #if DEBUG_GESTURES
  4360. ALOGD("Gestures: Resetting gesture since additional pointers went down for MULTITOUCH, "
  4361. "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime
  4362. + mConfig.pointerGestureMultitouchSettleInterval - when)
  4363. * 0.000001f);
  4364. #endif
  4365. *outCancelPreviousGesture = true;
  4366. } else {
  4367. // Continue previous gesture.
  4368. mPointerGesture.currentGestureMode = mPointerGesture.lastGestureMode;
  4369. }
  4370. if (*outFinishPreviousGesture || *outCancelPreviousGesture) {
  4371. mPointerGesture.currentGestureMode = PointerGesture::PRESS;
  4372. mPointerGesture.activeGestureId = 0;
  4373. mPointerGesture.referenceIdBits.clear();
  4374. mPointerVelocityControl.reset();
  4375. // Use the centroid and pointer location as the reference points for the gesture.
  4376. #if DEBUG_GESTURES
  4377. ALOGD("Gestures: Using centroid as reference for MULTITOUCH, "
  4378. "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime
  4379. + mConfig.pointerGestureMultitouchSettleInterval - when)
  4380. * 0.000001f);
  4381. #endif
  4382. mCurrentRawPointerData.getCentroidOfTouchingPointers(
  4383. &mPointerGesture.referenceTouchX,
  4384. &mPointerGesture.referenceTouchY);
  4385. mPointerController->getPosition(&mPointerGesture.referenceGestureX,
  4386. &mPointerGesture.referenceGestureY);
  4387. }
  4388. // Clear the reference deltas for fingers not yet included in the reference calculation.
  4389. for (BitSet32 idBits(mCurrentFingerIdBits.value
  4390. & ~mPointerGesture.referenceIdBits.value); !idBits.isEmpty(); ) {
  4391. uint32_t id = idBits.clearFirstMarkedBit();
  4392. mPointerGesture.referenceDeltas[id].dx = 0;
  4393. mPointerGesture.referenceDeltas[id].dy = 0;
  4394. }
  4395. mPointerGesture.referenceIdBits = mCurrentFingerIdBits;
  4396. // Add delta for all fingers and calculate a common movement delta.
  4397. float commonDeltaX = 0, commonDeltaY = 0;
  4398. BitSet32 commonIdBits(mLastFingerIdBits.value
  4399. & mCurrentFingerIdBits.value);
  4400. for (BitSet32 idBits(commonIdBits); !idBits.isEmpty(); ) {
  4401. bool first = (idBits == commonIdBits);
  4402. uint32_t id = idBits.clearFirstMarkedBit();
  4403. const RawPointerData::Pointer& cpd = mCurrentRawPointerData.pointerForId(id);
  4404. const RawPointerData::Pointer& lpd = mLastRawPointerData.pointerForId(id);
  4405. PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
  4406. delta.dx += cpd.x - lpd.x;
  4407. delta.dy += cpd.y - lpd.y;
  4408. if (first) {
  4409. commonDeltaX = delta.dx;
  4410. commonDeltaY = delta.dy;
  4411. } else {
  4412. commonDeltaX = calculateCommonVector(commonDeltaX, delta.dx);
  4413. commonDeltaY = calculateCommonVector(commonDeltaY, delta.dy);
  4414. }
  4415. }
  4416. // Consider transitions from PRESS to SWIPE or MULTITOUCH.
  4417. if (mPointerGesture.currentGestureMode == PointerGesture::PRESS) {
  4418. float dist[MAX_POINTER_ID + 1];
  4419. int32_t distOverThreshold = 0;
  4420. for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
  4421. uint32_t id = idBits.clearFirstMarkedBit();
  4422. PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
  4423. dist[id] = hypotf(delta.dx * mPointerXZoomScale,
  4424. delta.dy * mPointerYZoomScale);
  4425. if (dist[id] > mConfig.pointerGestureMultitouchMinDistance) {
  4426. distOverThreshold += 1;
  4427. }
  4428. }
  4429. // Only transition when at least two pointers have moved further than
  4430. // the minimum distance threshold.
  4431. if (distOverThreshold >= 2) {
  4432. if (currentFingerCount > 2) {
  4433. // There are more than two pointers, switch to FREEFORM.
  4434. #if DEBUG_GESTURES
  4435. ALOGD("Gestures: PRESS transitioned to FREEFORM, number of pointers %d > 2",
  4436. currentFingerCount);
  4437. #endif
  4438. *outCancelPreviousGesture = true;
  4439. mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
  4440. } else {
  4441. // There are exactly two pointers.
  4442. BitSet32 idBits(mCurrentFingerIdBits);
  4443. uint32_t id1 = idBits.clearFirstMarkedBit();
  4444. uint32_t id2 = idBits.firstMarkedBit();
  4445. const RawPointerData::Pointer& p1 = mCurrentRawPointerData.pointerForId(id1);
  4446. const RawPointerData::Pointer& p2 = mCurrentRawPointerData.pointerForId(id2);
  4447. float mutualDistance = distance(p1.x, p1.y, p2.x, p2.y);
  4448. if (mutualDistance > mPointerGestureMaxSwipeWidth) {
  4449. // There are two pointers but they are too far apart for a SWIPE,
  4450. // switch to FREEFORM.
  4451. #if DEBUG_GESTURES
  4452. ALOGD("Gestures: PRESS transitioned to FREEFORM, distance %0.3f > %0.3f",
  4453. mutualDistance, mPointerGestureMaxSwipeWidth);
  4454. #endif
  4455. *outCancelPreviousGesture = true;
  4456. mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
  4457. } else {
  4458. // There are two pointers. Wait for both pointers to start moving
  4459. // before deciding whether this is a SWIPE or FREEFORM gesture.
  4460. float dist1 = dist[id1];
  4461. float dist2 = dist[id2];
  4462. if (dist1 >= mConfig.pointerGestureMultitouchMinDistance
  4463. && dist2 >= mConfig.pointerGestureMultitouchMinDistance) {
  4464. // Calculate the dot product of the displacement vectors.
  4465. // When the vectors are oriented in approximately the same direction,
  4466. // the angle betweeen them is near zero and the cosine of the angle
  4467. // approches 1.0. Recall that dot(v1, v2) = cos(angle) * mag(v1) * mag(v2).
  4468. PointerGesture::Delta& delta1 = mPointerGesture.referenceDeltas[id1];
  4469. PointerGesture::Delta& delta2 = mPointerGesture.referenceDeltas[id2];
  4470. float dx1 = delta1.dx * mPointerXZoomScale;
  4471. float dy1 = delta1.dy * mPointerYZoomScale;
  4472. float dx2 = delta2.dx * mPointerXZoomScale;
  4473. float dy2 = delta2.dy * mPointerYZoomScale;
  4474. float dot = dx1 * dx2 + dy1 * dy2;
  4475. float cosine = dot / (dist1 * dist2); // denominator always > 0
  4476. if (cosine >= mConfig.pointerGestureSwipeTransitionAngleCosine) {
  4477. // Pointers are moving in the same direction. Switch to SWIPE.
  4478. #if DEBUG_GESTURES
  4479. ALOGD("Gestures: PRESS transitioned to SWIPE, "
  4480. "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
  4481. "cosine %0.3f >= %0.3f",
  4482. dist1, mConfig.pointerGestureMultitouchMinDistance,
  4483. dist2, mConfig.pointerGestureMultitouchMinDistance,
  4484. cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
  4485. #endif
  4486. mPointerGesture.currentGestureMode = PointerGesture::SWIPE;
  4487. } else {
  4488. // Pointers are moving in different directions. Switch to FREEFORM.
  4489. #if DEBUG_GESTURES
  4490. ALOGD("Gestures: PRESS transitioned to FREEFORM, "
  4491. "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
  4492. "cosine %0.3f < %0.3f",
  4493. dist1, mConfig.pointerGestureMultitouchMinDistance,
  4494. dist2, mConfig.pointerGestureMultitouchMinDistance,
  4495. cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
  4496. #endif
  4497. *outCancelPreviousGesture = true;
  4498. mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
  4499. }
  4500. }
  4501. }
  4502. }
  4503. }
  4504. } else if (mPointerGesture.currentGestureMode == PointerGesture::SWIPE) {
  4505. // Switch from SWIPE to FREEFORM if additional pointers go down.
  4506. // Cancel previous gesture.
  4507. if (currentFingerCount > 2) {
  4508. #if DEBUG_GESTURES
  4509. ALOGD("Gestures: SWIPE transitioned to FREEFORM, number of pointers %d > 2",
  4510. currentFingerCount);
  4511. #endif
  4512. *outCancelPreviousGesture = true;
  4513. mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
  4514. }
  4515. }
  4516. // Move the reference points based on the overall group motion of the fingers
  4517. // except in PRESS mode while waiting for a transition to occur.
  4518. if (mPointerGesture.currentGestureMode != PointerGesture::PRESS
  4519. && (commonDeltaX || commonDeltaY)) {
  4520. for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
  4521. uint32_t id = idBits.clearFirstMarkedBit();
  4522. PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
  4523. delta.dx = 0;
  4524. delta.dy = 0;
  4525. }
  4526. mPointerGesture.referenceTouchX += commonDeltaX;
  4527. mPointerGesture.referenceTouchY += commonDeltaY;
  4528. commonDeltaX *= mPointerXMovementScale;
  4529. commonDeltaY *= mPointerYMovementScale;
  4530. rotateDelta(mSurfaceOrientation, &commonDeltaX, &commonDeltaY);
  4531. mPointerVelocityControl.move(when, &commonDeltaX, &commonDeltaY);
  4532. mPointerGesture.referenceGestureX += commonDeltaX;
  4533. mPointerGesture.referenceGestureY += commonDeltaY;
  4534. }
  4535. // Report gestures.
  4536. if (mPointerGesture.currentGestureMode == PointerGesture::PRESS
  4537. || mPointerGesture.currentGestureMode == PointerGesture::SWIPE) {
  4538. // PRESS or SWIPE mode.
  4539. #if DEBUG_GESTURES
  4540. ALOGD("Gestures: PRESS or SWIPE activeTouchId=%d,"
  4541. "activeGestureId=%d, currentTouchPointerCount=%d",
  4542. activeTouchId, mPointerGesture.activeGestureId, currentFingerCount);
  4543. #endif
  4544. ALOG_ASSERT(mPointerGesture.activeGestureId >= 0);
  4545. mPointerGesture.currentGestureIdBits.clear();
  4546. mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
  4547. mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
  4548. mPointerGesture.currentGestureProperties[0].clear();
  4549. mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
  4550. mPointerGesture.currentGestureProperties[0].toolType =
  4551. AMOTION_EVENT_TOOL_TYPE_FINGER;
  4552. mPointerGesture.currentGestureCoords[0].clear();
  4553. mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X,
  4554. mPointerGesture.referenceGestureX);
  4555. mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y,
  4556. mPointerGesture.referenceGestureY);
  4557. mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
  4558. } else if (mPointerGesture.currentGestureMode == PointerGesture::FREEFORM) {
  4559. // FREEFORM mode.
  4560. #if DEBUG_GESTURES
  4561. ALOGD("Gestures: FREEFORM activeTouchId=%d,"
  4562. "activeGestureId=%d, currentTouchPointerCount=%d",
  4563. activeTouchId, mPointerGesture.activeGestureId, currentFingerCount);
  4564. #endif
  4565. ALOG_ASSERT(mPointerGesture.activeGestureId >= 0);
  4566. mPointerGesture.currentGestureIdBits.clear();
  4567. BitSet32 mappedTouchIdBits;
  4568. BitSet32 usedGestureIdBits;
  4569. if (mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) {
  4570. // Initially, assign the active gesture id to the active touch point
  4571. // if there is one. No other touch id bits are mapped yet.
  4572. if (!*outCancelPreviousGesture) {
  4573. mappedTouchIdBits.markBit(activeTouchId);
  4574. usedGestureIdBits.markBit(mPointerGesture.activeGestureId);
  4575. mPointerGesture.freeformTouchToGestureIdMap[activeTouchId] =
  4576. mPointerGesture.activeGestureId;
  4577. } else {
  4578. mPointerGesture.activeGestureId = -1;
  4579. }
  4580. } else {
  4581. // Otherwise, assume we mapped all touches from the previous frame.
  4582. // Reuse all mappings that are still applicable.
  4583. mappedTouchIdBits.value = mLastFingerIdBits.value
  4584. & mCurrentFingerIdBits.value;
  4585. usedGestureIdBits = mPointerGesture.lastGestureIdBits;
  4586. // Check whether we need to choose a new active gesture id because the
  4587. // current went went up.
  4588. for (BitSet32 upTouchIdBits(mLastFingerIdBits.value
  4589. & ~mCurrentFingerIdBits.value);
  4590. !upTouchIdBits.isEmpty(); ) {
  4591. uint32_t upTouchId = upTouchIdBits.clearFirstMarkedBit();
  4592. uint32_t upGestureId = mPointerGesture.freeformTouchToGestureIdMap[upTouchId];
  4593. if (upGestureId == uint32_t(mPointerGesture.activeGestureId)) {
  4594. mPointerGesture.activeGestureId = -1;
  4595. break;
  4596. }
  4597. }
  4598. }
  4599. #if DEBUG_GESTURES
  4600. ALOGD("Gestures: FREEFORM follow up "
  4601. "mappedTouchIdBits=0x%08x, usedGestureIdBits=0x%08x, "
  4602. "activeGestureId=%d",
  4603. mappedTouchIdBits.value, usedGestureIdBits.value,
  4604. mPointerGesture.activeGestureId);
  4605. #endif
  4606. BitSet32 idBits(mCurrentFingerIdBits);
  4607. for (uint32_t i = 0; i < currentFingerCount; i++) {
  4608. uint32_t touchId = idBits.clearFirstMarkedBit();
  4609. uint32_t gestureId;
  4610. if (!mappedTouchIdBits.hasBit(touchId)) {
  4611. gestureId = usedGestureIdBits.markFirstUnmarkedBit();
  4612. mPointerGesture.freeformTouchToGestureIdMap[touchId] = gestureId;
  4613. #if DEBUG_GESTURES
  4614. ALOGD("Gestures: FREEFORM "
  4615. "new mapping for touch id %d -> gesture id %d",
  4616. touchId, gestureId);
  4617. #endif
  4618. } else {
  4619. gestureId = mPointerGesture.freeformTouchToGestureIdMap[touchId];
  4620. #if DEBUG_GESTURES
  4621. ALOGD("Gestures: FREEFORM "
  4622. "existing mapping for touch id %d -> gesture id %d",
  4623. touchId, gestureId);
  4624. #endif
  4625. }
  4626. mPointerGesture.currentGestureIdBits.markBit(gestureId);
  4627. mPointerGesture.currentGestureIdToIndex[gestureId] = i;
  4628. const RawPointerData::Pointer& pointer =
  4629. mCurrentRawPointerData.pointerForId(touchId);
  4630. float deltaX = (pointer.x - mPointerGesture.referenceTouchX)
  4631. * mPointerXZoomScale;
  4632. float deltaY = (pointer.y - mPointerGesture.referenceTouchY)
  4633. * mPointerYZoomScale;
  4634. rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
  4635. mPointerGesture.currentGestureProperties[i].clear();
  4636. mPointerGesture.currentGestureProperties[i].id = gestureId;
  4637. mPointerGesture.currentGestureProperties[i].toolType =
  4638. AMOTION_EVENT_TOOL_TYPE_FINGER;
  4639. mPointerGesture.currentGestureCoords[i].clear();
  4640. mPointerGesture.currentGestureCoords[i].setAxisValue(
  4641. AMOTION_EVENT_AXIS_X, mPointerGesture.referenceGestureX + deltaX);
  4642. mPointerGesture.currentGestureCoords[i].setAxisValue(
  4643. AMOTION_EVENT_AXIS_Y, mPointerGesture.referenceGestureY + deltaY);
  4644. mPointerGesture.currentGestureCoords[i].setAxisValue(
  4645. AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
  4646. }
  4647. if (mPointerGesture.activeGestureId < 0) {
  4648. mPointerGesture.activeGestureId =
  4649. mPointerGesture.currentGestureIdBits.firstMarkedBit();
  4650. #if DEBUG_GESTURES
  4651. ALOGD("Gestures: FREEFORM new "
  4652. "activeGestureId=%d", mPointerGesture.activeGestureId);
  4653. #endif
  4654. }
  4655. }
  4656. }
  4657. mPointerController->setButtonState(mCurrentButtonState);
  4658. #if DEBUG_GESTURES
  4659. ALOGD("Gestures: finishPreviousGesture=%s, cancelPreviousGesture=%s, "
  4660. "currentGestureMode=%d, currentGestureIdBits=0x%08x, "
  4661. "lastGestureMode=%d, lastGestureIdBits=0x%08x",
  4662. toString(*outFinishPreviousGesture), toString(*outCancelPreviousGesture),
  4663. mPointerGesture.currentGestureMode, mPointerGesture.currentGestureIdBits.value,
  4664. mPointerGesture.lastGestureMode, mPointerGesture.lastGestureIdBits.value);
  4665. for (BitSet32 idBits = mPointerGesture.currentGestureIdBits; !idBits.isEmpty(); ) {
  4666. uint32_t id = idBits.clearFirstMarkedBit();
  4667. uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
  4668. const PointerProperties& properties = mPointerGesture.currentGestureProperties[index];
  4669. const PointerCoords& coords = mPointerGesture.currentGestureCoords[index];
  4670. ALOGD(" currentGesture[%d]: index=%d, toolType=%d, "
  4671. "x=%0.3f, y=%0.3f, pressure=%0.3f",
  4672. id, index, properties.toolType,
  4673. coords.getAxisValue(AMOTION_EVENT_AXIS_X),
  4674. coords.getAxisValue(AMOTION_EVENT_AXIS_Y),
  4675. coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
  4676. }
  4677. for (BitSet32 idBits = mPointerGesture.lastGestureIdBits; !idBits.isEmpty(); ) {
  4678. uint32_t id = idBits.clearFirstMarkedBit();
  4679. uint32_t index = mPointerGesture.lastGestureIdToIndex[id];
  4680. const PointerProperties& properties = mPointerGesture.lastGestureProperties[index];
  4681. const PointerCoords& coords = mPointerGesture.lastGestureCoords[index];
  4682. ALOGD(" lastGesture[%d]: index=%d, toolType=%d, "
  4683. "x=%0.3f, y=%0.3f, pressure=%0.3f",
  4684. id, index, properties.toolType,
  4685. coords.getAxisValue(AMOTION_EVENT_AXIS_X),
  4686. coords.getAxisValue(AMOTION_EVENT_AXIS_Y),
  4687. coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
  4688. }
  4689. #endif
  4690. return true;
  4691. }
  4692. void TouchInputMapper::dispatchPointerStylus(nsecs_t when, uint32_t policyFlags) {
  4693. mPointerSimple.currentCoords.clear();
  4694. mPointerSimple.currentProperties.clear();
  4695. bool down, hovering;
  4696. if (!mCurrentStylusIdBits.isEmpty()) {
  4697. uint32_t id = mCurrentStylusIdBits.firstMarkedBit();
  4698. uint32_t index = mCurrentCookedPointerData.idToIndex[id];
  4699. float x = mCurrentCookedPointerData.pointerCoords[index].getX();
  4700. float y = mCurrentCookedPointerData.pointerCoords[index].getY();
  4701. mPointerController->setPosition(x, y);
  4702. hovering = mCurrentCookedPointerData.hoveringIdBits.hasBit(id);
  4703. down = !hovering;
  4704. mPointerController->getPosition(&x, &y);
  4705. mPointerSimple.currentCoords.copyFrom(mCurrentCookedPointerData.pointerCoords[index]);
  4706. mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
  4707. mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
  4708. mPointerSimple.currentProperties.id = 0;
  4709. mPointerSimple.currentProperties.toolType =
  4710. mCurrentCookedPointerData.pointerProperties[index].toolType;
  4711. } else {
  4712. down = false;
  4713. hovering = false;
  4714. }
  4715. dispatchPointerSimple(when, policyFlags, down, hovering);
  4716. }
  4717. void TouchInputMapper::abortPointerStylus(nsecs_t when, uint32_t policyFlags) {
  4718. abortPointerSimple(when, policyFlags);
  4719. }
  4720. void TouchInputMapper::dispatchPointerMouse(nsecs_t when, uint32_t policyFlags) {
  4721. mPointerSimple.currentCoords.clear();
  4722. mPointerSimple.currentProperties.clear();
  4723. bool down, hovering;
  4724. if (!mCurrentMouseIdBits.isEmpty()) {
  4725. uint32_t id = mCurrentMouseIdBits.firstMarkedBit();
  4726. uint32_t currentIndex = mCurrentRawPointerData.idToIndex[id];
  4727. if (mLastMouseIdBits.hasBit(id)) {
  4728. uint32_t lastIndex = mCurrentRawPointerData.idToIndex[id];
  4729. float deltaX = (mCurrentRawPointerData.pointers[currentIndex].x
  4730. - mLastRawPointerData.pointers[lastIndex].x)
  4731. * mPointerXMovementScale;
  4732. float deltaY = (mCurrentRawPointerData.pointers[currentIndex].y
  4733. - mLastRawPointerData.pointers[lastIndex].y)
  4734. * mPointerYMovementScale;
  4735. rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
  4736. mPointerVelocityControl.move(when, &deltaX, &deltaY);
  4737. mPointerController->move(deltaX, deltaY);
  4738. } else {
  4739. mPointerVelocityControl.reset();
  4740. }
  4741. down = isPointerDown(mCurrentButtonState);
  4742. hovering = !down;
  4743. float x, y;
  4744. mPointerController->getPosition(&x, &y);
  4745. mPointerSimple.currentCoords.copyFrom(
  4746. mCurrentCookedPointerData.pointerCoords[currentIndex]);
  4747. mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
  4748. mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
  4749. mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
  4750. hovering ? 0.0f : 1.0f);
  4751. mPointerSimple.currentProperties.id = 0;
  4752. mPointerSimple.currentProperties.toolType =
  4753. mCurrentCookedPointerData.pointerProperties[currentIndex].toolType;
  4754. } else {
  4755. mPointerVelocityControl.reset();
  4756. down = false;
  4757. hovering = false;
  4758. }
  4759. dispatchPointerSimple(when, policyFlags, down, hovering);
  4760. }
  4761. void TouchInputMapper::abortPointerMouse(nsecs_t when, uint32_t policyFlags) {
  4762. abortPointerSimple(when, policyFlags);
  4763. mPointerVelocityControl.reset();
  4764. }
  4765. void TouchInputMapper::dispatchPointerSimple(nsecs_t when, uint32_t policyFlags,
  4766. bool down, bool hovering) {
  4767. int32_t metaState = getContext()->getGlobalMetaState();
  4768. if (mPointerController != NULL) {
  4769. if (down || hovering) {
  4770. mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
  4771. mPointerController->clearSpots();
  4772. mPointerController->setButtonState(mCurrentButtonState);
  4773. mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
  4774. } else if (!down && !hovering && (mPointerSimple.down || mPointerSimple.hovering)) {
  4775. mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
  4776. }
  4777. }
  4778. if (mPointerSimple.down && !down) {
  4779. mPointerSimple.down = false;
  4780. // Send up.
  4781. NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
  4782. AMOTION_EVENT_ACTION_UP, 0, metaState, mLastButtonState, 0,
  4783. mViewport.displayId,
  4784. 1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
  4785. mOrientedXPrecision, mOrientedYPrecision,
  4786. mPointerSimple.downTime);
  4787. getListener()->notifyMotion(&args);
  4788. }
  4789. if (mPointerSimple.hovering && !hovering) {
  4790. mPointerSimple.hovering = false;
  4791. // Send hover exit.
  4792. NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
  4793. AMOTION_EVENT_ACTION_HOVER_EXIT, 0, metaState, mLastButtonState, 0,
  4794. mViewport.displayId,
  4795. 1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
  4796. mOrientedXPrecision, mOrientedYPrecision,
  4797. mPointerSimple.downTime);
  4798. getListener()->notifyMotion(&args);
  4799. }
  4800. if (down) {
  4801. if (!mPointerSimple.down) {
  4802. mPointerSimple.down = true;
  4803. mPointerSimple.downTime = when;
  4804. // Send down.
  4805. NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
  4806. AMOTION_EVENT_ACTION_DOWN, 0, metaState, mCurrentButtonState, 0,
  4807. mViewport.displayId,
  4808. 1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
  4809. mOrientedXPrecision, mOrientedYPrecision,
  4810. mPointerSimple.downTime);
  4811. getListener()->notifyMotion(&args);
  4812. }
  4813. // Send move.
  4814. NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
  4815. AMOTION_EVENT_ACTION_MOVE, 0, metaState, mCurrentButtonState, 0,
  4816. mViewport.displayId,
  4817. 1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
  4818. mOrientedXPrecision, mOrientedYPrecision,
  4819. mPointerSimple.downTime);
  4820. getListener()->notifyMotion(&args);
  4821. }
  4822. if (hovering) {
  4823. if (!mPointerSimple.hovering) {
  4824. mPointerSimple.hovering = true;
  4825. // Send hover enter.
  4826. NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
  4827. AMOTION_EVENT_ACTION_HOVER_ENTER, 0, metaState, mCurrentButtonState, 0,
  4828. mViewport.displayId,
  4829. 1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
  4830. mOrientedXPrecision, mOrientedYPrecision,
  4831. mPointerSimple.downTime);
  4832. getListener()->notifyMotion(&args);
  4833. }
  4834. // Send hover move.
  4835. NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
  4836. AMOTION_EVENT_ACTION_HOVER_MOVE, 0, metaState, mCurrentButtonState, 0,
  4837. mViewport.displayId,
  4838. 1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
  4839. mOrientedXPrecision, mOrientedYPrecision,
  4840. mPointerSimple.downTime);
  4841. getListener()->notifyMotion(&args);
  4842. }
  4843. if (mCurrentRawVScroll || mCurrentRawHScroll) {
  4844. float vscroll = mCurrentRawVScroll;
  4845. float hscroll = mCurrentRawHScroll;
  4846. mWheelYVelocityControl.move(when, NULL, &vscroll);
  4847. mWheelXVelocityControl.move(when, &hscroll, NULL);
  4848. // Send scroll.
  4849. PointerCoords pointerCoords;
  4850. pointerCoords.copyFrom(mPointerSimple.currentCoords);
  4851. pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
  4852. pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
  4853. NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
  4854. AMOTION_EVENT_ACTION_SCROLL, 0, metaState, mCurrentButtonState, 0,
  4855. mViewport.displayId,
  4856. 1, &mPointerSimple.currentProperties, &pointerCoords,
  4857. mOrientedXPrecision, mOrientedYPrecision,
  4858. mPointerSimple.downTime);
  4859. getListener()->notifyMotion(&args);
  4860. }
  4861. // Save state.
  4862. if (down || hovering) {
  4863. mPointerSimple.lastCoords.copyFrom(mPointerSimple.currentCoords);
  4864. mPointerSimple.lastProperties.copyFrom(mPointerSimple.currentProperties);
  4865. } else {
  4866. mPointerSimple.reset();
  4867. }
  4868. }
  4869. void TouchInputMapper::abortPointerSimple(nsecs_t when, uint32_t policyFlags) {
  4870. mPointerSimple.currentCoords.clear();
  4871. mPointerSimple.currentProperties.clear();
  4872. dispatchPointerSimple(when, policyFlags, false, false);
  4873. }
  4874. void TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source,
  4875. int32_t action, int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags,
  4876. const PointerProperties* properties, const PointerCoords* coords,
  4877. const uint32_t* idToIndex, BitSet32 idBits,
  4878. int32_t changedId, float xPrecision, float yPrecision, nsecs_t downTime) {
  4879. PointerCoords pointerCoords[MAX_POINTERS];
  4880. PointerProperties pointerProperties[MAX_POINTERS];
  4881. uint32_t pointerCount = 0;
  4882. while (!idBits.isEmpty()) {
  4883. uint32_t id = idBits.clearFirstMarkedBit();
  4884. uint32_t index = idToIndex[id];
  4885. pointerProperties[pointerCount].copyFrom(properties[index]);
  4886. pointerCoords[pointerCount].copyFrom(coords[index]);
  4887. if (changedId >= 0 && id == uint32_t(changedId)) {
  4888. action |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
  4889. }
  4890. pointerCount += 1;
  4891. }
  4892. ALOG_ASSERT(pointerCount != 0);
  4893. if (changedId >= 0 && pointerCount == 1) {
  4894. // Replace initial down and final up action.
  4895. // We can compare the action without masking off the changed pointer index
  4896. // because we know the index is 0.
  4897. if (action == AMOTION_EVENT_ACTION_POINTER_DOWN) {
  4898. action = AMOTION_EVENT_ACTION_DOWN;
  4899. } else if (action == AMOTION_EVENT_ACTION_POINTER_UP) {
  4900. action = AMOTION_EVENT_ACTION_UP;
  4901. } else {
  4902. // Can't happen.
  4903. ALOG_ASSERT(false);
  4904. }
  4905. }
  4906. NotifyMotionArgs args(when, getDeviceId(), source, policyFlags,
  4907. action, flags, metaState, buttonState, edgeFlags,
  4908. mViewport.displayId, pointerCount, pointerProperties, pointerCoords,
  4909. xPrecision, yPrecision, downTime);
  4910. getListener()->notifyMotion(&args);
  4911. }
  4912. bool TouchInputMapper::updateMovedPointers(const PointerProperties* inProperties,
  4913. const PointerCoords* inCoords, const uint32_t* inIdToIndex,
  4914. PointerProperties* outProperties, PointerCoords* outCoords, const uint32_t* outIdToIndex,
  4915. BitSet32 idBits) const {
  4916. bool changed = false;
  4917. while (!idBits.isEmpty()) {
  4918. uint32_t id = idBits.clearFirstMarkedBit();
  4919. uint32_t inIndex = inIdToIndex[id];
  4920. uint32_t outIndex = outIdToIndex[id];
  4921. const PointerProperties& curInProperties = inProperties[inIndex];
  4922. const PointerCoords& curInCoords = inCoords[inIndex];
  4923. PointerProperties& curOutProperties = outProperties[outIndex];
  4924. PointerCoords& curOutCoords = outCoords[outIndex];
  4925. if (curInProperties != curOutProperties) {
  4926. curOutProperties.copyFrom(curInProperties);
  4927. changed = true;
  4928. }
  4929. if (curInCoords != curOutCoords) {
  4930. curOutCoords.copyFrom(curInCoords);
  4931. changed = true;
  4932. }
  4933. }
  4934. return changed;
  4935. }
  4936. void TouchInputMapper::fadePointer() {
  4937. if (mPointerController != NULL) {
  4938. mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
  4939. }
  4940. }
  4941. bool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) {
  4942. return x >= mRawPointerAxes.x.minValue && x <= mRawPointerAxes.x.maxValue
  4943. && y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue;
  4944. }
  4945. const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHit(
  4946. int32_t x, int32_t y) {
  4947. size_t numVirtualKeys = mVirtualKeys.size();
  4948. for (size_t i = 0; i < numVirtualKeys; i++) {
  4949. const VirtualKey& virtualKey = mVirtualKeys[i];
  4950. #if DEBUG_VIRTUAL_KEYS
  4951. ALOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, "
  4952. "left=%d, top=%d, right=%d, bottom=%d",
  4953. x, y,
  4954. virtualKey.keyCode, virtualKey.scanCode,
  4955. virtualKey.hitLeft, virtualKey.hitTop,
  4956. virtualKey.hitRight, virtualKey.hitBottom);
  4957. #endif
  4958. if (virtualKey.isHit(x, y)) {
  4959. return & virtualKey;
  4960. }
  4961. }
  4962. return NULL;
  4963. }
  4964. void TouchInputMapper::assignPointerIds() {
  4965. uint32_t currentPointerCount = mCurrentRawPointerData.pointerCount;
  4966. uint32_t lastPointerCount = mLastRawPointerData.pointerCount;
  4967. mCurrentRawPointerData.clearIdBits();
  4968. if (currentPointerCount == 0) {
  4969. // No pointers to assign.
  4970. return;
  4971. }
  4972. if (lastPointerCount == 0) {
  4973. // All pointers are new.
  4974. for (uint32_t i = 0; i < currentPointerCount; i++) {
  4975. uint32_t id = i;
  4976. mCurrentRawPointerData.pointers[i].id = id;
  4977. mCurrentRawPointerData.idToIndex[id] = i;
  4978. mCurrentRawPointerData.markIdBit(id, mCurrentRawPointerData.isHovering(i));
  4979. }
  4980. return;
  4981. }
  4982. if (currentPointerCount == 1 && lastPointerCount == 1
  4983. && mCurrentRawPointerData.pointers[0].toolType
  4984. == mLastRawPointerData.pointers[0].toolType) {
  4985. // Only one pointer and no change in count so it must have the same id as before.
  4986. uint32_t id = mLastRawPointerData.pointers[0].id;
  4987. mCurrentRawPointerData.pointers[0].id = id;
  4988. mCurrentRawPointerData.idToIndex[id] = 0;
  4989. mCurrentRawPointerData.markIdBit(id, mCurrentRawPointerData.isHovering(0));
  4990. return;
  4991. }
  4992. // General case.
  4993. // We build a heap of squared euclidean distances between current and last pointers
  4994. // associated with the current and last pointer indices. Then, we find the best
  4995. // match (by distance) for each current pointer.
  4996. // The pointers must have the same tool type but it is possible for them to
  4997. // transition from hovering to touching or vice-versa while retaining the same id.
  4998. PointerDistanceHeapElement heap[MAX_POINTERS * MAX_POINTERS];
  4999. uint32_t heapSize = 0;
  5000. for (uint32_t currentPointerIndex = 0; currentPointerIndex < currentPointerCount;
  5001. currentPointerIndex++) {
  5002. for (uint32_t lastPointerIndex = 0; lastPointerIndex < lastPointerCount;
  5003. lastPointerIndex++) {
  5004. const RawPointerData::Pointer& currentPointer =
  5005. mCurrentRawPointerData.pointers[currentPointerIndex];
  5006. const RawPointerData::Pointer& lastPointer =
  5007. mLastRawPointerData.pointers[lastPointerIndex];
  5008. if (currentPointer.toolType == lastPointer.toolType) {
  5009. int64_t deltaX = currentPointer.x - lastPointer.x;
  5010. int64_t deltaY = currentPointer.y - lastPointer.y;
  5011. uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY);
  5012. // Insert new element into the heap (sift up).
  5013. heap[heapSize].currentPointerIndex = currentPointerIndex;
  5014. heap[heapSize].lastPointerIndex = lastPointerIndex;
  5015. heap[heapSize].distance = distance;
  5016. heapSize += 1;
  5017. }
  5018. }
  5019. }
  5020. // Heapify
  5021. for (uint32_t startIndex = heapSize / 2; startIndex != 0; ) {
  5022. startIndex -= 1;
  5023. for (uint32_t parentIndex = startIndex; ;) {
  5024. uint32_t childIndex = parentIndex * 2 + 1;
  5025. if (childIndex >= heapSize) {
  5026. break;
  5027. }
  5028. if (childIndex + 1 < heapSize
  5029. && heap[childIndex + 1].distance < heap[childIndex].distance) {
  5030. childIndex += 1;
  5031. }
  5032. if (heap[parentIndex].distance <= heap[childIndex].distance) {
  5033. break;
  5034. }
  5035. swap(heap[parentIndex], heap[childIndex]);
  5036. parentIndex = childIndex;
  5037. }
  5038. }
  5039. #if DEBUG_POINTER_ASSIGNMENT
  5040. ALOGD("assignPointerIds - initial distance min-heap: size=%d", heapSize);
  5041. for (size_t i = 0; i < heapSize; i++) {
  5042. ALOGD(" heap[%d]: cur=%d, last=%d, distance=%lld",
  5043. i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
  5044. heap[i].distance);
  5045. }
  5046. #endif
  5047. // Pull matches out by increasing order of distance.
  5048. // To avoid reassigning pointers that have already been matched, the loop keeps track
  5049. // of which last and current pointers have been matched using the matchedXXXBits variables.
  5050. // It also tracks the used pointer id bits.
  5051. BitSet32 matchedLastBits(0);
  5052. BitSet32 matchedCurrentBits(0);
  5053. BitSet32 usedIdBits(0);
  5054. bool first = true;
  5055. for (uint32_t i = min(currentPointerCount, lastPointerCount); heapSize > 0 && i > 0; i--) {
  5056. while (heapSize > 0) {
  5057. if (first) {
  5058. // The first time through the loop, we just consume the root element of
  5059. // the heap (the one with smallest distance).
  5060. first = false;
  5061. } else {
  5062. // Previous iterations consumed the root element of the heap.
  5063. // Pop root element off of the heap (sift down).
  5064. heap[0] = heap[heapSize];
  5065. for (uint32_t parentIndex = 0; ;) {
  5066. uint32_t childIndex = parentIndex * 2 + 1;
  5067. if (childIndex >= heapSize) {
  5068. break;
  5069. }
  5070. if (childIndex + 1 < heapSize
  5071. && heap[childIndex + 1].distance < heap[childIndex].distance) {
  5072. childIndex += 1;
  5073. }
  5074. if (heap[parentIndex].distance <= heap[childIndex].distance) {
  5075. break;
  5076. }
  5077. swap(heap[parentIndex], heap[childIndex]);
  5078. parentIndex = childIndex;
  5079. }
  5080. #if DEBUG_POINTER_ASSIGNMENT
  5081. ALOGD("assignPointerIds - reduced distance min-heap: size=%d", heapSize);
  5082. for (size_t i = 0; i < heapSize; i++) {
  5083. ALOGD(" heap[%d]: cur=%d, last=%d, distance=%lld",
  5084. i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
  5085. heap[i].distance);
  5086. }
  5087. #endif
  5088. }
  5089. heapSize -= 1;
  5090. uint32_t currentPointerIndex = heap[0].currentPointerIndex;
  5091. if (matchedCurrentBits.hasBit(currentPointerIndex)) continue; // already matched
  5092. uint32_t lastPointerIndex = heap[0].lastPointerIndex;
  5093. if (matchedLastBits.hasBit(lastPointerIndex)) continue; // already matched
  5094. matchedCurrentBits.markBit(currentPointerIndex);
  5095. matchedLastBits.markBit(lastPointerIndex);
  5096. uint32_t id = mLastRawPointerData.pointers[lastPointerIndex].id;
  5097. mCurrentRawPointerData.pointers[currentPointerIndex].id = id;
  5098. mCurrentRawPointerData.idToIndex[id] = currentPointerIndex;
  5099. mCurrentRawPointerData.markIdBit(id,
  5100. mCurrentRawPointerData.isHovering(currentPointerIndex));
  5101. usedIdBits.markBit(id);
  5102. #if DEBUG_POINTER_ASSIGNMENT
  5103. ALOGD("assignPointerIds - matched: cur=%d, last=%d, id=%d, distance=%lld",
  5104. lastPointerIndex, currentPointerIndex, id, heap[0].distance);
  5105. #endif
  5106. break;
  5107. }
  5108. }
  5109. // Assign fresh ids to pointers that were not matched in the process.
  5110. for (uint32_t i = currentPointerCount - matchedCurrentBits.count(); i != 0; i--) {
  5111. uint32_t currentPointerIndex = matchedCurrentBits.markFirstUnmarkedBit();
  5112. uint32_t id = usedIdBits.markFirstUnmarkedBit();
  5113. mCurrentRawPointerData.pointers[currentPointerIndex].id = id;
  5114. mCurrentRawPointerData.idToIndex[id] = currentPointerIndex;
  5115. mCurrentRawPointerData.markIdBit(id,
  5116. mCurrentRawPointerData.isHovering(currentPointerIndex));
  5117. #if DEBUG_POINTER_ASSIGNMENT
  5118. ALOGD("assignPointerIds - assigned: cur=%d, id=%d",
  5119. currentPointerIndex, id);
  5120. #endif
  5121. }
  5122. }
  5123. int32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
  5124. if (mCurrentVirtualKey.down && mCurrentVirtualKey.keyCode == keyCode) {
  5125. return AKEY_STATE_VIRTUAL;
  5126. }
  5127. size_t numVirtualKeys = mVirtualKeys.size();
  5128. for (size_t i = 0; i < numVirtualKeys; i++) {
  5129. const VirtualKey& virtualKey = mVirtualKeys[i];
  5130. if (virtualKey.keyCode == keyCode) {
  5131. return AKEY_STATE_UP;
  5132. }
  5133. }
  5134. return AKEY_STATE_UNKNOWN;
  5135. }
  5136. int32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
  5137. if (mCurrentVirtualKey.down && mCurrentVirtualKey.scanCode == scanCode) {
  5138. return AKEY_STATE_VIRTUAL;
  5139. }
  5140. size_t numVirtualKeys = mVirtualKeys.size();
  5141. for (size_t i = 0; i < numVirtualKeys; i++) {
  5142. const VirtualKey& virtualKey = mVirtualKeys[i];
  5143. if (virtualKey.scanCode == scanCode) {
  5144. return AKEY_STATE_UP;
  5145. }
  5146. }
  5147. return AKEY_STATE_UNKNOWN;
  5148. }
  5149. bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
  5150. const int32_t* keyCodes, uint8_t* outFlags) {
  5151. size_t numVirtualKeys = mVirtualKeys.size();
  5152. for (size_t i = 0; i < numVirtualKeys; i++) {
  5153. const VirtualKey& virtualKey = mVirtualKeys[i];
  5154. for (size_t i = 0; i < numCodes; i++) {
  5155. if (virtualKey.keyCode == keyCodes[i]) {
  5156. outFlags[i] = 1;
  5157. }
  5158. }
  5159. }
  5160. return true;
  5161. }
  5162. // --- SingleTouchInputMapper ---
  5163. SingleTouchInputMapper::SingleTouchInputMapper(InputDevice* device) :
  5164. TouchInputMapper(device) {
  5165. }
  5166. SingleTouchInputMapper::~SingleTouchInputMapper() {
  5167. }
  5168. void SingleTouchInputMapper::reset(nsecs_t when) {
  5169. mSingleTouchMotionAccumulator.reset(getDevice());
  5170. TouchInputMapper::reset(when);
  5171. }
  5172. void SingleTouchInputMapper::process(const RawEvent* rawEvent) {
  5173. TouchInputMapper::process(rawEvent);
  5174. mSingleTouchMotionAccumulator.process(rawEvent);
  5175. }
  5176. void SingleTouchInputMapper::syncTouch(nsecs_t when, bool* outHavePointerIds) {
  5177. if (mTouchButtonAccumulator.isToolActive()) {
  5178. mCurrentRawPointerData.pointerCount = 1;
  5179. mCurrentRawPointerData.idToIndex[0] = 0;
  5180. bool isHovering = mTouchButtonAccumulator.getToolType() != AMOTION_EVENT_TOOL_TYPE_MOUSE
  5181. && (mTouchButtonAccumulator.isHovering()
  5182. || (mRawPointerAxes.pressure.valid
  5183. && mSingleTouchMotionAccumulator.getAbsolutePressure() <= 0));
  5184. mCurrentRawPointerData.markIdBit(0, isHovering);
  5185. RawPointerData::Pointer& outPointer = mCurrentRawPointerData.pointers[0];
  5186. outPointer.id = 0;
  5187. outPointer.x = mSingleTouchMotionAccumulator.getAbsoluteX();
  5188. outPointer.y = mSingleTouchMotionAccumulator.getAbsoluteY();
  5189. outPointer.pressure = mSingleTouchMotionAccumulator.getAbsolutePressure();
  5190. outPointer.touchMajor = 0;
  5191. outPointer.touchMinor = 0;
  5192. outPointer.toolMajor = mSingleTouchMotionAccumulator.getAbsoluteToolWidth();
  5193. outPointer.toolMinor = mSingleTouchMotionAccumulator.getAbsoluteToolWidth();
  5194. outPointer.orientation = 0;
  5195. outPointer.distance = mSingleTouchMotionAccumulator.getAbsoluteDistance();
  5196. outPointer.tiltX = mSingleTouchMotionAccumulator.getAbsoluteTiltX();
  5197. outPointer.tiltY = mSingleTouchMotionAccumulator.getAbsoluteTiltY();
  5198. outPointer.toolType = mTouchButtonAccumulator.getToolType();
  5199. if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
  5200. outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
  5201. }
  5202. outPointer.isHovering = isHovering;
  5203. }
  5204. }
  5205. void SingleTouchInputMapper::configureRawPointerAxes() {
  5206. TouchInputMapper::configureRawPointerAxes();
  5207. getAbsoluteAxisInfo(ABS_X, &mRawPointerAxes.x);
  5208. getAbsoluteAxisInfo(ABS_Y, &mRawPointerAxes.y);
  5209. getAbsoluteAxisInfo(ABS_PRESSURE, &mRawPointerAxes.pressure);
  5210. getAbsoluteAxisInfo(ABS_TOOL_WIDTH, &mRawPointerAxes.toolMajor);
  5211. getAbsoluteAxisInfo(ABS_DISTANCE, &mRawPointerAxes.distance);
  5212. getAbsoluteAxisInfo(ABS_TILT_X, &mRawPointerAxes.tiltX);
  5213. getAbsoluteAxisInfo(ABS_TILT_Y, &mRawPointerAxes.tiltY);
  5214. }
  5215. bool SingleTouchInputMapper::hasStylus() const {
  5216. return mTouchButtonAccumulator.hasStylus();
  5217. }
  5218. // --- MultiTouchInputMapper ---
  5219. MultiTouchInputMapper::MultiTouchInputMapper(InputDevice* device) :
  5220. TouchInputMapper(device) {
  5221. }
  5222. MultiTouchInputMapper::~MultiTouchInputMapper() {
  5223. }
  5224. void MultiTouchInputMapper::reset(nsecs_t when) {
  5225. mMultiTouchMotionAccumulator.reset(getDevice());
  5226. mPointerIdBits.clear();
  5227. TouchInputMapper::reset(when);
  5228. }
  5229. void MultiTouchInputMapper::process(const RawEvent* rawEvent) {
  5230. TouchInputMapper::process(rawEvent);
  5231. mMultiTouchMotionAccumulator.process(rawEvent);
  5232. }
  5233. void MultiTouchInputMapper::syncTouch(nsecs_t when, bool* outHavePointerIds) {
  5234. size_t inCount = mMultiTouchMotionAccumulator.getSlotCount();
  5235. size_t outCount = 0;
  5236. BitSet32 newPointerIdBits;
  5237. for (size_t inIndex = 0; inIndex < inCount; inIndex++) {
  5238. const MultiTouchMotionAccumulator::Slot* inSlot =
  5239. mMultiTouchMotionAccumulator.getSlot(inIndex);
  5240. if (!inSlot->isInUse()) {
  5241. continue;
  5242. }
  5243. if (outCount >= MAX_POINTERS) {
  5244. #if DEBUG_POINTERS
  5245. ALOGD("MultiTouch device %s emitted more than maximum of %d pointers; "
  5246. "ignoring the rest.",
  5247. getDeviceName().string(), MAX_POINTERS);
  5248. #endif
  5249. break; // too many fingers!
  5250. }
  5251. RawPointerData::Pointer& outPointer = mCurrentRawPointerData.pointers[outCount];
  5252. outPointer.x = inSlot->getX();
  5253. outPointer.y = inSlot->getY();
  5254. outPointer.pressure = inSlot->getPressure();
  5255. outPointer.touchMajor = inSlot->getTouchMajor();
  5256. outPointer.touchMinor = inSlot->getTouchMinor();
  5257. outPointer.toolMajor = inSlot->getToolMajor();
  5258. outPointer.toolMinor = inSlot->getToolMinor();
  5259. outPointer.orientation = inSlot->getOrientation();
  5260. outPointer.distance = inSlot->getDistance();
  5261. outPointer.tiltX = 0;
  5262. outPointer.tiltY = 0;
  5263. outPointer.toolType = inSlot->getToolType();
  5264. if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
  5265. outPointer.toolType = mTouchButtonAccumulator.getToolType();
  5266. if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
  5267. outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
  5268. }
  5269. }
  5270. bool isHovering = mTouchButtonAccumulator.getToolType() != AMOTION_EVENT_TOOL_TYPE_MOUSE
  5271. && (mTouchButtonAccumulator.isHovering()
  5272. || (mRawPointerAxes.pressure.valid && inSlot->getPressure() <= 0));
  5273. outPointer.isHovering = isHovering;
  5274. // Assign pointer id using tracking id if available.
  5275. if (*outHavePointerIds) {
  5276. int32_t trackingId = inSlot->getTrackingId();
  5277. int32_t id = -1;
  5278. if (trackingId >= 0) {
  5279. for (BitSet32 idBits(mPointerIdBits); !idBits.isEmpty(); ) {
  5280. uint32_t n = idBits.clearFirstMarkedBit();
  5281. if (mPointerTrackingIdMap[n] == trackingId) {
  5282. id = n;
  5283. }
  5284. }
  5285. if (id < 0 && !mPointerIdBits.isFull()) {
  5286. id = mPointerIdBits.markFirstUnmarkedBit();
  5287. mPointerTrackingIdMap[id] = trackingId;
  5288. }
  5289. }
  5290. if (id < 0) {
  5291. *outHavePointerIds = false;
  5292. mCurrentRawPointerData.clearIdBits();
  5293. newPointerIdBits.clear();
  5294. } else {
  5295. outPointer.id = id;
  5296. mCurrentRawPointerData.idToIndex[id] = outCount;
  5297. mCurrentRawPointerData.markIdBit(id, isHovering);
  5298. newPointerIdBits.markBit(id);
  5299. }
  5300. }
  5301. outCount += 1;
  5302. }
  5303. mCurrentRawPointerData.pointerCount = outCount;
  5304. mPointerIdBits = newPointerIdBits;
  5305. mMultiTouchMotionAccumulator.finishSync();
  5306. }
  5307. void MultiTouchInputMapper::configureRawPointerAxes() {
  5308. TouchInputMapper::configureRawPointerAxes();
  5309. getAbsoluteAxisInfo(ABS_MT_POSITION_X, &mRawPointerAxes.x);
  5310. getAbsoluteAxisInfo(ABS_MT_POSITION_Y, &mRawPointerAxes.y);
  5311. getAbsoluteAxisInfo(ABS_MT_TOUCH_MAJOR, &mRawPointerAxes.touchMajor);
  5312. getAbsoluteAxisInfo(ABS_MT_TOUCH_MINOR, &mRawPointerAxes.touchMinor);
  5313. getAbsoluteAxisInfo(ABS_MT_WIDTH_MAJOR, &mRawPointerAxes.toolMajor);
  5314. getAbsoluteAxisInfo(ABS_MT_WIDTH_MINOR, &mRawPointerAxes.toolMinor);
  5315. getAbsoluteAxisInfo(ABS_MT_ORIENTATION, &mRawPointerAxes.orientation);
  5316. getAbsoluteAxisInfo(ABS_MT_PRESSURE, &mRawPointerAxes.pressure);
  5317. getAbsoluteAxisInfo(ABS_MT_DISTANCE, &mRawPointerAxes.distance);
  5318. getAbsoluteAxisInfo(ABS_MT_TRACKING_ID, &mRawPointerAxes.trackingId);
  5319. getAbsoluteAxisInfo(ABS_MT_SLOT, &mRawPointerAxes.slot);
  5320. if (mRawPointerAxes.trackingId.valid
  5321. && mRawPointerAxes.slot.valid
  5322. && mRawPointerAxes.slot.minValue == 0 && mRawPointerAxes.slot.maxValue > 0) {
  5323. size_t slotCount = mRawPointerAxes.slot.maxValue + 1;
  5324. if (slotCount > MAX_SLOTS) {
  5325. ALOGW("MultiTouch Device %s reported %zu slots but the framework "
  5326. "only supports a maximum of %zu slots at this time.",
  5327. getDeviceName().string(), slotCount, MAX_SLOTS);
  5328. slotCount = MAX_SLOTS;
  5329. }
  5330. mMultiTouchMotionAccumulator.configure(getDevice(),
  5331. slotCount, true /*usingSlotsProtocol*/);
  5332. } else {
  5333. mMultiTouchMotionAccumulator.configure(getDevice(),
  5334. MAX_POINTERS, false /*usingSlotsProtocol*/);
  5335. }
  5336. }
  5337. bool MultiTouchInputMapper::hasStylus() const {
  5338. return mMultiTouchMotionAccumulator.hasStylus()
  5339. || mTouchButtonAccumulator.hasStylus();
  5340. }
  5341. // --- JoystickInputMapper ---
  5342. JoystickInputMapper::JoystickInputMapper(InputDevice* device) :
  5343. InputMapper(device) {
  5344. }
  5345. JoystickInputMapper::~JoystickInputMapper() {
  5346. }
  5347. uint32_t JoystickInputMapper::getSources() {
  5348. return AINPUT_SOURCE_JOYSTICK;
  5349. }
  5350. void JoystickInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
  5351. InputMapper::populateDeviceInfo(info);
  5352. for (size_t i = 0; i < mAxes.size(); i++) {
  5353. const Axis& axis = mAxes.valueAt(i);
  5354. addMotionRange(axis.axisInfo.axis, axis, info);
  5355. if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
  5356. addMotionRange(axis.axisInfo.highAxis, axis, info);
  5357. }
  5358. }
  5359. }
  5360. void JoystickInputMapper::addMotionRange(int32_t axisId, const Axis& axis,
  5361. InputDeviceInfo* info) {
  5362. info->addMotionRange(axisId, AINPUT_SOURCE_JOYSTICK,
  5363. axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
  5364. /* In order to ease the transition for developers from using the old axes
  5365. * to the newer, more semantically correct axes, we'll continue to register
  5366. * the old axes as duplicates of their corresponding new ones. */
  5367. int32_t compatAxis = getCompatAxis(axisId);
  5368. if (compatAxis >= 0) {
  5369. info->addMotionRange(compatAxis, AINPUT_SOURCE_JOYSTICK,
  5370. axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
  5371. }
  5372. }
  5373. /* A mapping from axes the joystick actually has to the axes that should be
  5374. * artificially created for compatibility purposes.
  5375. * Returns -1 if no compatibility axis is needed. */
  5376. int32_t JoystickInputMapper::getCompatAxis(int32_t axis) {
  5377. switch(axis) {
  5378. case AMOTION_EVENT_AXIS_LTRIGGER:
  5379. return AMOTION_EVENT_AXIS_BRAKE;
  5380. case AMOTION_EVENT_AXIS_RTRIGGER:
  5381. return AMOTION_EVENT_AXIS_GAS;
  5382. }
  5383. return -1;
  5384. }
  5385. void JoystickInputMapper::dump(String8& dump) {
  5386. dump.append(INDENT2 "Joystick Input Mapper:\n");
  5387. dump.append(INDENT3 "Axes:\n");
  5388. size_t numAxes = mAxes.size();
  5389. for (size_t i = 0; i < numAxes; i++) {
  5390. const Axis& axis = mAxes.valueAt(i);
  5391. const char* label = getAxisLabel(axis.axisInfo.axis);
  5392. if (label) {
  5393. dump.appendFormat(INDENT4 "%s", label);
  5394. } else {
  5395. dump.appendFormat(INDENT4 "%d", axis.axisInfo.axis);
  5396. }
  5397. if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
  5398. label = getAxisLabel(axis.axisInfo.highAxis);
  5399. if (label) {
  5400. dump.appendFormat(" / %s (split at %d)", label, axis.axisInfo.splitValue);
  5401. } else {
  5402. dump.appendFormat(" / %d (split at %d)", axis.axisInfo.highAxis,
  5403. axis.axisInfo.splitValue);
  5404. }
  5405. } else if (axis.axisInfo.mode == AxisInfo::MODE_INVERT) {
  5406. dump.append(" (invert)");
  5407. }
  5408. dump.appendFormat(": min=%0.5f, max=%0.5f, flat=%0.5f, fuzz=%0.5f, resolution=%0.5f\n",
  5409. axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
  5410. dump.appendFormat(INDENT4 " scale=%0.5f, offset=%0.5f, "
  5411. "highScale=%0.5f, highOffset=%0.5f\n",
  5412. axis.scale, axis.offset, axis.highScale, axis.highOffset);
  5413. dump.appendFormat(INDENT4 " rawAxis=%d, rawMin=%d, rawMax=%d, "
  5414. "rawFlat=%d, rawFuzz=%d, rawResolution=%d\n",
  5415. mAxes.keyAt(i), axis.rawAxisInfo.minValue, axis.rawAxisInfo.maxValue,
  5416. axis.rawAxisInfo.flat, axis.rawAxisInfo.fuzz, axis.rawAxisInfo.resolution);
  5417. }
  5418. }
  5419. void JoystickInputMapper::configure(nsecs_t when,
  5420. const InputReaderConfiguration* config, uint32_t changes) {
  5421. InputMapper::configure(when, config, changes);
  5422. if (!changes) { // first time only
  5423. // Collect all axes.
  5424. for (int32_t abs = 0; abs <= ABS_MAX; abs++) {
  5425. if (!(getAbsAxisUsage(abs, getDevice()->getClasses())
  5426. & INPUT_DEVICE_CLASS_JOYSTICK)) {
  5427. continue; // axis must be claimed by a different device
  5428. }
  5429. RawAbsoluteAxisInfo rawAxisInfo;
  5430. getAbsoluteAxisInfo(abs, &rawAxisInfo);
  5431. if (rawAxisInfo.valid) {
  5432. // Map axis.
  5433. AxisInfo axisInfo;
  5434. bool explicitlyMapped = !getEventHub()->mapAxis(getDeviceId(), abs, &axisInfo);
  5435. if (!explicitlyMapped) {
  5436. // Axis is not explicitly mapped, will choose a generic axis later.
  5437. axisInfo.mode = AxisInfo::MODE_NORMAL;
  5438. axisInfo.axis = -1;
  5439. }
  5440. // Apply flat override.
  5441. int32_t rawFlat = axisInfo.flatOverride < 0
  5442. ? rawAxisInfo.flat : axisInfo.flatOverride;
  5443. // Calculate scaling factors and limits.
  5444. Axis axis;
  5445. if (axisInfo.mode == AxisInfo::MODE_SPLIT) {
  5446. float scale = 1.0f / (axisInfo.splitValue - rawAxisInfo.minValue);
  5447. float highScale = 1.0f / (rawAxisInfo.maxValue - axisInfo.splitValue);
  5448. axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
  5449. scale, 0.0f, highScale, 0.0f,
  5450. 0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale,
  5451. rawAxisInfo.resolution * scale);
  5452. } else if (isCenteredAxis(axisInfo.axis)) {
  5453. float scale = 2.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
  5454. float offset = avg(rawAxisInfo.minValue, rawAxisInfo.maxValue) * -scale;
  5455. axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
  5456. scale, offset, scale, offset,
  5457. -1.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale,
  5458. rawAxisInfo.resolution * scale);
  5459. } else {
  5460. float scale = 1.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
  5461. axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
  5462. scale, 0.0f, scale, 0.0f,
  5463. 0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale,
  5464. rawAxisInfo.resolution * scale);
  5465. }
  5466. // To eliminate noise while the joystick is at rest, filter out small variations
  5467. // in axis values up front.
  5468. axis.filter = axis.flat * 0.25f;
  5469. mAxes.add(abs, axis);
  5470. }
  5471. }
  5472. // If there are too many axes, start dropping them.
  5473. // Prefer to keep explicitly mapped axes.
  5474. if (mAxes.size() > PointerCoords::MAX_AXES) {
  5475. ALOGI("Joystick '%s' has %zu axes but the framework only supports a maximum of %d.",
  5476. getDeviceName().string(), mAxes.size(), PointerCoords::MAX_AXES);
  5477. pruneAxes(true);
  5478. pruneAxes(false);
  5479. }
  5480. // Assign generic axis ids to remaining axes.
  5481. int32_t nextGenericAxisId = AMOTION_EVENT_AXIS_GENERIC_1;
  5482. size_t numAxes = mAxes.size();
  5483. for (size_t i = 0; i < numAxes; i++) {
  5484. Axis& axis = mAxes.editValueAt(i);
  5485. if (axis.axisInfo.axis < 0) {
  5486. while (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16
  5487. && haveAxis(nextGenericAxisId)) {
  5488. nextGenericAxisId += 1;
  5489. }
  5490. if (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16) {
  5491. axis.axisInfo.axis = nextGenericAxisId;
  5492. nextGenericAxisId += 1;
  5493. } else {
  5494. ALOGI("Ignoring joystick '%s' axis %d because all of the generic axis ids "
  5495. "have already been assigned to other axes.",
  5496. getDeviceName().string(), mAxes.keyAt(i));
  5497. mAxes.removeItemsAt(i--);
  5498. numAxes -= 1;
  5499. }
  5500. }
  5501. }
  5502. }
  5503. }
  5504. bool JoystickInputMapper::haveAxis(int32_t axisId) {
  5505. size_t numAxes = mAxes.size();
  5506. for (size_t i = 0; i < numAxes; i++) {
  5507. const Axis& axis = mAxes.valueAt(i);
  5508. if (axis.axisInfo.axis == axisId
  5509. || (axis.axisInfo.mode == AxisInfo::MODE_SPLIT
  5510. && axis.axisInfo.highAxis == axisId)) {
  5511. return true;
  5512. }
  5513. }
  5514. return false;
  5515. }
  5516. void JoystickInputMapper::pruneAxes(bool ignoreExplicitlyMappedAxes) {
  5517. size_t i = mAxes.size();
  5518. while (mAxes.size() > PointerCoords::MAX_AXES && i-- > 0) {
  5519. if (ignoreExplicitlyMappedAxes && mAxes.valueAt(i).explicitlyMapped) {
  5520. continue;
  5521. }
  5522. ALOGI("Discarding joystick '%s' axis %d because there are too many axes.",
  5523. getDeviceName().string(), mAxes.keyAt(i));
  5524. mAxes.removeItemsAt(i);
  5525. }
  5526. }
  5527. bool JoystickInputMapper::isCenteredAxis(int32_t axis) {
  5528. switch (axis) {
  5529. case AMOTION_EVENT_AXIS_X:
  5530. case AMOTION_EVENT_AXIS_Y:
  5531. case AMOTION_EVENT_AXIS_Z:
  5532. case AMOTION_EVENT_AXIS_RX:
  5533. case AMOTION_EVENT_AXIS_RY:
  5534. case AMOTION_EVENT_AXIS_RZ:
  5535. case AMOTION_EVENT_AXIS_HAT_X:
  5536. case AMOTION_EVENT_AXIS_HAT_Y:
  5537. case AMOTION_EVENT_AXIS_ORIENTATION:
  5538. case AMOTION_EVENT_AXIS_RUDDER:
  5539. case AMOTION_EVENT_AXIS_WHEEL:
  5540. return true;
  5541. default:
  5542. return false;
  5543. }
  5544. }
  5545. void JoystickInputMapper::reset(nsecs_t when) {
  5546. // Recenter all axes.
  5547. size_t numAxes = mAxes.size();
  5548. for (size_t i = 0; i < numAxes; i++) {
  5549. Axis& axis = mAxes.editValueAt(i);
  5550. axis.resetValue();
  5551. }
  5552. InputMapper::reset(when);
  5553. }
  5554. void JoystickInputMapper::process(const RawEvent* rawEvent) {
  5555. switch (rawEvent->type) {
  5556. case EV_ABS: {
  5557. ssize_t index = mAxes.indexOfKey(rawEvent->code);
  5558. if (index >= 0) {
  5559. Axis& axis = mAxes.editValueAt(index);
  5560. float newValue, highNewValue;
  5561. switch (axis.axisInfo.mode) {
  5562. case AxisInfo::MODE_INVERT:
  5563. newValue = (axis.rawAxisInfo.maxValue - rawEvent->value)
  5564. * axis.scale + axis.offset;
  5565. highNewValue = 0.0f;
  5566. break;
  5567. case AxisInfo::MODE_SPLIT:
  5568. if (rawEvent->value < axis.axisInfo.splitValue) {
  5569. newValue = (axis.axisInfo.splitValue - rawEvent->value)
  5570. * axis.scale + axis.offset;
  5571. highNewValue = 0.0f;
  5572. } else if (rawEvent->value > axis.axisInfo.splitValue) {
  5573. newValue = 0.0f;
  5574. highNewValue = (rawEvent->value - axis.axisInfo.splitValue)
  5575. * axis.highScale + axis.highOffset;
  5576. } else {
  5577. newValue = 0.0f;
  5578. highNewValue = 0.0f;
  5579. }
  5580. break;
  5581. default:
  5582. newValue = rawEvent->value * axis.scale + axis.offset;
  5583. highNewValue = 0.0f;
  5584. break;
  5585. }
  5586. axis.newValue = newValue;
  5587. axis.highNewValue = highNewValue;
  5588. }
  5589. break;
  5590. }
  5591. case EV_SYN:
  5592. switch (rawEvent->code) {
  5593. case SYN_REPORT:
  5594. sync(rawEvent->when, false /*force*/);
  5595. break;
  5596. }
  5597. break;
  5598. }
  5599. }
  5600. void JoystickInputMapper::sync(nsecs_t when, bool force) {
  5601. if (!filterAxes(force)) {
  5602. return;
  5603. }
  5604. int32_t metaState = mContext->getGlobalMetaState();
  5605. int32_t buttonState = 0;
  5606. PointerProperties pointerProperties;
  5607. pointerProperties.clear();
  5608. pointerProperties.id = 0;
  5609. pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
  5610. PointerCoords pointerCoords;
  5611. pointerCoords.clear();
  5612. size_t numAxes = mAxes.size();
  5613. for (size_t i = 0; i < numAxes; i++) {
  5614. const Axis& axis = mAxes.valueAt(i);
  5615. setPointerCoordsAxisValue(&pointerCoords, axis.axisInfo.axis, axis.currentValue);
  5616. if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
  5617. setPointerCoordsAxisValue(&pointerCoords, axis.axisInfo.highAxis,
  5618. axis.highCurrentValue);
  5619. }
  5620. }
  5621. // Moving a joystick axis should not wake the device because joysticks can
  5622. // be fairly noisy even when not in use. On the other hand, pushing a gamepad
  5623. // button will likely wake the device.
  5624. // TODO: Use the input device configuration to control this behavior more finely.
  5625. uint32_t policyFlags = 0;
  5626. NotifyMotionArgs args(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, policyFlags,
  5627. AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
  5628. ADISPLAY_ID_NONE, 1, &pointerProperties, &pointerCoords, 0, 0, 0);
  5629. getListener()->notifyMotion(&args);
  5630. }
  5631. void JoystickInputMapper::setPointerCoordsAxisValue(PointerCoords* pointerCoords,
  5632. int32_t axis, float value) {
  5633. pointerCoords->setAxisValue(axis, value);
  5634. /* In order to ease the transition for developers from using the old axes
  5635. * to the newer, more semantically correct axes, we'll continue to produce
  5636. * values for the old axes as mirrors of the value of their corresponding
  5637. * new axes. */
  5638. int32_t compatAxis = getCompatAxis(axis);
  5639. if (compatAxis >= 0) {
  5640. pointerCoords->setAxisValue(compatAxis, value);
  5641. }
  5642. }
  5643. bool JoystickInputMapper::filterAxes(bool force) {
  5644. bool atLeastOneSignificantChange = force;
  5645. size_t numAxes = mAxes.size();
  5646. for (size_t i = 0; i < numAxes; i++) {
  5647. Axis& axis = mAxes.editValueAt(i);
  5648. if (force || hasValueChangedSignificantly(axis.filter,
  5649. axis.newValue, axis.currentValue, axis.min, axis.max)) {
  5650. axis.currentValue = axis.newValue;
  5651. atLeastOneSignificantChange = true;
  5652. }
  5653. if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
  5654. if (force || hasValueChangedSignificantly(axis.filter,
  5655. axis.highNewValue, axis.highCurrentValue, axis.min, axis.max)) {
  5656. axis.highCurrentValue = axis.highNewValue;
  5657. atLeastOneSignificantChange = true;
  5658. }
  5659. }
  5660. }
  5661. return atLeastOneSignificantChange;
  5662. }
  5663. bool JoystickInputMapper::hasValueChangedSignificantly(
  5664. float filter, float newValue, float currentValue, float min, float max) {
  5665. if (newValue != currentValue) {
  5666. // Filter out small changes in value unless the value is converging on the axis
  5667. // bounds or center point. This is intended to reduce the amount of information
  5668. // sent to applications by particularly noisy joysticks (such as PS3).
  5669. if (fabs(newValue - currentValue) > filter
  5670. || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, min)
  5671. || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, max)
  5672. || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, 0)) {
  5673. return true;
  5674. }
  5675. }
  5676. return false;
  5677. }
  5678. bool JoystickInputMapper::hasMovedNearerToValueWithinFilteredRange(
  5679. float filter, float newValue, float currentValue, float thresholdValue) {
  5680. float newDistance = fabs(newValue - thresholdValue);
  5681. if (newDistance < filter) {
  5682. float oldDistance = fabs(currentValue - thresholdValue);
  5683. if (newDistance < oldDistance) {
  5684. return true;
  5685. }
  5686. }
  5687. return false;
  5688. }
  5689. } // namespace android