15912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown/*
25912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * Copyright (C) 2010 The Android Open Source Project
35912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown *
45912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
55912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * you may not use this file except in compliance with the License.
65912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * You may obtain a copy of the License at
75912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown *
85912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
95912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown *
105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * Unless required by applicable law or agreed to in writing, software
115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * See the License for the specific language governing permissions and
145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * limitations under the License.
155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown */
165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#define LOG_TAG "Input"
185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown//#define LOG_NDEBUG 0
195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <math.h>
215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <limits.h>
225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <input/Input.h>
24872db4f11e407accccba9d37c335ef7e3597eba4Michael Wright#include <input/InputEventLabels.h>
255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
266071da7ef84c60645572654504813d492b8b21d5Elliott Hughes#ifdef __ANDROID__
275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <binder/Parcel.h>
285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownnamespace android {
315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// --- InputEvent ---
335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid InputEvent::initialize(int32_t deviceId, int32_t source) {
355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mDeviceId = deviceId;
365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mSource = source;
375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid InputEvent::initialize(const InputEvent& from) {
405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mDeviceId = from.mDeviceId;
415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mSource = from.mSource;
425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// --- KeyEvent ---
455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
46872db4f11e407accccba9d37c335ef7e3597eba4Michael Wrightconst char* KeyEvent::getLabel(int32_t keyCode) {
47872db4f11e407accccba9d37c335ef7e3597eba4Michael Wright    return getLabelByKeyCode(keyCode);
485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
50872db4f11e407accccba9d37c335ef7e3597eba4Michael Wrightint32_t KeyEvent::getKeyCodeFromLabel(const char* label) {
51872db4f11e407accccba9d37c335ef7e3597eba4Michael Wright    return getKeyCodeByLabel(label);
525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid KeyEvent::initialize(
555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t deviceId,
565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t source,
575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t action,
585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t flags,
595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t keyCode,
605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t scanCode,
615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t metaState,
625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t repeatCount,
635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        nsecs_t downTime,
645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        nsecs_t eventTime) {
655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    InputEvent::initialize(deviceId, source);
665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mAction = action;
675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mFlags = flags;
685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mKeyCode = keyCode;
695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mScanCode = scanCode;
705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mMetaState = metaState;
715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mRepeatCount = repeatCount;
725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mDownTime = downTime;
735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mEventTime = eventTime;
745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid KeyEvent::initialize(const KeyEvent& from) {
775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    InputEvent::initialize(from);
785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mAction = from.mAction;
795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mFlags = from.mFlags;
805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mKeyCode = from.mKeyCode;
815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mScanCode = from.mScanCode;
825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mMetaState = from.mMetaState;
835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mRepeatCount = from.mRepeatCount;
845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mDownTime = from.mDownTime;
855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mEventTime = from.mEventTime;
865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// --- PointerCoords ---
905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownfloat PointerCoords::getAxisValue(int32_t axis) const {
9238dcdff3087f01ba02aabfc17b3ff6c549bb5707Michael Wright    if (axis < 0 || axis > 63 || !BitSet64::hasBit(bits, axis)){
935912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return 0;
945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
9538dcdff3087f01ba02aabfc17b3ff6c549bb5707Michael Wright    return values[BitSet64::getIndexOfBit(bits, axis)];
965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatus_t PointerCoords::setAxisValue(int32_t axis, float value) {
995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (axis < 0 || axis > 63) {
1005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return NAME_NOT_FOUND;
1015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
1025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
10338dcdff3087f01ba02aabfc17b3ff6c549bb5707Michael Wright    uint32_t index = BitSet64::getIndexOfBit(bits, axis);
10438dcdff3087f01ba02aabfc17b3ff6c549bb5707Michael Wright    if (!BitSet64::hasBit(bits, axis)) {
1055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (value == 0) {
1065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return OK; // axes with value 0 do not need to be stored
1075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
10838dcdff3087f01ba02aabfc17b3ff6c549bb5707Michael Wright
10938dcdff3087f01ba02aabfc17b3ff6c549bb5707Michael Wright        uint32_t count = BitSet64::count(bits);
1105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (count >= MAX_AXES) {
1115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            tooManyAxes(axis);
1125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return NO_MEMORY;
1135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
11438dcdff3087f01ba02aabfc17b3ff6c549bb5707Michael Wright        BitSet64::markBit(bits, axis);
1155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        for (uint32_t i = count; i > index; i--) {
1165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            values[i] = values[i - 1];
1175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
1185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
11938dcdff3087f01ba02aabfc17b3ff6c549bb5707Michael Wright
1205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    values[index] = value;
1215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return OK;
1225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
1235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatic inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
1255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    float value = c.getAxisValue(axis);
1265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (value != 0) {
1275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        c.setAxisValue(axis, value * scaleFactor);
1285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
1295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
1305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid PointerCoords::scale(float scaleFactor) {
1325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // No need to scale pressure or size since they are normalized.
1335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // No need to scale orientation since it is meaningless to do so.
1345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, scaleFactor);
1355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, scaleFactor);
1365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, scaleFactor);
1375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, scaleFactor);
1385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, scaleFactor);
1395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor);
1405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
1415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
142f086ddbb97e59bd4a0c27745f6e6cc9832a2d4f8Jeff Brownvoid PointerCoords::applyOffset(float xOffset, float yOffset) {
143f086ddbb97e59bd4a0c27745f6e6cc9832a2d4f8Jeff Brown    setAxisValue(AMOTION_EVENT_AXIS_X, getX() + xOffset);
144f086ddbb97e59bd4a0c27745f6e6cc9832a2d4f8Jeff Brown    setAxisValue(AMOTION_EVENT_AXIS_Y, getY() + yOffset);
145f086ddbb97e59bd4a0c27745f6e6cc9832a2d4f8Jeff Brown}
146f086ddbb97e59bd4a0c27745f6e6cc9832a2d4f8Jeff Brown
1476071da7ef84c60645572654504813d492b8b21d5Elliott Hughes#ifdef __ANDROID__
1485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatus_t PointerCoords::readFromParcel(Parcel* parcel) {
1495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    bits = parcel->readInt64();
1505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
15138dcdff3087f01ba02aabfc17b3ff6c549bb5707Michael Wright    uint32_t count = BitSet64::count(bits);
1525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (count > MAX_AXES) {
1535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return BAD_VALUE;
1545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
1555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (uint32_t i = 0; i < count; i++) {
1575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        values[i] = parcel->readFloat();
1585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
1595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return OK;
1605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
1615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatus_t PointerCoords::writeToParcel(Parcel* parcel) const {
1635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeInt64(bits);
1645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
16538dcdff3087f01ba02aabfc17b3ff6c549bb5707Michael Wright    uint32_t count = BitSet64::count(bits);
1665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (uint32_t i = 0; i < count; i++) {
1675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        parcel->writeFloat(values[i]);
1685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
1695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return OK;
1705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
1715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
1725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid PointerCoords::tooManyAxes(int axis) {
1745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    ALOGW("Could not set value for axis %d because the PointerCoords structure is full and "
1755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            "cannot contain more than %d axis values.", axis, int(MAX_AXES));
1765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
1775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownbool PointerCoords::operator==(const PointerCoords& other) const {
1795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (bits != other.bits) {
1805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return false;
1815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
18238dcdff3087f01ba02aabfc17b3ff6c549bb5707Michael Wright    uint32_t count = BitSet64::count(bits);
1835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (uint32_t i = 0; i < count; i++) {
1845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (values[i] != other.values[i]) {
1855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return false;
1865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
1875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
1885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return true;
1895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
1905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid PointerCoords::copyFrom(const PointerCoords& other) {
1925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    bits = other.bits;
19338dcdff3087f01ba02aabfc17b3ff6c549bb5707Michael Wright    uint32_t count = BitSet64::count(bits);
1945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (uint32_t i = 0; i < count; i++) {
1955912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        values[i] = other.values[i];
1965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
1975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
1985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// --- PointerProperties ---
2015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownbool PointerProperties::operator==(const PointerProperties& other) const {
2035912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return id == other.id
2045912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            && toolType == other.toolType;
2055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
2065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid PointerProperties::copyFrom(const PointerProperties& other) {
2085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    id = other.id;
2095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    toolType = other.toolType;
2105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
2115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// --- MotionEvent ---
2145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid MotionEvent::initialize(
2165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t deviceId,
2175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t source,
2185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t action,
2197b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright        int32_t actionButton,
2205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t flags,
2215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t edgeFlags,
2225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t metaState,
2235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t buttonState,
2245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        float xOffset,
2255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        float yOffset,
2265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        float xPrecision,
2275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        float yPrecision,
2285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        nsecs_t downTime,
2295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        nsecs_t eventTime,
2305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        size_t pointerCount,
2315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        const PointerProperties* pointerProperties,
2325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        const PointerCoords* pointerCoords) {
2335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    InputEvent::initialize(deviceId, source);
2345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mAction = action;
2357b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    mActionButton = actionButton;
2365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mFlags = flags;
2375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mEdgeFlags = edgeFlags;
2385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mMetaState = metaState;
2395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mButtonState = buttonState;
2405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mXOffset = xOffset;
2415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mYOffset = yOffset;
2425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mXPrecision = xPrecision;
2435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mYPrecision = yPrecision;
2445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mDownTime = downTime;
2455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mPointerProperties.clear();
2465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mPointerProperties.appendArray(pointerProperties, pointerCount);
2475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mSampleEventTimes.clear();
2485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mSamplePointerCoords.clear();
2495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    addSample(eventTime, pointerCoords);
2505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
2515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
2535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    InputEvent::initialize(other->mDeviceId, other->mSource);
2545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mAction = other->mAction;
2557b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    mActionButton = other->mActionButton;
2565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mFlags = other->mFlags;
2575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mEdgeFlags = other->mEdgeFlags;
2585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mMetaState = other->mMetaState;
2595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mButtonState = other->mButtonState;
2605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mXOffset = other->mXOffset;
2615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mYOffset = other->mYOffset;
2625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mXPrecision = other->mXPrecision;
2635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mYPrecision = other->mYPrecision;
2645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mDownTime = other->mDownTime;
2655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mPointerProperties = other->mPointerProperties;
2665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (keepHistory) {
2685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mSampleEventTimes = other->mSampleEventTimes;
2695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mSamplePointerCoords = other->mSamplePointerCoords;
2705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    } else {
2715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mSampleEventTimes.clear();
2725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mSampleEventTimes.push(other->getEventTime());
2735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mSamplePointerCoords.clear();
2745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        size_t pointerCount = other->getPointerCount();
2755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        size_t historySize = other->getHistorySize();
2765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
2775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                + (historySize * pointerCount), pointerCount);
2785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
2795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
2805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid MotionEvent::addSample(
2825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int64_t eventTime,
2835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        const PointerCoords* pointerCoords) {
2845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mSampleEventTimes.push(eventTime);
2855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
2865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
2875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownconst PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
2895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
2905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
2915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownfloat MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
2935912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
2945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
2955912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownfloat MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
2975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
2985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    switch (axis) {
2995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    case AMOTION_EVENT_AXIS_X:
3005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return value + mXOffset;
3015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    case AMOTION_EVENT_AXIS_Y:
3025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return value + mYOffset;
3035912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
3045912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return value;
3055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
3065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownconst PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
3085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        size_t pointerIndex, size_t historicalIndex) const {
3095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
3105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
3115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownfloat MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
3135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        size_t historicalIndex) const {
3145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
3155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
3165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownfloat MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
3185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        size_t historicalIndex) const {
3195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
3205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    switch (axis) {
3215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    case AMOTION_EVENT_AXIS_X:
3225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return value + mXOffset;
3235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    case AMOTION_EVENT_AXIS_Y:
3245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return value + mYOffset;
3255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
3265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return value;
3275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
3285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
3305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    size_t pointerCount = mPointerProperties.size();
3315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (size_t i = 0; i < pointerCount; i++) {
3325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (mPointerProperties.itemAt(i).id == pointerId) {
3335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return i;
3345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
3355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
3365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return -1;
3375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
3385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid MotionEvent::offsetLocation(float xOffset, float yOffset) {
3405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mXOffset += xOffset;
3415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mYOffset += yOffset;
3425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
3435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid MotionEvent::scale(float scaleFactor) {
3455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mXOffset *= scaleFactor;
3465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mYOffset *= scaleFactor;
3475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mXPrecision *= scaleFactor;
3485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mYPrecision *= scaleFactor;
3495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    size_t numSamples = mSamplePointerCoords.size();
3515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (size_t i = 0; i < numSamples; i++) {
3525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mSamplePointerCoords.editItemAt(i).scale(scaleFactor);
3535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
3545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
3555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3565a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brownstatic void transformPoint(const float matrix[9], float x, float y, float *outX, float *outY) {
3575a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    // Apply perspective transform like Skia.
3585a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    float newX = matrix[0] * x + matrix[1] * y + matrix[2];
3595a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    float newY = matrix[3] * x + matrix[4] * y + matrix[5];
3605a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    float newZ = matrix[6] * x + matrix[7] * y + matrix[8];
3615a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    if (newZ) {
3625a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown        newZ = 1.0f / newZ;
3635a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    }
3645a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    *outX = newX * newZ;
3655a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    *outY = newY * newZ;
3665a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown}
3675a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown
3685a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brownstatic float transformAngle(const float matrix[9], float angleRadians,
3695a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown        float originX, float originY) {
3705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Construct and transform a vector oriented at the specified clockwise angle from vertical.
3715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Coordinate system: down is increasing Y, right is increasing X.
3725a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    float x = sinf(angleRadians);
3735a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    float y = -cosf(angleRadians);
3745a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    transformPoint(matrix, x, y, &x, &y);
3755a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    x -= originX;
3765a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    y -= originY;
3775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Derive the transformed vector's clockwise angle from vertical.
3795a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    float result = atan2f(x, -y);
3805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (result < - M_PI_2) {
3815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        result += M_PI;
3825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    } else if (result > M_PI_2) {
3835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        result -= M_PI;
3845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
3855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return result;
3865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
3875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3885a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brownvoid MotionEvent::transform(const float matrix[9]) {
3895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // The tricky part of this implementation is to preserve the value of
3905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // rawX and rawY.  So we apply the transformation to the first point
3915a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    // then derive an appropriate new X/Y offset that will preserve rawX
3925a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown     // and rawY for that point.
3935a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    float oldXOffset = mXOffset;
3945a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    float oldYOffset = mYOffset;
3955a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    float newX, newY;
3965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    float rawX = getRawX(0);
3975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    float rawY = getRawY(0);
3985a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    transformPoint(matrix, rawX + oldXOffset, rawY + oldYOffset, &newX, &newY);
3995a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    mXOffset = newX - rawX;
4005a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    mYOffset = newY - rawY;
4015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4025a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    // Determine how the origin is transformed by the matrix so that we
4035a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    // can transform orientation vectors.
4045a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    float originX, originY;
4055a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    transformPoint(matrix, 0, 0, &originX, &originY);
4065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Apply the transformation to all samples.
4085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    size_t numSamples = mSamplePointerCoords.size();
4095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (size_t i = 0; i < numSamples; i++) {
4105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        PointerCoords& c = mSamplePointerCoords.editItemAt(i);
4115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
4125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
4135a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown        transformPoint(matrix, x, y, &x, &y);
4145a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown        c.setAxisValue(AMOTION_EVENT_AXIS_X, x - mXOffset);
4155a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown        c.setAxisValue(AMOTION_EVENT_AXIS_Y, y - mYOffset);
4165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
4185a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown        c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
4195a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown                transformAngle(matrix, orientation, originX, originY));
4205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
4215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
4225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4236071da7ef84c60645572654504813d492b8b21d5Elliott Hughes#ifdef __ANDROID__
4245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatus_t MotionEvent::readFromParcel(Parcel* parcel) {
4255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    size_t pointerCount = parcel->readInt32();
4265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    size_t sampleCount = parcel->readInt32();
427552a8a5d8df32f659b8d11311a244cdc6d3b7733Flanker    if (pointerCount == 0 || pointerCount > MAX_POINTERS ||
428552a8a5d8df32f659b8d11311a244cdc6d3b7733Flanker            sampleCount == 0 || sampleCount > MAX_SAMPLES) {
4295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return BAD_VALUE;
4305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
4315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mDeviceId = parcel->readInt32();
4335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mSource = parcel->readInt32();
4345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mAction = parcel->readInt32();
4357b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    mActionButton = parcel->readInt32();
4365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mFlags = parcel->readInt32();
4375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mEdgeFlags = parcel->readInt32();
4385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mMetaState = parcel->readInt32();
4395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mButtonState = parcel->readInt32();
4405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mXOffset = parcel->readFloat();
4415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mYOffset = parcel->readFloat();
4425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mXPrecision = parcel->readFloat();
4435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mYPrecision = parcel->readFloat();
4445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mDownTime = parcel->readInt64();
4455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mPointerProperties.clear();
4475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mPointerProperties.setCapacity(pointerCount);
4485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mSampleEventTimes.clear();
4495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mSampleEventTimes.setCapacity(sampleCount);
4505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mSamplePointerCoords.clear();
4515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
4525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (size_t i = 0; i < pointerCount; i++) {
4545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mPointerProperties.push();
4555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        PointerProperties& properties = mPointerProperties.editTop();
4565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        properties.id = parcel->readInt32();
4575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        properties.toolType = parcel->readInt32();
4585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
4595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
460c94fc45bc5c07724e63e4da5151cfea90bd87986Dan Austin    while (sampleCount > 0) {
461c94fc45bc5c07724e63e4da5151cfea90bd87986Dan Austin        sampleCount--;
4625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mSampleEventTimes.push(parcel->readInt64());
4635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        for (size_t i = 0; i < pointerCount; i++) {
4645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            mSamplePointerCoords.push();
4655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
4665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            if (status) {
4675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                return status;
4685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            }
4695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
4705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
4715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return OK;
4725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
4735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatus_t MotionEvent::writeToParcel(Parcel* parcel) const {
4755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    size_t pointerCount = mPointerProperties.size();
4765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    size_t sampleCount = mSampleEventTimes.size();
4775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeInt32(pointerCount);
4795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeInt32(sampleCount);
4805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeInt32(mDeviceId);
4825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeInt32(mSource);
4835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeInt32(mAction);
4847b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    parcel->writeInt32(mActionButton);
4855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeInt32(mFlags);
4865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeInt32(mEdgeFlags);
4875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeInt32(mMetaState);
4885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeInt32(mButtonState);
4895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeFloat(mXOffset);
4905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeFloat(mYOffset);
4915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeFloat(mXPrecision);
4925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeFloat(mYPrecision);
4935912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeInt64(mDownTime);
4945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4955912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (size_t i = 0; i < pointerCount; i++) {
4965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        const PointerProperties& properties = mPointerProperties.itemAt(i);
4975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        parcel->writeInt32(properties.id);
4985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        parcel->writeInt32(properties.toolType);
4995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
5005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    const PointerCoords* pc = mSamplePointerCoords.array();
5025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (size_t h = 0; h < sampleCount; h++) {
5035912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        parcel->writeInt64(mSampleEventTimes.itemAt(h));
5045912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        for (size_t i = 0; i < pointerCount; i++) {
5055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            status_t status = (pc++)->writeToParcel(parcel);
5065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            if (status) {
5075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                return status;
5085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            }
5095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
5105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
5115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return OK;
5125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
5135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
5145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownbool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
5165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (source & AINPUT_SOURCE_CLASS_POINTER) {
5175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        // Specifically excludes HOVER_MOVE and SCROLL.
5185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        switch (action & AMOTION_EVENT_ACTION_MASK) {
5195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AMOTION_EVENT_ACTION_DOWN:
5205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AMOTION_EVENT_ACTION_MOVE:
5215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AMOTION_EVENT_ACTION_UP:
5225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AMOTION_EVENT_ACTION_POINTER_DOWN:
5235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AMOTION_EVENT_ACTION_POINTER_UP:
5245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AMOTION_EVENT_ACTION_CANCEL:
5255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AMOTION_EVENT_ACTION_OUTSIDE:
5265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return true;
5275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
5285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
5295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return false;
5305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
5315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
532872db4f11e407accccba9d37c335ef7e3597eba4Michael Wrightconst char* MotionEvent::getLabel(int32_t axis) {
533872db4f11e407accccba9d37c335ef7e3597eba4Michael Wright    return getAxisLabel(axis);
534872db4f11e407accccba9d37c335ef7e3597eba4Michael Wright}
535872db4f11e407accccba9d37c335ef7e3597eba4Michael Wright
536872db4f11e407accccba9d37c335ef7e3597eba4Michael Wrightint32_t MotionEvent::getAxisFromLabel(const char* label) {
537872db4f11e407accccba9d37c335ef7e3597eba4Michael Wright    return getAxisByLabel(label);
538872db4f11e407accccba9d37c335ef7e3597eba4Michael Wright}
539872db4f11e407accccba9d37c335ef7e3597eba4Michael Wright
5405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// --- PooledInputEventFactory ---
5425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff BrownPooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
5445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mMaxPoolSize(maxPoolSize) {
5455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
5465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff BrownPooledInputEventFactory::~PooledInputEventFactory() {
5485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (size_t i = 0; i < mKeyEventPool.size(); i++) {
5495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        delete mKeyEventPool.itemAt(i);
5505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
5515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (size_t i = 0; i < mMotionEventPool.size(); i++) {
5525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        delete mMotionEventPool.itemAt(i);
5535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
5545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
5555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff BrownKeyEvent* PooledInputEventFactory::createKeyEvent() {
5575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (!mKeyEventPool.isEmpty()) {
5585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        KeyEvent* event = mKeyEventPool.top();
5595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mKeyEventPool.pop();
5605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return event;
5615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
5625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return new KeyEvent();
5635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
5645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff BrownMotionEvent* PooledInputEventFactory::createMotionEvent() {
5665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (!mMotionEventPool.isEmpty()) {
5675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        MotionEvent* event = mMotionEventPool.top();
5685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mMotionEventPool.pop();
5695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return event;
5705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
5715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return new MotionEvent();
5725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
5735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid PooledInputEventFactory::recycle(InputEvent* event) {
5755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    switch (event->getType()) {
5765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    case AINPUT_EVENT_TYPE_KEY:
5775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (mKeyEventPool.size() < mMaxPoolSize) {
5785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            mKeyEventPool.push(static_cast<KeyEvent*>(event));
5795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return;
5805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
5815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        break;
5825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    case AINPUT_EVENT_TYPE_MOTION:
5835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (mMotionEventPool.size() < mMaxPoolSize) {
5845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            mMotionEventPool.push(static_cast<MotionEvent*>(event));
5855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return;
5865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
5875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        break;
5885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
5895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    delete event;
5905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
5915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown} // namespace android
593