Input.cpp revision be1aa8250cee7819c49741e819e81659d1d03823
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 10ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown// Log debug messages about keymap probing. 1147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#define DEBUG_PROBE 0 1247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown 13ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown// Log debug messages about velocity tracking. 14ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#define DEBUG_VELOCITY 0 15ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown 1619c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown// Log debug messages about acceleration. 1719c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown#define DEBUG_ACCELERATION 0 1819c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown 1919c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown 2047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#include <stdlib.h> 2147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#include <unistd.h> 229065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown#include <ctype.h> 2347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown 2446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <ui/Input.h> 2546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 2691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown#include <math.h> 2719c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown#include <limits.h> 2891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 2991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown#ifdef HAVE_ANDROID_OS 3091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown#include <binder/Parcel.h> 3191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 3291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown#include "SkPoint.h" 3391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown#include "SkMatrix.h" 3491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown#include "SkScalar.h" 3591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown#endif 3691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 3746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownnamespace android { 3846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 3947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brownstatic const char* CONFIGURATION_FILE_DIR[] = { 4047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown "idc/", 4147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown "keylayout/", 4247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown "keychars/", 4347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown}; 4447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown 4547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brownstatic const char* CONFIGURATION_FILE_EXTENSION[] = { 4647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown ".idc", 4747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown ".kl", 4847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown ".kcm", 4947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown}; 5047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown 519065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brownstatic bool isValidNameChar(char ch) { 529065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown return isascii(ch) && (isdigit(ch) || isalpha(ch) || ch == '-' || ch == '_'); 539065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown} 549065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown 5547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brownstatic void appendInputDeviceConfigurationFileRelativePath(String8& path, 5647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown const String8& name, InputDeviceConfigurationFileType type) { 5747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown path.append(CONFIGURATION_FILE_DIR[type]); 5847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown for (size_t i = 0; i < name.length(); i++) { 5947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown char ch = name[i]; 609065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown if (!isValidNameChar(ch)) { 6147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown ch = '_'; 6247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown } 6347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown path.append(&ch, 1); 6447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown } 6547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown path.append(CONFIGURATION_FILE_EXTENSION[type]); 6647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown} 6747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown 689065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff BrownString8 getInputDeviceConfigurationFilePathByDeviceIdentifier( 699065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown const InputDeviceIdentifier& deviceIdentifier, 709065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown InputDeviceConfigurationFileType type) { 719065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown if (deviceIdentifier.vendor !=0 && deviceIdentifier.product != 0) { 729065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown if (deviceIdentifier.version != 0) { 739065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown // Try vendor product version. 749065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown String8 versionPath(getInputDeviceConfigurationFilePathByName( 759065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown String8::format("Vendor_%04x_Product_%04x_Version_%04x", 769065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown deviceIdentifier.vendor, deviceIdentifier.product, 779065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown deviceIdentifier.version), 789065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown type)); 799065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown if (!versionPath.isEmpty()) { 809065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown return versionPath; 819065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown } 829065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown } 839065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown 849065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown // Try vendor product. 859065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown String8 productPath(getInputDeviceConfigurationFilePathByName( 869065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown String8::format("Vendor_%04x_Product_%04x", 879065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown deviceIdentifier.vendor, deviceIdentifier.product), 889065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown type)); 899065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown if (!productPath.isEmpty()) { 909065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown return productPath; 919065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown } 929065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown } 939065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown 949065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown // Try device name. 959065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown return getInputDeviceConfigurationFilePathByName(deviceIdentifier.name, type); 969065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown} 979065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown 989065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff BrownString8 getInputDeviceConfigurationFilePathByName( 9947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown const String8& name, InputDeviceConfigurationFileType type) { 10047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown // Search system repository. 10147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown String8 path; 10247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown path.setTo(getenv("ANDROID_ROOT")); 10347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown path.append("/usr/"); 10447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown appendInputDeviceConfigurationFileRelativePath(path, name, type); 10547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#if DEBUG_PROBE 10647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown LOGD("Probing for system provided input device configuration file: path='%s'", path.string()); 10747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#endif 10847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown if (!access(path.string(), R_OK)) { 10947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#if DEBUG_PROBE 11047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown LOGD("Found"); 11147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#endif 11247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown return path; 11347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown } 11447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown 11547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown // Search user repository. 11647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown // TODO Should only look here if not in safe mode. 11747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown path.setTo(getenv("ANDROID_DATA")); 11847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown path.append("/system/devices/"); 11947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown appendInputDeviceConfigurationFileRelativePath(path, name, type); 12047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#if DEBUG_PROBE 12147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown LOGD("Probing for system user input device configuration file: path='%s'", path.string()); 12247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#endif 12347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown if (!access(path.string(), R_OK)) { 12447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#if DEBUG_PROBE 12547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown LOGD("Found"); 12647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#endif 12747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown return path; 12847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown } 12947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown 13047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown // Not found. 13147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#if DEBUG_PROBE 13247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown LOGD("Probe failed to find input device configuration file: name='%s', type=%d", 13347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown name.string(), type); 13447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown#endif 13547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown return String8(); 13647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown} 13747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown 13847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown 13947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown// --- InputEvent --- 14046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 141c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brownvoid InputEvent::initialize(int32_t deviceId, int32_t source) { 14246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown mDeviceId = deviceId; 143c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown mSource = source; 14446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 14546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 1462c6081ce3593712f30dacd990a97209c791d6cedDianne Hackbornvoid InputEvent::initialize(const InputEvent& from) { 1472c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn mDeviceId = from.mDeviceId; 1482c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn mSource = from.mSource; 1492c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn} 1502c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn 15147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown// --- KeyEvent --- 15246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 1533c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornbool KeyEvent::hasDefaultAction(int32_t keyCode) { 1543c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn switch (keyCode) { 155fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_HOME: 156fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_BACK: 157fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_CALL: 158fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_ENDCALL: 159fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_VOLUME_UP: 160fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_VOLUME_DOWN: 161b0418da0e7594a8c2164a46985c5f1993632e010Jeff Brown case AKEYCODE_VOLUME_MUTE: 162fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_POWER: 163fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_CAMERA: 164fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_HEADSETHOOK: 165fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_MENU: 166fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_NOTIFICATION: 167fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_FOCUS: 168fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_SEARCH: 169b0418da0e7594a8c2164a46985c5f1993632e010Jeff Brown case AKEYCODE_MEDIA_PLAY: 170b0418da0e7594a8c2164a46985c5f1993632e010Jeff Brown case AKEYCODE_MEDIA_PAUSE: 171fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_MEDIA_PLAY_PAUSE: 172fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_MEDIA_STOP: 173fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_MEDIA_NEXT: 174fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_MEDIA_PREVIOUS: 175fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_MEDIA_REWIND: 176b0418da0e7594a8c2164a46985c5f1993632e010Jeff Brown case AKEYCODE_MEDIA_RECORD: 177fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_MEDIA_FAST_FORWARD: 178fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_MUTE: 1793c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn return true; 1803c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn } 1813c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn 1823c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn return false; 1833c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn} 1843c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn 1853c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornbool KeyEvent::hasDefaultAction() const { 1863c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn return hasDefaultAction(getKeyCode()); 1873c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn} 1883c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn 1893c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornbool KeyEvent::isSystemKey(int32_t keyCode) { 1903c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn switch (keyCode) { 191fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_MENU: 192fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_SOFT_RIGHT: 193fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_HOME: 194fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_BACK: 195fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_CALL: 196fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_ENDCALL: 197fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_VOLUME_UP: 198fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_VOLUME_DOWN: 199b0418da0e7594a8c2164a46985c5f1993632e010Jeff Brown case AKEYCODE_VOLUME_MUTE: 200fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_MUTE: 201fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_POWER: 202fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_HEADSETHOOK: 203b0418da0e7594a8c2164a46985c5f1993632e010Jeff Brown case AKEYCODE_MEDIA_PLAY: 204b0418da0e7594a8c2164a46985c5f1993632e010Jeff Brown case AKEYCODE_MEDIA_PAUSE: 205fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_MEDIA_PLAY_PAUSE: 206fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_MEDIA_STOP: 207fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_MEDIA_NEXT: 208fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_MEDIA_PREVIOUS: 209fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_MEDIA_REWIND: 210b0418da0e7594a8c2164a46985c5f1993632e010Jeff Brown case AKEYCODE_MEDIA_RECORD: 211fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_MEDIA_FAST_FORWARD: 212fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_CAMERA: 213fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_FOCUS: 214fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown case AKEYCODE_SEARCH: 2153c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn return true; 2163c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn } 2173c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn 2183c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn return false; 2193c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn} 2203c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn 2213c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornbool KeyEvent::isSystemKey() const { 2223c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn return isSystemKey(getKeyCode()); 2233c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn} 2243c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn 22546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownvoid KeyEvent::initialize( 22646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown int32_t deviceId, 227c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown int32_t source, 22846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown int32_t action, 22946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown int32_t flags, 23046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown int32_t keyCode, 23146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown int32_t scanCode, 23246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown int32_t metaState, 23346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown int32_t repeatCount, 23446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown nsecs_t downTime, 23546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown nsecs_t eventTime) { 236c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown InputEvent::initialize(deviceId, source); 23746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown mAction = action; 23846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown mFlags = flags; 23946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown mKeyCode = keyCode; 24046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown mScanCode = scanCode; 24146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown mMetaState = metaState; 24246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown mRepeatCount = repeatCount; 24346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown mDownTime = downTime; 24446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown mEventTime = eventTime; 24546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 24646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 2472c6081ce3593712f30dacd990a97209c791d6cedDianne Hackbornvoid KeyEvent::initialize(const KeyEvent& from) { 2482c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn InputEvent::initialize(from); 2492c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn mAction = from.mAction; 2502c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn mFlags = from.mFlags; 2512c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn mKeyCode = from.mKeyCode; 2522c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn mScanCode = from.mScanCode; 2532c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn mMetaState = from.mMetaState; 2542c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn mRepeatCount = from.mRepeatCount; 2552c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn mDownTime = from.mDownTime; 2562c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn mEventTime = from.mEventTime; 2572c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn} 2582c6081ce3593712f30dacd990a97209c791d6cedDianne Hackborn 25991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 26091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown// --- PointerCoords --- 26191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 2626f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brownfloat PointerCoords::getAxisValue(int32_t axis) const { 2636f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown if (axis < 0 || axis > 63) { 2646f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown return 0; 2656f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown } 2666f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown 2676f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown uint64_t axisBit = 1LL << axis; 2686f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown if (!(bits & axisBit)) { 2696f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown return 0; 2706f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown } 2716f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL)); 2726f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown return values[index]; 2736f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown} 2746f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown 2756f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brownstatus_t PointerCoords::setAxisValue(int32_t axis, float value) { 2766f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown if (axis < 0 || axis > 63) { 2776f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown return NAME_NOT_FOUND; 2786f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown } 2796f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown 2806f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown uint64_t axisBit = 1LL << axis; 2816f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL)); 2826f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown if (!(bits & axisBit)) { 283be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown if (value == 0) { 284be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown return OK; // axes with value 0 do not need to be stored 285be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown } 2866f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown uint32_t count = __builtin_popcountll(bits); 2876f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown if (count >= MAX_AXES) { 2886f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown tooManyAxes(axis); 2896f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown return NO_MEMORY; 2906f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown } 2916f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown bits |= axisBit; 2926f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown for (uint32_t i = count; i > index; i--) { 2936f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown values[i] = values[i - 1]; 2946f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown } 2956f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown } 2966f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown values[index] = value; 2976f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown return OK; 2986f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown} 2996f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown 300e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackbornstatic inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) { 301be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown float value = c.getAxisValue(axis); 302be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown if (value != 0) { 303be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown c.setAxisValue(axis, value * scaleFactor); 304e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn } 305e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn} 306e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn 307e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackbornvoid PointerCoords::scale(float scaleFactor) { 308e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn // No need to scale pressure or size since they are normalized. 309e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn // No need to scale orientation since it is meaningless to do so. 310e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, scaleFactor); 311e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, scaleFactor); 312e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, scaleFactor); 313e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, scaleFactor); 314e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, scaleFactor); 315e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor); 316e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn} 317e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn 31891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown#ifdef HAVE_ANDROID_OS 31991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatus_t PointerCoords::readFromParcel(Parcel* parcel) { 3206f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown bits = parcel->readInt64(); 32191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 3226f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown uint32_t count = __builtin_popcountll(bits); 32391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown if (count > MAX_AXES) { 32491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown return BAD_VALUE; 32591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown } 32691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 32791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown for (uint32_t i = 0; i < count; i++) { 32891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown values[i] = parcel->readInt32(); 32991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown } 33091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown return OK; 33191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown} 33291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 33391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatus_t PointerCoords::writeToParcel(Parcel* parcel) const { 3346f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown parcel->writeInt64(bits); 33591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 3366f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown uint32_t count = __builtin_popcountll(bits); 33791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown for (uint32_t i = 0; i < count; i++) { 33891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown parcel->writeInt32(values[i]); 33991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown } 34091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown return OK; 34191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown} 34291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown#endif 34391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 34491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownvoid PointerCoords::tooManyAxes(int axis) { 34591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown LOGW("Could not set value for axis %d because the PointerCoords structure is full and " 34691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown "cannot contain more than %d axis values.", axis, int(MAX_AXES)); 34791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown} 34891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 349ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brownbool PointerCoords::operator==(const PointerCoords& other) const { 350ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown if (bits != other.bits) { 351ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown return false; 352ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown } 353ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown uint32_t count = __builtin_popcountll(bits); 354ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown for (uint32_t i = 0; i < count; i++) { 355ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown if (values[i] != other.values[i]) { 356ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown return false; 357ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown } 358ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown } 359ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown return true; 360ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown} 361ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown 362ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brownvoid PointerCoords::copyFrom(const PointerCoords& other) { 363ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown bits = other.bits; 364ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown uint32_t count = __builtin_popcountll(bits); 365ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown for (uint32_t i = 0; i < count; i++) { 366ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown values[i] = other.values[i]; 367ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown } 368ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown} 369ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown 37091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 371fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown// --- PointerProperties --- 372fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown 373fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownbool PointerProperties::operator==(const PointerProperties& other) const { 374fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown return id == other.id 375fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown && toolType == other.toolType; 376fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown} 377fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown 378fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownvoid PointerProperties::copyFrom(const PointerProperties& other) { 379fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown id = other.id; 380fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown toolType = other.toolType; 381fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown} 382fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown 383fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown 38447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown// --- MotionEvent --- 38546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 38646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownvoid MotionEvent::initialize( 38746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown int32_t deviceId, 388c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown int32_t source, 38946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown int32_t action, 39085a3176704b5bfbeece9bd928369fbb76eec7dc6Jeff Brown int32_t flags, 39146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown int32_t edgeFlags, 39246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown int32_t metaState, 393fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown int32_t buttonState, 3945c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown float xOffset, 3955c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown float yOffset, 39646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown float xPrecision, 39746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown float yPrecision, 39846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown nsecs_t downTime, 39946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown nsecs_t eventTime, 40046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown size_t pointerCount, 401fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown const PointerProperties* pointerProperties, 40246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown const PointerCoords* pointerCoords) { 403c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown InputEvent::initialize(deviceId, source); 40446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown mAction = action; 40585a3176704b5bfbeece9bd928369fbb76eec7dc6Jeff Brown mFlags = flags; 40646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown mEdgeFlags = edgeFlags; 40746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown mMetaState = metaState; 408fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown mButtonState = buttonState; 4095c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown mXOffset = xOffset; 4105c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown mYOffset = yOffset; 41146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown mXPrecision = xPrecision; 41246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown mYPrecision = yPrecision; 41346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown mDownTime = downTime; 414fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown mPointerProperties.clear(); 415fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown mPointerProperties.appendArray(pointerProperties, pointerCount); 41646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown mSampleEventTimes.clear(); 41746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown mSamplePointerCoords.clear(); 41846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown addSample(eventTime, pointerCoords); 41946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 42046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 42191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownvoid MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) { 42291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown InputEvent::initialize(other->mDeviceId, other->mSource); 42391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mAction = other->mAction; 42491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mFlags = other->mFlags; 42591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mEdgeFlags = other->mEdgeFlags; 42691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mMetaState = other->mMetaState; 427fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown mButtonState = other->mButtonState; 42891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mXOffset = other->mXOffset; 42991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mYOffset = other->mYOffset; 43091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mXPrecision = other->mXPrecision; 43191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mYPrecision = other->mYPrecision; 43291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mDownTime = other->mDownTime; 433fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown mPointerProperties = other->mPointerProperties; 43491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 43591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown if (keepHistory) { 43691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mSampleEventTimes = other->mSampleEventTimes; 43791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mSamplePointerCoords = other->mSamplePointerCoords; 43891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown } else { 43991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mSampleEventTimes.clear(); 44091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mSampleEventTimes.push(other->getEventTime()); 44191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mSamplePointerCoords.clear(); 44291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown size_t pointerCount = other->getPointerCount(); 44391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown size_t historySize = other->getHistorySize(); 44491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array() 44591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown + (historySize * pointerCount), pointerCount); 44691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown } 44791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown} 44891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 44946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownvoid MotionEvent::addSample( 45046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown int64_t eventTime, 45146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown const PointerCoords* pointerCoords) { 45246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown mSampleEventTimes.push(eventTime); 45346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown mSamplePointerCoords.appendArray(pointerCoords, getPointerCount()); 45446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 45546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 45691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownconst PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const { 45791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex]; 45891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown} 45991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 46091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownfloat MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const { 46191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown return getRawPointerCoords(pointerIndex)->getAxisValue(axis); 46291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown} 46391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 46491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownfloat MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const { 46591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis); 46691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown switch (axis) { 467ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown case AMOTION_EVENT_AXIS_X: 468e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn return value + mXOffset; 469ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown case AMOTION_EVENT_AXIS_Y: 470e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn return value + mYOffset; 47191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown } 47291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown return value; 47391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown} 47491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 47591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownconst PointerCoords* MotionEvent::getHistoricalRawPointerCoords( 47691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown size_t pointerIndex, size_t historicalIndex) const { 47791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex]; 47891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown} 47991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 48091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownfloat MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex, 48191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown size_t historicalIndex) const { 48291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis); 48391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown} 48491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 48591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownfloat MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex, 48691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown size_t historicalIndex) const { 48791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis); 48891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown switch (axis) { 489ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown case AMOTION_EVENT_AXIS_X: 490e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn return value + mXOffset; 491ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown case AMOTION_EVENT_AXIS_Y: 492e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn return value + mYOffset; 49391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown } 49491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown return value; 49591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown} 49691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 4972ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownssize_t MotionEvent::findPointerIndex(int32_t pointerId) const { 498fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown size_t pointerCount = mPointerProperties.size(); 4992ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown for (size_t i = 0; i < pointerCount; i++) { 500fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown if (mPointerProperties.itemAt(i).id == pointerId) { 5012ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown return i; 5022ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown } 5032ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown } 5042ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown return -1; 5052ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown} 5062ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown 50746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownvoid MotionEvent::offsetLocation(float xOffset, float yOffset) { 5085c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown mXOffset += xOffset; 5095c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown mYOffset += yOffset; 51046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 51146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 51291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownvoid MotionEvent::scale(float scaleFactor) { 51391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mXOffset *= scaleFactor; 51491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mYOffset *= scaleFactor; 51591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mXPrecision *= scaleFactor; 51691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mYPrecision *= scaleFactor; 51791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 51891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown size_t numSamples = mSamplePointerCoords.size(); 51991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown for (size_t i = 0; i < numSamples; i++) { 520e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn mSamplePointerCoords.editItemAt(i).scale(scaleFactor); 52191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown } 52291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown} 52391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 52491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown#ifdef HAVE_ANDROID_OS 52591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatic inline float transformAngle(const SkMatrix* matrix, float angleRadians) { 52691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown // Construct and transform a vector oriented at the specified clockwise angle from vertical. 52791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown // Coordinate system: down is increasing Y, right is increasing X. 52891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown SkPoint vector; 52991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown vector.fX = SkFloatToScalar(sinf(angleRadians)); 53091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown vector.fY = SkFloatToScalar(-cosf(angleRadians)); 53191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown matrix->mapVectors(& vector, 1); 53291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 53391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown // Derive the transformed vector's clockwise angle from vertical. 53491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown float result = atan2f(SkScalarToFloat(vector.fX), SkScalarToFloat(-vector.fY)); 53591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown if (result < - M_PI_2) { 53691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown result += M_PI; 53791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown } else if (result > M_PI_2) { 53891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown result -= M_PI; 53991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown } 54091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown return result; 54191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown} 54291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 54391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownvoid MotionEvent::transform(const SkMatrix* matrix) { 54491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown float oldXOffset = mXOffset; 54591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown float oldYOffset = mYOffset; 54691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 54791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown // The tricky part of this implementation is to preserve the value of 54891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown // rawX and rawY. So we apply the transformation to the first point 54991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown // then derive an appropriate new X/Y offset that will preserve rawX and rawY. 55091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown SkPoint point; 55191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown float rawX = getRawX(0); 55291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown float rawY = getRawY(0); 55391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown matrix->mapXY(SkFloatToScalar(rawX + oldXOffset), SkFloatToScalar(rawY + oldYOffset), 55491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown & point); 55591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown float newX = SkScalarToFloat(point.fX); 55691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown float newY = SkScalarToFloat(point.fY); 55791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown float newXOffset = newX - rawX; 55891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown float newYOffset = newY - rawY; 55991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 56091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mXOffset = newXOffset; 56191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mYOffset = newYOffset; 56291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 56391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown // Apply the transformation to all samples. 56491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown size_t numSamples = mSamplePointerCoords.size(); 56591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown for (size_t i = 0; i < numSamples; i++) { 56691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown PointerCoords& c = mSamplePointerCoords.editItemAt(i); 567be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset; 568be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset; 569be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), &point); 570be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown c.setAxisValue(AMOTION_EVENT_AXIS_X, SkScalarToFloat(point.fX) - newXOffset); 571be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown c.setAxisValue(AMOTION_EVENT_AXIS_Y, SkScalarToFloat(point.fY) - newYOffset); 57291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 573be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION); 574be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, transformAngle(matrix, orientation)); 57591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown } 57691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown} 57791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 57891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatus_t MotionEvent::readFromParcel(Parcel* parcel) { 57991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown size_t pointerCount = parcel->readInt32(); 58091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown size_t sampleCount = parcel->readInt32(); 58191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown if (pointerCount == 0 || pointerCount > MAX_POINTERS || sampleCount == 0) { 58291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown return BAD_VALUE; 58391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown } 58491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 58591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mDeviceId = parcel->readInt32(); 58691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mSource = parcel->readInt32(); 58791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mAction = parcel->readInt32(); 58891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mFlags = parcel->readInt32(); 58991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mEdgeFlags = parcel->readInt32(); 59091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mMetaState = parcel->readInt32(); 591fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown mButtonState = parcel->readInt32(); 59291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mXOffset = parcel->readFloat(); 59391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mYOffset = parcel->readFloat(); 59491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mXPrecision = parcel->readFloat(); 59591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mYPrecision = parcel->readFloat(); 59691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mDownTime = parcel->readInt64(); 59791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 598fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown mPointerProperties.clear(); 599fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown mPointerProperties.setCapacity(pointerCount); 60091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mSampleEventTimes.clear(); 60191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mSampleEventTimes.setCapacity(sampleCount); 60291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mSamplePointerCoords.clear(); 60391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mSamplePointerCoords.setCapacity(sampleCount * pointerCount); 60491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 60591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown for (size_t i = 0; i < pointerCount; i++) { 606fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown mPointerProperties.push(); 607fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown PointerProperties& properties = mPointerProperties.editTop(); 608fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown properties.id = parcel->readInt32(); 609fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown properties.toolType = parcel->readInt32(); 61091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown } 61191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 61291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown while (sampleCount-- > 0) { 61391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mSampleEventTimes.push(parcel->readInt64()); 61491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown for (size_t i = 0; i < pointerCount; i++) { 61591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown mSamplePointerCoords.push(); 61691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel); 617ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown if (status) { 61891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown return status; 61991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown } 62091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown } 62191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown } 62291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown return OK; 62391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown} 62491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 62591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brownstatus_t MotionEvent::writeToParcel(Parcel* parcel) const { 626fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown size_t pointerCount = mPointerProperties.size(); 62791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown size_t sampleCount = mSampleEventTimes.size(); 62891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 62991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown parcel->writeInt32(pointerCount); 63091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown parcel->writeInt32(sampleCount); 63191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 63291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown parcel->writeInt32(mDeviceId); 63391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown parcel->writeInt32(mSource); 63491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown parcel->writeInt32(mAction); 63591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown parcel->writeInt32(mFlags); 63691c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown parcel->writeInt32(mEdgeFlags); 63791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown parcel->writeInt32(mMetaState); 638fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown parcel->writeInt32(mButtonState); 63991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown parcel->writeFloat(mXOffset); 64091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown parcel->writeFloat(mYOffset); 64191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown parcel->writeFloat(mXPrecision); 64291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown parcel->writeFloat(mYPrecision); 64391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown parcel->writeInt64(mDownTime); 64491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 64591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown for (size_t i = 0; i < pointerCount; i++) { 646fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown const PointerProperties& properties = mPointerProperties.itemAt(i); 647fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown parcel->writeInt32(properties.id); 648fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown parcel->writeInt32(properties.toolType); 64991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown } 65091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 65191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown const PointerCoords* pc = mSamplePointerCoords.array(); 65291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown for (size_t h = 0; h < sampleCount; h++) { 65391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown parcel->writeInt64(mSampleEventTimes.itemAt(h)); 65491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown for (size_t i = 0; i < pointerCount; i++) { 65591c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown status_t status = (pc++)->writeToParcel(parcel); 656ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown if (status) { 65791c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown return status; 65891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown } 65991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown } 66091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown } 66191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown return OK; 66291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown} 66391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown#endif 66491c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 66556194ebec6212e229f4ccdaa4b187166d20013efJeff Brownbool MotionEvent::isTouchEvent(int32_t source, int32_t action) { 66656194ebec6212e229f4ccdaa4b187166d20013efJeff Brown if (source & AINPUT_SOURCE_CLASS_POINTER) { 66756194ebec6212e229f4ccdaa4b187166d20013efJeff Brown // Specifically excludes HOVER_MOVE and SCROLL. 66856194ebec6212e229f4ccdaa4b187166d20013efJeff Brown switch (action & AMOTION_EVENT_ACTION_MASK) { 66956194ebec6212e229f4ccdaa4b187166d20013efJeff Brown case AMOTION_EVENT_ACTION_DOWN: 67056194ebec6212e229f4ccdaa4b187166d20013efJeff Brown case AMOTION_EVENT_ACTION_MOVE: 67156194ebec6212e229f4ccdaa4b187166d20013efJeff Brown case AMOTION_EVENT_ACTION_UP: 67256194ebec6212e229f4ccdaa4b187166d20013efJeff Brown case AMOTION_EVENT_ACTION_POINTER_DOWN: 67356194ebec6212e229f4ccdaa4b187166d20013efJeff Brown case AMOTION_EVENT_ACTION_POINTER_UP: 67456194ebec6212e229f4ccdaa4b187166d20013efJeff Brown case AMOTION_EVENT_ACTION_CANCEL: 67556194ebec6212e229f4ccdaa4b187166d20013efJeff Brown case AMOTION_EVENT_ACTION_OUTSIDE: 67656194ebec6212e229f4ccdaa4b187166d20013efJeff Brown return true; 67756194ebec6212e229f4ccdaa4b187166d20013efJeff Brown } 67856194ebec6212e229f4ccdaa4b187166d20013efJeff Brown } 67956194ebec6212e229f4ccdaa4b187166d20013efJeff Brown return false; 68056194ebec6212e229f4ccdaa4b187166d20013efJeff Brown} 68156194ebec6212e229f4ccdaa4b187166d20013efJeff Brown 68291c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown 683ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown// --- VelocityTracker --- 684ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown 68519c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brownconst uint32_t VelocityTracker::HISTORY_SIZE; 68619c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brownconst nsecs_t VelocityTracker::MAX_AGE; 68719c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brownconst nsecs_t VelocityTracker::MIN_DURATION; 68819c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown 689ace13b17866dc9136aeecf6dfaf7077f37434469Jeff BrownVelocityTracker::VelocityTracker() { 690ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown clear(); 691ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown} 692ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown 693ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brownvoid VelocityTracker::clear() { 694ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown mIndex = 0; 695ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown mMovements[0].idBits.clear(); 6962ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown mActivePointerId = -1; 6972ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown} 6982ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown 6992ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownvoid VelocityTracker::clearPointers(BitSet32 idBits) { 7002ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown BitSet32 remainingIdBits(mMovements[mIndex].idBits.value & ~idBits.value); 7012ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown mMovements[mIndex].idBits = remainingIdBits; 7022ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown 7032ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown if (mActivePointerId >= 0 && idBits.hasBit(mActivePointerId)) { 7042ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown mActivePointerId = !remainingIdBits.isEmpty() ? remainingIdBits.firstMarkedBit() : -1; 7052ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown } 706ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown} 707ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown 708ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brownvoid VelocityTracker::addMovement(nsecs_t eventTime, BitSet32 idBits, const Position* positions) { 709ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown if (++mIndex == HISTORY_SIZE) { 710ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown mIndex = 0; 711ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown } 7122ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown 7132ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown while (idBits.count() > MAX_POINTERS) { 714be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown idBits.clearLastMarkedBit(); 7152ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown } 7162ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown 717ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown Movement& movement = mMovements[mIndex]; 718ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown movement.eventTime = eventTime; 719ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown movement.idBits = idBits; 720ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown uint32_t count = idBits.count(); 721ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown for (uint32_t i = 0; i < count; i++) { 722ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown movement.positions[i] = positions[i]; 723ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown } 724ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown 7252ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown if (mActivePointerId < 0 || !idBits.hasBit(mActivePointerId)) { 7262ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown mActivePointerId = count != 0 ? idBits.firstMarkedBit() : -1; 7272ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown } 7282ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown 729ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_VELOCITY 7302ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown LOGD("VelocityTracker: addMovement eventTime=%lld, idBits=0x%08x, activePointerId=%d", 7312ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown eventTime, idBits.value, mActivePointerId); 732ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown for (BitSet32 iterBits(idBits); !iterBits.isEmpty(); ) { 733ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown uint32_t id = iterBits.firstMarkedBit(); 734ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown uint32_t index = idBits.getIndexOfBit(id); 735ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown iterBits.clearBit(id); 736ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown float vx, vy; 737ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown bool available = getVelocity(id, &vx, &vy); 738ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown if (available) { 7392ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown LOGD(" %d: position (%0.3f, %0.3f), vx=%0.3f, vy=%0.3f, speed=%0.3f", 740ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown id, positions[index].x, positions[index].y, vx, vy, sqrtf(vx * vx + vy * vy)); 741ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown } else { 742b6110c2de0cd7950360aeb2c248a44e4ea5f33f5Jeff Brown LOG_ASSERT(vx == 0 && vy == 0); 743ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown LOGD(" %d: position (%0.3f, %0.3f), velocity not available", 744ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown id, positions[index].x, positions[index].y); 745ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown } 746ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown } 747ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif 748ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown} 749ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown 7502ed2462aa29c564f5231f317c27b3188da875e52Jeff Brownvoid VelocityTracker::addMovement(const MotionEvent* event) { 7512ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown int32_t actionMasked = event->getActionMasked(); 7522ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown 7532ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown switch (actionMasked) { 7542ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown case AMOTION_EVENT_ACTION_DOWN: 7552ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown // Clear all pointers on down before adding the new movement. 7562ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown clear(); 7572ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown break; 7582ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown case AMOTION_EVENT_ACTION_POINTER_DOWN: { 7592ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown // Start a new movement trace for a pointer that just went down. 7602ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown // We do this on down instead of on up because the client may want to query the 7612ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown // final velocity for a pointer that just went up. 7622ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown BitSet32 downIdBits; 763be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown downIdBits.markBit(event->getPointerId(event->getActionIndex())); 7642ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown clearPointers(downIdBits); 7652ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown break; 7662ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown } 7672ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown case AMOTION_EVENT_ACTION_OUTSIDE: 7682ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown case AMOTION_EVENT_ACTION_CANCEL: 7692ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown case AMOTION_EVENT_ACTION_SCROLL: 7702ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown case AMOTION_EVENT_ACTION_UP: 7712ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown case AMOTION_EVENT_ACTION_POINTER_UP: 7722ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown // Ignore these actions because they do not convey any new information about 7732ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown // pointer movement. We also want to preserve the last known velocity of the pointers. 7742ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown // Note that ACTION_UP and ACTION_POINTER_UP always report the last known position 7752ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown // of the pointers that went up. ACTION_POINTER_UP does include the new position of 7762ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown // pointers that remained down but we will also receive an ACTION_MOVE with this 7772ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown // information if any of them actually moved. Since we don't know how many pointers 7782ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown // will be going up at once it makes sense to just wait for the following ACTION_MOVE 7792ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown // before adding the movement. 7802ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown return; 7812ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown } 7822ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown 7832ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown size_t pointerCount = event->getPointerCount(); 7842ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown if (pointerCount > MAX_POINTERS) { 7852ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown pointerCount = MAX_POINTERS; 7862ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown } 7872ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown 7882ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown BitSet32 idBits; 7892ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown for (size_t i = 0; i < pointerCount; i++) { 7902ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown idBits.markBit(event->getPointerId(i)); 7912ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown } 7922ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown 7932ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown nsecs_t eventTime; 7942ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown Position positions[pointerCount]; 7952ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown 7962ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown size_t historySize = event->getHistorySize(); 7972ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown for (size_t h = 0; h < historySize; h++) { 7982ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown eventTime = event->getHistoricalEventTime(h); 7992ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown for (size_t i = 0; i < pointerCount; i++) { 8002ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown positions[i].x = event->getHistoricalX(i, h); 8012ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown positions[i].y = event->getHistoricalY(i, h); 8022ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown } 8032ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown addMovement(eventTime, idBits, positions); 8042ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown } 8052ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown 8062ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown eventTime = event->getEventTime(); 8072ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown for (size_t i = 0; i < pointerCount; i++) { 8082ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown positions[i].x = event->getX(i); 8092ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown positions[i].y = event->getY(i); 8102ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown } 8112ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown addMovement(eventTime, idBits, positions); 8122ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown} 8132ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown 814ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brownbool VelocityTracker::getVelocity(uint32_t id, float* outVx, float* outVy) const { 815ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown const Movement& newestMovement = mMovements[mIndex]; 816ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown if (newestMovement.idBits.hasBit(id)) { 817ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown // Find the oldest sample that contains the pointer and that is not older than MAX_AGE. 818ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown nsecs_t minTime = newestMovement.eventTime - MAX_AGE; 819ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown uint32_t oldestIndex = mIndex; 820ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown uint32_t numTouches = 1; 821ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown do { 822ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown uint32_t nextOldestIndex = (oldestIndex == 0 ? HISTORY_SIZE : oldestIndex) - 1; 823ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown const Movement& nextOldestMovement = mMovements[nextOldestIndex]; 824ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown if (!nextOldestMovement.idBits.hasBit(id) 825ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown || nextOldestMovement.eventTime < minTime) { 826ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown break; 827ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown } 828ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown oldestIndex = nextOldestIndex; 829ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown } while (++numTouches < HISTORY_SIZE); 830ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown 8312ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown // Calculate an exponentially weighted moving average of the velocity estimate 8322ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown // at different points in time measured relative to the oldest sample. 8332ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown // This is essentially an IIR filter. Newer samples are weighted more heavily 8342ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown // than older samples. Samples at equal time points are weighted more or less 8352ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown // equally. 836ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown // 8372ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown // One tricky problem is that the sample data may be poorly conditioned. 838ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown // Sometimes samples arrive very close together in time which can cause us to 839ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown // overestimate the velocity at that time point. Most samples might be measured 8402ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown // 16ms apart but some consecutive samples could be only 0.5sm apart because 8412ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown // the hardware or driver reports them irregularly or in bursts. 842ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown float accumVx = 0; 843ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown float accumVy = 0; 844ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown uint32_t index = oldestIndex; 845ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown uint32_t samplesUsed = 0; 846ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown const Movement& oldestMovement = mMovements[oldestIndex]; 847ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown const Position& oldestPosition = 848ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown oldestMovement.positions[oldestMovement.idBits.getIndexOfBit(id)]; 8492ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown nsecs_t lastDuration = 0; 8502352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown 851ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown while (numTouches-- > 1) { 852ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown if (++index == HISTORY_SIZE) { 853ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown index = 0; 854ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown } 855ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown const Movement& movement = mMovements[index]; 856ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown nsecs_t duration = movement.eventTime - oldestMovement.eventTime; 8572ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown 8582ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown // If the duration between samples is small, we may significantly overestimate 8592ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown // the velocity. Consequently, we impose a minimum duration constraint on the 8602ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown // samples that we include in the calculation. 8612ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown if (duration >= MIN_DURATION) { 862ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown const Position& position = movement.positions[movement.idBits.getIndexOfBit(id)]; 863ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown float scale = 1000000000.0f / duration; // one over time delta in seconds 864ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown float vx = (position.x - oldestPosition.x) * scale; 865ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown float vy = (position.y - oldestPosition.y) * scale; 8662ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown 8672ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown accumVx = (accumVx * lastDuration + vx * duration) / (duration + lastDuration); 8682ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown accumVy = (accumVy * lastDuration + vy * duration) / (duration + lastDuration); 8692ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown 8702ed2462aa29c564f5231f317c27b3188da875e52Jeff Brown lastDuration = duration; 871ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown samplesUsed += 1; 872ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown } 873ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown } 874ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown 875ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown // Make sure we used at least one sample. 876ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown if (samplesUsed != 0) { 877ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown *outVx = accumVx; 878ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown *outVy = accumVy; 879ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown return true; 880ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown } 881ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown } 882ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown 883ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown // No data available for this pointer. 884ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown *outVx = 0; 885ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown *outVy = 0; 886ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown return false; 887ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown} 888ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown 889ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown 89019c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown// --- VelocityControl --- 89119c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown 89219c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brownconst nsecs_t VelocityControl::STOP_TIME; 89319c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown 89419c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff BrownVelocityControl::VelocityControl() { 89519c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown reset(); 89619c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown} 89719c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown 89819c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brownvoid VelocityControl::setParameters(const VelocityControlParameters& parameters) { 89919c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown mParameters = parameters; 90019c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown reset(); 90119c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown} 90219c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown 90319c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brownvoid VelocityControl::reset() { 90419c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown mLastMovementTime = LLONG_MIN; 90519c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown mRawPosition.x = 0; 90619c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown mRawPosition.y = 0; 90719c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown mVelocityTracker.clear(); 90819c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown} 90919c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown 91019c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brownvoid VelocityControl::move(nsecs_t eventTime, float* deltaX, float* deltaY) { 91119c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown if ((deltaX && *deltaX) || (deltaY && *deltaY)) { 91219c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown if (eventTime >= mLastMovementTime + STOP_TIME) { 91319c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown#if DEBUG_ACCELERATION 91419c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown LOGD("VelocityControl: stopped, last movement was %0.3fms ago", 91519c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown (eventTime - mLastMovementTime) * 0.000001f); 91619c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown#endif 91719c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown reset(); 91819c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown } 91919c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown 92019c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown mLastMovementTime = eventTime; 92119c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown if (deltaX) { 92219c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown mRawPosition.x += *deltaX; 92319c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown } 92419c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown if (deltaY) { 92519c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown mRawPosition.y += *deltaY; 92619c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown } 92719c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown mVelocityTracker.addMovement(eventTime, BitSet32(BitSet32::valueForBit(0)), &mRawPosition); 92819c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown 92919c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown float vx, vy; 93019c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown float scale = mParameters.scale; 93119c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown if (mVelocityTracker.getVelocity(0, &vx, &vy)) { 93219c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown float speed = hypotf(vx, vy) * scale; 93319c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown if (speed >= mParameters.highThreshold) { 93419c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown // Apply full acceleration above the high speed threshold. 93519c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown scale *= mParameters.acceleration; 93619c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown } else if (speed > mParameters.lowThreshold) { 93719c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown // Linearly interpolate the acceleration to apply between the low and high 93819c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown // speed thresholds. 93919c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown scale *= 1 + (speed - mParameters.lowThreshold) 94019c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown / (mParameters.highThreshold - mParameters.lowThreshold) 94119c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown * (mParameters.acceleration - 1); 94219c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown } 94319c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown 94419c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown#if DEBUG_ACCELERATION 94519c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown LOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): " 94619c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown "vx=%0.3f, vy=%0.3f, speed=%0.3f, accel=%0.3f", 94719c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold, 94819c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown mParameters.acceleration, 94919c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown vx, vy, speed, scale / mParameters.scale); 95019c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown#endif 95119c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown } else { 95219c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown#if DEBUG_ACCELERATION 95319c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown LOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): unknown velocity", 95419c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold, 95519c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown mParameters.acceleration); 95619c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown#endif 95719c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown } 95819c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown 95919c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown if (deltaX) { 96019c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown *deltaX *= scale; 96119c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown } 96219c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown if (deltaY) { 96319c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown *deltaY *= scale; 96419c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown } 96519c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown } 96619c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown} 96719c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown 96819c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown 96947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown// --- InputDeviceInfo --- 9706d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown 9716d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownInputDeviceInfo::InputDeviceInfo() { 9726d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown initialize(-1, String8("uninitialized device info")); 9736d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown} 9746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown 9756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownInputDeviceInfo::InputDeviceInfo(const InputDeviceInfo& other) : 9766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown mId(other.mId), mName(other.mName), mSources(other.mSources), 9776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown mKeyboardType(other.mKeyboardType), 9786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown mMotionRanges(other.mMotionRanges) { 9796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown} 9806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown 9816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownInputDeviceInfo::~InputDeviceInfo() { 9826d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown} 9836d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown 9846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid InputDeviceInfo::initialize(int32_t id, const String8& name) { 9856d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown mId = id; 9866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown mName = name; 9876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown mSources = 0; 9886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown mKeyboardType = AINPUT_KEYBOARD_TYPE_NONE; 9896d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown mMotionRanges.clear(); 9906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown} 9916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown 992efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brownconst InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange( 993efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown int32_t axis, uint32_t source) const { 994efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown size_t numRanges = mMotionRanges.size(); 995efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown for (size_t i = 0; i < numRanges; i++) { 996efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown const MotionRange& range = mMotionRanges.itemAt(i); 997efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown if (range.axis == axis && range.source == source) { 998efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown return ⦥ 999efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown } 1000efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown } 1001efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown return NULL; 10026d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown} 10036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown 10046d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid InputDeviceInfo::addSource(uint32_t source) { 10056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown mSources |= source; 10066d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown} 10076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown 1008efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brownvoid InputDeviceInfo::addMotionRange(int32_t axis, uint32_t source, float min, float max, 10096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown float flat, float fuzz) { 1010efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown MotionRange range = { axis, source, min, max, flat, fuzz }; 1011efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown mMotionRanges.add(range); 10126d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown} 10136d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown 1014efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brownvoid InputDeviceInfo::addMotionRange(const MotionRange& range) { 1015efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown mMotionRanges.add(range); 10166d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown} 10176d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown 101846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} // namespace android 1019