Input.cpp revision ebbd5d14ad3b1e762d9fcfa026e19413cc857e05
146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown//
246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// Copyright 2010 The Android Open Source Project
346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown//
446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// Provides a pipe-based transport for native events in the NDK.
546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown//
646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define LOG_TAG "Input"
746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown//#define LOG_NDEBUG 0
946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#define DEBUG_PROBE 0
1147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
1247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#include <stdlib.h>
1347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#include <unistd.h>
149065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown#include <ctype.h>
1547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
1646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <ui/Input.h>
1746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown#include <math.h>
1991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
2091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown#ifdef HAVE_ANDROID_OS
2191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown#include <binder/Parcel.h>
2291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
2391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown#include "SkPoint.h"
2491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown#include "SkMatrix.h"
2591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown#include "SkScalar.h"
2691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown#endif
2791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
2846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownnamespace android {
2946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brownstatic const char* CONFIGURATION_FILE_DIR[] = {
3147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        "idc/",
3247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        "keylayout/",
3347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        "keychars/",
3447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown};
3547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
3647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brownstatic const char* CONFIGURATION_FILE_EXTENSION[] = {
3747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        ".idc",
3847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        ".kl",
3947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        ".kcm",
4047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown};
4147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
429065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brownstatic bool isValidNameChar(char ch) {
439065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown    return isascii(ch) && (isdigit(ch) || isalpha(ch) || ch == '-' || ch == '_');
449065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown}
459065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown
4647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brownstatic void appendInputDeviceConfigurationFileRelativePath(String8& path,
4747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        const String8& name, InputDeviceConfigurationFileType type) {
4847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    path.append(CONFIGURATION_FILE_DIR[type]);
4947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    for (size_t i = 0; i < name.length(); i++) {
5047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        char ch = name[i];
519065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown        if (!isValidNameChar(ch)) {
5247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            ch = '_';
5347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        }
5447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        path.append(&ch, 1);
5547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    }
5647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    path.append(CONFIGURATION_FILE_EXTENSION[type]);
5747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown}
5847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
599065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff BrownString8 getInputDeviceConfigurationFilePathByDeviceIdentifier(
609065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown        const InputDeviceIdentifier& deviceIdentifier,
619065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown        InputDeviceConfigurationFileType type) {
629065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown    if (deviceIdentifier.vendor !=0 && deviceIdentifier.product != 0) {
639065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown        if (deviceIdentifier.version != 0) {
649065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown            // Try vendor product version.
659065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown            String8 versionPath(getInputDeviceConfigurationFilePathByName(
669065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown                    String8::format("Vendor_%04x_Product_%04x_Version_%04x",
679065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown                            deviceIdentifier.vendor, deviceIdentifier.product,
689065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown                            deviceIdentifier.version),
699065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown                    type));
709065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown            if (!versionPath.isEmpty()) {
719065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown                return versionPath;
729065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown            }
739065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown        }
749065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown
759065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown        // Try vendor product.
769065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown        String8 productPath(getInputDeviceConfigurationFilePathByName(
779065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown                String8::format("Vendor_%04x_Product_%04x",
789065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown                        deviceIdentifier.vendor, deviceIdentifier.product),
799065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown                type));
809065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown        if (!productPath.isEmpty()) {
819065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown            return productPath;
829065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown        }
839065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown    }
849065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown
859065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown    // Try device name.
869065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown    return getInputDeviceConfigurationFilePathByName(deviceIdentifier.name, type);
879065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown}
889065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown
899065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff BrownString8 getInputDeviceConfigurationFilePathByName(
9047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        const String8& name, InputDeviceConfigurationFileType type) {
9147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    // Search system repository.
9247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    String8 path;
9347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    path.setTo(getenv("ANDROID_ROOT"));
9447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    path.append("/usr/");
9547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    appendInputDeviceConfigurationFileRelativePath(path, name, type);
9647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#if DEBUG_PROBE
9747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    LOGD("Probing for system provided input device configuration file: path='%s'", path.string());
9847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#endif
9947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    if (!access(path.string(), R_OK)) {
10047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#if DEBUG_PROBE
10147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        LOGD("Found");
10247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#endif
10347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        return path;
10447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    }
10547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
10647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    // Search user repository.
10747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    // TODO Should only look here if not in safe mode.
10847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    path.setTo(getenv("ANDROID_DATA"));
10947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    path.append("/system/devices/");
11047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    appendInputDeviceConfigurationFileRelativePath(path, name, type);
11147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#if DEBUG_PROBE
11247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    LOGD("Probing for system user input device configuration file: path='%s'", path.string());
11347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#endif
11447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    if (!access(path.string(), R_OK)) {
11547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#if DEBUG_PROBE
11647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        LOGD("Found");
11747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#endif
11847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        return path;
11947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    }
12047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
12147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    // Not found.
12247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#if DEBUG_PROBE
12347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    LOGD("Probe failed to find input device configuration file: name='%s', type=%d",
12447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            name.string(), type);
12547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#endif
12647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    return String8();
12747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown}
12847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
12947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
13047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown// --- InputEvent ---
13146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
132c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brownvoid InputEvent::initialize(int32_t deviceId, int32_t source) {
13346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mDeviceId = deviceId;
134c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown    mSource = source;
13546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
13646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1372c6081ce3593712f30dacd990a97209c791d6cedDianne Hackbornvoid InputEvent::initialize(const InputEvent& from) {
1382c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mDeviceId = from.mDeviceId;
1392c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mSource = from.mSource;
1402c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn}
1412c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
14247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown// --- KeyEvent ---
14346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1443c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornbool KeyEvent::hasDefaultAction(int32_t keyCode) {
1453c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    switch (keyCode) {
146fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_HOME:
147fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_BACK:
148fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_CALL:
149fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_ENDCALL:
150fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_VOLUME_UP:
151fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_VOLUME_DOWN:
152b0418da0e7594a8c2164a46985c5f1993632e010Jeff Brown        case AKEYCODE_VOLUME_MUTE:
153fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_POWER:
154fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_CAMERA:
155fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_HEADSETHOOK:
156fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_MENU:
157fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_NOTIFICATION:
158fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_FOCUS:
159fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_SEARCH:
160b0418da0e7594a8c2164a46985c5f1993632e010Jeff Brown        case AKEYCODE_MEDIA_PLAY:
161b0418da0e7594a8c2164a46985c5f1993632e010Jeff Brown        case AKEYCODE_MEDIA_PAUSE:
162fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_MEDIA_PLAY_PAUSE:
163fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_MEDIA_STOP:
164fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_MEDIA_NEXT:
165fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_MEDIA_PREVIOUS:
166fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_MEDIA_REWIND:
167b0418da0e7594a8c2164a46985c5f1993632e010Jeff Brown        case AKEYCODE_MEDIA_RECORD:
168fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_MEDIA_FAST_FORWARD:
169fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_MUTE:
1703c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            return true;
1713c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
1723c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
1733c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    return false;
1743c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn}
1753c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
1763c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornbool KeyEvent::hasDefaultAction() const {
1773c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    return hasDefaultAction(getKeyCode());
1783c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn}
1793c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
1803c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornbool KeyEvent::isSystemKey(int32_t keyCode) {
1813c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    switch (keyCode) {
182fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_MENU:
183fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_SOFT_RIGHT:
184fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_HOME:
185fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_BACK:
186fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_CALL:
187fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_ENDCALL:
188fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_VOLUME_UP:
189fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_VOLUME_DOWN:
190b0418da0e7594a8c2164a46985c5f1993632e010Jeff Brown        case AKEYCODE_VOLUME_MUTE:
191fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_MUTE:
192fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_POWER:
193fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_HEADSETHOOK:
194b0418da0e7594a8c2164a46985c5f1993632e010Jeff Brown        case AKEYCODE_MEDIA_PLAY:
195b0418da0e7594a8c2164a46985c5f1993632e010Jeff Brown        case AKEYCODE_MEDIA_PAUSE:
196fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_MEDIA_PLAY_PAUSE:
197fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_MEDIA_STOP:
198fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_MEDIA_NEXT:
199fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_MEDIA_PREVIOUS:
200fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_MEDIA_REWIND:
201b0418da0e7594a8c2164a46985c5f1993632e010Jeff Brown        case AKEYCODE_MEDIA_RECORD:
202fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_MEDIA_FAST_FORWARD:
203fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_CAMERA:
204fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_FOCUS:
205fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        case AKEYCODE_SEARCH:
2063c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn            return true;
2073c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    }
2083c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
2093c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    return false;
2103c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn}
2113c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
2123c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornbool KeyEvent::isSystemKey() const {
2133c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    return isSystemKey(getKeyCode());
2143c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn}
2153c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
21646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownvoid KeyEvent::initialize(
21746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        int32_t deviceId,
218c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown        int32_t source,
21946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        int32_t action,
22046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        int32_t flags,
22146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        int32_t keyCode,
22246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        int32_t scanCode,
22346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        int32_t metaState,
22446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        int32_t repeatCount,
22546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        nsecs_t downTime,
22646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        nsecs_t eventTime) {
227c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown    InputEvent::initialize(deviceId, source);
22846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mAction = action;
22946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mFlags = flags;
23046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mKeyCode = keyCode;
23146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mScanCode = scanCode;
23246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mMetaState = metaState;
23346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mRepeatCount = repeatCount;
23446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mDownTime = downTime;
23546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mEventTime = eventTime;
23646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
23746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2382c6081ce3593712f30dacd990a97209c791d6cedDianne Hackbornvoid KeyEvent::initialize(const KeyEvent& from) {
2392c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    InputEvent::initialize(from);
2402c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mAction = from.mAction;
2412c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mFlags = from.mFlags;
2422c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mKeyCode = from.mKeyCode;
2432c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mScanCode = from.mScanCode;
2442c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mMetaState = from.mMetaState;
2452c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mRepeatCount = from.mRepeatCount;
2462c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mDownTime = from.mDownTime;
2472c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn    mEventTime = from.mEventTime;
2482c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn}
2492c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn
25091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
25191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown// --- PointerCoords ---
25291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
25391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown#ifdef HAVE_ANDROID_OS
25491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatus_t PointerCoords::readFromParcel(Parcel* parcel) {
25591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    bits = parcel->readInt32();
25691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
25791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    uint32_t count = __builtin_popcount(bits);
25891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (count > MAX_AXES) {
25991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return BAD_VALUE;
26091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
26191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
26291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    for (uint32_t i = 0; i < count; i++) {
26391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        values[i] = parcel->readInt32();
26491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
26591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return OK;
26691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
26791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
26891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatus_t PointerCoords::writeToParcel(Parcel* parcel) const {
26991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    parcel->writeInt32(bits);
27091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
27191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    uint32_t count = __builtin_popcount(bits);
27291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    for (uint32_t i = 0; i < count; i++) {
27391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        parcel->writeInt32(values[i]);
27491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
27591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return OK;
27691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
27791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown#endif
27891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
27991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownvoid PointerCoords::tooManyAxes(int axis) {
28091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    LOGW("Could not set value for axis %d because the PointerCoords structure is full and "
28191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            "cannot contain more than %d axis values.", axis, int(MAX_AXES));
28291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
28391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
28491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
28547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown// --- MotionEvent ---
28646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
28746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownvoid MotionEvent::initialize(
28846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        int32_t deviceId,
289c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown        int32_t source,
29046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        int32_t action,
29185a3176704b5bfbeece9bd928369fbb76eec7dc6Jeff Brown        int32_t flags,
29246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        int32_t edgeFlags,
29346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        int32_t metaState,
2945c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown        float xOffset,
2955c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown        float yOffset,
29646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        float xPrecision,
29746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        float yPrecision,
29846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        nsecs_t downTime,
29946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        nsecs_t eventTime,
30046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        size_t pointerCount,
30146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        const int32_t* pointerIds,
30246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        const PointerCoords* pointerCoords) {
303c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown    InputEvent::initialize(deviceId, source);
30446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mAction = action;
30585a3176704b5bfbeece9bd928369fbb76eec7dc6Jeff Brown    mFlags = flags;
30646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mEdgeFlags = edgeFlags;
30746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mMetaState = metaState;
3085c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    mXOffset = xOffset;
3095c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    mYOffset = yOffset;
31046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mXPrecision = xPrecision;
31146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mYPrecision = yPrecision;
31246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mDownTime = downTime;
31346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mPointerIds.clear();
31446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mPointerIds.appendArray(pointerIds, pointerCount);
31546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mSampleEventTimes.clear();
31646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mSamplePointerCoords.clear();
31746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    addSample(eventTime, pointerCoords);
31846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
31946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
32091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownvoid MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
32191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    InputEvent::initialize(other->mDeviceId, other->mSource);
32291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mAction = other->mAction;
32391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mFlags = other->mFlags;
32491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mEdgeFlags = other->mEdgeFlags;
32591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mMetaState = other->mMetaState;
32691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mXOffset = other->mXOffset;
32791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mYOffset = other->mYOffset;
32891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mXPrecision = other->mXPrecision;
32991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mYPrecision = other->mYPrecision;
33091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mDownTime = other->mDownTime;
33191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mPointerIds = other->mPointerIds;
33291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
33391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (keepHistory) {
33491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        mSampleEventTimes = other->mSampleEventTimes;
33591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        mSamplePointerCoords = other->mSamplePointerCoords;
33691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    } else {
33791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        mSampleEventTimes.clear();
33891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        mSampleEventTimes.push(other->getEventTime());
33991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        mSamplePointerCoords.clear();
34091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        size_t pointerCount = other->getPointerCount();
34191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        size_t historySize = other->getHistorySize();
34291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
34391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                + (historySize * pointerCount), pointerCount);
34491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
34591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
34691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
34746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownvoid MotionEvent::addSample(
34846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        int64_t eventTime,
34946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        const PointerCoords* pointerCoords) {
35046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mSampleEventTimes.push(eventTime);
35146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
35246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
35346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
35491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownconst PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
35591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
35691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
35791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
35891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownfloat MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
35991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
36091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
36191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
36291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownfloat MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
36391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
36491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    switch (axis) {
365ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    case AMOTION_EVENT_AXIS_X:
36691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        value += mXOffset;
36791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        break;
368ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    case AMOTION_EVENT_AXIS_Y:
36991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        value += mYOffset;
37091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        break;
37191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
37291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return value;
37391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
37491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
37591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownconst PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
37691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        size_t pointerIndex, size_t historicalIndex) const {
37791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
37891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
37991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
38091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownfloat MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
38191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        size_t historicalIndex) const {
38291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
38391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
38491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
38591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownfloat MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
38691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        size_t historicalIndex) const {
38791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
38891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    switch (axis) {
389ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    case AMOTION_EVENT_AXIS_X:
39091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        value += mXOffset;
39191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        break;
392ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown    case AMOTION_EVENT_AXIS_Y:
39391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        value += mYOffset;
39491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        break;
39591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
39691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return value;
39791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
39891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
39946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownvoid MotionEvent::offsetLocation(float xOffset, float yOffset) {
4005c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    mXOffset += xOffset;
4015c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    mYOffset += yOffset;
40246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
40346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
40491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
40591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    float* value = c.editAxisValue(axis);
40691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (value) {
40791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        *value *= scaleFactor;
40891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
40991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
41091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
41191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownvoid MotionEvent::scale(float scaleFactor) {
41291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mXOffset *= scaleFactor;
41391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mYOffset *= scaleFactor;
41491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mXPrecision *= scaleFactor;
41591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mYPrecision *= scaleFactor;
41691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
41791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    size_t numSamples = mSamplePointerCoords.size();
41891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    for (size_t i = 0; i < numSamples; i++) {
41991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        PointerCoords& c = mSamplePointerCoords.editItemAt(i);
42091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        // No need to scale pressure or size since they are normalized.
42191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        // No need to scale orientation since it is meaningless to do so.
422ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown        scaleAxisValue(c, AMOTION_EVENT_AXIS_X, scaleFactor);
423ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown        scaleAxisValue(c, AMOTION_EVENT_AXIS_Y, scaleFactor);
424ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown        scaleAxisValue(c, AMOTION_EVENT_AXIS_TOUCH_MAJOR, scaleFactor);
425ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown        scaleAxisValue(c, AMOTION_EVENT_AXIS_TOUCH_MINOR, scaleFactor);
426ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown        scaleAxisValue(c, AMOTION_EVENT_AXIS_TOOL_MAJOR, scaleFactor);
427ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown        scaleAxisValue(c, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor);
42891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
42991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
43091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
43191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown#ifdef HAVE_ANDROID_OS
43291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic inline float transformAngle(const SkMatrix* matrix, float angleRadians) {
43391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    // Construct and transform a vector oriented at the specified clockwise angle from vertical.
43491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    // Coordinate system: down is increasing Y, right is increasing X.
43591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    SkPoint vector;
43691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    vector.fX = SkFloatToScalar(sinf(angleRadians));
43791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    vector.fY = SkFloatToScalar(-cosf(angleRadians));
43891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    matrix->mapVectors(& vector, 1);
43991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
44091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    // Derive the transformed vector's clockwise angle from vertical.
44191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    float result = atan2f(SkScalarToFloat(vector.fX), SkScalarToFloat(-vector.fY));
44291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (result < - M_PI_2) {
44391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        result += M_PI;
44491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    } else if (result > M_PI_2) {
44591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        result -= M_PI;
44691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
44791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return result;
44891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
44991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
45091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownvoid MotionEvent::transform(const SkMatrix* matrix) {
45191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    float oldXOffset = mXOffset;
45291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    float oldYOffset = mYOffset;
45391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
45491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    // The tricky part of this implementation is to preserve the value of
45591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    // rawX and rawY.  So we apply the transformation to the first point
45691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    // then derive an appropriate new X/Y offset that will preserve rawX and rawY.
45791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    SkPoint point;
45891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    float rawX = getRawX(0);
45991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    float rawY = getRawY(0);
46091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    matrix->mapXY(SkFloatToScalar(rawX + oldXOffset), SkFloatToScalar(rawY + oldYOffset),
46191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            & point);
46291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    float newX = SkScalarToFloat(point.fX);
46391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    float newY = SkScalarToFloat(point.fY);
46491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    float newXOffset = newX - rawX;
46591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    float newYOffset = newY - rawY;
46691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
46791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mXOffset = newXOffset;
46891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mYOffset = newYOffset;
46991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
47091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    // Apply the transformation to all samples.
47191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    size_t numSamples = mSamplePointerCoords.size();
47291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    for (size_t i = 0; i < numSamples; i++) {
47391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        PointerCoords& c = mSamplePointerCoords.editItemAt(i);
474ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown        float* xPtr = c.editAxisValue(AMOTION_EVENT_AXIS_X);
475ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown        float* yPtr = c.editAxisValue(AMOTION_EVENT_AXIS_Y);
47691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        if (xPtr && yPtr) {
47791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            float x = *xPtr + oldXOffset;
47891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            float y = *yPtr + oldYOffset;
47991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), & point);
48091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            *xPtr = SkScalarToFloat(point.fX) - newXOffset;
48191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            *yPtr = SkScalarToFloat(point.fY) - newYOffset;
48291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        }
48391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
484ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown        float* orientationPtr = c.editAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
48591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        if (orientationPtr) {
48691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            *orientationPtr = transformAngle(matrix, *orientationPtr);
48791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        }
48891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
48991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
49091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
49191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatus_t MotionEvent::readFromParcel(Parcel* parcel) {
49291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    size_t pointerCount = parcel->readInt32();
49391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    size_t sampleCount = parcel->readInt32();
49491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    if (pointerCount == 0 || pointerCount > MAX_POINTERS || sampleCount == 0) {
49591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        return BAD_VALUE;
49691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
49791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
49891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mDeviceId = parcel->readInt32();
49991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mSource = parcel->readInt32();
50091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mAction = parcel->readInt32();
50191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mFlags = parcel->readInt32();
50291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mEdgeFlags = parcel->readInt32();
50391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mMetaState = parcel->readInt32();
50491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mXOffset = parcel->readFloat();
50591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mYOffset = parcel->readFloat();
50691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mXPrecision = parcel->readFloat();
50791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mYPrecision = parcel->readFloat();
50891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mDownTime = parcel->readInt64();
50991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
51091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mPointerIds.clear();
51191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mPointerIds.setCapacity(pointerCount);
51291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mSampleEventTimes.clear();
51391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mSampleEventTimes.setCapacity(sampleCount);
51491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mSamplePointerCoords.clear();
51591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
51691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
51791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    for (size_t i = 0; i < pointerCount; i++) {
51891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        mPointerIds.push(parcel->readInt32());
51991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
52091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
52191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    while (sampleCount-- > 0) {
52291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        mSampleEventTimes.push(parcel->readInt64());
52391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        for (size_t i = 0; i < pointerCount; i++) {
52491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            mSamplePointerCoords.push();
52591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
526ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            if (status) {
52791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                return status;
52891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            }
52991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        }
53091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
53191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return OK;
53291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
53391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
53491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatus_t MotionEvent::writeToParcel(Parcel* parcel) const {
53591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    size_t pointerCount = mPointerIds.size();
53691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    size_t sampleCount = mSampleEventTimes.size();
53791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
53891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    parcel->writeInt32(pointerCount);
53991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    parcel->writeInt32(sampleCount);
54091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
54191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    parcel->writeInt32(mDeviceId);
54291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    parcel->writeInt32(mSource);
54391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    parcel->writeInt32(mAction);
54491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    parcel->writeInt32(mFlags);
54591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    parcel->writeInt32(mEdgeFlags);
54691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    parcel->writeInt32(mMetaState);
54791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    parcel->writeFloat(mXOffset);
54891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    parcel->writeFloat(mYOffset);
54991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    parcel->writeFloat(mXPrecision);
55091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    parcel->writeFloat(mYPrecision);
55191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    parcel->writeInt64(mDownTime);
55291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
55391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    for (size_t i = 0; i < pointerCount; i++) {
55491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        parcel->writeInt32(mPointerIds.itemAt(i));
55591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
55691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
55791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    const PointerCoords* pc = mSamplePointerCoords.array();
55891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    for (size_t h = 0; h < sampleCount; h++) {
55991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        parcel->writeInt64(mSampleEventTimes.itemAt(h));
56091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        for (size_t i = 0; i < pointerCount; i++) {
56191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            status_t status = (pc++)->writeToParcel(parcel);
562ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            if (status) {
56391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown                return status;
56491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            }
56591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        }
56691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    }
56791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    return OK;
56891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown}
56991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown#endif
57091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
57191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
57247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown// --- InputDeviceInfo ---
5736d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownInputDeviceInfo::InputDeviceInfo() {
5756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    initialize(-1, String8("uninitialized device info"));
5766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
5776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownInputDeviceInfo::InputDeviceInfo(const InputDeviceInfo& other) :
5796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mId(other.mId), mName(other.mName), mSources(other.mSources),
5806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mKeyboardType(other.mKeyboardType),
5816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mMotionRanges(other.mMotionRanges) {
5826d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
5836d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownInputDeviceInfo::~InputDeviceInfo() {
5856d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
5866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid InputDeviceInfo::initialize(int32_t id, const String8& name) {
5886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mId = id;
5896d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mName = name;
5906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mSources = 0;
5916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mKeyboardType = AINPUT_KEYBOARD_TYPE_NONE;
5926d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mMotionRanges.clear();
5936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
5946d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
59591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownconst InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange(int32_t axis) const {
59691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    ssize_t index = mMotionRanges.indexOfKey(axis);
5976d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return index >= 0 ? & mMotionRanges.valueAt(index) : NULL;
5986d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
5996d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
6006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid InputDeviceInfo::addSource(uint32_t source) {
6016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mSources |= source;
6026d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
6036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
60491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownvoid InputDeviceInfo::addMotionRange(int32_t axis, float min, float max,
6056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        float flat, float fuzz) {
6066d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    MotionRange range = { min, max, flat, fuzz };
60791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    addMotionRange(axis, range);
6086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
6096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
61091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownvoid InputDeviceInfo::addMotionRange(int32_t axis, const MotionRange& range) {
61191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown    mMotionRanges.add(axis, range);
6126d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
6136d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
61446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} // namespace android
615