Wed, 31 Dec 2014 07:22:50 +0100
Correct previous dual key logic pending first delivery installment.
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 */
17 #define LOG_TAG "Input"
18 //#define LOG_NDEBUG 0
19 #include "cutils_log.h"
21 #include <math.h>
22 #include <limits.h>
24 #include "Input.h"
26 #ifdef HAVE_ANDROID_OS
27 #include <binder/Parcel.h>
29 #include "SkPoint.h"
30 #include "SkMatrix.h"
31 #include "SkScalar.h"
32 #endif
34 namespace android {
36 // --- InputEvent ---
38 void InputEvent::initialize(int32_t deviceId, int32_t source) {
39 mDeviceId = deviceId;
40 mSource = source;
41 }
43 void InputEvent::initialize(const InputEvent& from) {
44 mDeviceId = from.mDeviceId;
45 mSource = from.mSource;
46 }
48 // --- KeyEvent ---
50 bool KeyEvent::hasDefaultAction(int32_t keyCode) {
51 switch (keyCode) {
52 case AKEYCODE_HOME:
53 case AKEYCODE_BACK:
54 case AKEYCODE_CALL:
55 case AKEYCODE_ENDCALL:
56 case AKEYCODE_VOLUME_UP:
57 case AKEYCODE_VOLUME_DOWN:
58 case AKEYCODE_VOLUME_MUTE:
59 case AKEYCODE_POWER:
60 case AKEYCODE_CAMERA:
61 case AKEYCODE_HEADSETHOOK:
62 case AKEYCODE_MENU:
63 case AKEYCODE_NOTIFICATION:
64 case AKEYCODE_FOCUS:
65 case AKEYCODE_SEARCH:
66 case AKEYCODE_MEDIA_PLAY:
67 case AKEYCODE_MEDIA_PAUSE:
68 case AKEYCODE_MEDIA_PLAY_PAUSE:
69 case AKEYCODE_MEDIA_STOP:
70 case AKEYCODE_MEDIA_NEXT:
71 case AKEYCODE_MEDIA_PREVIOUS:
72 case AKEYCODE_MEDIA_REWIND:
73 case AKEYCODE_MEDIA_RECORD:
74 case AKEYCODE_MEDIA_FAST_FORWARD:
75 case AKEYCODE_MUTE:
76 case AKEYCODE_BRIGHTNESS_DOWN:
77 case AKEYCODE_BRIGHTNESS_UP:
78 return true;
79 }
81 return false;
82 }
84 bool KeyEvent::hasDefaultAction() const {
85 return hasDefaultAction(getKeyCode());
86 }
88 bool 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:
116 return true;
117 }
119 return false;
120 }
122 bool KeyEvent::isSystemKey() const {
123 return isSystemKey(getKeyCode());
124 }
126 void KeyEvent::initialize(
127 int32_t deviceId,
128 int32_t source,
129 int32_t action,
130 int32_t flags,
131 int32_t keyCode,
132 int32_t scanCode,
133 int32_t metaState,
134 int32_t repeatCount,
135 nsecs_t downTime,
136 nsecs_t eventTime) {
137 InputEvent::initialize(deviceId, source);
138 mAction = action;
139 mFlags = flags;
140 mKeyCode = keyCode;
141 mScanCode = scanCode;
142 mMetaState = metaState;
143 mRepeatCount = repeatCount;
144 mDownTime = downTime;
145 mEventTime = eventTime;
146 }
148 void KeyEvent::initialize(const KeyEvent& from) {
149 InputEvent::initialize(from);
150 mAction = from.mAction;
151 mFlags = from.mFlags;
152 mKeyCode = from.mKeyCode;
153 mScanCode = from.mScanCode;
154 mMetaState = from.mMetaState;
155 mRepeatCount = from.mRepeatCount;
156 mDownTime = from.mDownTime;
157 mEventTime = from.mEventTime;
158 }
161 // --- PointerCoords ---
163 float PointerCoords::getAxisValue(int32_t axis) const {
164 if (axis < 0 || axis > 63) {
165 return 0;
166 }
168 uint64_t axisBit = 1LL << axis;
169 if (!(bits & axisBit)) {
170 return 0;
171 }
172 uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
173 return values[index];
174 }
176 status_t PointerCoords::setAxisValue(int32_t axis, float value) {
177 if (axis < 0 || axis > 63) {
178 return NAME_NOT_FOUND;
179 }
181 uint64_t axisBit = 1LL << axis;
182 uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
183 if (!(bits & axisBit)) {
184 if (value == 0) {
185 return OK; // axes with value 0 do not need to be stored
186 }
187 uint32_t count = __builtin_popcountll(bits);
188 if (count >= MAX_AXES) {
189 tooManyAxes(axis);
190 return NO_MEMORY;
191 }
192 bits |= axisBit;
193 for (uint32_t i = count; i > index; i--) {
194 values[i] = values[i - 1];
195 }
196 }
197 values[index] = value;
198 return OK;
199 }
201 static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
202 float value = c.getAxisValue(axis);
203 if (value != 0) {
204 c.setAxisValue(axis, value * scaleFactor);
205 }
206 }
208 void PointerCoords::scale(float scaleFactor) {
209 // No need to scale pressure or size since they are normalized.
210 // No need to scale orientation since it is meaningless to do so.
211 scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, scaleFactor);
212 scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, scaleFactor);
213 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, scaleFactor);
214 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, scaleFactor);
215 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, scaleFactor);
216 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor);
217 }
219 #ifdef HAVE_ANDROID_OS
220 status_t PointerCoords::readFromParcel(Parcel* parcel) {
221 bits = parcel->readInt64();
223 uint32_t count = __builtin_popcountll(bits);
224 if (count > MAX_AXES) {
225 return BAD_VALUE;
226 }
228 for (uint32_t i = 0; i < count; i++) {
229 values[i] = parcel->readFloat();
230 }
231 return OK;
232 }
234 status_t PointerCoords::writeToParcel(Parcel* parcel) const {
235 parcel->writeInt64(bits);
237 uint32_t count = __builtin_popcountll(bits);
238 for (uint32_t i = 0; i < count; i++) {
239 parcel->writeFloat(values[i]);
240 }
241 return OK;
242 }
243 #endif
245 void PointerCoords::tooManyAxes(int axis) {
246 ALOGW("Could not set value for axis %d because the PointerCoords structure is full and "
247 "cannot contain more than %d axis values.", axis, int(MAX_AXES));
248 }
250 bool PointerCoords::operator==(const PointerCoords& other) const {
251 if (bits != other.bits) {
252 return false;
253 }
254 uint32_t count = __builtin_popcountll(bits);
255 for (uint32_t i = 0; i < count; i++) {
256 if (values[i] != other.values[i]) {
257 return false;
258 }
259 }
260 return true;
261 }
263 void PointerCoords::copyFrom(const PointerCoords& other) {
264 bits = other.bits;
265 uint32_t count = __builtin_popcountll(bits);
266 for (uint32_t i = 0; i < count; i++) {
267 values[i] = other.values[i];
268 }
269 }
272 // --- PointerProperties ---
274 bool PointerProperties::operator==(const PointerProperties& other) const {
275 return id == other.id
276 && toolType == other.toolType;
277 }
279 void PointerProperties::copyFrom(const PointerProperties& other) {
280 id = other.id;
281 toolType = other.toolType;
282 }
285 // --- MotionEvent ---
287 void MotionEvent::initialize(
288 int32_t deviceId,
289 int32_t source,
290 int32_t action,
291 int32_t flags,
292 int32_t edgeFlags,
293 int32_t metaState,
294 int32_t buttonState,
295 float xOffset,
296 float yOffset,
297 float xPrecision,
298 float yPrecision,
299 nsecs_t downTime,
300 nsecs_t eventTime,
301 size_t pointerCount,
302 const PointerProperties* pointerProperties,
303 const PointerCoords* pointerCoords) {
304 InputEvent::initialize(deviceId, source);
305 mAction = action;
306 mFlags = flags;
307 mEdgeFlags = edgeFlags;
308 mMetaState = metaState;
309 mButtonState = buttonState;
310 mXOffset = xOffset;
311 mYOffset = yOffset;
312 mXPrecision = xPrecision;
313 mYPrecision = yPrecision;
314 mDownTime = downTime;
315 mPointerProperties.clear();
316 mPointerProperties.appendArray(pointerProperties, pointerCount);
317 mSampleEventTimes.clear();
318 mSamplePointerCoords.clear();
319 addSample(eventTime, pointerCoords);
320 }
322 void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
323 InputEvent::initialize(other->mDeviceId, other->mSource);
324 mAction = other->mAction;
325 mFlags = other->mFlags;
326 mEdgeFlags = other->mEdgeFlags;
327 mMetaState = other->mMetaState;
328 mButtonState = other->mButtonState;
329 mXOffset = other->mXOffset;
330 mYOffset = other->mYOffset;
331 mXPrecision = other->mXPrecision;
332 mYPrecision = other->mYPrecision;
333 mDownTime = other->mDownTime;
334 mPointerProperties = other->mPointerProperties;
336 if (keepHistory) {
337 mSampleEventTimes = other->mSampleEventTimes;
338 mSamplePointerCoords = other->mSamplePointerCoords;
339 } else {
340 mSampleEventTimes.clear();
341 mSampleEventTimes.push(other->getEventTime());
342 mSamplePointerCoords.clear();
343 size_t pointerCount = other->getPointerCount();
344 size_t historySize = other->getHistorySize();
345 mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
346 + (historySize * pointerCount), pointerCount);
347 }
348 }
350 void MotionEvent::addSample(
351 int64_t eventTime,
352 const PointerCoords* pointerCoords) {
353 mSampleEventTimes.push(eventTime);
354 mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
355 }
357 const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
358 return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
359 }
361 float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
362 return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
363 }
365 float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
366 float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
367 switch (axis) {
368 case AMOTION_EVENT_AXIS_X:
369 return value + mXOffset;
370 case AMOTION_EVENT_AXIS_Y:
371 return value + mYOffset;
372 }
373 return value;
374 }
376 const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
377 size_t pointerIndex, size_t historicalIndex) const {
378 return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
379 }
381 float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
382 size_t historicalIndex) const {
383 return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
384 }
386 float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
387 size_t historicalIndex) const {
388 float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
389 switch (axis) {
390 case AMOTION_EVENT_AXIS_X:
391 return value + mXOffset;
392 case AMOTION_EVENT_AXIS_Y:
393 return value + mYOffset;
394 }
395 return value;
396 }
398 ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
399 size_t pointerCount = mPointerProperties.size();
400 for (size_t i = 0; i < pointerCount; i++) {
401 if (mPointerProperties.itemAt(i).id == pointerId) {
402 return i;
403 }
404 }
405 return -1;
406 }
408 void MotionEvent::offsetLocation(float xOffset, float yOffset) {
409 mXOffset += xOffset;
410 mYOffset += yOffset;
411 }
413 void MotionEvent::scale(float scaleFactor) {
414 mXOffset *= scaleFactor;
415 mYOffset *= scaleFactor;
416 mXPrecision *= scaleFactor;
417 mYPrecision *= scaleFactor;
419 size_t numSamples = mSamplePointerCoords.size();
420 for (size_t i = 0; i < numSamples; i++) {
421 mSamplePointerCoords.editItemAt(i).scale(scaleFactor);
422 }
423 }
425 #ifdef HAVE_ANDROID_OS
426 static inline float transformAngle(const SkMatrix* matrix, float angleRadians) {
427 // Construct and transform a vector oriented at the specified clockwise angle from vertical.
428 // Coordinate system: down is increasing Y, right is increasing X.
429 SkPoint vector;
430 vector.fX = SkFloatToScalar(sinf(angleRadians));
431 vector.fY = SkFloatToScalar(-cosf(angleRadians));
432 matrix->mapVectors(& vector, 1);
434 // Derive the transformed vector's clockwise angle from vertical.
435 float result = atan2f(SkScalarToFloat(vector.fX), SkScalarToFloat(-vector.fY));
436 if (result < - M_PI_2) {
437 result += M_PI;
438 } else if (result > M_PI_2) {
439 result -= M_PI;
440 }
441 return result;
442 }
444 void MotionEvent::transform(const SkMatrix* matrix) {
445 float oldXOffset = mXOffset;
446 float oldYOffset = mYOffset;
448 // The tricky part of this implementation is to preserve the value of
449 // rawX and rawY. So we apply the transformation to the first point
450 // then derive an appropriate new X/Y offset that will preserve rawX and rawY.
451 SkPoint point;
452 float rawX = getRawX(0);
453 float rawY = getRawY(0);
454 matrix->mapXY(SkFloatToScalar(rawX + oldXOffset), SkFloatToScalar(rawY + oldYOffset),
455 & point);
456 float newX = SkScalarToFloat(point.fX);
457 float newY = SkScalarToFloat(point.fY);
458 float newXOffset = newX - rawX;
459 float newYOffset = newY - rawY;
461 mXOffset = newXOffset;
462 mYOffset = newYOffset;
464 // Apply the transformation to all samples.
465 size_t numSamples = mSamplePointerCoords.size();
466 for (size_t i = 0; i < numSamples; i++) {
467 PointerCoords& c = mSamplePointerCoords.editItemAt(i);
468 float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
469 float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
470 matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), &point);
471 c.setAxisValue(AMOTION_EVENT_AXIS_X, SkScalarToFloat(point.fX) - newXOffset);
472 c.setAxisValue(AMOTION_EVENT_AXIS_Y, SkScalarToFloat(point.fY) - newYOffset);
474 float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
475 c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, transformAngle(matrix, orientation));
476 }
477 }
479 status_t MotionEvent::readFromParcel(Parcel* parcel) {
480 size_t pointerCount = parcel->readInt32();
481 size_t sampleCount = parcel->readInt32();
482 if (pointerCount == 0 || pointerCount > MAX_POINTERS || sampleCount == 0) {
483 return BAD_VALUE;
484 }
486 mDeviceId = parcel->readInt32();
487 mSource = parcel->readInt32();
488 mAction = parcel->readInt32();
489 mFlags = parcel->readInt32();
490 mEdgeFlags = parcel->readInt32();
491 mMetaState = parcel->readInt32();
492 mButtonState = parcel->readInt32();
493 mXOffset = parcel->readFloat();
494 mYOffset = parcel->readFloat();
495 mXPrecision = parcel->readFloat();
496 mYPrecision = parcel->readFloat();
497 mDownTime = parcel->readInt64();
499 mPointerProperties.clear();
500 mPointerProperties.setCapacity(pointerCount);
501 mSampleEventTimes.clear();
502 mSampleEventTimes.setCapacity(sampleCount);
503 mSamplePointerCoords.clear();
504 mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
506 for (size_t i = 0; i < pointerCount; i++) {
507 mPointerProperties.push();
508 PointerProperties& properties = mPointerProperties.editTop();
509 properties.id = parcel->readInt32();
510 properties.toolType = parcel->readInt32();
511 }
513 while (sampleCount-- > 0) {
514 mSampleEventTimes.push(parcel->readInt64());
515 for (size_t i = 0; i < pointerCount; i++) {
516 mSamplePointerCoords.push();
517 status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
518 if (status) {
519 return status;
520 }
521 }
522 }
523 return OK;
524 }
526 status_t MotionEvent::writeToParcel(Parcel* parcel) const {
527 size_t pointerCount = mPointerProperties.size();
528 size_t sampleCount = mSampleEventTimes.size();
530 parcel->writeInt32(pointerCount);
531 parcel->writeInt32(sampleCount);
533 parcel->writeInt32(mDeviceId);
534 parcel->writeInt32(mSource);
535 parcel->writeInt32(mAction);
536 parcel->writeInt32(mFlags);
537 parcel->writeInt32(mEdgeFlags);
538 parcel->writeInt32(mMetaState);
539 parcel->writeInt32(mButtonState);
540 parcel->writeFloat(mXOffset);
541 parcel->writeFloat(mYOffset);
542 parcel->writeFloat(mXPrecision);
543 parcel->writeFloat(mYPrecision);
544 parcel->writeInt64(mDownTime);
546 for (size_t i = 0; i < pointerCount; i++) {
547 const PointerProperties& properties = mPointerProperties.itemAt(i);
548 parcel->writeInt32(properties.id);
549 parcel->writeInt32(properties.toolType);
550 }
552 const PointerCoords* pc = mSamplePointerCoords.array();
553 for (size_t h = 0; h < sampleCount; h++) {
554 parcel->writeInt64(mSampleEventTimes.itemAt(h));
555 for (size_t i = 0; i < pointerCount; i++) {
556 status_t status = (pc++)->writeToParcel(parcel);
557 if (status) {
558 return status;
559 }
560 }
561 }
562 return OK;
563 }
564 #endif
566 bool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
567 if (source & AINPUT_SOURCE_CLASS_POINTER) {
568 // Specifically excludes HOVER_MOVE and SCROLL.
569 switch (action & AMOTION_EVENT_ACTION_MASK) {
570 case AMOTION_EVENT_ACTION_DOWN:
571 case AMOTION_EVENT_ACTION_MOVE:
572 case AMOTION_EVENT_ACTION_UP:
573 case AMOTION_EVENT_ACTION_POINTER_DOWN:
574 case AMOTION_EVENT_ACTION_POINTER_UP:
575 case AMOTION_EVENT_ACTION_CANCEL:
576 case AMOTION_EVENT_ACTION_OUTSIDE:
577 return true;
578 }
579 }
580 return false;
581 }
584 // --- PooledInputEventFactory ---
586 PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
587 mMaxPoolSize(maxPoolSize) {
588 }
590 PooledInputEventFactory::~PooledInputEventFactory() {
591 for (size_t i = 0; i < mKeyEventPool.size(); i++) {
592 delete mKeyEventPool.itemAt(i);
593 }
594 for (size_t i = 0; i < mMotionEventPool.size(); i++) {
595 delete mMotionEventPool.itemAt(i);
596 }
597 }
599 KeyEvent* PooledInputEventFactory::createKeyEvent() {
600 if (!mKeyEventPool.isEmpty()) {
601 KeyEvent* event = mKeyEventPool.top();
602 mKeyEventPool.pop();
603 return event;
604 }
605 return new KeyEvent();
606 }
608 MotionEvent* PooledInputEventFactory::createMotionEvent() {
609 if (!mMotionEventPool.isEmpty()) {
610 MotionEvent* event = mMotionEventPool.top();
611 mMotionEventPool.pop();
612 return event;
613 }
614 return new MotionEvent();
615 }
617 void PooledInputEventFactory::recycle(InputEvent* event) {
618 switch (event->getType()) {
619 case AINPUT_EVENT_TYPE_KEY:
620 if (mKeyEventPool.size() < mMaxPoolSize) {
621 mKeyEventPool.push(static_cast<KeyEvent*>(event));
622 return;
623 }
624 break;
625 case AINPUT_EVENT_TYPE_MOTION:
626 if (mMotionEventPool.size() < mMaxPoolSize) {
627 mMotionEventPool.push(static_cast<MotionEvent*>(event));
628 return;
629 }
630 break;
631 }
632 delete event;
633 }
635 } // namespace android