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