Input.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  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 "Input"
  17. //#define LOG_NDEBUG 0
  18. #include <math.h>
  19. #include <limits.h>
  20. #include <input/Input.h>
  21. #include <input/InputEventLabels.h>
  22. #ifdef __ANDROID__
  23. #include <binder/Parcel.h>
  24. #endif
  25. namespace android {
  26. const char* motionClassificationToString(MotionClassification classification) {
  27. switch (classification) {
  28. case MotionClassification::NONE:
  29. return "NONE";
  30. case MotionClassification::AMBIGUOUS_GESTURE:
  31. return "AMBIGUOUS_GESTURE";
  32. case MotionClassification::DEEP_PRESS:
  33. return "DEEP_PRESS";
  34. }
  35. }
  36. // --- InputEvent ---
  37. void InputEvent::initialize(int32_t deviceId, int32_t source, int32_t displayId) {
  38. mDeviceId = deviceId;
  39. mSource = source;
  40. mDisplayId = displayId;
  41. }
  42. void InputEvent::initialize(const InputEvent& from) {
  43. mDeviceId = from.mDeviceId;
  44. mSource = from.mSource;
  45. mDisplayId = from.mDisplayId;
  46. }
  47. // --- KeyEvent ---
  48. const char* KeyEvent::getLabel(int32_t keyCode) {
  49. return getLabelByKeyCode(keyCode);
  50. }
  51. int32_t KeyEvent::getKeyCodeFromLabel(const char* label) {
  52. return getKeyCodeByLabel(label);
  53. }
  54. void KeyEvent::initialize(
  55. int32_t deviceId,
  56. int32_t source,
  57. int32_t displayId,
  58. int32_t action,
  59. int32_t flags,
  60. int32_t keyCode,
  61. int32_t scanCode,
  62. int32_t metaState,
  63. int32_t repeatCount,
  64. nsecs_t downTime,
  65. nsecs_t eventTime) {
  66. InputEvent::initialize(deviceId, source, displayId);
  67. mAction = action;
  68. mFlags = flags;
  69. mKeyCode = keyCode;
  70. mScanCode = scanCode;
  71. mMetaState = metaState;
  72. mRepeatCount = repeatCount;
  73. mDownTime = downTime;
  74. mEventTime = eventTime;
  75. }
  76. void KeyEvent::initialize(const KeyEvent& from) {
  77. InputEvent::initialize(from);
  78. mAction = from.mAction;
  79. mFlags = from.mFlags;
  80. mKeyCode = from.mKeyCode;
  81. mScanCode = from.mScanCode;
  82. mMetaState = from.mMetaState;
  83. mRepeatCount = from.mRepeatCount;
  84. mDownTime = from.mDownTime;
  85. mEventTime = from.mEventTime;
  86. }
  87. // --- PointerCoords ---
  88. float PointerCoords::getAxisValue(int32_t axis) const {
  89. if (axis < 0 || axis > 63 || !BitSet64::hasBit(bits, axis)){
  90. return 0;
  91. }
  92. return values[BitSet64::getIndexOfBit(bits, axis)];
  93. }
  94. status_t PointerCoords::setAxisValue(int32_t axis, float value) {
  95. if (axis < 0 || axis > 63) {
  96. return NAME_NOT_FOUND;
  97. }
  98. uint32_t index = BitSet64::getIndexOfBit(bits, axis);
  99. if (!BitSet64::hasBit(bits, axis)) {
  100. if (value == 0) {
  101. return OK; // axes with value 0 do not need to be stored
  102. }
  103. uint32_t count = BitSet64::count(bits);
  104. if (count >= MAX_AXES) {
  105. tooManyAxes(axis);
  106. return NO_MEMORY;
  107. }
  108. BitSet64::markBit(bits, axis);
  109. for (uint32_t i = count; i > index; i--) {
  110. values[i] = values[i - 1];
  111. }
  112. }
  113. values[index] = value;
  114. return OK;
  115. }
  116. static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
  117. float value = c.getAxisValue(axis);
  118. if (value != 0) {
  119. c.setAxisValue(axis, value * scaleFactor);
  120. }
  121. }
  122. void PointerCoords::scale(float globalScaleFactor, float windowXScale, float windowYScale) {
  123. // No need to scale pressure or size since they are normalized.
  124. // No need to scale orientation since it is meaningless to do so.
  125. // If there is a global scale factor, it is included in the windowX/YScale
  126. // so we don't need to apply it twice to the X/Y axes.
  127. // However we don't want to apply any windowXYScale not included in the global scale
  128. // to the TOUCH_MAJOR/MINOR coordinates.
  129. scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, windowXScale);
  130. scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, windowYScale);
  131. scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, globalScaleFactor);
  132. scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, globalScaleFactor);
  133. scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, globalScaleFactor);
  134. scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, globalScaleFactor);
  135. }
  136. void PointerCoords::scale(float globalScaleFactor) {
  137. scale(globalScaleFactor, globalScaleFactor, globalScaleFactor);
  138. }
  139. void PointerCoords::applyOffset(float xOffset, float yOffset) {
  140. setAxisValue(AMOTION_EVENT_AXIS_X, getX() + xOffset);
  141. setAxisValue(AMOTION_EVENT_AXIS_Y, getY() + yOffset);
  142. }
  143. #ifdef __ANDROID__
  144. status_t PointerCoords::readFromParcel(Parcel* parcel) {
  145. bits = parcel->readInt64();
  146. uint32_t count = BitSet64::count(bits);
  147. if (count > MAX_AXES) {
  148. return BAD_VALUE;
  149. }
  150. for (uint32_t i = 0; i < count; i++) {
  151. values[i] = parcel->readFloat();
  152. }
  153. return OK;
  154. }
  155. status_t PointerCoords::writeToParcel(Parcel* parcel) const {
  156. parcel->writeInt64(bits);
  157. uint32_t count = BitSet64::count(bits);
  158. for (uint32_t i = 0; i < count; i++) {
  159. parcel->writeFloat(values[i]);
  160. }
  161. return OK;
  162. }
  163. #endif
  164. void PointerCoords::tooManyAxes(int axis) {
  165. ALOGW("Could not set value for axis %d because the PointerCoords structure is full and "
  166. "cannot contain more than %d axis values.", axis, int(MAX_AXES));
  167. }
  168. bool PointerCoords::operator==(const PointerCoords& other) const {
  169. if (bits != other.bits) {
  170. return false;
  171. }
  172. uint32_t count = BitSet64::count(bits);
  173. for (uint32_t i = 0; i < count; i++) {
  174. if (values[i] != other.values[i]) {
  175. return false;
  176. }
  177. }
  178. return true;
  179. }
  180. void PointerCoords::copyFrom(const PointerCoords& other) {
  181. bits = other.bits;
  182. uint32_t count = BitSet64::count(bits);
  183. for (uint32_t i = 0; i < count; i++) {
  184. values[i] = other.values[i];
  185. }
  186. }
  187. // --- PointerProperties ---
  188. bool PointerProperties::operator==(const PointerProperties& other) const {
  189. return id == other.id
  190. && toolType == other.toolType;
  191. }
  192. void PointerProperties::copyFrom(const PointerProperties& other) {
  193. id = other.id;
  194. toolType = other.toolType;
  195. }
  196. // --- MotionEvent ---
  197. void MotionEvent::initialize(
  198. int32_t deviceId,
  199. int32_t source,
  200. int32_t displayId,
  201. int32_t action,
  202. int32_t actionButton,
  203. int32_t flags,
  204. int32_t edgeFlags,
  205. int32_t metaState,
  206. int32_t buttonState,
  207. MotionClassification classification,
  208. float xOffset,
  209. float yOffset,
  210. float xPrecision,
  211. float yPrecision,
  212. nsecs_t downTime,
  213. nsecs_t eventTime,
  214. size_t pointerCount,
  215. const PointerProperties* pointerProperties,
  216. const PointerCoords* pointerCoords) {
  217. InputEvent::initialize(deviceId, source, displayId);
  218. mAction = action;
  219. mActionButton = actionButton;
  220. mFlags = flags;
  221. mEdgeFlags = edgeFlags;
  222. mMetaState = metaState;
  223. mButtonState = buttonState;
  224. mClassification = classification;
  225. mXOffset = xOffset;
  226. mYOffset = yOffset;
  227. mXPrecision = xPrecision;
  228. mYPrecision = yPrecision;
  229. mDownTime = downTime;
  230. mPointerProperties.clear();
  231. mPointerProperties.appendArray(pointerProperties, pointerCount);
  232. mSampleEventTimes.clear();
  233. mSamplePointerCoords.clear();
  234. addSample(eventTime, pointerCoords);
  235. }
  236. void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
  237. InputEvent::initialize(other->mDeviceId, other->mSource, other->mDisplayId);
  238. mAction = other->mAction;
  239. mActionButton = other->mActionButton;
  240. mFlags = other->mFlags;
  241. mEdgeFlags = other->mEdgeFlags;
  242. mMetaState = other->mMetaState;
  243. mButtonState = other->mButtonState;
  244. mClassification = other->mClassification;
  245. mXOffset = other->mXOffset;
  246. mYOffset = other->mYOffset;
  247. mXPrecision = other->mXPrecision;
  248. mYPrecision = other->mYPrecision;
  249. mDownTime = other->mDownTime;
  250. mPointerProperties = other->mPointerProperties;
  251. if (keepHistory) {
  252. mSampleEventTimes = other->mSampleEventTimes;
  253. mSamplePointerCoords = other->mSamplePointerCoords;
  254. } else {
  255. mSampleEventTimes.clear();
  256. mSampleEventTimes.push(other->getEventTime());
  257. mSamplePointerCoords.clear();
  258. size_t pointerCount = other->getPointerCount();
  259. size_t historySize = other->getHistorySize();
  260. mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
  261. + (historySize * pointerCount), pointerCount);
  262. }
  263. }
  264. void MotionEvent::addSample(
  265. int64_t eventTime,
  266. const PointerCoords* pointerCoords) {
  267. mSampleEventTimes.push(eventTime);
  268. mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
  269. }
  270. const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
  271. return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
  272. }
  273. float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
  274. return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
  275. }
  276. float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
  277. float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
  278. switch (axis) {
  279. case AMOTION_EVENT_AXIS_X:
  280. return value + mXOffset;
  281. case AMOTION_EVENT_AXIS_Y:
  282. return value + mYOffset;
  283. }
  284. return value;
  285. }
  286. const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
  287. size_t pointerIndex, size_t historicalIndex) const {
  288. return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
  289. }
  290. float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
  291. size_t historicalIndex) const {
  292. return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
  293. }
  294. float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
  295. size_t historicalIndex) const {
  296. float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
  297. switch (axis) {
  298. case AMOTION_EVENT_AXIS_X:
  299. return value + mXOffset;
  300. case AMOTION_EVENT_AXIS_Y:
  301. return value + mYOffset;
  302. }
  303. return value;
  304. }
  305. ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
  306. size_t pointerCount = mPointerProperties.size();
  307. for (size_t i = 0; i < pointerCount; i++) {
  308. if (mPointerProperties.itemAt(i).id == pointerId) {
  309. return i;
  310. }
  311. }
  312. return -1;
  313. }
  314. void MotionEvent::offsetLocation(float xOffset, float yOffset) {
  315. mXOffset += xOffset;
  316. mYOffset += yOffset;
  317. }
  318. void MotionEvent::scale(float globalScaleFactor) {
  319. mXOffset *= globalScaleFactor;
  320. mYOffset *= globalScaleFactor;
  321. mXPrecision *= globalScaleFactor;
  322. mYPrecision *= globalScaleFactor;
  323. size_t numSamples = mSamplePointerCoords.size();
  324. for (size_t i = 0; i < numSamples; i++) {
  325. mSamplePointerCoords.editItemAt(i).scale(globalScaleFactor);
  326. }
  327. }
  328. static void transformPoint(const float matrix[9], float x, float y, float *outX, float *outY) {
  329. // Apply perspective transform like Skia.
  330. float newX = matrix[0] * x + matrix[1] * y + matrix[2];
  331. float newY = matrix[3] * x + matrix[4] * y + matrix[5];
  332. float newZ = matrix[6] * x + matrix[7] * y + matrix[8];
  333. if (newZ) {
  334. newZ = 1.0f / newZ;
  335. }
  336. *outX = newX * newZ;
  337. *outY = newY * newZ;
  338. }
  339. static float transformAngle(const float matrix[9], float angleRadians,
  340. float originX, float originY) {
  341. // Construct and transform a vector oriented at the specified clockwise angle from vertical.
  342. // Coordinate system: down is increasing Y, right is increasing X.
  343. float x = sinf(angleRadians);
  344. float y = -cosf(angleRadians);
  345. transformPoint(matrix, x, y, &x, &y);
  346. x -= originX;
  347. y -= originY;
  348. // Derive the transformed vector's clockwise angle from vertical.
  349. float result = atan2f(x, -y);
  350. if (result < - M_PI_2) {
  351. result += M_PI;
  352. } else if (result > M_PI_2) {
  353. result -= M_PI;
  354. }
  355. return result;
  356. }
  357. void MotionEvent::transform(const float matrix[9]) {
  358. // The tricky part of this implementation is to preserve the value of
  359. // rawX and rawY. So we apply the transformation to the first point
  360. // then derive an appropriate new X/Y offset that will preserve rawX
  361. // and rawY for that point.
  362. float oldXOffset = mXOffset;
  363. float oldYOffset = mYOffset;
  364. float newX, newY;
  365. float rawX = getRawX(0);
  366. float rawY = getRawY(0);
  367. transformPoint(matrix, rawX + oldXOffset, rawY + oldYOffset, &newX, &newY);
  368. mXOffset = newX - rawX;
  369. mYOffset = newY - rawY;
  370. // Determine how the origin is transformed by the matrix so that we
  371. // can transform orientation vectors.
  372. float originX, originY;
  373. transformPoint(matrix, 0, 0, &originX, &originY);
  374. // Apply the transformation to all samples.
  375. size_t numSamples = mSamplePointerCoords.size();
  376. for (size_t i = 0; i < numSamples; i++) {
  377. PointerCoords& c = mSamplePointerCoords.editItemAt(i);
  378. float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
  379. float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
  380. transformPoint(matrix, x, y, &x, &y);
  381. c.setAxisValue(AMOTION_EVENT_AXIS_X, x - mXOffset);
  382. c.setAxisValue(AMOTION_EVENT_AXIS_Y, y - mYOffset);
  383. float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
  384. c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
  385. transformAngle(matrix, orientation, originX, originY));
  386. }
  387. }
  388. #ifdef __ANDROID__
  389. status_t MotionEvent::readFromParcel(Parcel* parcel) {
  390. size_t pointerCount = parcel->readInt32();
  391. size_t sampleCount = parcel->readInt32();
  392. if (pointerCount == 0 || pointerCount > MAX_POINTERS ||
  393. sampleCount == 0 || sampleCount > MAX_SAMPLES) {
  394. return BAD_VALUE;
  395. }
  396. mDeviceId = parcel->readInt32();
  397. mSource = parcel->readInt32();
  398. mDisplayId = parcel->readInt32();
  399. mAction = parcel->readInt32();
  400. mActionButton = parcel->readInt32();
  401. mFlags = parcel->readInt32();
  402. mEdgeFlags = parcel->readInt32();
  403. mMetaState = parcel->readInt32();
  404. mButtonState = parcel->readInt32();
  405. mClassification = static_cast<MotionClassification>(parcel->readByte());
  406. mXOffset = parcel->readFloat();
  407. mYOffset = parcel->readFloat();
  408. mXPrecision = parcel->readFloat();
  409. mYPrecision = parcel->readFloat();
  410. mDownTime = parcel->readInt64();
  411. mPointerProperties.clear();
  412. mPointerProperties.setCapacity(pointerCount);
  413. mSampleEventTimes.clear();
  414. mSampleEventTimes.setCapacity(sampleCount);
  415. mSamplePointerCoords.clear();
  416. mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
  417. for (size_t i = 0; i < pointerCount; i++) {
  418. mPointerProperties.push();
  419. PointerProperties& properties = mPointerProperties.editTop();
  420. properties.id = parcel->readInt32();
  421. properties.toolType = parcel->readInt32();
  422. }
  423. while (sampleCount > 0) {
  424. sampleCount--;
  425. mSampleEventTimes.push(parcel->readInt64());
  426. for (size_t i = 0; i < pointerCount; i++) {
  427. mSamplePointerCoords.push();
  428. status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
  429. if (status) {
  430. return status;
  431. }
  432. }
  433. }
  434. return OK;
  435. }
  436. status_t MotionEvent::writeToParcel(Parcel* parcel) const {
  437. size_t pointerCount = mPointerProperties.size();
  438. size_t sampleCount = mSampleEventTimes.size();
  439. parcel->writeInt32(pointerCount);
  440. parcel->writeInt32(sampleCount);
  441. parcel->writeInt32(mDeviceId);
  442. parcel->writeInt32(mSource);
  443. parcel->writeInt32(mDisplayId);
  444. parcel->writeInt32(mAction);
  445. parcel->writeInt32(mActionButton);
  446. parcel->writeInt32(mFlags);
  447. parcel->writeInt32(mEdgeFlags);
  448. parcel->writeInt32(mMetaState);
  449. parcel->writeInt32(mButtonState);
  450. parcel->writeByte(static_cast<int8_t>(mClassification));
  451. parcel->writeFloat(mXOffset);
  452. parcel->writeFloat(mYOffset);
  453. parcel->writeFloat(mXPrecision);
  454. parcel->writeFloat(mYPrecision);
  455. parcel->writeInt64(mDownTime);
  456. for (size_t i = 0; i < pointerCount; i++) {
  457. const PointerProperties& properties = mPointerProperties.itemAt(i);
  458. parcel->writeInt32(properties.id);
  459. parcel->writeInt32(properties.toolType);
  460. }
  461. const PointerCoords* pc = mSamplePointerCoords.array();
  462. for (size_t h = 0; h < sampleCount; h++) {
  463. parcel->writeInt64(mSampleEventTimes.itemAt(h));
  464. for (size_t i = 0; i < pointerCount; i++) {
  465. status_t status = (pc++)->writeToParcel(parcel);
  466. if (status) {
  467. return status;
  468. }
  469. }
  470. }
  471. return OK;
  472. }
  473. #endif
  474. bool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
  475. if (source & AINPUT_SOURCE_CLASS_POINTER) {
  476. // Specifically excludes HOVER_MOVE and SCROLL.
  477. switch (action & AMOTION_EVENT_ACTION_MASK) {
  478. case AMOTION_EVENT_ACTION_DOWN:
  479. case AMOTION_EVENT_ACTION_MOVE:
  480. case AMOTION_EVENT_ACTION_UP:
  481. case AMOTION_EVENT_ACTION_POINTER_DOWN:
  482. case AMOTION_EVENT_ACTION_POINTER_UP:
  483. case AMOTION_EVENT_ACTION_CANCEL:
  484. case AMOTION_EVENT_ACTION_OUTSIDE:
  485. return true;
  486. }
  487. }
  488. return false;
  489. }
  490. const char* MotionEvent::getLabel(int32_t axis) {
  491. return getAxisLabel(axis);
  492. }
  493. int32_t MotionEvent::getAxisFromLabel(const char* label) {
  494. return getAxisByLabel(label);
  495. }
  496. // --- PooledInputEventFactory ---
  497. PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
  498. mMaxPoolSize(maxPoolSize) {
  499. }
  500. PooledInputEventFactory::~PooledInputEventFactory() {
  501. for (size_t i = 0; i < mKeyEventPool.size(); i++) {
  502. delete mKeyEventPool.itemAt(i);
  503. }
  504. for (size_t i = 0; i < mMotionEventPool.size(); i++) {
  505. delete mMotionEventPool.itemAt(i);
  506. }
  507. }
  508. KeyEvent* PooledInputEventFactory::createKeyEvent() {
  509. if (!mKeyEventPool.isEmpty()) {
  510. KeyEvent* event = mKeyEventPool.top();
  511. mKeyEventPool.pop();
  512. return event;
  513. }
  514. return new KeyEvent();
  515. }
  516. MotionEvent* PooledInputEventFactory::createMotionEvent() {
  517. if (!mMotionEventPool.isEmpty()) {
  518. MotionEvent* event = mMotionEventPool.top();
  519. mMotionEventPool.pop();
  520. return event;
  521. }
  522. return new MotionEvent();
  523. }
  524. void PooledInputEventFactory::recycle(InputEvent* event) {
  525. switch (event->getType()) {
  526. case AINPUT_EVENT_TYPE_KEY:
  527. if (mKeyEventPool.size() < mMaxPoolSize) {
  528. mKeyEventPool.push(static_cast<KeyEvent*>(event));
  529. return;
  530. }
  531. break;
  532. case AINPUT_EVENT_TYPE_MOTION:
  533. if (mMotionEventPool.size() < mMaxPoolSize) {
  534. mMotionEventPool.push(static_cast<MotionEvent*>(event));
  535. return;
  536. }
  537. break;
  538. }
  539. delete event;
  540. }
  541. } // namespace android