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