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>
245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#ifdef HAVE_ANDROID_OS
265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <binder/Parcel.h>
275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownnamespace android {
305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// --- InputEvent ---
325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid InputEvent::initialize(int32_t deviceId, int32_t source) {
345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mDeviceId = deviceId;
355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mSource = source;
365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid InputEvent::initialize(const InputEvent& from) {
395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mDeviceId = from.mDeviceId;
405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mSource = from.mSource;
415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// --- KeyEvent ---
445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownbool KeyEvent::hasDefaultAction(int32_t keyCode) {
465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    switch (keyCode) {
475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_HOME:
485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_BACK:
495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_CALL:
505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_ENDCALL:
515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_VOLUME_UP:
525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_VOLUME_DOWN:
535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_VOLUME_MUTE:
545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_POWER:
555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_CAMERA:
565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_HEADSETHOOK:
575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_MENU:
585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_NOTIFICATION:
595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_FOCUS:
605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_SEARCH:
615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_MEDIA_PLAY:
625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_MEDIA_PAUSE:
635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_MEDIA_PLAY_PAUSE:
645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_MEDIA_STOP:
655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_MEDIA_NEXT:
665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_MEDIA_PREVIOUS:
675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_MEDIA_REWIND:
685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_MEDIA_RECORD:
695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_MEDIA_FAST_FORWARD:
705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_MUTE:
715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_BRIGHTNESS_DOWN:
725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_BRIGHTNESS_UP:
738d06dcf9c663cccc44318c01c13f2b3ba0001b4cJaekyun Seok        case AKEYCODE_MEDIA_AUDIO_TRACK:
745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return true;
755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return false;
785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownbool KeyEvent::hasDefaultAction() const {
815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return hasDefaultAction(getKeyCode());
825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownbool KeyEvent::isSystemKey(int32_t keyCode) {
855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    switch (keyCode) {
865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_MENU:
875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_SOFT_RIGHT:
885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_HOME:
895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_BACK:
905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_CALL:
915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_ENDCALL:
925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_VOLUME_UP:
935912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_VOLUME_DOWN:
945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_VOLUME_MUTE:
955912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_MUTE:
965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_POWER:
975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_HEADSETHOOK:
985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_MEDIA_PLAY:
995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_MEDIA_PAUSE:
1005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_MEDIA_PLAY_PAUSE:
1015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_MEDIA_STOP:
1025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_MEDIA_NEXT:
1035912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_MEDIA_PREVIOUS:
1045912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_MEDIA_REWIND:
1055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_MEDIA_RECORD:
1065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_MEDIA_FAST_FORWARD:
1075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_CAMERA:
1085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_FOCUS:
1095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_SEARCH:
1105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_BRIGHTNESS_DOWN:
1115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AKEYCODE_BRIGHTNESS_UP:
1128d06dcf9c663cccc44318c01c13f2b3ba0001b4cJaekyun Seok        case AKEYCODE_MEDIA_AUDIO_TRACK:
1135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return true;
1145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
1155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return false;
1175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
1185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownbool KeyEvent::isSystemKey() const {
1205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return isSystemKey(getKeyCode());
1215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
1225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid KeyEvent::initialize(
1245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t deviceId,
1255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t source,
1265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t action,
1275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t flags,
1285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t keyCode,
1295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t scanCode,
1305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t metaState,
1315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t repeatCount,
1325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        nsecs_t downTime,
1335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        nsecs_t eventTime) {
1345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    InputEvent::initialize(deviceId, source);
1355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mAction = action;
1365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mFlags = flags;
1375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mKeyCode = keyCode;
1385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mScanCode = scanCode;
1395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mMetaState = metaState;
1405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mRepeatCount = repeatCount;
1415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mDownTime = downTime;
1425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mEventTime = eventTime;
1435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
1445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid KeyEvent::initialize(const KeyEvent& from) {
1465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    InputEvent::initialize(from);
1475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mAction = from.mAction;
1485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mFlags = from.mFlags;
1495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mKeyCode = from.mKeyCode;
1505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mScanCode = from.mScanCode;
1515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mMetaState = from.mMetaState;
1525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mRepeatCount = from.mRepeatCount;
1535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mDownTime = from.mDownTime;
1545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mEventTime = from.mEventTime;
1555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
1565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// --- PointerCoords ---
1595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownfloat PointerCoords::getAxisValue(int32_t axis) const {
1615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (axis < 0 || axis > 63) {
1625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return 0;
1635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
1645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    uint64_t axisBit = 1LL << axis;
1665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (!(bits & axisBit)) {
1675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return 0;
1685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
1695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
1705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return values[index];
1715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
1725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatus_t PointerCoords::setAxisValue(int32_t axis, float value) {
1745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (axis < 0 || axis > 63) {
1755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return NAME_NOT_FOUND;
1765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
1775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    uint64_t axisBit = 1LL << axis;
1795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
1805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (!(bits & axisBit)) {
1815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (value == 0) {
1825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return OK; // axes with value 0 do not need to be stored
1835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
1845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        uint32_t count = __builtin_popcountll(bits);
1855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (count >= MAX_AXES) {
1865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            tooManyAxes(axis);
1875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return NO_MEMORY;
1885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
1895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        bits |= axisBit;
1905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        for (uint32_t i = count; i > index; i--) {
1915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            values[i] = values[i - 1];
1925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
1935912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
1945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    values[index] = value;
1955912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return OK;
1965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
1975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatic inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
1995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    float value = c.getAxisValue(axis);
2005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (value != 0) {
2015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        c.setAxisValue(axis, value * scaleFactor);
2025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
2035912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
2045912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid PointerCoords::scale(float scaleFactor) {
2065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // No need to scale pressure or size since they are normalized.
2075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // No need to scale orientation since it is meaningless to do so.
2085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, scaleFactor);
2095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, scaleFactor);
2105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, scaleFactor);
2115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, scaleFactor);
2125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, scaleFactor);
2135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor);
2145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
2155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#ifdef HAVE_ANDROID_OS
2175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatus_t PointerCoords::readFromParcel(Parcel* parcel) {
2185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    bits = parcel->readInt64();
2195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    uint32_t count = __builtin_popcountll(bits);
2215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (count > MAX_AXES) {
2225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return BAD_VALUE;
2235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
2245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (uint32_t i = 0; i < count; i++) {
2265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        values[i] = parcel->readFloat();
2275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
2285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return OK;
2295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
2305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatus_t PointerCoords::writeToParcel(Parcel* parcel) const {
2325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeInt64(bits);
2335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    uint32_t count = __builtin_popcountll(bits);
2355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (uint32_t i = 0; i < count; i++) {
2365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        parcel->writeFloat(values[i]);
2375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
2385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return OK;
2395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
2405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
2415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid PointerCoords::tooManyAxes(int axis) {
2435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    ALOGW("Could not set value for axis %d because the PointerCoords structure is full and "
2445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            "cannot contain more than %d axis values.", axis, int(MAX_AXES));
2455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
2465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownbool PointerCoords::operator==(const PointerCoords& other) const {
2485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (bits != other.bits) {
2495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return false;
2505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
2515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    uint32_t count = __builtin_popcountll(bits);
2525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (uint32_t i = 0; i < count; i++) {
2535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (values[i] != other.values[i]) {
2545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return false;
2555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
2565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
2575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return true;
2585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
2595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid PointerCoords::copyFrom(const PointerCoords& other) {
2615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    bits = other.bits;
2625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    uint32_t count = __builtin_popcountll(bits);
2635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (uint32_t i = 0; i < count; i++) {
2645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        values[i] = other.values[i];
2655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
2665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
2675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// --- PointerProperties ---
2705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownbool PointerProperties::operator==(const PointerProperties& other) const {
2725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return id == other.id
2735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            && toolType == other.toolType;
2745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
2755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid PointerProperties::copyFrom(const PointerProperties& other) {
2775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    id = other.id;
2785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    toolType = other.toolType;
2795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
2805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// --- MotionEvent ---
2835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid MotionEvent::initialize(
2855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t deviceId,
2865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t source,
2875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t action,
2885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t flags,
2895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t edgeFlags,
2905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t metaState,
2915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t buttonState,
2925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        float xOffset,
2935912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        float yOffset,
2945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        float xPrecision,
2955912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        float yPrecision,
2965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        nsecs_t downTime,
2975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        nsecs_t eventTime,
2985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        size_t pointerCount,
2995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        const PointerProperties* pointerProperties,
3005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        const PointerCoords* pointerCoords) {
3015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    InputEvent::initialize(deviceId, source);
3025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mAction = action;
3035912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mFlags = flags;
3045912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mEdgeFlags = edgeFlags;
3055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mMetaState = metaState;
3065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mButtonState = buttonState;
3075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mXOffset = xOffset;
3085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mYOffset = yOffset;
3095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mXPrecision = xPrecision;
3105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mYPrecision = yPrecision;
3115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mDownTime = downTime;
3125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mPointerProperties.clear();
3135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mPointerProperties.appendArray(pointerProperties, pointerCount);
3145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mSampleEventTimes.clear();
3155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mSamplePointerCoords.clear();
3165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    addSample(eventTime, pointerCoords);
3175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
3185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
3205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    InputEvent::initialize(other->mDeviceId, other->mSource);
3215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mAction = other->mAction;
3225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mFlags = other->mFlags;
3235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mEdgeFlags = other->mEdgeFlags;
3245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mMetaState = other->mMetaState;
3255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mButtonState = other->mButtonState;
3265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mXOffset = other->mXOffset;
3275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mYOffset = other->mYOffset;
3285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mXPrecision = other->mXPrecision;
3295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mYPrecision = other->mYPrecision;
3305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mDownTime = other->mDownTime;
3315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mPointerProperties = other->mPointerProperties;
3325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (keepHistory) {
3345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mSampleEventTimes = other->mSampleEventTimes;
3355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mSamplePointerCoords = other->mSamplePointerCoords;
3365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    } else {
3375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mSampleEventTimes.clear();
3385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mSampleEventTimes.push(other->getEventTime());
3395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mSamplePointerCoords.clear();
3405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        size_t pointerCount = other->getPointerCount();
3415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        size_t historySize = other->getHistorySize();
3425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
3435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                + (historySize * pointerCount), pointerCount);
3445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
3455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
3465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid MotionEvent::addSample(
3485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int64_t eventTime,
3495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        const PointerCoords* pointerCoords) {
3505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mSampleEventTimes.push(eventTime);
3515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
3525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
3535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownconst PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
3555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
3565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
3575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownfloat MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
3595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
3605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
3615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownfloat MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
3635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
3645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    switch (axis) {
3655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    case AMOTION_EVENT_AXIS_X:
3665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return value + mXOffset;
3675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    case AMOTION_EVENT_AXIS_Y:
3685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return value + mYOffset;
3695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
3705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return value;
3715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
3725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownconst PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
3745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        size_t pointerIndex, size_t historicalIndex) const {
3755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
3765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
3775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownfloat MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
3795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        size_t historicalIndex) const {
3805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
3815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
3825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownfloat MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
3845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        size_t historicalIndex) const {
3855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
3865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    switch (axis) {
3875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    case AMOTION_EVENT_AXIS_X:
3885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return value + mXOffset;
3895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    case AMOTION_EVENT_AXIS_Y:
3905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return value + mYOffset;
3915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
3925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return value;
3935912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
3945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3955912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
3965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    size_t pointerCount = mPointerProperties.size();
3975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (size_t i = 0; i < pointerCount; i++) {
3985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (mPointerProperties.itemAt(i).id == pointerId) {
3995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return i;
4005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
4015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
4025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return -1;
4035912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
4045912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid MotionEvent::offsetLocation(float xOffset, float yOffset) {
4065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mXOffset += xOffset;
4075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mYOffset += yOffset;
4085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
4095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid MotionEvent::scale(float scaleFactor) {
4115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mXOffset *= scaleFactor;
4125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mYOffset *= scaleFactor;
4135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mXPrecision *= scaleFactor;
4145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mYPrecision *= scaleFactor;
4155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    size_t numSamples = mSamplePointerCoords.size();
4175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (size_t i = 0; i < numSamples; i++) {
4185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mSamplePointerCoords.editItemAt(i).scale(scaleFactor);
4195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
4205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
4215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4225a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brownstatic void transformPoint(const float matrix[9], float x, float y, float *outX, float *outY) {
4235a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    // Apply perspective transform like Skia.
4245a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    float newX = matrix[0] * x + matrix[1] * y + matrix[2];
4255a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    float newY = matrix[3] * x + matrix[4] * y + matrix[5];
4265a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    float newZ = matrix[6] * x + matrix[7] * y + matrix[8];
4275a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    if (newZ) {
4285a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown        newZ = 1.0f / newZ;
4295a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    }
4305a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    *outX = newX * newZ;
4315a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    *outY = newY * newZ;
4325a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown}
4335a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown
4345a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brownstatic float transformAngle(const float matrix[9], float angleRadians,
4355a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown        float originX, float originY) {
4365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Construct and transform a vector oriented at the specified clockwise angle from vertical.
4375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Coordinate system: down is increasing Y, right is increasing X.
4385a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    float x = sinf(angleRadians);
4395a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    float y = -cosf(angleRadians);
4405a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    transformPoint(matrix, x, y, &x, &y);
4415a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    x -= originX;
4425a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    y -= originY;
4435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Derive the transformed vector's clockwise angle from vertical.
4455a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    float result = atan2f(x, -y);
4465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (result < - M_PI_2) {
4475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        result += M_PI;
4485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    } else if (result > M_PI_2) {
4495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        result -= M_PI;
4505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
4515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return result;
4525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
4535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4545a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brownvoid MotionEvent::transform(const float matrix[9]) {
4555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // The tricky part of this implementation is to preserve the value of
4565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // rawX and rawY.  So we apply the transformation to the first point
4575a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    // then derive an appropriate new X/Y offset that will preserve rawX
4585a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown     // and rawY for that point.
4595a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    float oldXOffset = mXOffset;
4605a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    float oldYOffset = mYOffset;
4615a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    float newX, newY;
4625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    float rawX = getRawX(0);
4635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    float rawY = getRawY(0);
4645a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    transformPoint(matrix, rawX + oldXOffset, rawY + oldYOffset, &newX, &newY);
4655a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    mXOffset = newX - rawX;
4665a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    mYOffset = newY - rawY;
4675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4685a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    // Determine how the origin is transformed by the matrix so that we
4695a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    // can transform orientation vectors.
4705a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    float originX, originY;
4715a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown    transformPoint(matrix, 0, 0, &originX, &originY);
4725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Apply the transformation to all samples.
4745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    size_t numSamples = mSamplePointerCoords.size();
4755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (size_t i = 0; i < numSamples; i++) {
4765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        PointerCoords& c = mSamplePointerCoords.editItemAt(i);
4775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
4785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
4795a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown        transformPoint(matrix, x, y, &x, &y);
4805a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown        c.setAxisValue(AMOTION_EVENT_AXIS_X, x - mXOffset);
4815a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown        c.setAxisValue(AMOTION_EVENT_AXIS_Y, y - mYOffset);
4825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
4845a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown        c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
4855a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown                transformAngle(matrix, orientation, originX, originY));
4865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
4875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
4885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4895a2f68e5a5526ba80b5192776e2f0e349626777dJeff Brown#ifdef HAVE_ANDROID_OS
4905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatus_t MotionEvent::readFromParcel(Parcel* parcel) {
4915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    size_t pointerCount = parcel->readInt32();
4925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    size_t sampleCount = parcel->readInt32();
4935912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (pointerCount == 0 || pointerCount > MAX_POINTERS || sampleCount == 0) {
4945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return BAD_VALUE;
4955912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
4965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mDeviceId = parcel->readInt32();
4985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mSource = parcel->readInt32();
4995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mAction = parcel->readInt32();
5005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mFlags = parcel->readInt32();
5015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mEdgeFlags = parcel->readInt32();
5025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mMetaState = parcel->readInt32();
5035912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mButtonState = parcel->readInt32();
5045912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mXOffset = parcel->readFloat();
5055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mYOffset = parcel->readFloat();
5065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mXPrecision = parcel->readFloat();
5075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mYPrecision = parcel->readFloat();
5085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mDownTime = parcel->readInt64();
5095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mPointerProperties.clear();
5115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mPointerProperties.setCapacity(pointerCount);
5125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mSampleEventTimes.clear();
5135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mSampleEventTimes.setCapacity(sampleCount);
5145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mSamplePointerCoords.clear();
5155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
5165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (size_t i = 0; i < pointerCount; i++) {
5185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mPointerProperties.push();
5195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        PointerProperties& properties = mPointerProperties.editTop();
5205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        properties.id = parcel->readInt32();
5215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        properties.toolType = parcel->readInt32();
5225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
5235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    while (sampleCount-- > 0) {
5255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mSampleEventTimes.push(parcel->readInt64());
5265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        for (size_t i = 0; i < pointerCount; i++) {
5275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            mSamplePointerCoords.push();
5285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
5295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            if (status) {
5305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                return status;
5315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            }
5325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
5335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
5345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return OK;
5355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
5365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatus_t MotionEvent::writeToParcel(Parcel* parcel) const {
5385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    size_t pointerCount = mPointerProperties.size();
5395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    size_t sampleCount = mSampleEventTimes.size();
5405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeInt32(pointerCount);
5425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeInt32(sampleCount);
5435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeInt32(mDeviceId);
5455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeInt32(mSource);
5465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeInt32(mAction);
5475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeInt32(mFlags);
5485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeInt32(mEdgeFlags);
5495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeInt32(mMetaState);
5505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeInt32(mButtonState);
5515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeFloat(mXOffset);
5525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeFloat(mYOffset);
5535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeFloat(mXPrecision);
5545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeFloat(mYPrecision);
5555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    parcel->writeInt64(mDownTime);
5565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (size_t i = 0; i < pointerCount; i++) {
5585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        const PointerProperties& properties = mPointerProperties.itemAt(i);
5595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        parcel->writeInt32(properties.id);
5605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        parcel->writeInt32(properties.toolType);
5615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
5625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    const PointerCoords* pc = mSamplePointerCoords.array();
5645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (size_t h = 0; h < sampleCount; h++) {
5655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        parcel->writeInt64(mSampleEventTimes.itemAt(h));
5665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        for (size_t i = 0; i < pointerCount; i++) {
5675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            status_t status = (pc++)->writeToParcel(parcel);
5685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            if (status) {
5695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                return status;
5705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            }
5715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
5725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
5735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return OK;
5745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
5755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
5765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownbool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
5785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (source & AINPUT_SOURCE_CLASS_POINTER) {
5795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        // Specifically excludes HOVER_MOVE and SCROLL.
5805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        switch (action & AMOTION_EVENT_ACTION_MASK) {
5815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AMOTION_EVENT_ACTION_DOWN:
5825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AMOTION_EVENT_ACTION_MOVE:
5835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AMOTION_EVENT_ACTION_UP:
5845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AMOTION_EVENT_ACTION_POINTER_DOWN:
5855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AMOTION_EVENT_ACTION_POINTER_UP:
5865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AMOTION_EVENT_ACTION_CANCEL:
5875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AMOTION_EVENT_ACTION_OUTSIDE:
5885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return true;
5895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
5905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
5915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return false;
5925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
5935912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5955912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// --- PooledInputEventFactory ---
5965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff BrownPooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
5985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mMaxPoolSize(maxPoolSize) {
5995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
6005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
6015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff BrownPooledInputEventFactory::~PooledInputEventFactory() {
6025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (size_t i = 0; i < mKeyEventPool.size(); i++) {
6035912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        delete mKeyEventPool.itemAt(i);
6045912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
6055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (size_t i = 0; i < mMotionEventPool.size(); i++) {
6065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        delete mMotionEventPool.itemAt(i);
6075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
6085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
6095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
6105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff BrownKeyEvent* PooledInputEventFactory::createKeyEvent() {
6115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (!mKeyEventPool.isEmpty()) {
6125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        KeyEvent* event = mKeyEventPool.top();
6135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mKeyEventPool.pop();
6145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return event;
6155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
6165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return new KeyEvent();
6175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
6185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
6195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff BrownMotionEvent* PooledInputEventFactory::createMotionEvent() {
6205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (!mMotionEventPool.isEmpty()) {
6215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        MotionEvent* event = mMotionEventPool.top();
6225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mMotionEventPool.pop();
6235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return event;
6245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
6255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return new MotionEvent();
6265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
6275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
6285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid PooledInputEventFactory::recycle(InputEvent* event) {
6295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    switch (event->getType()) {
6305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    case AINPUT_EVENT_TYPE_KEY:
6315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (mKeyEventPool.size() < mMaxPoolSize) {
6325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            mKeyEventPool.push(static_cast<KeyEvent*>(event));
6335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return;
6345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
6355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        break;
6365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    case AINPUT_EVENT_TYPE_MOTION:
6375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (mMotionEventPool.size() < mMaxPoolSize) {
6385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            mMotionEventPool.push(static_cast<MotionEvent*>(event));
6395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return;
6405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
6415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        break;
6425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
6435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    delete event;
6445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
6455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
6465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown} // namespace android
647