blob: 841f4bc73a40a874b4c452173a391cbe15f7a1da [file] [log] [blame]
Jeff Brown5912f952013-07-01 19:10:31 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Input"
18//#define LOG_NDEBUG 0
19
20#include <math.h>
21#include <limits.h>
22
23#include <input/Input.h>
24
25#ifdef HAVE_ANDROID_OS
26#include <binder/Parcel.h>
27
28#include "SkPoint.h"
29#include "SkMatrix.h"
30#include "SkScalar.h"
31#endif
32
33namespace android {
34
35// --- InputEvent ---
36
37void InputEvent::initialize(int32_t deviceId, int32_t source) {
38 mDeviceId = deviceId;
39 mSource = source;
40}
41
42void InputEvent::initialize(const InputEvent& from) {
43 mDeviceId = from.mDeviceId;
44 mSource = from.mSource;
45}
46
47// --- KeyEvent ---
48
49bool KeyEvent::hasDefaultAction(int32_t keyCode) {
50 switch (keyCode) {
51 case AKEYCODE_HOME:
52 case AKEYCODE_BACK:
53 case AKEYCODE_CALL:
54 case AKEYCODE_ENDCALL:
55 case AKEYCODE_VOLUME_UP:
56 case AKEYCODE_VOLUME_DOWN:
57 case AKEYCODE_VOLUME_MUTE:
58 case AKEYCODE_POWER:
59 case AKEYCODE_CAMERA:
60 case AKEYCODE_HEADSETHOOK:
61 case AKEYCODE_MENU:
62 case AKEYCODE_NOTIFICATION:
63 case AKEYCODE_FOCUS:
64 case AKEYCODE_SEARCH:
65 case AKEYCODE_MEDIA_PLAY:
66 case AKEYCODE_MEDIA_PAUSE:
67 case AKEYCODE_MEDIA_PLAY_PAUSE:
68 case AKEYCODE_MEDIA_STOP:
69 case AKEYCODE_MEDIA_NEXT:
70 case AKEYCODE_MEDIA_PREVIOUS:
71 case AKEYCODE_MEDIA_REWIND:
72 case AKEYCODE_MEDIA_RECORD:
73 case AKEYCODE_MEDIA_FAST_FORWARD:
74 case AKEYCODE_MUTE:
75 case AKEYCODE_BRIGHTNESS_DOWN:
76 case AKEYCODE_BRIGHTNESS_UP:
Jaekyun Seok8d06dcf2013-07-08 13:56:02 +090077 case AKEYCODE_MEDIA_AUDIO_TRACK:
Jeff Brown5912f952013-07-01 19:10:31 -070078 return true;
79 }
80
81 return false;
82}
83
84bool KeyEvent::hasDefaultAction() const {
85 return hasDefaultAction(getKeyCode());
86}
87
88bool KeyEvent::isSystemKey(int32_t keyCode) {
89 switch (keyCode) {
90 case AKEYCODE_MENU:
91 case AKEYCODE_SOFT_RIGHT:
92 case AKEYCODE_HOME:
93 case AKEYCODE_BACK:
94 case AKEYCODE_CALL:
95 case AKEYCODE_ENDCALL:
96 case AKEYCODE_VOLUME_UP:
97 case AKEYCODE_VOLUME_DOWN:
98 case AKEYCODE_VOLUME_MUTE:
99 case AKEYCODE_MUTE:
100 case AKEYCODE_POWER:
101 case AKEYCODE_HEADSETHOOK:
102 case AKEYCODE_MEDIA_PLAY:
103 case AKEYCODE_MEDIA_PAUSE:
104 case AKEYCODE_MEDIA_PLAY_PAUSE:
105 case AKEYCODE_MEDIA_STOP:
106 case AKEYCODE_MEDIA_NEXT:
107 case AKEYCODE_MEDIA_PREVIOUS:
108 case AKEYCODE_MEDIA_REWIND:
109 case AKEYCODE_MEDIA_RECORD:
110 case AKEYCODE_MEDIA_FAST_FORWARD:
111 case AKEYCODE_CAMERA:
112 case AKEYCODE_FOCUS:
113 case AKEYCODE_SEARCH:
114 case AKEYCODE_BRIGHTNESS_DOWN:
115 case AKEYCODE_BRIGHTNESS_UP:
Jaekyun Seok8d06dcf2013-07-08 13:56:02 +0900116 case AKEYCODE_MEDIA_AUDIO_TRACK:
Jeff Brown5912f952013-07-01 19:10:31 -0700117 return true;
118 }
119
120 return false;
121}
122
123bool KeyEvent::isSystemKey() const {
124 return isSystemKey(getKeyCode());
125}
126
127void KeyEvent::initialize(
128 int32_t deviceId,
129 int32_t source,
130 int32_t action,
131 int32_t flags,
132 int32_t keyCode,
133 int32_t scanCode,
134 int32_t metaState,
135 int32_t repeatCount,
136 nsecs_t downTime,
137 nsecs_t eventTime) {
138 InputEvent::initialize(deviceId, source);
139 mAction = action;
140 mFlags = flags;
141 mKeyCode = keyCode;
142 mScanCode = scanCode;
143 mMetaState = metaState;
144 mRepeatCount = repeatCount;
145 mDownTime = downTime;
146 mEventTime = eventTime;
147}
148
149void KeyEvent::initialize(const KeyEvent& from) {
150 InputEvent::initialize(from);
151 mAction = from.mAction;
152 mFlags = from.mFlags;
153 mKeyCode = from.mKeyCode;
154 mScanCode = from.mScanCode;
155 mMetaState = from.mMetaState;
156 mRepeatCount = from.mRepeatCount;
157 mDownTime = from.mDownTime;
158 mEventTime = from.mEventTime;
159}
160
161
162// --- PointerCoords ---
163
164float PointerCoords::getAxisValue(int32_t axis) const {
165 if (axis < 0 || axis > 63) {
166 return 0;
167 }
168
169 uint64_t axisBit = 1LL << axis;
170 if (!(bits & axisBit)) {
171 return 0;
172 }
173 uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
174 return values[index];
175}
176
177status_t PointerCoords::setAxisValue(int32_t axis, float value) {
178 if (axis < 0 || axis > 63) {
179 return NAME_NOT_FOUND;
180 }
181
182 uint64_t axisBit = 1LL << axis;
183 uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
184 if (!(bits & axisBit)) {
185 if (value == 0) {
186 return OK; // axes with value 0 do not need to be stored
187 }
188 uint32_t count = __builtin_popcountll(bits);
189 if (count >= MAX_AXES) {
190 tooManyAxes(axis);
191 return NO_MEMORY;
192 }
193 bits |= axisBit;
194 for (uint32_t i = count; i > index; i--) {
195 values[i] = values[i - 1];
196 }
197 }
198 values[index] = value;
199 return OK;
200}
201
202static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
203 float value = c.getAxisValue(axis);
204 if (value != 0) {
205 c.setAxisValue(axis, value * scaleFactor);
206 }
207}
208
209void PointerCoords::scale(float scaleFactor) {
210 // No need to scale pressure or size since they are normalized.
211 // No need to scale orientation since it is meaningless to do so.
212 scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, scaleFactor);
213 scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, scaleFactor);
214 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, scaleFactor);
215 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, scaleFactor);
216 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, scaleFactor);
217 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor);
218}
219
220#ifdef HAVE_ANDROID_OS
221status_t PointerCoords::readFromParcel(Parcel* parcel) {
222 bits = parcel->readInt64();
223
224 uint32_t count = __builtin_popcountll(bits);
225 if (count > MAX_AXES) {
226 return BAD_VALUE;
227 }
228
229 for (uint32_t i = 0; i < count; i++) {
230 values[i] = parcel->readFloat();
231 }
232 return OK;
233}
234
235status_t PointerCoords::writeToParcel(Parcel* parcel) const {
236 parcel->writeInt64(bits);
237
238 uint32_t count = __builtin_popcountll(bits);
239 for (uint32_t i = 0; i < count; i++) {
240 parcel->writeFloat(values[i]);
241 }
242 return OK;
243}
244#endif
245
246void PointerCoords::tooManyAxes(int axis) {
247 ALOGW("Could not set value for axis %d because the PointerCoords structure is full and "
248 "cannot contain more than %d axis values.", axis, int(MAX_AXES));
249}
250
251bool PointerCoords::operator==(const PointerCoords& other) const {
252 if (bits != other.bits) {
253 return false;
254 }
255 uint32_t count = __builtin_popcountll(bits);
256 for (uint32_t i = 0; i < count; i++) {
257 if (values[i] != other.values[i]) {
258 return false;
259 }
260 }
261 return true;
262}
263
264void PointerCoords::copyFrom(const PointerCoords& other) {
265 bits = other.bits;
266 uint32_t count = __builtin_popcountll(bits);
267 for (uint32_t i = 0; i < count; i++) {
268 values[i] = other.values[i];
269 }
270}
271
272
273// --- PointerProperties ---
274
275bool PointerProperties::operator==(const PointerProperties& other) const {
276 return id == other.id
277 && toolType == other.toolType;
278}
279
280void PointerProperties::copyFrom(const PointerProperties& other) {
281 id = other.id;
282 toolType = other.toolType;
283}
284
285
286// --- MotionEvent ---
287
288void MotionEvent::initialize(
289 int32_t deviceId,
290 int32_t source,
291 int32_t action,
292 int32_t flags,
293 int32_t edgeFlags,
294 int32_t metaState,
295 int32_t buttonState,
296 float xOffset,
297 float yOffset,
298 float xPrecision,
299 float yPrecision,
300 nsecs_t downTime,
301 nsecs_t eventTime,
302 size_t pointerCount,
303 const PointerProperties* pointerProperties,
304 const PointerCoords* pointerCoords) {
305 InputEvent::initialize(deviceId, source);
306 mAction = action;
307 mFlags = flags;
308 mEdgeFlags = edgeFlags;
309 mMetaState = metaState;
310 mButtonState = buttonState;
311 mXOffset = xOffset;
312 mYOffset = yOffset;
313 mXPrecision = xPrecision;
314 mYPrecision = yPrecision;
315 mDownTime = downTime;
316 mPointerProperties.clear();
317 mPointerProperties.appendArray(pointerProperties, pointerCount);
318 mSampleEventTimes.clear();
319 mSamplePointerCoords.clear();
320 addSample(eventTime, pointerCoords);
321}
322
323void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
324 InputEvent::initialize(other->mDeviceId, other->mSource);
325 mAction = other->mAction;
326 mFlags = other->mFlags;
327 mEdgeFlags = other->mEdgeFlags;
328 mMetaState = other->mMetaState;
329 mButtonState = other->mButtonState;
330 mXOffset = other->mXOffset;
331 mYOffset = other->mYOffset;
332 mXPrecision = other->mXPrecision;
333 mYPrecision = other->mYPrecision;
334 mDownTime = other->mDownTime;
335 mPointerProperties = other->mPointerProperties;
336
337 if (keepHistory) {
338 mSampleEventTimes = other->mSampleEventTimes;
339 mSamplePointerCoords = other->mSamplePointerCoords;
340 } else {
341 mSampleEventTimes.clear();
342 mSampleEventTimes.push(other->getEventTime());
343 mSamplePointerCoords.clear();
344 size_t pointerCount = other->getPointerCount();
345 size_t historySize = other->getHistorySize();
346 mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
347 + (historySize * pointerCount), pointerCount);
348 }
349}
350
351void MotionEvent::addSample(
352 int64_t eventTime,
353 const PointerCoords* pointerCoords) {
354 mSampleEventTimes.push(eventTime);
355 mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
356}
357
358const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
359 return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
360}
361
362float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
363 return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
364}
365
366float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
367 float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
368 switch (axis) {
369 case AMOTION_EVENT_AXIS_X:
370 return value + mXOffset;
371 case AMOTION_EVENT_AXIS_Y:
372 return value + mYOffset;
373 }
374 return value;
375}
376
377const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
378 size_t pointerIndex, size_t historicalIndex) const {
379 return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
380}
381
382float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
383 size_t historicalIndex) const {
384 return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
385}
386
387float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
388 size_t historicalIndex) const {
389 float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
390 switch (axis) {
391 case AMOTION_EVENT_AXIS_X:
392 return value + mXOffset;
393 case AMOTION_EVENT_AXIS_Y:
394 return value + mYOffset;
395 }
396 return value;
397}
398
399ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
400 size_t pointerCount = mPointerProperties.size();
401 for (size_t i = 0; i < pointerCount; i++) {
402 if (mPointerProperties.itemAt(i).id == pointerId) {
403 return i;
404 }
405 }
406 return -1;
407}
408
409void MotionEvent::offsetLocation(float xOffset, float yOffset) {
410 mXOffset += xOffset;
411 mYOffset += yOffset;
412}
413
414void MotionEvent::scale(float scaleFactor) {
415 mXOffset *= scaleFactor;
416 mYOffset *= scaleFactor;
417 mXPrecision *= scaleFactor;
418 mYPrecision *= scaleFactor;
419
420 size_t numSamples = mSamplePointerCoords.size();
421 for (size_t i = 0; i < numSamples; i++) {
422 mSamplePointerCoords.editItemAt(i).scale(scaleFactor);
423 }
424}
425
426#ifdef HAVE_ANDROID_OS
427static inline float transformAngle(const SkMatrix* matrix, float angleRadians) {
428 // Construct and transform a vector oriented at the specified clockwise angle from vertical.
429 // Coordinate system: down is increasing Y, right is increasing X.
430 SkPoint vector;
431 vector.fX = SkFloatToScalar(sinf(angleRadians));
432 vector.fY = SkFloatToScalar(-cosf(angleRadians));
433 matrix->mapVectors(& vector, 1);
434
435 // Derive the transformed vector's clockwise angle from vertical.
436 float result = atan2f(SkScalarToFloat(vector.fX), SkScalarToFloat(-vector.fY));
437 if (result < - M_PI_2) {
438 result += M_PI;
439 } else if (result > M_PI_2) {
440 result -= M_PI;
441 }
442 return result;
443}
444
445void MotionEvent::transform(const SkMatrix* matrix) {
446 float oldXOffset = mXOffset;
447 float oldYOffset = mYOffset;
448
449 // The tricky part of this implementation is to preserve the value of
450 // rawX and rawY. So we apply the transformation to the first point
451 // then derive an appropriate new X/Y offset that will preserve rawX and rawY.
452 SkPoint point;
453 float rawX = getRawX(0);
454 float rawY = getRawY(0);
455 matrix->mapXY(SkFloatToScalar(rawX + oldXOffset), SkFloatToScalar(rawY + oldYOffset),
456 & point);
457 float newX = SkScalarToFloat(point.fX);
458 float newY = SkScalarToFloat(point.fY);
459 float newXOffset = newX - rawX;
460 float newYOffset = newY - rawY;
461
462 mXOffset = newXOffset;
463 mYOffset = newYOffset;
464
465 // Apply the transformation to all samples.
466 size_t numSamples = mSamplePointerCoords.size();
467 for (size_t i = 0; i < numSamples; i++) {
468 PointerCoords& c = mSamplePointerCoords.editItemAt(i);
469 float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
470 float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
471 matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), &point);
472 c.setAxisValue(AMOTION_EVENT_AXIS_X, SkScalarToFloat(point.fX) - newXOffset);
473 c.setAxisValue(AMOTION_EVENT_AXIS_Y, SkScalarToFloat(point.fY) - newYOffset);
474
475 float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
476 c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, transformAngle(matrix, orientation));
477 }
478}
479
480status_t MotionEvent::readFromParcel(Parcel* parcel) {
481 size_t pointerCount = parcel->readInt32();
482 size_t sampleCount = parcel->readInt32();
483 if (pointerCount == 0 || pointerCount > MAX_POINTERS || sampleCount == 0) {
484 return BAD_VALUE;
485 }
486
487 mDeviceId = parcel->readInt32();
488 mSource = parcel->readInt32();
489 mAction = parcel->readInt32();
490 mFlags = parcel->readInt32();
491 mEdgeFlags = parcel->readInt32();
492 mMetaState = parcel->readInt32();
493 mButtonState = parcel->readInt32();
494 mXOffset = parcel->readFloat();
495 mYOffset = parcel->readFloat();
496 mXPrecision = parcel->readFloat();
497 mYPrecision = parcel->readFloat();
498 mDownTime = parcel->readInt64();
499
500 mPointerProperties.clear();
501 mPointerProperties.setCapacity(pointerCount);
502 mSampleEventTimes.clear();
503 mSampleEventTimes.setCapacity(sampleCount);
504 mSamplePointerCoords.clear();
505 mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
506
507 for (size_t i = 0; i < pointerCount; i++) {
508 mPointerProperties.push();
509 PointerProperties& properties = mPointerProperties.editTop();
510 properties.id = parcel->readInt32();
511 properties.toolType = parcel->readInt32();
512 }
513
514 while (sampleCount-- > 0) {
515 mSampleEventTimes.push(parcel->readInt64());
516 for (size_t i = 0; i < pointerCount; i++) {
517 mSamplePointerCoords.push();
518 status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
519 if (status) {
520 return status;
521 }
522 }
523 }
524 return OK;
525}
526
527status_t MotionEvent::writeToParcel(Parcel* parcel) const {
528 size_t pointerCount = mPointerProperties.size();
529 size_t sampleCount = mSampleEventTimes.size();
530
531 parcel->writeInt32(pointerCount);
532 parcel->writeInt32(sampleCount);
533
534 parcel->writeInt32(mDeviceId);
535 parcel->writeInt32(mSource);
536 parcel->writeInt32(mAction);
537 parcel->writeInt32(mFlags);
538 parcel->writeInt32(mEdgeFlags);
539 parcel->writeInt32(mMetaState);
540 parcel->writeInt32(mButtonState);
541 parcel->writeFloat(mXOffset);
542 parcel->writeFloat(mYOffset);
543 parcel->writeFloat(mXPrecision);
544 parcel->writeFloat(mYPrecision);
545 parcel->writeInt64(mDownTime);
546
547 for (size_t i = 0; i < pointerCount; i++) {
548 const PointerProperties& properties = mPointerProperties.itemAt(i);
549 parcel->writeInt32(properties.id);
550 parcel->writeInt32(properties.toolType);
551 }
552
553 const PointerCoords* pc = mSamplePointerCoords.array();
554 for (size_t h = 0; h < sampleCount; h++) {
555 parcel->writeInt64(mSampleEventTimes.itemAt(h));
556 for (size_t i = 0; i < pointerCount; i++) {
557 status_t status = (pc++)->writeToParcel(parcel);
558 if (status) {
559 return status;
560 }
561 }
562 }
563 return OK;
564}
565#endif
566
567bool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
568 if (source & AINPUT_SOURCE_CLASS_POINTER) {
569 // Specifically excludes HOVER_MOVE and SCROLL.
570 switch (action & AMOTION_EVENT_ACTION_MASK) {
571 case AMOTION_EVENT_ACTION_DOWN:
572 case AMOTION_EVENT_ACTION_MOVE:
573 case AMOTION_EVENT_ACTION_UP:
574 case AMOTION_EVENT_ACTION_POINTER_DOWN:
575 case AMOTION_EVENT_ACTION_POINTER_UP:
576 case AMOTION_EVENT_ACTION_CANCEL:
577 case AMOTION_EVENT_ACTION_OUTSIDE:
578 return true;
579 }
580 }
581 return false;
582}
583
584
585// --- PooledInputEventFactory ---
586
587PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
588 mMaxPoolSize(maxPoolSize) {
589}
590
591PooledInputEventFactory::~PooledInputEventFactory() {
592 for (size_t i = 0; i < mKeyEventPool.size(); i++) {
593 delete mKeyEventPool.itemAt(i);
594 }
595 for (size_t i = 0; i < mMotionEventPool.size(); i++) {
596 delete mMotionEventPool.itemAt(i);
597 }
598}
599
600KeyEvent* PooledInputEventFactory::createKeyEvent() {
601 if (!mKeyEventPool.isEmpty()) {
602 KeyEvent* event = mKeyEventPool.top();
603 mKeyEventPool.pop();
604 return event;
605 }
606 return new KeyEvent();
607}
608
609MotionEvent* PooledInputEventFactory::createMotionEvent() {
610 if (!mMotionEventPool.isEmpty()) {
611 MotionEvent* event = mMotionEventPool.top();
612 mMotionEventPool.pop();
613 return event;
614 }
615 return new MotionEvent();
616}
617
618void PooledInputEventFactory::recycle(InputEvent* event) {
619 switch (event->getType()) {
620 case AINPUT_EVENT_TYPE_KEY:
621 if (mKeyEventPool.size() < mMaxPoolSize) {
622 mKeyEventPool.push(static_cast<KeyEvent*>(event));
623 return;
624 }
625 break;
626 case AINPUT_EVENT_TYPE_MOTION:
627 if (mMotionEventPool.size() < mMaxPoolSize) {
628 mMotionEventPool.push(static_cast<MotionEvent*>(event));
629 return;
630 }
631 break;
632 }
633 delete event;
634}
635
636} // namespace android