1b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown/*
2b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * Copyright (C) 2010 The Android Open Source Project
3b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown *
4b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
5b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * you may not use this file except in compliance with the License.
6b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * You may obtain a copy of the License at
7b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown *
8b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
9b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown *
10b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * Unless required by applicable law or agreed to in writing, software
11b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
12b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * See the License for the specific language governing permissions and
14b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * limitations under the License.
15b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown */
16b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
1746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define LOG_TAG "InputReader"
1846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown//#define LOG_NDEBUG 0
2046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// Log debug messages for each raw event received from the EventHub.
2246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define DEBUG_RAW_EVENTS 0
2346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// Log debug messages about touch screen filtering hacks.
25349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown#define DEBUG_HACKS 0
2646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// Log debug messages about virtual key processing.
28349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown#define DEBUG_VIRTUAL_KEYS 0
2946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// Log debug messages about pointers.
319f2106f2bcbb82cd2d8a80f24ab0cdafeb6b5d8fJeff Brown#define DEBUG_POINTERS 0
3246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
335c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown// Log debug messages about pointer assignment calculations.
345c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown#define DEBUG_POINTER_ASSIGNMENT 0
355c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown
36ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown// Log debug messages about gesture detection.
37ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#define DEBUG_GESTURES 0
38ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
39a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown// Log debug messages about the vibrator.
40a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown#define DEBUG_VIBRATOR 0
41a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
42b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown#include "InputReader.h"
43b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
4446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <cutils/log.h>
45b93a03f841d93498bfea6cc92a22faa34bce1337Mathias Agopian#include <androidfw/Keyboard.h>
46b93a03f841d93498bfea6cc92a22faa34bce1337Mathias Agopian#include <androidfw/VirtualKeyMap.h>
4746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <stddef.h>
498d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown#include <stdlib.h>
5046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <unistd.h>
5146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <errno.h>
5246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <limits.h>
53c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown#include <math.h>
5446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
558d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown#define INDENT "  "
56ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown#define INDENT2 "    "
57ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown#define INDENT3 "      "
58ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown#define INDENT4 "        "
59aba321aa6f1be57beac70bd540812eea1c8262c5Jeff Brown#define INDENT5 "          "
608d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
6146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownnamespace android {
6246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
63ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown// --- Constants ---
64ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
6580fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown// Maximum number of slots supported when using the slot-based Multitouch Protocol B.
6680fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brownstatic const size_t MAX_SLOTS = 32;
6780fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
6846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// --- Static Functions ---
6946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
7046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Browntemplate<typename T>
7146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Browninline static T abs(const T& value) {
7246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    return value < 0 ? - value : value;
7346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
7446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
7546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Browntemplate<typename T>
7646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Browninline static T min(const T& a, const T& b) {
7746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    return a < b ? a : b;
7846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
7946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
805c225b1680e696ae8bbf505a1997d6f720672f74Jeff Browntemplate<typename T>
815c225b1680e696ae8bbf505a1997d6f720672f74Jeff Browninline static void swap(T& a, T& b) {
825c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    T temp = a;
835c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    a = b;
845c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    b = temp;
855c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown}
865c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown
878d60866e2100db70ecf0502c14768a384514d7e9Jeff Browninline static float avg(float x, float y) {
888d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    return (x + y) / 2;
898d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown}
908d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
912352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Browninline static float distance(float x1, float y1, float x2, float y2) {
922352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    return hypotf(x1 - x2, y1 - y2);
93ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown}
94ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
95517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Browninline static int32_t signExtendNybble(int32_t value) {
96517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown    return value >= 8 ? value - 16 : value;
97517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown}
98517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown
99ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brownstatic inline const char* toString(bool value) {
100ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    return value ? "true" : "false";
101ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown}
102ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
1039626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brownstatic int32_t rotateValueUsingRotationMap(int32_t value, int32_t orientation,
1049626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        const int32_t map[][4], size_t mapSize) {
1059626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown    if (orientation != DISPLAY_ORIENTATION_0) {
1069626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        for (size_t i = 0; i < mapSize; i++) {
1079626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            if (value == map[i][0]) {
1089626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                return map[i][orientation];
1099626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            }
1109626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        }
1119626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown    }
1129626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown    return value;
1139626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown}
1149626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown
11546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic const int32_t keyCodeRotationMap[][4] = {
11646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        // key codes enumerated counter-clockwise with the original (unrotated) key first
11746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        // no rotation,        90 degree rotation,  180 degree rotation, 270 degree rotation
118fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        { AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT },
119fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        { AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN },
120fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        { AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT },
121fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        { AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP },
12246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown};
1239626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brownstatic const size_t keyCodeRotationMapSize =
12446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        sizeof(keyCodeRotationMap) / sizeof(keyCodeRotationMap[0]);
12546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1266069139356ceb4d257f749954a2220b1f4fbf9cbJeff Brownstatic int32_t rotateKeyCode(int32_t keyCode, int32_t orientation) {
1279626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown    return rotateValueUsingRotationMap(keyCode, orientation,
1289626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            keyCodeRotationMap, keyCodeRotationMapSize);
1299626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown}
1309626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown
131612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brownstatic void rotateDelta(int32_t orientation, float* deltaX, float* deltaY) {
132612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown    float temp;
133612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown    switch (orientation) {
134612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown    case DISPLAY_ORIENTATION_90:
135612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown        temp = *deltaX;
136612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown        *deltaX = *deltaY;
137612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown        *deltaY = -temp;
138612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown        break;
139612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown
140612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown    case DISPLAY_ORIENTATION_180:
141612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown        *deltaX = -*deltaX;
142612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown        *deltaY = -*deltaY;
143612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown        break;
144612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown
145612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown    case DISPLAY_ORIENTATION_270:
146612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown        temp = *deltaX;
147612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown        *deltaX = -*deltaY;
148612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown        *deltaY = temp;
149612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown        break;
150612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown    }
151612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown}
152612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown
1536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownstatic inline bool sourcesMatchMask(uint32_t sources, uint32_t sourceMask) {
1546d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return (sources & sourceMask & ~ AINPUT_SOURCE_CLASS_MASK) != 0;
1556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
1566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
157efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown// Returns true if the pointer should be reported as being down given the specified
158fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown// button states.  This determines whether the event is reported as a touch event.
159fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownstatic bool isPointerDown(int32_t buttonState) {
160fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    return buttonState &
161fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            (AMOTION_EVENT_BUTTON_PRIMARY | AMOTION_EVENT_BUTTON_SECONDARY
16253ca3f13e70fda98aa9f39bb0c15afaf435e3904Jeff Brown                    | AMOTION_EVENT_BUTTON_TERTIARY);
163efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown}
164efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown
1652352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownstatic float calculateCommonVector(float a, float b) {
1662352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    if (a > 0 && b > 0) {
1672352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        return a < b ? a : b;
1682352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    } else if (a < 0 && b < 0) {
1692352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        return a > b ? a : b;
1702352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    } else {
1712352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        return 0;
1722352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    }
1732352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown}
1742352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
175fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownstatic void synthesizeButtonKey(InputReaderContext* context, int32_t action,
176fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        nsecs_t when, int32_t deviceId, uint32_t source,
177fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        uint32_t policyFlags, int32_t lastButtonState, int32_t currentButtonState,
178fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        int32_t buttonState, int32_t keyCode) {
179fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    if (
180fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            (action == AKEY_EVENT_ACTION_DOWN
181fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    && !(lastButtonState & buttonState)
182fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    && (currentButtonState & buttonState))
183fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            || (action == AKEY_EVENT_ACTION_UP
184fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    && (lastButtonState & buttonState)
185fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    && !(currentButtonState & buttonState))) {
186be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        NotifyKeyArgs args(when, deviceId, source, policyFlags,
187fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                action, 0, keyCode, 0, context->getGlobalMetaState(), when);
188be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        context->getListener()->notifyKey(&args);
189fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    }
190fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown}
191fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
192fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownstatic void synthesizeButtonKeys(InputReaderContext* context, int32_t action,
193fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        nsecs_t when, int32_t deviceId, uint32_t source,
194fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        uint32_t policyFlags, int32_t lastButtonState, int32_t currentButtonState) {
195fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    synthesizeButtonKey(context, action, when, deviceId, source, policyFlags,
196fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            lastButtonState, currentButtonState,
197fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            AMOTION_EVENT_BUTTON_BACK, AKEYCODE_BACK);
198fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    synthesizeButtonKey(context, action, when, deviceId, source, policyFlags,
199fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            lastButtonState, currentButtonState,
200fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            AMOTION_EVENT_BUTTON_FORWARD, AKEYCODE_FORWARD);
201fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown}
202fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
20346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
20465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown// --- InputReaderConfiguration ---
20565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
206d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brownbool InputReaderConfiguration::getDisplayInfo(bool external, DisplayViewport* outViewport) const {
207d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    const DisplayViewport& viewport = external ? mExternalDisplay : mInternalDisplay;
208d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    if (viewport.displayId >= 0) {
209d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        *outViewport = viewport;
210d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        return true;
21165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
21265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    return false;
21365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
21465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
215d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brownvoid InputReaderConfiguration::setDisplayInfo(bool external, const DisplayViewport& viewport) {
216d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    DisplayViewport& v = external ? mExternalDisplay : mInternalDisplay;
217d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    v = viewport;
21865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
21965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
22065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
22146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// --- InputReader ---
22246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
22346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff BrownInputReader::InputReader(const sp<EventHubInterface>& eventHub,
2249c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown        const sp<InputReaderPolicyInterface>& policy,
225be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        const sp<InputListenerInterface>& listener) :
226be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mContext(this), mEventHub(eventHub), mPolicy(policy),
227af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown        mGlobalMetaState(0), mGeneration(1),
228af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown        mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
229474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        mConfigurationChangesToRefresh(0) {
230be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mQueuedListener = new QueuedInputListener(listener);
231be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
232be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    { // acquire lock
233be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        AutoMutex _l(mLock);
234be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
235be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        refreshConfigurationLocked(0);
236be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        updateGlobalMetaStateLocked();
237be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    } // release lock
23846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
23946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
24046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff BrownInputReader::~InputReader() {
24146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    for (size_t i = 0; i < mDevices.size(); i++) {
24246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        delete mDevices.valueAt(i);
24346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
24446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
24546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
24646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownvoid InputReader::loopOnce() {
247af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    int32_t oldGeneration;
248be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t timeoutMillis;
249af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    bool inputDevicesChanged = false;
250af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    Vector<InputDeviceInfo> inputDevices;
251474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    { // acquire lock
252be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        AutoMutex _l(mLock);
253be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
254af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown        oldGeneration = mGeneration;
255af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown        timeoutMillis = -1;
256af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown
257be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        uint32_t changes = mConfigurationChangesToRefresh;
258be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (changes) {
259be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mConfigurationChangesToRefresh = 0;
260af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown            timeoutMillis = 0;
261be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            refreshConfigurationLocked(changes);
262a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        } else if (mNextTimeout != LLONG_MAX) {
263be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
264be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
265be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
266474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    } // release lock
267474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown
268be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
2691a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown
270be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    { // acquire lock
271be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        AutoMutex _l(mLock);
272112b5f52c5a4b6743eeb7b26a8896c7636c74455Jeff Brown        mReaderIsAliveCondition.broadcast();
27346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
274be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (count) {
275be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            processEventsLocked(mEventBuffer, count);
276be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
277af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown
278af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown        if (mNextTimeout != LLONG_MAX) {
279be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
280112b5f52c5a4b6743eeb7b26a8896c7636c74455Jeff Brown            if (now >= mNextTimeout) {
281aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown#if DEBUG_RAW_EVENTS
282112b5f52c5a4b6743eeb7b26a8896c7636c74455Jeff Brown                ALOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
283aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown#endif
284112b5f52c5a4b6743eeb7b26a8896c7636c74455Jeff Brown                mNextTimeout = LLONG_MAX;
285112b5f52c5a4b6743eeb7b26a8896c7636c74455Jeff Brown                timeoutExpiredLocked(now);
286112b5f52c5a4b6743eeb7b26a8896c7636c74455Jeff Brown            }
287be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
288af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown
289af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown        if (oldGeneration != mGeneration) {
290af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown            inputDevicesChanged = true;
291af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown            getInputDevicesLocked(inputDevices);
292af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown        }
293be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    } // release lock
294be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
295af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    // Send out a message that the describes the changed input devices.
296af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    if (inputDevicesChanged) {
297af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown        mPolicy->notifyInputDevicesChanged(inputDevices);
298af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    }
299af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown
300be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // Flush queued events out to the listener.
301be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // This must happen outside of the lock because the listener could potentially call
302be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // back into the InputReader's methods, such as getScanCodeState, or become blocked
303be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // on another thread similarly waiting to acquire the InputReader lock thereby
304be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // resulting in a deadlock.  This situation is actually quite plausible because the
305be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // listener is actually the input dispatcher, which calls into the window manager,
306be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // which occasionally calls into the input reader.
307be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mQueuedListener->flush();
30846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
30946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
310be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
311b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown    for (const RawEvent* rawEvent = rawEvents; count;) {
312b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown        int32_t type = rawEvent->type;
313b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown        size_t batchSize = 1;
314b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown        if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
315b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown            int32_t deviceId = rawEvent->deviceId;
316b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown            while (batchSize < count) {
317b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown                if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT
318b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown                        || rawEvent[batchSize].deviceId != deviceId) {
319b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown                    break;
320b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown                }
321b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown                batchSize += 1;
322b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown            }
323b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown#if DEBUG_RAW_EVENTS
3245baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("BatchSize: %d Count: %d", batchSize, count);
325b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown#endif
326be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
327b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown        } else {
328b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown            switch (rawEvent->type) {
329b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown            case EventHubInterface::DEVICE_ADDED:
33065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                addDeviceLocked(rawEvent->when, rawEvent->deviceId);
331b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown                break;
332b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown            case EventHubInterface::DEVICE_REMOVED:
33365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                removeDeviceLocked(rawEvent->when, rawEvent->deviceId);
334b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown                break;
335b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown            case EventHubInterface::FINISHED_DEVICE_SCAN:
336be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                handleConfigurationChangedLocked(rawEvent->when);
337b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown                break;
338b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown            default:
339ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block                ALOG_ASSERT(false); // can't happen
340b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown                break;
341b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown            }
342b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown        }
343b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown        count -= batchSize;
344b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown        rawEvent += batchSize;
3456d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
3466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
34746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
34865fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid InputReader::addDeviceLocked(nsecs_t when, int32_t deviceId) {
349af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
350af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    if (deviceIndex >= 0) {
351af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown        ALOGW("Ignoring spurious device added event for deviceId %d.", deviceId);
352af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown        return;
353af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    }
354af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown
355e38fdfae9196afd1bdc14c5ec6c12793af1e2550Jeff Brown    InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceId);
3566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    uint32_t classes = mEventHub->getDeviceClasses(deviceId);
35746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
358e38fdfae9196afd1bdc14c5ec6c12793af1e2550Jeff Brown    InputDevice* device = createDeviceLocked(deviceId, identifier, classes);
35965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    device->configure(when, &mConfig, 0);
36065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    device->reset(when);
36146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3628d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    if (device->isIgnored()) {
363e38fdfae9196afd1bdc14c5ec6c12793af1e2550Jeff Brown        ALOGI("Device added: id=%d, name='%s' (ignored non-input device)", deviceId,
364e38fdfae9196afd1bdc14c5ec6c12793af1e2550Jeff Brown                identifier.name.string());
3658d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    } else {
366e38fdfae9196afd1bdc14c5ec6c12793af1e2550Jeff Brown        ALOGI("Device added: id=%d, name='%s', sources=0x%08x", deviceId,
367e38fdfae9196afd1bdc14c5ec6c12793af1e2550Jeff Brown                identifier.name.string(), device->getSources());
3688d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
3698d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
370af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    mDevices.add(deviceId, device);
371af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    bumpGenerationLocked();
37246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
37346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
37465fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid InputReader::removeDeviceLocked(nsecs_t when, int32_t deviceId) {
3756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    InputDevice* device = NULL;
376be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
377af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    if (deviceIndex < 0) {
3788564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("Ignoring spurious device removed event for deviceId %d.", deviceId);
3796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        return;
3806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
38146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
382af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    device = mDevices.valueAt(deviceIndex);
383af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    mDevices.removeItemsAt(deviceIndex, 1);
384af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    bumpGenerationLocked();
385af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown
3866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (device->isIgnored()) {
3876215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block        ALOGI("Device removed: id=%d, name='%s' (ignored non-input device)",
3886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                device->getId(), device->getName().string());
3896d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    } else {
3906215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block        ALOGI("Device removed: id=%d, name='%s', sources=0x%08x",
3916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                device->getId(), device->getName().string(), device->getSources());
39246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
3936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
39465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    device->reset(when);
3956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    delete device;
39646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
39746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
398be1aa8250cee7819c49741e819e81659d1d03823Jeff BrownInputDevice* InputReader::createDeviceLocked(int32_t deviceId,
399e38fdfae9196afd1bdc14c5ec6c12793af1e2550Jeff Brown        const InputDeviceIdentifier& identifier, uint32_t classes) {
400af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    InputDevice* device = new InputDevice(&mContext, deviceId, bumpGenerationLocked(),
401af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown            identifier, classes);
40246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
40356194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // External devices.
40456194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    if (classes & INPUT_DEVICE_CLASS_EXTERNAL) {
40556194ebec6212e229f4ccdaa4b187166d20013efJeff Brown        device->setExternal(true);
40656194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    }
40756194ebec6212e229f4ccdaa4b187166d20013efJeff Brown
4086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // Switch-like devices.
4096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (classes & INPUT_DEVICE_CLASS_SWITCH) {
4106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        device->addMapper(new SwitchInputMapper(device));
411fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown    }
412fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown
413a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    // Vibrator-like devices.
414a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    if (classes & INPUT_DEVICE_CLASS_VIBRATOR) {
415a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        device->addMapper(new VibratorInputMapper(device));
416a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    }
417a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
4186d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // Keyboard-like devices.
419efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown    uint32_t keyboardSource = 0;
4206d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
4216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (classes & INPUT_DEVICE_CLASS_KEYBOARD) {
422efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown        keyboardSource |= AINPUT_SOURCE_KEYBOARD;
4236d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
4246d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (classes & INPUT_DEVICE_CLASS_ALPHAKEY) {
4256d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC;
4266d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
4276d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (classes & INPUT_DEVICE_CLASS_DPAD) {
428efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown        keyboardSource |= AINPUT_SOURCE_DPAD;
4296d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
430cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    if (classes & INPUT_DEVICE_CLASS_GAMEPAD) {
431efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown        keyboardSource |= AINPUT_SOURCE_GAMEPAD;
432cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
433fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown
434efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown    if (keyboardSource != 0) {
435efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown        device->addMapper(new KeyboardInputMapper(device, keyboardSource, keyboardType));
436fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown    }
43746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
43883c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    // Cursor-like devices.
43983c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    if (classes & INPUT_DEVICE_CLASS_CURSOR) {
44083c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        device->addMapper(new CursorInputMapper(device));
4416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
44246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
44358a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown    // Touchscreens and touchpad devices.
44458a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown    if (classes & INPUT_DEVICE_CLASS_TOUCH_MT) {
44547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        device->addMapper(new MultiTouchInputMapper(device));
44658a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown    } else if (classes & INPUT_DEVICE_CLASS_TOUCH) {
44747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        device->addMapper(new SingleTouchInputMapper(device));
44846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
4496d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
450cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    // Joystick-like devices.
451cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    if (classes & INPUT_DEVICE_CLASS_JOYSTICK) {
452cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        device->addMapper(new JoystickInputMapper(device));
453cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
454cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
4556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return device;
45646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
45746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
458be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputReader::processEventsForDeviceLocked(int32_t deviceId,
459b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown        const RawEvent* rawEvents, size_t count) {
460be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
461be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (deviceIndex < 0) {
4628564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("Discarding event for unknown deviceId %d.", deviceId);
463be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        return;
464be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
4656d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
466be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    InputDevice* device = mDevices.valueAt(deviceIndex);
467be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (device->isIgnored()) {
4685baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        //ALOGD("Discarding event for ignored deviceId %d.", deviceId);
469be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        return;
470be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
4716d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
472be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    device->process(rawEvents, count);
47346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
47446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
475be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputReader::timeoutExpiredLocked(nsecs_t when) {
476be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (size_t i = 0; i < mDevices.size(); i++) {
477be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        InputDevice* device = mDevices.valueAt(i);
478be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (!device->isIgnored()) {
479be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            device->timeoutExpired(when);
480aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown        }
481be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
482aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown}
483aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown
484be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputReader::handleConfigurationChangedLocked(nsecs_t when) {
4856d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // Reset global meta state because it depends on the list of all configured devices.
486be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    updateGlobalMetaStateLocked();
4876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
4886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // Enqueue configuration changed.
489be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    NotifyConfigurationChangedArgs args(when);
490be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mQueuedListener->notifyConfigurationChanged(&args);
49146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
49246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
493be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputReader::refreshConfigurationLocked(uint32_t changes) {
4941a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown    mPolicy->getReaderConfiguration(&mConfig);
4951a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown    mEventHub->setExcludedDevices(mConfig.excludedDeviceNames);
4961a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown
497474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    if (changes) {
4986215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block        ALOGI("Reconfiguring input devices.  changes=0x%08x", changes);
49965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
500474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown
501474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        if (changes & InputReaderConfiguration::CHANGE_MUST_REOPEN) {
502474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mEventHub->requestReopenDevices();
503474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        } else {
5046d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            for (size_t i = 0; i < mDevices.size(); i++) {
5056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                InputDevice* device = mDevices.valueAt(i);
50665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                device->configure(now, &mConfig, changes);
5076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
508be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
509be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
5106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
51146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
512be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputReader::updateGlobalMetaStateLocked() {
513be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mGlobalMetaState = 0;
51446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
515be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (size_t i = 0; i < mDevices.size(); i++) {
516be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        InputDevice* device = mDevices.valueAt(i);
517be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mGlobalMetaState |= device->getMetaState();
518be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
5196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
52046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
521be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownint32_t InputReader::getGlobalMetaStateLocked() {
522be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return mGlobalMetaState;
523be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
52446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
525be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputReader::disableVirtualKeysUntilLocked(nsecs_t time) {
526fe50892af3b365806a767298dfd8e86447682581Jeff Brown    mDisableVirtualKeysTimeout = time;
527fe50892af3b365806a767298dfd8e86447682581Jeff Brown}
528fe50892af3b365806a767298dfd8e86447682581Jeff Brown
529be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownbool InputReader::shouldDropVirtualKeyLocked(nsecs_t now,
530fe50892af3b365806a767298dfd8e86447682581Jeff Brown        InputDevice* device, int32_t keyCode, int32_t scanCode) {
531fe50892af3b365806a767298dfd8e86447682581Jeff Brown    if (now < mDisableVirtualKeysTimeout) {
5326215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block        ALOGI("Dropping virtual key from device %s because virtual keys are "
533fe50892af3b365806a767298dfd8e86447682581Jeff Brown                "temporarily disabled for the next %0.3fms.  keyCode=%d, scanCode=%d",
534fe50892af3b365806a767298dfd8e86447682581Jeff Brown                device->getName().string(),
535fe50892af3b365806a767298dfd8e86447682581Jeff Brown                (mDisableVirtualKeysTimeout - now) * 0.000001,
536fe50892af3b365806a767298dfd8e86447682581Jeff Brown                keyCode, scanCode);
537fe50892af3b365806a767298dfd8e86447682581Jeff Brown        return true;
538fe50892af3b365806a767298dfd8e86447682581Jeff Brown    } else {
539fe50892af3b365806a767298dfd8e86447682581Jeff Brown        return false;
540fe50892af3b365806a767298dfd8e86447682581Jeff Brown    }
541fe50892af3b365806a767298dfd8e86447682581Jeff Brown}
542fe50892af3b365806a767298dfd8e86447682581Jeff Brown
543be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputReader::fadePointerLocked() {
544be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (size_t i = 0; i < mDevices.size(); i++) {
545be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        InputDevice* device = mDevices.valueAt(i);
546be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        device->fadePointer();
547be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
54805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown}
54905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
550be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputReader::requestTimeoutAtTimeLocked(nsecs_t when) {
551aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown    if (when < mNextTimeout) {
552aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown        mNextTimeout = when;
553a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        mEventHub->wake();
554aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown    }
555aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown}
556aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown
557af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownint32_t InputReader::bumpGenerationLocked() {
558af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    return ++mGeneration;
559af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown}
560af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown
561af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownvoid InputReader::getInputDevices(Vector<InputDeviceInfo>& outInputDevices) {
562be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    AutoMutex _l(mLock);
563af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    getInputDevicesLocked(outInputDevices);
5646d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
56546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
566af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownvoid InputReader::getInputDevicesLocked(Vector<InputDeviceInfo>& outInputDevices) {
567af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    outInputDevices.clear();
56846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
569be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    size_t numDevices = mDevices.size();
570be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (size_t i = 0; i < numDevices; i++) {
571be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        InputDevice* device = mDevices.valueAt(i);
572be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (!device->isIgnored()) {
573af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown            outInputDevices.push();
574af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown            device->getDeviceInfo(&outInputDevices.editTop());
57546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
576be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
5776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
57846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
5806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        int32_t keyCode) {
581be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    AutoMutex _l(mLock);
582be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
583be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return getStateLocked(deviceId, sourceMask, keyCode, &InputDevice::getKeyCodeState);
5846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
585c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown
5866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputReader::getScanCodeState(int32_t deviceId, uint32_t sourceMask,
5876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        int32_t scanCode) {
588be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    AutoMutex _l(mLock);
589be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
590be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return getStateLocked(deviceId, sourceMask, scanCode, &InputDevice::getScanCodeState);
5916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
592c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown
5936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputReader::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t switchCode) {
594be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    AutoMutex _l(mLock);
595be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
596be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return getStateLocked(deviceId, sourceMask, switchCode, &InputDevice::getSwitchState);
5976d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
598c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown
599be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownint32_t InputReader::getStateLocked(int32_t deviceId, uint32_t sourceMask, int32_t code,
6006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        GetStateFunc getStateFunc) {
601be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t result = AKEY_STATE_UNKNOWN;
602be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (deviceId >= 0) {
603be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
604be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (deviceIndex >= 0) {
605be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            InputDevice* device = mDevices.valueAt(deviceIndex);
606be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
607be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                result = (device->*getStateFunc)(sourceMask, code);
6086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
609be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
610be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    } else {
611be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        size_t numDevices = mDevices.size();
612be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        for (size_t i = 0; i < numDevices; i++) {
613be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            InputDevice* device = mDevices.valueAt(i);
614be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
615fbca596721ea19daa2972639095898ce62100490David Deephanphongs                // If any device reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
616fbca596721ea19daa2972639095898ce62100490David Deephanphongs                // value.  Otherwise, return AKEY_STATE_UP as long as one device reports it.
617fbca596721ea19daa2972639095898ce62100490David Deephanphongs                int32_t currentResult = (device->*getStateFunc)(sourceMask, code);
618fbca596721ea19daa2972639095898ce62100490David Deephanphongs                if (currentResult >= AKEY_STATE_DOWN) {
619fbca596721ea19daa2972639095898ce62100490David Deephanphongs                    return currentResult;
620fbca596721ea19daa2972639095898ce62100490David Deephanphongs                } else if (currentResult == AKEY_STATE_UP) {
621fbca596721ea19daa2972639095898ce62100490David Deephanphongs                    result = currentResult;
6226d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
6236d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
6246d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
625be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
626be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return result;
6276d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
62846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
6296d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownbool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask,
6306d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
631be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    AutoMutex _l(mLock);
632be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
6336d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    memset(outFlags, 0, numCodes);
634be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return markSupportedKeyCodesLocked(deviceId, sourceMask, numCodes, keyCodes, outFlags);
6356d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
63646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
637be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownbool InputReader::markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask,
638be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
639be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    bool result = false;
640be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (deviceId >= 0) {
641be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
642be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (deviceIndex >= 0) {
643be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            InputDevice* device = mDevices.valueAt(deviceIndex);
644be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
645be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                result = device->markSupportedKeyCodes(sourceMask,
646be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        numCodes, keyCodes, outFlags);
6476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
648be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
649be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    } else {
650be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        size_t numDevices = mDevices.size();
651be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        for (size_t i = 0; i < numDevices; i++) {
652be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            InputDevice* device = mDevices.valueAt(i);
653be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
654be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                result |= device->markSupportedKeyCodes(sourceMask,
655be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        numCodes, keyCodes, outFlags);
65646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            }
65746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
658be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
659be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return result;
6606d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
66146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
662474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brownvoid InputReader::requestRefreshConfiguration(uint32_t changes) {
663be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    AutoMutex _l(mLock);
664474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown
665be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (changes) {
666be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        bool needWake = !mConfigurationChangesToRefresh;
667be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mConfigurationChangesToRefresh |= changes;
66893fa9b30b91f75ee161d0791ff17f98d1a603812Jeff Brown
669474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        if (needWake) {
670474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mEventHub->wake();
671474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        }
672474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    }
6731a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown}
6741a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown
675a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid InputReader::vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
676a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        ssize_t repeat, int32_t token) {
677a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    AutoMutex _l(mLock);
678a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
679a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
680a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    if (deviceIndex >= 0) {
681a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        InputDevice* device = mDevices.valueAt(deviceIndex);
682a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        device->vibrate(pattern, patternSize, repeat, token);
683a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    }
684a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
685a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
686a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid InputReader::cancelVibrate(int32_t deviceId, int32_t token) {
687a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    AutoMutex _l(mLock);
688a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
689a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
690a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    if (deviceIndex >= 0) {
691a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        InputDevice* device = mDevices.valueAt(deviceIndex);
692a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        device->cancelVibrate(token);
693a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    }
694a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
695a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
696b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownvoid InputReader::dump(String8& dump) {
697be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    AutoMutex _l(mLock);
698be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
699f2f487183052865d50c004a835360be1728b5a52Jeff Brown    mEventHub->dump(dump);
700f2f487183052865d50c004a835360be1728b5a52Jeff Brown    dump.append("\n");
701f2f487183052865d50c004a835360be1728b5a52Jeff Brown
702f2f487183052865d50c004a835360be1728b5a52Jeff Brown    dump.append("Input Reader State:\n");
703f2f487183052865d50c004a835360be1728b5a52Jeff Brown
704be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (size_t i = 0; i < mDevices.size(); i++) {
705be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mDevices.valueAt(i)->dump(dump);
706be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
707214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown
708214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.append(INDENT "Configuration:\n");
709214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.append(INDENT2 "ExcludedDeviceNames: [");
710214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    for (size_t i = 0; i < mConfig.excludedDeviceNames.size(); i++) {
711214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown        if (i != 0) {
712214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown            dump.append(", ");
713214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown        }
714214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown        dump.append(mConfig.excludedDeviceNames.itemAt(i).string());
715214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    }
716214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.append("]\n");
717214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT2 "VirtualKeyQuietTime: %0.1fms\n",
718214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown            mConfig.virtualKeyQuietTime * 0.000001f);
719214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown
72019c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown    dump.appendFormat(INDENT2 "PointerVelocityControlParameters: "
72119c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, acceleration=%0.3f\n",
72219c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            mConfig.pointerVelocityControlParameters.scale,
72319c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            mConfig.pointerVelocityControlParameters.lowThreshold,
72419c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            mConfig.pointerVelocityControlParameters.highThreshold,
72519c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            mConfig.pointerVelocityControlParameters.acceleration);
72619c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown
72719c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown    dump.appendFormat(INDENT2 "WheelVelocityControlParameters: "
72819c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, acceleration=%0.3f\n",
72919c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            mConfig.wheelVelocityControlParameters.scale,
73019c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            mConfig.wheelVelocityControlParameters.lowThreshold,
73119c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            mConfig.wheelVelocityControlParameters.highThreshold,
73219c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            mConfig.wheelVelocityControlParameters.acceleration);
73319c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown
734214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT2 "PointerGesture:\n");
735474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    dump.appendFormat(INDENT3 "Enabled: %s\n",
736474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            toString(mConfig.pointerGesturesEnabled));
737214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT3 "QuietInterval: %0.1fms\n",
738214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown            mConfig.pointerGestureQuietInterval * 0.000001f);
739214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT3 "DragMinSwitchSpeed: %0.1fpx/s\n",
740214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown            mConfig.pointerGestureDragMinSwitchSpeed);
741214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT3 "TapInterval: %0.1fms\n",
742214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown            mConfig.pointerGestureTapInterval * 0.000001f);
743214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT3 "TapDragInterval: %0.1fms\n",
744214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown            mConfig.pointerGestureTapDragInterval * 0.000001f);
745214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT3 "TapSlop: %0.1fpx\n",
746214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown            mConfig.pointerGestureTapSlop);
747214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT3 "MultitouchSettleInterval: %0.1fms\n",
748214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown            mConfig.pointerGestureMultitouchSettleInterval * 0.000001f);
749bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown    dump.appendFormat(INDENT3 "MultitouchMinDistance: %0.1fpx\n",
750bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            mConfig.pointerGestureMultitouchMinDistance);
751214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT3 "SwipeTransitionAngleCosine: %0.1f\n",
752214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown            mConfig.pointerGestureSwipeTransitionAngleCosine);
753214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT3 "SwipeMaxWidthRatio: %0.1f\n",
754214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown            mConfig.pointerGestureSwipeMaxWidthRatio);
755214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT3 "MovementSpeedRatio: %0.1f\n",
756214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown            mConfig.pointerGestureMovementSpeedRatio);
757214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT3 "ZoomSpeedRatio: %0.1f\n",
758214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown            mConfig.pointerGestureZoomSpeedRatio);
759b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
760b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
76189ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brownvoid InputReader::monitor() {
76289ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown    // Acquire and release the lock to ensure that the reader has not deadlocked.
76389ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown    mLock.lock();
764112b5f52c5a4b6743eeb7b26a8896c7636c74455Jeff Brown    mEventHub->wake();
765112b5f52c5a4b6743eeb7b26a8896c7636c74455Jeff Brown    mReaderIsAliveCondition.wait(mLock);
76689ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown    mLock.unlock();
76789ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown
76889ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown    // Check the EventHub
76989ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown    mEventHub->monitor();
77089ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown}
77189ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown
77246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
773be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown// --- InputReader::ContextImpl ---
774be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
775be1aa8250cee7819c49741e819e81659d1d03823Jeff BrownInputReader::ContextImpl::ContextImpl(InputReader* reader) :
776be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mReader(reader) {
777be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
778be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
779be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputReader::ContextImpl::updateGlobalMetaState() {
780be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // lock is already held by the input loop
781be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mReader->updateGlobalMetaStateLocked();
782be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
783be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
784be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownint32_t InputReader::ContextImpl::getGlobalMetaState() {
785be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // lock is already held by the input loop
786be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return mReader->getGlobalMetaStateLocked();
787be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
788be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
789be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputReader::ContextImpl::disableVirtualKeysUntil(nsecs_t time) {
790be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // lock is already held by the input loop
791be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mReader->disableVirtualKeysUntilLocked(time);
792be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
793be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
794be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownbool InputReader::ContextImpl::shouldDropVirtualKey(nsecs_t now,
795be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        InputDevice* device, int32_t keyCode, int32_t scanCode) {
796be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // lock is already held by the input loop
797be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return mReader->shouldDropVirtualKeyLocked(now, device, keyCode, scanCode);
798be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
799be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
800be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputReader::ContextImpl::fadePointer() {
801be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // lock is already held by the input loop
802be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mReader->fadePointerLocked();
803be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
804be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
805be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputReader::ContextImpl::requestTimeoutAtTime(nsecs_t when) {
806be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // lock is already held by the input loop
807be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mReader->requestTimeoutAtTimeLocked(when);
808be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
809be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
810af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownint32_t InputReader::ContextImpl::bumpGeneration() {
811af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    // lock is already held by the input loop
812af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    return mReader->bumpGenerationLocked();
813af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown}
814af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown
815be1aa8250cee7819c49741e819e81659d1d03823Jeff BrownInputReaderPolicyInterface* InputReader::ContextImpl::getPolicy() {
816be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return mReader->mPolicy.get();
817be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
818be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
819be1aa8250cee7819c49741e819e81659d1d03823Jeff BrownInputListenerInterface* InputReader::ContextImpl::getListener() {
820be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return mReader->mQueuedListener.get();
821be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
822be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
823be1aa8250cee7819c49741e819e81659d1d03823Jeff BrownEventHubInterface* InputReader::ContextImpl::getEventHub() {
824be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return mReader->mEventHub.get();
825be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
826be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
827be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
8286d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown// --- InputReaderThread ---
82946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
8306d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownInputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) :
8316d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        Thread(/*canCallJava*/ true), mReader(reader) {
83246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
83346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
8346d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownInputReaderThread::~InputReaderThread() {
8356d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
83646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
8376d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownbool InputReaderThread::threadLoop() {
8386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mReader->loopOnce();
8396d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return true;
8406d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
84146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
84246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
8436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown// --- InputDevice ---
84446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
845af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff BrownInputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
846e38fdfae9196afd1bdc14c5ec6c12793af1e2550Jeff Brown        const InputDeviceIdentifier& identifier, uint32_t classes) :
847af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown        mContext(context), mId(id), mGeneration(generation),
848af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown        mIdentifier(identifier), mClasses(classes),
8499ee285afe740ff13d176c9d8430979dfd9575a23Jeff Brown        mSources(0), mIsExternal(false), mDropUntilNextSync(false) {
8506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
85146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
8526d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownInputDevice::~InputDevice() {
8536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    size_t numMappers = mMappers.size();
8546d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
8556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        delete mMappers[i];
85646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
8576d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mMappers.clear();
8586d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
85946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
860ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brownvoid InputDevice::dump(String8& dump) {
861ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    InputDeviceInfo deviceInfo;
862ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    getDeviceInfo(& deviceInfo);
863ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
8649065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown    dump.appendFormat(INDENT "Device %d: %s\n", deviceInfo.getId(),
8655bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown            deviceInfo.getDisplayName().string());
866af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    dump.appendFormat(INDENT2 "Generation: %d\n", mGeneration);
86756194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    dump.appendFormat(INDENT2 "IsExternal: %s\n", toString(mIsExternal));
868ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
869ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    dump.appendFormat(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
870cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown
871efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown    const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
872cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown    if (!ranges.isEmpty()) {
873ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT2 "Motion Ranges:\n");
874cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown        for (size_t i = 0; i < ranges.size(); i++) {
875efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown            const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
876efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown            const char* label = getAxisLabel(range.axis);
877cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown            char name[32];
878cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown            if (label) {
879cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown                strncpy(name, label, sizeof(name));
880cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown                name[sizeof(name) - 1] = '\0';
881cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown            } else {
882efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown                snprintf(name, sizeof(name), "%d", range.axis);
883cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown            }
884efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown            dump.appendFormat(INDENT3 "%s: source=0x%08x, "
885efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown                    "min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f\n",
886efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown                    name, range.source, range.min, range.max, range.flat, range.fuzz);
887cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown        }
888ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    }
889ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
890ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    size_t numMappers = mMappers.size();
891ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
892ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        InputMapper* mapper = mMappers[i];
893ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        mapper->dump(dump);
894ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    }
895ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown}
896ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
8976d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid InputDevice::addMapper(InputMapper* mapper) {
8986d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mMappers.add(mapper);
8996d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
900349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown
90165fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes) {
9026d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mSources = 0;
9036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
904474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    if (!isIgnored()) {
905474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        if (!changes) { // first time only
906474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mContext->getEventHub()->getConfiguration(mId, &mConfiguration);
907474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        }
908474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown
9096ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown        if (!changes || (changes & InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS)) {
91061c08240585a6186b4bd879d87f238b3efc368f8Jeff Brown            if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
91161c08240585a6186b4bd879d87f238b3efc368f8Jeff Brown                sp<KeyCharacterMap> keyboardLayout =
91261c08240585a6186b4bd879d87f238b3efc368f8Jeff Brown                        mContext->getPolicy()->getKeyboardLayoutOverlay(mIdentifier.descriptor);
91361c08240585a6186b4bd879d87f238b3efc368f8Jeff Brown                if (mContext->getEventHub()->setKeyboardLayoutOverlay(mId, keyboardLayout)) {
91461c08240585a6186b4bd879d87f238b3efc368f8Jeff Brown                    bumpGeneration();
91561c08240585a6186b4bd879d87f238b3efc368f8Jeff Brown                }
9166ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown            }
9176ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown        }
9186ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown
9195bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown        if (!changes || (changes & InputReaderConfiguration::CHANGE_DEVICE_ALIAS)) {
9205bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown            if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
9215bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown                String8 alias = mContext->getPolicy()->getDeviceAlias(mIdentifier);
9225bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown                if (mAlias != alias) {
9235bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown                    mAlias = alias;
9245bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown                    bumpGeneration();
9255bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown                }
9265bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown            }
9275bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown        }
9285bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown
929474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        size_t numMappers = mMappers.size();
930474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        for (size_t i = 0; i < numMappers; i++) {
931474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            InputMapper* mapper = mMappers[i];
93265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mapper->configure(when, config, changes);
933474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mSources |= mapper->getSources();
934474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        }
935349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown    }
9366d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
937349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown
93865fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid InputDevice::reset(nsecs_t when) {
9396d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    size_t numMappers = mMappers.size();
9406d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
9416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        InputMapper* mapper = mMappers[i];
94265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mapper->reset(when);
943349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown    }
94465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
94565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mContext->updateGlobalMetaState();
94665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
94765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    notifyReset(when);
9486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
949349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown
950b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brownvoid InputDevice::process(const RawEvent* rawEvents, size_t count) {
951b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown    // Process all of the events in order for each mapper.
952b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown    // We cannot simply ask each mapper to process them in bulk because mappers may
953b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown    // have side-effects that must be interleaved.  For example, joystick movement events and
954b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown    // gamepad button presses are handled by different mappers but they should be dispatched
955b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown    // in the order received.
9566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    size_t numMappers = mMappers.size();
957b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown    for (const RawEvent* rawEvent = rawEvents; count--; rawEvent++) {
958b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown#if DEBUG_RAW_EVENTS
959f33b2b2b2483fa824c650b281159ca62e1d0123aJeff Brown        ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%lld",
960f33b2b2b2483fa824c650b281159ca62e1d0123aJeff Brown                rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value,
961f33b2b2b2483fa824c650b281159ca62e1d0123aJeff Brown                rawEvent->when);
962b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown#endif
963b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown
96480fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        if (mDropUntilNextSync) {
96549ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown            if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
96680fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                mDropUntilNextSync = false;
96780fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown#if DEBUG_RAW_EVENTS
9685baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Recovered from input event buffer overrun.");
96980fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown#endif
97080fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            } else {
97180fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown#if DEBUG_RAW_EVENTS
9725baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Dropped input event while waiting for next input sync.");
97380fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown#endif
97480fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            }
97549ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
976e38fdfae9196afd1bdc14c5ec6c12793af1e2550Jeff Brown            ALOGI("Detected input event buffer overrun for device %s.", getName().string());
97780fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            mDropUntilNextSync = true;
97865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            reset(rawEvent->when);
97980fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        } else {
98080fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            for (size_t i = 0; i < numMappers; i++) {
98180fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                InputMapper* mapper = mMappers[i];
98280fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                mapper->process(rawEvent);
98380fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            }
984b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown        }
98546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
9866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
98746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
988aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brownvoid InputDevice::timeoutExpired(nsecs_t when) {
989aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown    size_t numMappers = mMappers.size();
990aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown    for (size_t i = 0; i < numMappers; i++) {
991aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown        InputMapper* mapper = mMappers[i];
992aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown        mapper->timeoutExpired(when);
993aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown    }
994aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown}
995aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown
9966d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
997daa3753a04699724d2cfe824ac1f5a266d643a05Jeff Brown    outDeviceInfo->initialize(mId, mGeneration, mIdentifier, mAlias, mIsExternal);
99846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
9996d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    size_t numMappers = mMappers.size();
10006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
10016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        InputMapper* mapper = mMappers[i];
10026d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mapper->populateDeviceInfo(outDeviceInfo);
100346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
100446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
100546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
10066d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputDevice::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
10076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return getState(sourceMask, keyCode, & InputMapper::getKeyCodeState);
10086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
100946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
10106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputDevice::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
10116d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return getState(sourceMask, scanCode, & InputMapper::getScanCodeState);
10126d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
101346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
10146d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputDevice::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
10156d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return getState(sourceMask, switchCode, & InputMapper::getSwitchState);
10166d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
101746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
10186d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) {
10196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    int32_t result = AKEY_STATE_UNKNOWN;
10206d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    size_t numMappers = mMappers.size();
10216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
10226d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        InputMapper* mapper = mMappers[i];
10236d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
1024fbca596721ea19daa2972639095898ce62100490David Deephanphongs            // If any mapper reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
1025fbca596721ea19daa2972639095898ce62100490David Deephanphongs            // value.  Otherwise, return AKEY_STATE_UP as long as one mapper reports it.
1026fbca596721ea19daa2972639095898ce62100490David Deephanphongs            int32_t currentResult = (mapper->*getStateFunc)(sourceMask, code);
1027fbca596721ea19daa2972639095898ce62100490David Deephanphongs            if (currentResult >= AKEY_STATE_DOWN) {
1028fbca596721ea19daa2972639095898ce62100490David Deephanphongs                return currentResult;
1029fbca596721ea19daa2972639095898ce62100490David Deephanphongs            } else if (currentResult == AKEY_STATE_UP) {
1030fbca596721ea19daa2972639095898ce62100490David Deephanphongs                result = currentResult;
10316d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
103246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
103346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
10346d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return result;
10356d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
103646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
10376d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownbool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
10386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        const int32_t* keyCodes, uint8_t* outFlags) {
10396d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    bool result = false;
10406d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    size_t numMappers = mMappers.size();
10416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
10426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        InputMapper* mapper = mMappers[i];
10436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
10446d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            result |= mapper->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
104546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
104646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
10476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return result;
10486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
104946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1050a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid InputDevice::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
1051a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        int32_t token) {
1052a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    size_t numMappers = mMappers.size();
1053a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
1054a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        InputMapper* mapper = mMappers[i];
1055a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        mapper->vibrate(pattern, patternSize, repeat, token);
1056a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    }
1057a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1058a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1059a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid InputDevice::cancelVibrate(int32_t token) {
1060a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    size_t numMappers = mMappers.size();
1061a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
1062a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        InputMapper* mapper = mMappers[i];
1063a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        mapper->cancelVibrate(token);
1064a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    }
1065a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1066a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
10676d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputDevice::getMetaState() {
10686d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    int32_t result = 0;
10696d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    size_t numMappers = mMappers.size();
10706d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
10716d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        InputMapper* mapper = mMappers[i];
10726d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        result |= mapper->getMetaState();
107346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
10746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return result;
10756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
107646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
107705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownvoid InputDevice::fadePointer() {
107805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    size_t numMappers = mMappers.size();
107905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    for (size_t i = 0; i < numMappers; i++) {
108005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        InputMapper* mapper = mMappers[i];
108105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        mapper->fadePointer();
108205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    }
108305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown}
108405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
1085af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownvoid InputDevice::bumpGeneration() {
1086af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    mGeneration = mContext->bumpGeneration();
1087af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown}
1088af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown
108965fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid InputDevice::notifyReset(nsecs_t when) {
109065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    NotifyDeviceResetArgs args(when, mId);
109165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mContext->getListener()->notifyDeviceReset(&args);
109265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
109365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
109446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
109549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown// --- CursorButtonAccumulator ---
109649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
109749754db5a304d995c1cc108ff6f19e4ba4265572Jeff BrownCursorButtonAccumulator::CursorButtonAccumulator() {
109849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    clearButtons();
109949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
110049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
110165fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid CursorButtonAccumulator::reset(InputDevice* device) {
110265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnLeft = device->isKeyPressed(BTN_LEFT);
110365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnRight = device->isKeyPressed(BTN_RIGHT);
110465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnMiddle = device->isKeyPressed(BTN_MIDDLE);
110565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnBack = device->isKeyPressed(BTN_BACK);
110665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnSide = device->isKeyPressed(BTN_SIDE);
110765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnForward = device->isKeyPressed(BTN_FORWARD);
110865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnExtra = device->isKeyPressed(BTN_EXTRA);
110965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnTask = device->isKeyPressed(BTN_TASK);
111065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
111165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
111249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownvoid CursorButtonAccumulator::clearButtons() {
111349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnLeft = 0;
111449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnRight = 0;
111549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnMiddle = 0;
111649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnBack = 0;
111749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnSide = 0;
111849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnForward = 0;
111949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnExtra = 0;
112049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnTask = 0;
112149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
112249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
112349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownvoid CursorButtonAccumulator::process(const RawEvent* rawEvent) {
112449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (rawEvent->type == EV_KEY) {
112549ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        switch (rawEvent->code) {
112649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_LEFT:
112749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnLeft = rawEvent->value;
112849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
112949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_RIGHT:
113049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnRight = rawEvent->value;
113149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
113249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_MIDDLE:
113349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnMiddle = rawEvent->value;
113449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
113549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_BACK:
113649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnBack = rawEvent->value;
113749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
113849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_SIDE:
113949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnSide = rawEvent->value;
114049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
114149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_FORWARD:
114249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnForward = rawEvent->value;
114349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
114449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_EXTRA:
114549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnExtra = rawEvent->value;
114649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
114749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_TASK:
114849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnTask = rawEvent->value;
114949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
115049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        }
115149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
115249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
115349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
115449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownuint32_t CursorButtonAccumulator::getButtonState() const {
115549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    uint32_t result = 0;
115649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (mBtnLeft) {
115749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        result |= AMOTION_EVENT_BUTTON_PRIMARY;
115849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
115949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (mBtnRight) {
116049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        result |= AMOTION_EVENT_BUTTON_SECONDARY;
116149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
116249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (mBtnMiddle) {
116349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        result |= AMOTION_EVENT_BUTTON_TERTIARY;
116449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
116549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (mBtnBack || mBtnSide) {
116649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        result |= AMOTION_EVENT_BUTTON_BACK;
116749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
116849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (mBtnForward || mBtnExtra) {
116949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        result |= AMOTION_EVENT_BUTTON_FORWARD;
117049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
117149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    return result;
117249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
117349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
117449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
117549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown// --- CursorMotionAccumulator ---
117649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
117765fd251c3913fc921468a3dad190810db19eb9dfJeff BrownCursorMotionAccumulator::CursorMotionAccumulator() {
117849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    clearRelativeAxes();
117949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
118049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
118165fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid CursorMotionAccumulator::reset(InputDevice* device) {
118265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    clearRelativeAxes();
118349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
118449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
118549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownvoid CursorMotionAccumulator::clearRelativeAxes() {
118649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mRelX = 0;
118749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mRelY = 0;
118849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
118949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
119049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownvoid CursorMotionAccumulator::process(const RawEvent* rawEvent) {
119149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (rawEvent->type == EV_REL) {
119249ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        switch (rawEvent->code) {
119349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case REL_X:
119449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mRelX = rawEvent->value;
119549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
119649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case REL_Y:
119749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mRelY = rawEvent->value;
119849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
119965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
120065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
120165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
120265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
120365fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid CursorMotionAccumulator::finishSync() {
120465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    clearRelativeAxes();
120565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
120665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
120765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
120865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown// --- CursorScrollAccumulator ---
120965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
121065fd251c3913fc921468a3dad190810db19eb9dfJeff BrownCursorScrollAccumulator::CursorScrollAccumulator() :
121165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mHaveRelWheel(false), mHaveRelHWheel(false) {
121265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    clearRelativeAxes();
121365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
121465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
121565fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid CursorScrollAccumulator::configure(InputDevice* device) {
121665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mHaveRelWheel = device->getEventHub()->hasRelativeAxis(device->getId(), REL_WHEEL);
121765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mHaveRelHWheel = device->getEventHub()->hasRelativeAxis(device->getId(), REL_HWHEEL);
121865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
121965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
122065fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid CursorScrollAccumulator::reset(InputDevice* device) {
122165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    clearRelativeAxes();
122265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
122365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
122465fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid CursorScrollAccumulator::clearRelativeAxes() {
122565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mRelWheel = 0;
122665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mRelHWheel = 0;
122765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
122865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
122965fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid CursorScrollAccumulator::process(const RawEvent* rawEvent) {
123065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (rawEvent->type == EV_REL) {
123149ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        switch (rawEvent->code) {
123249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case REL_WHEEL:
123349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mRelWheel = rawEvent->value;
123449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
123549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case REL_HWHEEL:
123649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mRelHWheel = rawEvent->value;
123749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
123849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        }
123949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
124049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
124149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
124265fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid CursorScrollAccumulator::finishSync() {
124365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    clearRelativeAxes();
124465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
124565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
124649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
124749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown// --- TouchButtonAccumulator ---
124849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
124949754db5a304d995c1cc108ff6f19e4ba4265572Jeff BrownTouchButtonAccumulator::TouchButtonAccumulator() :
125000710e906bdafd58386ee7f81fa84addd218122fJeff Brown        mHaveBtnTouch(false), mHaveStylus(false) {
125149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    clearButtons();
125249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
125349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
125449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownvoid TouchButtonAccumulator::configure(InputDevice* device) {
125565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mHaveBtnTouch = device->hasKey(BTN_TOUCH);
125600710e906bdafd58386ee7f81fa84addd218122fJeff Brown    mHaveStylus = device->hasKey(BTN_TOOL_PEN)
125700710e906bdafd58386ee7f81fa84addd218122fJeff Brown            || device->hasKey(BTN_TOOL_RUBBER)
125800710e906bdafd58386ee7f81fa84addd218122fJeff Brown            || device->hasKey(BTN_TOOL_BRUSH)
125900710e906bdafd58386ee7f81fa84addd218122fJeff Brown            || device->hasKey(BTN_TOOL_PENCIL)
126000710e906bdafd58386ee7f81fa84addd218122fJeff Brown            || device->hasKey(BTN_TOOL_AIRBRUSH);
126165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
126265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
126365fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchButtonAccumulator::reset(InputDevice* device) {
126465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnTouch = device->isKeyPressed(BTN_TOUCH);
126565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnStylus = device->isKeyPressed(BTN_STYLUS);
126665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnStylus2 = device->isKeyPressed(BTN_STYLUS);
126765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolFinger = device->isKeyPressed(BTN_TOOL_FINGER);
126865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolPen = device->isKeyPressed(BTN_TOOL_PEN);
126965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolRubber = device->isKeyPressed(BTN_TOOL_RUBBER);
127065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolBrush = device->isKeyPressed(BTN_TOOL_BRUSH);
127165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolPencil = device->isKeyPressed(BTN_TOOL_PENCIL);
127265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolAirbrush = device->isKeyPressed(BTN_TOOL_AIRBRUSH);
127365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolMouse = device->isKeyPressed(BTN_TOOL_MOUSE);
127465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolLens = device->isKeyPressed(BTN_TOOL_LENS);
1275ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown    mBtnToolDoubleTap = device->isKeyPressed(BTN_TOOL_DOUBLETAP);
1276ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown    mBtnToolTripleTap = device->isKeyPressed(BTN_TOOL_TRIPLETAP);
1277ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown    mBtnToolQuadTap = device->isKeyPressed(BTN_TOOL_QUADTAP);
127849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
127949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
128049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownvoid TouchButtonAccumulator::clearButtons() {
128149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnTouch = 0;
128249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnStylus = 0;
128349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnStylus2 = 0;
128449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnToolFinger = 0;
128549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnToolPen = 0;
128649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnToolRubber = 0;
128765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolBrush = 0;
128865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolPencil = 0;
128965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolAirbrush = 0;
129065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolMouse = 0;
129165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolLens = 0;
1292ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown    mBtnToolDoubleTap = 0;
1293ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown    mBtnToolTripleTap = 0;
1294ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown    mBtnToolQuadTap = 0;
129549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
129649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
129749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownvoid TouchButtonAccumulator::process(const RawEvent* rawEvent) {
129849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (rawEvent->type == EV_KEY) {
129949ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        switch (rawEvent->code) {
130049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_TOUCH:
130149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnTouch = rawEvent->value;
130249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
130349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_STYLUS:
130449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnStylus = rawEvent->value;
130549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
130649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_STYLUS2:
130749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnStylus2 = rawEvent->value;
130849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
130949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_TOOL_FINGER:
131049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnToolFinger = rawEvent->value;
131149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
131249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_TOOL_PEN:
131349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnToolPen = rawEvent->value;
131449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
131549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_TOOL_RUBBER:
131649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnToolRubber = rawEvent->value;
131749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
131865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        case BTN_TOOL_BRUSH:
131965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mBtnToolBrush = rawEvent->value;
132065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            break;
132165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        case BTN_TOOL_PENCIL:
132265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mBtnToolPencil = rawEvent->value;
132365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            break;
132465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        case BTN_TOOL_AIRBRUSH:
132565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mBtnToolAirbrush = rawEvent->value;
132665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            break;
132765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        case BTN_TOOL_MOUSE:
132865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mBtnToolMouse = rawEvent->value;
132965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            break;
133065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        case BTN_TOOL_LENS:
133165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mBtnToolLens = rawEvent->value;
133265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            break;
1333ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown        case BTN_TOOL_DOUBLETAP:
1334ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown            mBtnToolDoubleTap = rawEvent->value;
1335ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown            break;
1336ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown        case BTN_TOOL_TRIPLETAP:
1337ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown            mBtnToolTripleTap = rawEvent->value;
1338ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown            break;
1339ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown        case BTN_TOOL_QUADTAP:
1340ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown            mBtnToolQuadTap = rawEvent->value;
1341ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown            break;
134249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        }
134349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
134449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
134549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
134649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownuint32_t TouchButtonAccumulator::getButtonState() const {
134749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    uint32_t result = 0;
134849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (mBtnStylus) {
134949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        result |= AMOTION_EVENT_BUTTON_SECONDARY;
135049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
135149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (mBtnStylus2) {
135249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        result |= AMOTION_EVENT_BUTTON_TERTIARY;
135349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
135449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    return result;
135549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
135649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
135749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownint32_t TouchButtonAccumulator::getToolType() const {
135865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mBtnToolMouse || mBtnToolLens) {
135965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        return AMOTION_EVENT_TOOL_TYPE_MOUSE;
136065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
136149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (mBtnToolRubber) {
136249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        return AMOTION_EVENT_TOOL_TYPE_ERASER;
136349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
136465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mBtnToolPen || mBtnToolBrush || mBtnToolPencil || mBtnToolAirbrush) {
136549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        return AMOTION_EVENT_TOOL_TYPE_STYLUS;
136649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
1367ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown    if (mBtnToolFinger || mBtnToolDoubleTap || mBtnToolTripleTap || mBtnToolQuadTap) {
136849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        return AMOTION_EVENT_TOOL_TYPE_FINGER;
136949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
137049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    return AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
137149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
137249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
1373d87c6d5fd5e620ecb1a7a401d2b31c6cf2e1a851Jeff Brownbool TouchButtonAccumulator::isToolActive() const {
137465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    return mBtnTouch || mBtnToolFinger || mBtnToolPen || mBtnToolRubber
137565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            || mBtnToolBrush || mBtnToolPencil || mBtnToolAirbrush
1376ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown            || mBtnToolMouse || mBtnToolLens
1377ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown            || mBtnToolDoubleTap || mBtnToolTripleTap || mBtnToolQuadTap;
137849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
137949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
138049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownbool TouchButtonAccumulator::isHovering() const {
138149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    return mHaveBtnTouch && !mBtnTouch;
138249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
138349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
138400710e906bdafd58386ee7f81fa84addd218122fJeff Brownbool TouchButtonAccumulator::hasStylus() const {
138500710e906bdafd58386ee7f81fa84addd218122fJeff Brown    return mHaveStylus;
138600710e906bdafd58386ee7f81fa84addd218122fJeff Brown}
138700710e906bdafd58386ee7f81fa84addd218122fJeff Brown
138849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
1389be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown// --- RawPointerAxes ---
1390be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1391be1aa8250cee7819c49741e819e81659d1d03823Jeff BrownRawPointerAxes::RawPointerAxes() {
1392be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    clear();
1393be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
1394be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1395be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid RawPointerAxes::clear() {
1396be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    x.clear();
1397be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    y.clear();
1398be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    pressure.clear();
1399be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    touchMajor.clear();
1400be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    touchMinor.clear();
1401be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    toolMajor.clear();
1402be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    toolMinor.clear();
1403be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    orientation.clear();
1404be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    distance.clear();
140565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    tiltX.clear();
140665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    tiltY.clear();
1407be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    trackingId.clear();
1408be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    slot.clear();
1409be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
1410be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1411be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1412be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown// --- RawPointerData ---
1413be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1414be1aa8250cee7819c49741e819e81659d1d03823Jeff BrownRawPointerData::RawPointerData() {
1415be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    clear();
1416be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
1417be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1418be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid RawPointerData::clear() {
1419be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    pointerCount = 0;
1420be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    clearIdBits();
1421be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
1422be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1423be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid RawPointerData::copyFrom(const RawPointerData& other) {
1424be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    pointerCount = other.pointerCount;
1425be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    hoveringIdBits = other.hoveringIdBits;
1426be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    touchingIdBits = other.touchingIdBits;
1427be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1428be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (uint32_t i = 0; i < pointerCount; i++) {
1429be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        pointers[i] = other.pointers[i];
1430be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1431be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        int id = pointers[i].id;
1432be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        idToIndex[id] = other.idToIndex[id];
1433be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
1434be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
1435be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1436be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid RawPointerData::getCentroidOfTouchingPointers(float* outX, float* outY) const {
1437be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    float x = 0, y = 0;
1438be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    uint32_t count = touchingIdBits.count();
1439be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (count) {
1440be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        for (BitSet32 idBits(touchingIdBits); !idBits.isEmpty(); ) {
1441be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t id = idBits.clearFirstMarkedBit();
1442be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const Pointer& pointer = pointerForId(id);
1443be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            x += pointer.x;
1444be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            y += pointer.y;
1445be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
1446be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        x /= count;
1447be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        y /= count;
1448be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
1449be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    *outX = x;
1450be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    *outY = y;
1451be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
1452be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1453be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1454be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown// --- CookedPointerData ---
1455be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1456be1aa8250cee7819c49741e819e81659d1d03823Jeff BrownCookedPointerData::CookedPointerData() {
1457be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    clear();
1458be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
1459be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1460be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid CookedPointerData::clear() {
1461be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    pointerCount = 0;
1462be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    hoveringIdBits.clear();
1463be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    touchingIdBits.clear();
1464be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
1465be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1466be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid CookedPointerData::copyFrom(const CookedPointerData& other) {
1467be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    pointerCount = other.pointerCount;
1468be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    hoveringIdBits = other.hoveringIdBits;
1469be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    touchingIdBits = other.touchingIdBits;
1470be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1471be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (uint32_t i = 0; i < pointerCount; i++) {
1472be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        pointerProperties[i].copyFrom(other.pointerProperties[i]);
1473be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        pointerCoords[i].copyFrom(other.pointerCoords[i]);
1474be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1475be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        int id = pointerProperties[i].id;
1476be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        idToIndex[id] = other.idToIndex[id];
1477be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
1478be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
1479be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1480be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
148149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown// --- SingleTouchMotionAccumulator ---
148249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
148349754db5a304d995c1cc108ff6f19e4ba4265572Jeff BrownSingleTouchMotionAccumulator::SingleTouchMotionAccumulator() {
148449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    clearAbsoluteAxes();
148549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
148649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
148765fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid SingleTouchMotionAccumulator::reset(InputDevice* device) {
148865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mAbsX = device->getAbsoluteAxisValue(ABS_X);
148965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mAbsY = device->getAbsoluteAxisValue(ABS_Y);
149065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mAbsPressure = device->getAbsoluteAxisValue(ABS_PRESSURE);
149165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mAbsToolWidth = device->getAbsoluteAxisValue(ABS_TOOL_WIDTH);
149265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mAbsDistance = device->getAbsoluteAxisValue(ABS_DISTANCE);
149365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mAbsTiltX = device->getAbsoluteAxisValue(ABS_TILT_X);
149465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mAbsTiltY = device->getAbsoluteAxisValue(ABS_TILT_Y);
149565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
149665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
149749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownvoid SingleTouchMotionAccumulator::clearAbsoluteAxes() {
149849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsX = 0;
149949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsY = 0;
150049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsPressure = 0;
150149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsToolWidth = 0;
150249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsDistance = 0;
150365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mAbsTiltX = 0;
150465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mAbsTiltY = 0;
150549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
150649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
150749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownvoid SingleTouchMotionAccumulator::process(const RawEvent* rawEvent) {
150849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (rawEvent->type == EV_ABS) {
150949ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        switch (rawEvent->code) {
151049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case ABS_X:
151149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mAbsX = rawEvent->value;
151249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
151349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case ABS_Y:
151449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mAbsY = rawEvent->value;
151549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
151649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case ABS_PRESSURE:
151749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mAbsPressure = rawEvent->value;
151849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
151949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case ABS_TOOL_WIDTH:
152049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mAbsToolWidth = rawEvent->value;
152149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
152249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case ABS_DISTANCE:
152349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mAbsDistance = rawEvent->value;
152449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
152565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        case ABS_TILT_X:
152665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mAbsTiltX = rawEvent->value;
152765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            break;
152865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        case ABS_TILT_Y:
152965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mAbsTiltY = rawEvent->value;
153065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            break;
153149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        }
153249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
153349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
153449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
153549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
153649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown// --- MultiTouchMotionAccumulator ---
153749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
153849754db5a304d995c1cc108ff6f19e4ba4265572Jeff BrownMultiTouchMotionAccumulator::MultiTouchMotionAccumulator() :
153900710e906bdafd58386ee7f81fa84addd218122fJeff Brown        mCurrentSlot(-1), mSlots(NULL), mSlotCount(0), mUsingSlotsProtocol(false),
154000710e906bdafd58386ee7f81fa84addd218122fJeff Brown        mHaveStylus(false) {
154149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
154249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
154349754db5a304d995c1cc108ff6f19e4ba4265572Jeff BrownMultiTouchMotionAccumulator::~MultiTouchMotionAccumulator() {
154449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    delete[] mSlots;
154549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
154649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
154700710e906bdafd58386ee7f81fa84addd218122fJeff Brownvoid MultiTouchMotionAccumulator::configure(InputDevice* device,
154800710e906bdafd58386ee7f81fa84addd218122fJeff Brown        size_t slotCount, bool usingSlotsProtocol) {
154949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mSlotCount = slotCount;
155049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mUsingSlotsProtocol = usingSlotsProtocol;
155100710e906bdafd58386ee7f81fa84addd218122fJeff Brown    mHaveStylus = device->hasAbsoluteAxis(ABS_MT_TOOL_TYPE);
155249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
155349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    delete[] mSlots;
155449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mSlots = new Slot[slotCount];
155549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
155649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
155765fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid MultiTouchMotionAccumulator::reset(InputDevice* device) {
155865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Unfortunately there is no way to read the initial contents of the slots.
155965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // So when we reset the accumulator, we must assume they are all zeroes.
156065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mUsingSlotsProtocol) {
156165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Query the driver for the current slot index and use it as the initial slot
156265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // before we start reading events from the device.  It is possible that the
156365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // current slot index will not be the same as it was when the first event was
156465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // written into the evdev buffer, which means the input mapper could start
156565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // out of sync with the initial state of the events in the evdev buffer.
156665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // In the extremely unlikely case that this happens, the data from
156765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // two slots will be confused until the next ABS_MT_SLOT event is received.
156865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // This can cause the touch point to "jump", but at least there will be
156965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // no stuck touches.
157065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        int32_t initialSlot;
157165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        status_t status = device->getEventHub()->getAbsoluteAxisValue(device->getId(),
157265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                ABS_MT_SLOT, &initialSlot);
157365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (status) {
15745baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Could not retrieve current multitouch slot index.  status=%d", status);
157565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            initialSlot = -1;
157665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
157765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        clearSlots(initialSlot);
157865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    } else {
157965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        clearSlots(-1);
158065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
158165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
158265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
158349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownvoid MultiTouchMotionAccumulator::clearSlots(int32_t initialSlot) {
158465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mSlots) {
158565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        for (size_t i = 0; i < mSlotCount; i++) {
158665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mSlots[i].clear();
158765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
158849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
158949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mCurrentSlot = initialSlot;
159049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
159149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
159249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownvoid MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
159349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (rawEvent->type == EV_ABS) {
159449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        bool newSlot = false;
159549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        if (mUsingSlotsProtocol) {
159649ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown            if (rawEvent->code == ABS_MT_SLOT) {
159749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                mCurrentSlot = rawEvent->value;
159849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                newSlot = true;
159949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            }
160049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        } else if (mCurrentSlot < 0) {
160149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mCurrentSlot = 0;
160249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        }
160349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
160449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        if (mCurrentSlot < 0 || size_t(mCurrentSlot) >= mSlotCount) {
160549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown#if DEBUG_POINTERS
160649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            if (newSlot) {
16078564c8da817a845353d213acd8636b76f567b234Steve Block                ALOGW("MultiTouch device emitted invalid slot index %d but it "
160849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                        "should be between 0 and %d; ignoring this slot.",
160949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                        mCurrentSlot, mSlotCount - 1);
161049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            }
161149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown#endif
161249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        } else {
161349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            Slot* slot = &mSlots[mCurrentSlot];
161449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
161549ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown            switch (rawEvent->code) {
161649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            case ABS_MT_POSITION_X:
161749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mInUse = true;
161849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mAbsMTPositionX = rawEvent->value;
161949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                break;
162049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            case ABS_MT_POSITION_Y:
162149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mInUse = true;
162249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mAbsMTPositionY = rawEvent->value;
162349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                break;
162449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            case ABS_MT_TOUCH_MAJOR:
162549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mInUse = true;
162649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mAbsMTTouchMajor = rawEvent->value;
162749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                break;
162849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            case ABS_MT_TOUCH_MINOR:
162949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mInUse = true;
163049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mAbsMTTouchMinor = rawEvent->value;
163149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mHaveAbsMTTouchMinor = true;
163249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                break;
163349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            case ABS_MT_WIDTH_MAJOR:
163449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mInUse = true;
163549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mAbsMTWidthMajor = rawEvent->value;
163649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                break;
163749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            case ABS_MT_WIDTH_MINOR:
163849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mInUse = true;
163949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mAbsMTWidthMinor = rawEvent->value;
164049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mHaveAbsMTWidthMinor = true;
164149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                break;
164249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            case ABS_MT_ORIENTATION:
164349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mInUse = true;
164449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mAbsMTOrientation = rawEvent->value;
164549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                break;
164649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            case ABS_MT_TRACKING_ID:
164749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                if (mUsingSlotsProtocol && rawEvent->value < 0) {
16488bcbbefa3b4e149099b2057547543ea95a7be400Jeff Brown                    // The slot is no longer in use but it retains its previous contents,
16498bcbbefa3b4e149099b2057547543ea95a7be400Jeff Brown                    // which may be reused for subsequent touches.
16508bcbbefa3b4e149099b2057547543ea95a7be400Jeff Brown                    slot->mInUse = false;
165149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                } else {
165249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                    slot->mInUse = true;
165349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                    slot->mAbsMTTrackingId = rawEvent->value;
165449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                }
165549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                break;
165649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            case ABS_MT_PRESSURE:
165749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mInUse = true;
165849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mAbsMTPressure = rawEvent->value;
165949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                break;
1660be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            case ABS_MT_DISTANCE:
1661be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                slot->mInUse = true;
1662be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                slot->mAbsMTDistance = rawEvent->value;
1663be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                break;
166449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            case ABS_MT_TOOL_TYPE:
166549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mInUse = true;
166649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mAbsMTToolType = rawEvent->value;
166749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mHaveAbsMTToolType = true;
166849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                break;
166949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            }
167049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        }
167149ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown    } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_MT_REPORT) {
167249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        // MultiTouch Sync: The driver has returned all data for *one* of the pointers.
167349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        mCurrentSlot += 1;
167449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
167549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
167649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
167765fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid MultiTouchMotionAccumulator::finishSync() {
167865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (!mUsingSlotsProtocol) {
167965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        clearSlots(-1);
168065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
168165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
168265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
168300710e906bdafd58386ee7f81fa84addd218122fJeff Brownbool MultiTouchMotionAccumulator::hasStylus() const {
168400710e906bdafd58386ee7f81fa84addd218122fJeff Brown    return mHaveStylus;
168500710e906bdafd58386ee7f81fa84addd218122fJeff Brown}
168600710e906bdafd58386ee7f81fa84addd218122fJeff Brown
168749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
168849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown// --- MultiTouchMotionAccumulator::Slot ---
168949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
169049754db5a304d995c1cc108ff6f19e4ba4265572Jeff BrownMultiTouchMotionAccumulator::Slot::Slot() {
169149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    clear();
169249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
169349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
169449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownvoid MultiTouchMotionAccumulator::Slot::clear() {
169549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mInUse = false;
169649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mHaveAbsMTTouchMinor = false;
169749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mHaveAbsMTWidthMinor = false;
169849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mHaveAbsMTToolType = false;
169949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsMTPositionX = 0;
170049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsMTPositionY = 0;
170149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsMTTouchMajor = 0;
170249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsMTTouchMinor = 0;
170349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsMTWidthMajor = 0;
170449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsMTWidthMinor = 0;
170549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsMTOrientation = 0;
170649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsMTTrackingId = -1;
170749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsMTPressure = 0;
170849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsMTDistance = 0;
1709be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mAbsMTToolType = 0;
171049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
171149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
171249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownint32_t MultiTouchMotionAccumulator::Slot::getToolType() const {
171349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (mHaveAbsMTToolType) {
171449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        switch (mAbsMTToolType) {
171549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case MT_TOOL_FINGER:
171649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            return AMOTION_EVENT_TOOL_TYPE_FINGER;
171749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case MT_TOOL_PEN:
171849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            return AMOTION_EVENT_TOOL_TYPE_STYLUS;
171949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        }
172049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
172149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    return AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
172249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
172349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
172449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
17256d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown// --- InputMapper ---
172646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
17276d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownInputMapper::InputMapper(InputDevice* device) :
17286d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mDevice(device), mContext(device->getContext()) {
17296d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
173046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
17316d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownInputMapper::~InputMapper() {
17326d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
173346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
17346d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid InputMapper::populateDeviceInfo(InputDeviceInfo* info) {
17356d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    info->addSource(getSources());
173646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
173746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1738ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brownvoid InputMapper::dump(String8& dump) {
1739ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown}
1740ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
174165fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid InputMapper::configure(nsecs_t when,
174265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        const InputReaderConfiguration* config, uint32_t changes) {
17436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
174446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
174565fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid InputMapper::reset(nsecs_t when) {
17466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
174746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1748aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brownvoid InputMapper::timeoutExpired(nsecs_t when) {
1749aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown}
1750aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown
17516d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
17526d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return AKEY_STATE_UNKNOWN;
17536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
175446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
17556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
17566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return AKEY_STATE_UNKNOWN;
17576d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
175846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
17596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
17606d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return AKEY_STATE_UNKNOWN;
176146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
176246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
17636d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownbool InputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
17646d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        const int32_t* keyCodes, uint8_t* outFlags) {
17656d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return false;
17666d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
1767349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown
1768a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid InputMapper::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
1769a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        int32_t token) {
1770a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1771a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1772a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid InputMapper::cancelVibrate(int32_t token) {
1773a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1774a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
17756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputMapper::getMetaState() {
17766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return 0;
17776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
177846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
177905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownvoid InputMapper::fadePointer() {
178005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown}
178105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
1782be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownstatus_t InputMapper::getAbsoluteAxisInfo(int32_t axis, RawAbsoluteAxisInfo* axisInfo) {
1783be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return getEventHub()->getAbsoluteAxisInfo(getDeviceId(), axis, axisInfo);
1784be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
1785be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1786af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownvoid InputMapper::bumpGeneration() {
1787af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    mDevice->bumpGeneration();
1788af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown}
1789af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown
1790cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brownvoid InputMapper::dumpRawAbsoluteAxisInfo(String8& dump,
1791cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        const RawAbsoluteAxisInfo& axis, const char* name) {
1792cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    if (axis.valid) {
1793b3a2d1330716812784aee91b6d6275764b5e4210Jeff Brown        dump.appendFormat(INDENT4 "%s: min=%d, max=%d, flat=%d, fuzz=%d, resolution=%d\n",
1794b3a2d1330716812784aee91b6d6275764b5e4210Jeff Brown                name, axis.minValue, axis.maxValue, axis.flat, axis.fuzz, axis.resolution);
1795cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    } else {
1796cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        dump.appendFormat(INDENT4 "%s: unknown range\n", name);
1797cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
1798cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
1799cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
18006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
18016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown// --- SwitchInputMapper ---
18026d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
18036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownSwitchInputMapper::SwitchInputMapper(InputDevice* device) :
1804bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown        InputMapper(device), mUpdatedSwitchValues(0), mUpdatedSwitchMask(0) {
180546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
180646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
18076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownSwitchInputMapper::~SwitchInputMapper() {
18086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
18096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
18106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownuint32_t SwitchInputMapper::getSources() {
181189de57a8d252a25ef2412a11a66089a9ff6ffe29Jeff Brown    return AINPUT_SOURCE_SWITCH;
18126d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
18136d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
18146d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid SwitchInputMapper::process(const RawEvent* rawEvent) {
18156d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    switch (rawEvent->type) {
18166d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    case EV_SW:
1817bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown        processSwitch(rawEvent->code, rawEvent->value);
18186d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        break;
1819bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown
1820bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown    case EV_SYN:
1821bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown        if (rawEvent->code == SYN_REPORT) {
1822bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown            sync(rawEvent->when);
1823bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown        }
1824bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown    }
1825bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown}
1826bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown
1827bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brownvoid SwitchInputMapper::processSwitch(int32_t switchCode, int32_t switchValue) {
1828bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown    if (switchCode >= 0 && switchCode < 32) {
1829bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown        if (switchValue) {
1830bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown            mUpdatedSwitchValues |= 1 << switchCode;
1831bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown        }
1832bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown        mUpdatedSwitchMask |= 1 << switchCode;
183346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
18346d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
183546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1836bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brownvoid SwitchInputMapper::sync(nsecs_t when) {
1837bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown    if (mUpdatedSwitchMask) {
1838bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown        NotifySwitchArgs args(when, 0, mUpdatedSwitchValues, mUpdatedSwitchMask);
1839bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown        getListener()->notifySwitch(&args);
1840bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown
1841bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown        mUpdatedSwitchValues = 0;
1842bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown        mUpdatedSwitchMask = 0;
1843bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown    }
18446d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
184546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
18466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
18476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return getEventHub()->getSwitchState(getDeviceId(), switchCode);
18486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
184946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
185046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1851a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown// --- VibratorInputMapper ---
1852a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1853a47425a13c19f95057df78b8bb65bb25657e8753Jeff BrownVibratorInputMapper::VibratorInputMapper(InputDevice* device) :
1854a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        InputMapper(device), mVibrating(false) {
1855a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1856a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1857a47425a13c19f95057df78b8bb65bb25657e8753Jeff BrownVibratorInputMapper::~VibratorInputMapper() {
1858a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1859a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1860a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownuint32_t VibratorInputMapper::getSources() {
1861a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    return 0;
1862a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1863a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1864a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid VibratorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
1865a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    InputMapper::populateDeviceInfo(info);
1866a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1867a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    info->setVibrator(true);
1868a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1869a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1870a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid VibratorInputMapper::process(const RawEvent* rawEvent) {
1871a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    // TODO: Handle FF_STATUS, although it does not seem to be widely supported.
1872a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1873a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1874a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid VibratorInputMapper::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
1875a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        int32_t token) {
1876a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown#if DEBUG_VIBRATOR
1877a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    String8 patternStr;
1878a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    for (size_t i = 0; i < patternSize; i++) {
1879a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        if (i != 0) {
1880a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown            patternStr.append(", ");
1881a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        }
1882a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        patternStr.appendFormat("%lld", pattern[i]);
1883a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    }
1884a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    ALOGD("vibrate: deviceId=%d, pattern=[%s], repeat=%ld, token=%d",
1885a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown            getDeviceId(), patternStr.string(), repeat, token);
1886a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown#endif
1887a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1888a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    mVibrating = true;
1889a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    memcpy(mPattern, pattern, patternSize * sizeof(nsecs_t));
1890a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    mPatternSize = patternSize;
1891a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    mRepeat = repeat;
1892a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    mToken = token;
1893a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    mIndex = -1;
1894a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1895a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    nextStep();
1896a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1897a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1898a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid VibratorInputMapper::cancelVibrate(int32_t token) {
1899a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown#if DEBUG_VIBRATOR
1900a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    ALOGD("cancelVibrate: deviceId=%d, token=%d", getDeviceId(), token);
1901a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown#endif
1902a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1903a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    if (mVibrating && mToken == token) {
1904a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        stopVibrating();
1905a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    }
1906a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1907a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1908a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid VibratorInputMapper::timeoutExpired(nsecs_t when) {
1909a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    if (mVibrating) {
1910a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        if (when >= mNextStepTime) {
1911a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown            nextStep();
1912a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        } else {
1913a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown            getContext()->requestTimeoutAtTime(mNextStepTime);
1914a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        }
1915a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    }
1916a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1917a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1918a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid VibratorInputMapper::nextStep() {
1919a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    mIndex += 1;
1920a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    if (size_t(mIndex) >= mPatternSize) {
1921a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        if (mRepeat < 0) {
1922a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown            // We are done.
1923a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown            stopVibrating();
1924a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown            return;
1925a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        }
1926a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        mIndex = mRepeat;
1927a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    }
1928a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1929a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    bool vibratorOn = mIndex & 1;
1930a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    nsecs_t duration = mPattern[mIndex];
1931a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    if (vibratorOn) {
1932a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown#if DEBUG_VIBRATOR
1933a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        ALOGD("nextStep: sending vibrate deviceId=%d, duration=%lld",
1934a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown                getDeviceId(), duration);
1935a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown#endif
1936a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        getEventHub()->vibrate(getDeviceId(), duration);
1937a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    } else {
1938a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown#if DEBUG_VIBRATOR
1939a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        ALOGD("nextStep: sending cancel vibrate deviceId=%d", getDeviceId());
1940a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown#endif
1941a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        getEventHub()->cancelVibrate(getDeviceId());
1942a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    }
1943a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
1944a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    mNextStepTime = now + duration;
1945a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    getContext()->requestTimeoutAtTime(mNextStepTime);
1946a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown#if DEBUG_VIBRATOR
1947a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    ALOGD("nextStep: scheduled timeout in %0.3fms", duration * 0.000001f);
1948a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown#endif
1949a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1950a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1951a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid VibratorInputMapper::stopVibrating() {
1952a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    mVibrating = false;
1953a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown#if DEBUG_VIBRATOR
1954a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    ALOGD("stopVibrating: sending cancel vibrate deviceId=%d", getDeviceId());
1955a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown#endif
1956a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    getEventHub()->cancelVibrate(getDeviceId());
1957a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1958a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1959a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid VibratorInputMapper::dump(String8& dump) {
1960a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    dump.append(INDENT2 "Vibrator Input Mapper:\n");
1961a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    dump.appendFormat(INDENT3 "Vibrating: %s\n", toString(mVibrating));
1962a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1963a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1964a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
19656d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown// --- KeyboardInputMapper ---
19666d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
196747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff BrownKeyboardInputMapper::KeyboardInputMapper(InputDevice* device,
1968efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown        uint32_t source, int32_t keyboardType) :
1969efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown        InputMapper(device), mSource(source),
19706d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mKeyboardType(keyboardType) {
19716d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
19726d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
19736d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownKeyboardInputMapper::~KeyboardInputMapper() {
19746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
19756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
19766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownuint32_t KeyboardInputMapper::getSources() {
1977efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown    return mSource;
19786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
19796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
19806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
19816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    InputMapper::populateDeviceInfo(info);
19826d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
19836d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    info->setKeyboardType(mKeyboardType);
19849f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown    info->setKeyCharacterMap(getEventHub()->getKeyCharacterMap(getDeviceId()));
19856d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
19866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
1987ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brownvoid KeyboardInputMapper::dump(String8& dump) {
1988be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.append(INDENT2 "Keyboard Input Mapper:\n");
1989be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpParameters(dump);
1990be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "KeyboardType: %d\n", mKeyboardType);
199165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    dump.appendFormat(INDENT3 "Orientation: %d\n", mOrientation);
1992be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "KeyDowns: %d keys currently down\n", mKeyDowns.size());
1993be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "MetaState: 0x%0x\n", mMetaState);
1994be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "DownTime: %lld\n", mDownTime);
1995ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown}
1996ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
199747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
199865fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid KeyboardInputMapper::configure(nsecs_t when,
199965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        const InputReaderConfiguration* config, uint32_t changes) {
200065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    InputMapper::configure(when, config, changes);
200147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
2002474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    if (!changes) { // first time only
2003474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        // Configure basic parameters.
2004474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        configureParameters();
200565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
200649ed71db425c5054e3ad9526496a7e116c89556bJeff Brown
200765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
2008d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
2009d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            DisplayViewport v;
2010d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            if (config->getDisplayInfo(false /*external*/, &v)) {
2011d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                mOrientation = v.orientation;
2012d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            } else {
201365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mOrientation = DISPLAY_ORIENTATION_0;
201465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            }
201565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        } else {
201665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientation = DISPLAY_ORIENTATION_0;
201765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
201849ed71db425c5054e3ad9526496a7e116c89556bJeff Brown    }
201947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown}
202047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
202147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brownvoid KeyboardInputMapper::configureParameters() {
202247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    mParameters.orientationAware = false;
202347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    getDevice()->getConfiguration().tryGetProperty(String8("keyboard.orientationAware"),
202447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            mParameters.orientationAware);
202547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
2026d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    mParameters.hasAssociatedDisplay = false;
2027bc68a59c024bdb745dac8e2ec7408a9f30595f1aJeff Brown    if (mParameters.orientationAware) {
2028d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        mParameters.hasAssociatedDisplay = true;
2029bc68a59c024bdb745dac8e2ec7408a9f30595f1aJeff Brown    }
203047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown}
203147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
203247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brownvoid KeyboardInputMapper::dumpParameters(String8& dump) {
203347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    dump.append(INDENT3 "Parameters:\n");
2034d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    dump.appendFormat(INDENT4 "HasAssociatedDisplay: %s\n",
2035d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            toString(mParameters.hasAssociatedDisplay));
203647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    dump.appendFormat(INDENT4 "OrientationAware: %s\n",
203747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            toString(mParameters.orientationAware));
203847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown}
203947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
204065fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid KeyboardInputMapper::reset(nsecs_t when) {
204165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mMetaState = AMETA_NONE;
204265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mDownTime = 0;
204365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mKeyDowns.clear();
204449ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown    mCurrentHidUsage = 0;
20456d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
2046be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    resetLedState();
2047be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
204865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    InputMapper::reset(when);
20496d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
20506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
20516d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid KeyboardInputMapper::process(const RawEvent* rawEvent) {
20526d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    switch (rawEvent->type) {
20536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    case EV_KEY: {
205449ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        int32_t scanCode = rawEvent->code;
205549ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        int32_t usageCode = mCurrentHidUsage;
205649ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        mCurrentHidUsage = 0;
205749ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown
20586d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (isKeyboardOrGamepadKey(scanCode)) {
205949ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown            int32_t keyCode;
206049ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown            uint32_t flags;
206149ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown            if (getEventHub()->mapKey(getDeviceId(), scanCode, usageCode, &keyCode, &flags)) {
206249ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown                keyCode = AKEYCODE_UNKNOWN;
206349ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown                flags = 0;
206449ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown            }
206549ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown            processKey(rawEvent->when, rawEvent->value != 0, keyCode, scanCode, flags);
206646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
20676d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        break;
20686d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
206949ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown    case EV_MSC: {
207049ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        if (rawEvent->code == MSC_SCAN) {
207149ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown            mCurrentHidUsage = rawEvent->value;
207249ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        }
207349ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        break;
207449ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown    }
207549ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown    case EV_SYN: {
207649ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        if (rawEvent->code == SYN_REPORT) {
207749ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown            mCurrentHidUsage = 0;
207849ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        }
207949ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown    }
20806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
20816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
208246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
20836d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownbool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) {
20846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return scanCode < BTN_MOUSE
20856d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        || scanCode >= KEY_OK
20869e8e40cb5f8aeb0702002eee60d1ce394bf699eeJeff Brown        || (scanCode >= BTN_MISC && scanCode < BTN_MOUSE)
2087cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        || (scanCode >= BTN_JOYSTICK && scanCode < BTN_DIGI);
20886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
208946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
20906328cdc89e099806a1893b89e4c724d596272d9eJeff Brownvoid KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
20916328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        int32_t scanCode, uint32_t policyFlags) {
20926328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
2093be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (down) {
2094be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        // Rotate key codes according to orientation if needed.
2095d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
209665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            keyCode = rotateKeyCode(keyCode, mOrientation);
2097be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
20986d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
2099be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        // Add key down.
2100be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        ssize_t keyDownIndex = findKeyDown(scanCode);
2101be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (keyDownIndex >= 0) {
2102be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            // key repeat, be sure to use same keycode as before in case of rotation
2103be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
21046d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        } else {
2105be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            // key down
2106be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if ((policyFlags & POLICY_FLAG_VIRTUAL)
2107be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    && mContext->shouldDropVirtualKey(when,
2108be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            getDevice(), keyCode, scanCode)) {
21096328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                return;
21106328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            }
2111be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
2112be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mKeyDowns.push();
2113be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            KeyDown& keyDown = mKeyDowns.editTop();
2114be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            keyDown.keyCode = keyCode;
2115be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            keyDown.scanCode = scanCode;
21166d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
21176328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
2118be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mDownTime = when;
2119be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    } else {
2120be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        // Remove key down.
2121be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        ssize_t keyDownIndex = findKeyDown(scanCode);
2122be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (keyDownIndex >= 0) {
2123be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            // key up, be sure to use same keycode as before in case of rotation
2124be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
2125be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mKeyDowns.removeAt(size_t(keyDownIndex));
2126be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        } else {
2127be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            // key was not actually down
21286215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block            ALOGI("Dropping key up from device %s because the key was not down.  "
2129be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    "keyCode=%d, scanCode=%d",
2130be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    getDeviceName().string(), keyCode, scanCode);
2131be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            return;
213246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
2133be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
213446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2135be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    bool metaStateChanged = false;
2136be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t oldMetaState = mMetaState;
2137be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t newMetaState = updateMetaState(keyCode, down, oldMetaState);
2138be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (oldMetaState != newMetaState) {
2139be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mMetaState = newMetaState;
2140be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        metaStateChanged = true;
2141be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        updateLedState(false);
2142be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
2143be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
2144be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    nsecs_t downTime = mDownTime;
21456328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
214656194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // Key down on external an keyboard should wake the device.
214756194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // We don't do this for internal keyboards to prevent them from waking up in your pocket.
214856194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // For internal keyboards, the key layout file should specify the policy flags for
214956194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // each wake key individually.
215056194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // TODO: Use the input device configuration to control this behavior more finely.
215156194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    if (down && getDevice()->isExternal()
215256194ebec6212e229f4ccdaa4b187166d20013efJeff Brown            && !(policyFlags & (POLICY_FLAG_WAKE | POLICY_FLAG_WAKE_DROPPED))) {
215356194ebec6212e229f4ccdaa4b187166d20013efJeff Brown        policyFlags |= POLICY_FLAG_WAKE_DROPPED;
215456194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    }
215556194ebec6212e229f4ccdaa4b187166d20013efJeff Brown
21566328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    if (metaStateChanged) {
21576d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        getContext()->updateGlobalMetaState();
215846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
215946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
216005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    if (down && !isMetaKey(keyCode)) {
216105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        getContext()->fadePointer();
216205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    }
216305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
2164be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
2165b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
2166b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
2167be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getListener()->notifyKey(&args);
21686d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
2169c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown
2170be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownssize_t KeyboardInputMapper::findKeyDown(int32_t scanCode) {
2171be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    size_t n = mKeyDowns.size();
21726d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (size_t i = 0; i < n; i++) {
2173be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (mKeyDowns[i].scanCode == scanCode) {
21746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            return i;
217546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
21766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
21776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return -1;
21786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
217946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
21806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t KeyboardInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
21816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return getEventHub()->getKeyCodeState(getDeviceId(), keyCode);
21826d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
2183c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown
21846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t KeyboardInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
21856d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
21866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
218746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
21886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownbool KeyboardInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
21896d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        const int32_t* keyCodes, uint8_t* outFlags) {
21906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return getEventHub()->markSupportedKeyCodes(getDeviceId(), numCodes, keyCodes, outFlags);
21916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
219246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
21936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t KeyboardInputMapper::getMetaState() {
2194be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return mMetaState;
21956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
219600ba884436dc8b222ad850c73c936d87bf4e84deJeff Brown
2197be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid KeyboardInputMapper::resetLedState() {
2198be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    initializeLedState(mCapsLockLedState, LED_CAPSL);
2199be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    initializeLedState(mNumLockLedState, LED_NUML);
2200be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    initializeLedState(mScrollLockLedState, LED_SCROLLL);
220149ed71db425c5054e3ad9526496a7e116c89556bJeff Brown
2202be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    updateLedState(true);
220349ed71db425c5054e3ad9526496a7e116c89556bJeff Brown}
220449ed71db425c5054e3ad9526496a7e116c89556bJeff Brown
2205be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid KeyboardInputMapper::initializeLedState(LedState& ledState, int32_t led) {
220649ed71db425c5054e3ad9526496a7e116c89556bJeff Brown    ledState.avail = getEventHub()->hasLed(getDeviceId(), led);
220749ed71db425c5054e3ad9526496a7e116c89556bJeff Brown    ledState.on = false;
220849ed71db425c5054e3ad9526496a7e116c89556bJeff Brown}
220949ed71db425c5054e3ad9526496a7e116c89556bJeff Brown
2210be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid KeyboardInputMapper::updateLedState(bool reset) {
2211be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    updateLedStateForModifier(mCapsLockLedState, LED_CAPSL,
221251e7fe7545e3509ebb5c31c10440acd31cec89a2Jeff Brown            AMETA_CAPS_LOCK_ON, reset);
2213be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    updateLedStateForModifier(mNumLockLedState, LED_NUML,
221451e7fe7545e3509ebb5c31c10440acd31cec89a2Jeff Brown            AMETA_NUM_LOCK_ON, reset);
2215be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    updateLedStateForModifier(mScrollLockLedState, LED_SCROLLL,
221651e7fe7545e3509ebb5c31c10440acd31cec89a2Jeff Brown            AMETA_SCROLL_LOCK_ON, reset);
2217497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown}
2218497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown
2219be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid KeyboardInputMapper::updateLedStateForModifier(LedState& ledState,
2220497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown        int32_t led, int32_t modifier, bool reset) {
2221497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown    if (ledState.avail) {
2222be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        bool desiredState = (mMetaState & modifier) != 0;
222349ed71db425c5054e3ad9526496a7e116c89556bJeff Brown        if (reset || ledState.on != desiredState) {
2224497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown            getEventHub()->setLedState(getDeviceId(), led, desiredState);
2225497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown            ledState.on = desiredState;
2226497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown        }
2227497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown    }
2228497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown}
2229497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown
22306d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
223183c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown// --- CursorInputMapper ---
22326d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
223383c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff BrownCursorInputMapper::CursorInputMapper(InputDevice* device) :
223447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        InputMapper(device) {
22356d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
22366d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
223783c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff BrownCursorInputMapper::~CursorInputMapper() {
22386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
22396d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
224083c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownuint32_t CursorInputMapper::getSources() {
2241efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown    return mSource;
22426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
22436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
224483c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownvoid CursorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
22456d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    InputMapper::populateDeviceInfo(info);
22466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
224783c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    if (mParameters.mode == Parameters::MODE_POINTER) {
224883c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        float minX, minY, maxX, maxY;
224983c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
2250efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown            info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, minX, maxX, 0.0f, 0.0f);
2251efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown            info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, minY, maxY, 0.0f, 0.0f);
225283c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        }
225383c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    } else {
2254efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown        info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, -1.0f, 1.0f, 0.0f, mXScale);
2255efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown        info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, -1.0f, 1.0f, 0.0f, mYScale);
22566f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
2257efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown    info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mSource, 0.0f, 1.0f, 0.0f, 0.0f);
22586f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
225965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mCursorScrollAccumulator.haveRelativeVWheel()) {
2260efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown        info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f);
22616f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
226265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mCursorScrollAccumulator.haveRelativeHWheel()) {
2263efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown        info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f);
226483c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    }
22656d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
22666d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
226783c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownvoid CursorInputMapper::dump(String8& dump) {
2268be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.append(INDENT2 "Cursor Input Mapper:\n");
2269be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpParameters(dump);
2270be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "XScale: %0.3f\n", mXScale);
2271be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "YScale: %0.3f\n", mYScale);
2272be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision);
2273be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision);
2274be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "HaveVWheel: %s\n",
227565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            toString(mCursorScrollAccumulator.haveRelativeVWheel()));
2276be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "HaveHWheel: %s\n",
227765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            toString(mCursorScrollAccumulator.haveRelativeHWheel()));
2278be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale);
2279be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale);
228065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    dump.appendFormat(INDENT3 "Orientation: %d\n", mOrientation);
2281be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "ButtonState: 0x%08x\n", mButtonState);
2282be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "Down: %s\n", toString(isPointerDown(mButtonState)));
2283be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "DownTime: %lld\n", mDownTime);
2284ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown}
2285ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
228665fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid CursorInputMapper::configure(nsecs_t when,
228765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        const InputReaderConfiguration* config, uint32_t changes) {
228865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    InputMapper::configure(when, config, changes);
228947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
2290474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    if (!changes) { // first time only
229165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mCursorScrollAccumulator.configure(getDevice());
229249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
2293474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        // Configure basic parameters.
2294474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        configureParameters();
229583c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown
2296474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        // Configure device mode.
2297474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        switch (mParameters.mode) {
2298474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        case Parameters::MODE_POINTER:
2299474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mSource = AINPUT_SOURCE_MOUSE;
2300474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mXPrecision = 1.0f;
2301474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mYPrecision = 1.0f;
2302474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mXScale = 1.0f;
2303474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mYScale = 1.0f;
2304474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mPointerController = getPolicy()->obtainPointerController(getDeviceId());
2305474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            break;
2306474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        case Parameters::MODE_NAVIGATION:
2307474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mSource = AINPUT_SOURCE_TRACKBALL;
2308474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
2309474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
2310474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
2311474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
2312474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            break;
2313474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        }
23146f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
2315474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        mVWheelScale = 1.0f;
2316474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        mHWheelScale = 1.0f;
2317474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    }
231819c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown
2319474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
2320474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        mPointerVelocityControl.setParameters(config->pointerVelocityControlParameters);
2321474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        mWheelXVelocityControl.setParameters(config->wheelVelocityControlParameters);
2322474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        mWheelYVelocityControl.setParameters(config->wheelVelocityControlParameters);
2323474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    }
232465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
232565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
2326d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
2327d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            DisplayViewport v;
2328d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            if (config->getDisplayInfo(false /*external*/, &v)) {
2329d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                mOrientation = v.orientation;
2330d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            } else {
233165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mOrientation = DISPLAY_ORIENTATION_0;
233265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            }
233365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        } else {
233465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientation = DISPLAY_ORIENTATION_0;
233565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
2336af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown        bumpGeneration();
233765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
233847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown}
233947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
234083c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownvoid CursorInputMapper::configureParameters() {
234183c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    mParameters.mode = Parameters::MODE_POINTER;
234283c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    String8 cursorModeString;
234383c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    if (getDevice()->getConfiguration().tryGetProperty(String8("cursor.mode"), cursorModeString)) {
234483c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        if (cursorModeString == "navigation") {
234583c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown            mParameters.mode = Parameters::MODE_NAVIGATION;
234683c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        } else if (cursorModeString != "pointer" && cursorModeString != "default") {
23478564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Invalid value for cursor.mode: '%s'", cursorModeString.string());
234883c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        }
234983c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    }
235083c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown
235147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    mParameters.orientationAware = false;
235283c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    getDevice()->getConfiguration().tryGetProperty(String8("cursor.orientationAware"),
235347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            mParameters.orientationAware);
235447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
2355d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    mParameters.hasAssociatedDisplay = false;
2356bc68a59c024bdb745dac8e2ec7408a9f30595f1aJeff Brown    if (mParameters.mode == Parameters::MODE_POINTER || mParameters.orientationAware) {
2357d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        mParameters.hasAssociatedDisplay = true;
2358bc68a59c024bdb745dac8e2ec7408a9f30595f1aJeff Brown    }
235947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown}
236047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
236183c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownvoid CursorInputMapper::dumpParameters(String8& dump) {
236247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    dump.append(INDENT3 "Parameters:\n");
2363d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    dump.appendFormat(INDENT4 "HasAssociatedDisplay: %s\n",
2364d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            toString(mParameters.hasAssociatedDisplay));
236583c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown
236683c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    switch (mParameters.mode) {
236783c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    case Parameters::MODE_POINTER:
236883c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        dump.append(INDENT4 "Mode: pointer\n");
236983c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        break;
237083c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    case Parameters::MODE_NAVIGATION:
237183c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        dump.append(INDENT4 "Mode: navigation\n");
237283c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        break;
237383c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    default:
2374ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block        ALOG_ASSERT(false);
237583c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    }
237683c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown
237747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    dump.appendFormat(INDENT4 "OrientationAware: %s\n",
237847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            toString(mParameters.orientationAware));
237947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown}
238047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
238165fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid CursorInputMapper::reset(nsecs_t when) {
2382be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mButtonState = 0;
2383be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mDownTime = 0;
23846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
2385be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mPointerVelocityControl.reset();
2386be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mWheelXVelocityControl.reset();
2387be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mWheelYVelocityControl.reset();
23886328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
238965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCursorButtonAccumulator.reset(getDevice());
239065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCursorMotionAccumulator.reset(getDevice());
239165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCursorScrollAccumulator.reset(getDevice());
239246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
239365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    InputMapper::reset(when);
23946d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
23956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
239683c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownvoid CursorInputMapper::process(const RawEvent* rawEvent) {
239749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mCursorButtonAccumulator.process(rawEvent);
239849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mCursorMotionAccumulator.process(rawEvent);
239965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCursorScrollAccumulator.process(rawEvent);
24006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
240149ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown    if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
240249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        sync(rawEvent->when);
24036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
240446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
240546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
240683c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownvoid CursorInputMapper::sync(nsecs_t when) {
2407be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t lastButtonState = mButtonState;
2408be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t currentButtonState = mCursorButtonAccumulator.getButtonState();
2409be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mButtonState = currentButtonState;
2410be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
2411be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    bool wasDown = isPointerDown(lastButtonState);
2412be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    bool down = isPointerDown(currentButtonState);
2413be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    bool downChanged;
2414be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (!wasDown && down) {
2415be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mDownTime = when;
2416be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        downChanged = true;
2417be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    } else if (wasDown && !down) {
2418be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        downChanged = true;
2419be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    } else {
2420be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        downChanged = false;
2421be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
2422be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    nsecs_t downTime = mDownTime;
2423be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    bool buttonsChanged = currentButtonState != lastButtonState;
2424c28306ad4ac9ce7a7d5f10c2e38d422ffc309a1fJeff Brown    bool buttonsPressed = currentButtonState & ~lastButtonState;
242549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
2426be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    float deltaX = mCursorMotionAccumulator.getRelativeX() * mXScale;
2427be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    float deltaY = mCursorMotionAccumulator.getRelativeY() * mYScale;
2428be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    bool moved = deltaX != 0 || deltaY != 0;
24296328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
243065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Rotate delta according to orientation if needed.
2431d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    if (mParameters.orientationAware && mParameters.hasAssociatedDisplay
2432be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            && (deltaX != 0.0f || deltaY != 0.0f)) {
243365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        rotateDelta(mOrientation, &deltaX, &deltaY);
2434be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
2435fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
243665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Move the pointer.
2437be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    PointerProperties pointerProperties;
2438be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    pointerProperties.clear();
2439be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    pointerProperties.id = 0;
2440be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;
2441fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
2442be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    PointerCoords pointerCoords;
2443be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    pointerCoords.clear();
244419c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown
244565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    float vscroll = mCursorScrollAccumulator.getRelativeVWheel();
244665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    float hscroll = mCursorScrollAccumulator.getRelativeHWheel();
2447be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    bool scrolled = vscroll != 0 || hscroll != 0;
244819c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown
2449be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mWheelYVelocityControl.move(when, NULL, &vscroll);
2450be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mWheelXVelocityControl.move(when, &hscroll, NULL);
24512352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
2452be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mPointerVelocityControl.move(when, &deltaX, &deltaY);
24532352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
245483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    int32_t displayId;
2455be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (mPointerController != NULL) {
2456be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (moved || scrolled || buttonsChanged) {
2457be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mPointerController->setPresentation(
2458be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    PointerControllerInterface::PRESENTATION_POINTER);
24592352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
2460be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (moved) {
2461be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mPointerController->move(deltaX, deltaY);
2462be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            }
24632352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
2464be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (buttonsChanged) {
2465be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mPointerController->setButtonState(currentButtonState);
246683c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown            }
2467efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown
2468be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
246983c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        }
247083c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown
2471be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        float x, y;
2472be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mPointerController->getPosition(&x, &y);
2473be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
2474be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
247583d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        displayId = ADISPLAY_ID_DEFAULT;
2476be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    } else {
2477be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
2478be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
247983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        displayId = ADISPLAY_ID_NONE;
2480be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
2481be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
2482be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);
248346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
248456194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // Moving an external trackball or mouse should wake the device.
248556194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // We don't do this for internal cursor devices to prevent them from waking up
248656194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // the device in your pocket.
248756194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // TODO: Use the input device configuration to control this behavior more finely.
248856194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    uint32_t policyFlags = 0;
2489c28306ad4ac9ce7a7d5f10c2e38d422ffc309a1fJeff Brown    if ((buttonsPressed || moved || scrolled) && getDevice()->isExternal()) {
249056194ebec6212e229f4ccdaa4b187166d20013efJeff Brown        policyFlags |= POLICY_FLAG_WAKE_DROPPED;
249156194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    }
249256194ebec6212e229f4ccdaa4b187166d20013efJeff Brown
2493fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    // Synthesize key down from buttons if needed.
2494fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mSource,
2495fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            policyFlags, lastButtonState, currentButtonState);
2496fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
2497fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    // Send motion event.
2498be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (downChanged || moved || scrolled || buttonsChanged) {
2499be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        int32_t metaState = mContext->getGlobalMetaState();
2500be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        int32_t motionEventAction;
2501be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (downChanged) {
2502be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
2503be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        } else if (down || mPointerController == NULL) {
2504be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            motionEventAction = AMOTION_EVENT_ACTION_MOVE;
2505be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        } else {
2506be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
2507be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
2508be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
2509be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
2510be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                motionEventAction, 0, metaState, currentButtonState, 0,
251183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                displayId, 1, &pointerProperties, &pointerCoords,
251283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                mXPrecision, mYPrecision, downTime);
2513be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        getListener()->notifyMotion(&args);
2514be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
2515be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        // Send hover move after UP to tell the application that the mouse is hovering now.
2516be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (motionEventAction == AMOTION_EVENT_ACTION_UP
2517be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                && mPointerController != NULL) {
2518be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            NotifyMotionArgs hoverArgs(when, getDeviceId(), mSource, policyFlags,
2519be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
2520be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    metaState, currentButtonState, AMOTION_EVENT_EDGE_FLAG_NONE,
252183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                    displayId, 1, &pointerProperties, &pointerCoords,
252283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                    mXPrecision, mYPrecision, downTime);
2523be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            getListener()->notifyMotion(&hoverArgs);
2524be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
252533bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown
2526be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        // Send scroll events.
2527be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (scrolled) {
2528be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
2529be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
253033bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown
2531be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, policyFlags,
2532be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    AMOTION_EVENT_ACTION_SCROLL, 0, metaState, currentButtonState,
2533be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    AMOTION_EVENT_EDGE_FLAG_NONE,
253483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                    displayId, 1, &pointerProperties, &pointerCoords,
253583d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                    mXPrecision, mYPrecision, downTime);
2536be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            getListener()->notifyMotion(&scrollArgs);
2537be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
253833bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown    }
2539a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
2540fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    // Synthesize key up from buttons if needed.
2541fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mSource,
2542fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            policyFlags, lastButtonState, currentButtonState);
2543fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
254465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCursorMotionAccumulator.finishSync();
254565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCursorScrollAccumulator.finishSync();
254646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
254746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
254883c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownint32_t CursorInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
2549c3fc2d03d58a258c53c9265a70143d4af076b764Jeff Brown    if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) {
2550c3fc2d03d58a258c53c9265a70143d4af076b764Jeff Brown        return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
2551c3fc2d03d58a258c53c9265a70143d4af076b764Jeff Brown    } else {
2552c3fc2d03d58a258c53c9265a70143d4af076b764Jeff Brown        return AKEY_STATE_UNKNOWN;
2553c3fc2d03d58a258c53c9265a70143d4af076b764Jeff Brown    }
2554c3fc2d03d58a258c53c9265a70143d4af076b764Jeff Brown}
2555c3fc2d03d58a258c53c9265a70143d4af076b764Jeff Brown
255605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownvoid CursorInputMapper::fadePointer() {
2557be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (mPointerController != NULL) {
2558be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
2559be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
256005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown}
256105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
256246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
25636d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown// --- TouchInputMapper ---
256446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
256547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff BrownTouchInputMapper::TouchInputMapper(InputDevice* device) :
2566be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        InputMapper(device),
256765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mSource(0), mDeviceMode(DEVICE_MODE_DISABLED),
256883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        mSurfaceWidth(-1), mSurfaceHeight(-1), mSurfaceLeft(0), mSurfaceTop(0),
256983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        mSurfaceOrientation(DISPLAY_ORIENTATION_0) {
25706d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
257146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
25726d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownTouchInputMapper::~TouchInputMapper() {
257346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
257446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
25756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownuint32_t TouchInputMapper::getSources() {
257665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    return mSource;
25776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
257846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
25796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
25806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    InputMapper::populateDeviceInfo(info);
25816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
258265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mDeviceMode != DEVICE_MODE_DISABLED) {
258365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        info->addMotionRange(mOrientedRanges.x);
258465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        info->addMotionRange(mOrientedRanges.y);
2585be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        info->addMotionRange(mOrientedRanges.pressure);
25868d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
258765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mOrientedRanges.haveSize) {
258865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            info->addMotionRange(mOrientedRanges.size);
258965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
25908d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
259165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mOrientedRanges.haveTouchSize) {
259265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            info->addMotionRange(mOrientedRanges.touchMajor);
259365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            info->addMotionRange(mOrientedRanges.touchMinor);
259465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
25958d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
259665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mOrientedRanges.haveToolSize) {
259765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            info->addMotionRange(mOrientedRanges.toolMajor);
259865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            info->addMotionRange(mOrientedRanges.toolMinor);
259965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
26008d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
260165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mOrientedRanges.haveOrientation) {
260265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            info->addMotionRange(mOrientedRanges.orientation);
260365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
2604ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
260565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mOrientedRanges.haveDistance) {
260665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            info->addMotionRange(mOrientedRanges.distance);
260765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
260880fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
260965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mOrientedRanges.haveTilt) {
261065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            info->addMotionRange(mOrientedRanges.tilt);
261165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
261265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
261365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mCursorScrollAccumulator.haveRelativeVWheel()) {
261465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f);
261565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
261665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mCursorScrollAccumulator.haveRelativeHWheel()) {
261765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f);
2618ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
2619be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
26206d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
26216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
2622ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brownvoid TouchInputMapper::dump(String8& dump) {
2623be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.append(INDENT2 "Touch Input Mapper:\n");
2624be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpParameters(dump);
2625be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpVirtualKeys(dump);
2626be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpRawPointerAxes(dump);
2627be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpCalibration(dump);
2628be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpSurface(dump);
2629be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
2630be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n");
263183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    dump.appendFormat(INDENT4 "XTranslate: %0.3f\n", mXTranslate);
263283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    dump.appendFormat(INDENT4 "YTranslate: %0.3f\n", mYTranslate);
2633be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT4 "XScale: %0.3f\n", mXScale);
2634be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT4 "YScale: %0.3f\n", mYScale);
2635be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mXPrecision);
2636be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT4 "YPrecision: %0.3f\n", mYPrecision);
2637be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT4 "GeometricScale: %0.3f\n", mGeometricScale);
2638be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mPressureScale);
2639be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mSizeScale);
2640be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT4 "OrientationScale: %0.3f\n", mOrientationScale);
2641be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT4 "DistanceScale: %0.3f\n", mDistanceScale);
264265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    dump.appendFormat(INDENT4 "HaveTilt: %s\n", toString(mHaveTilt));
264365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    dump.appendFormat(INDENT4 "TiltXCenter: %0.3f\n", mTiltXCenter);
264465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    dump.appendFormat(INDENT4 "TiltXScale: %0.3f\n", mTiltXScale);
264565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    dump.appendFormat(INDENT4 "TiltYCenter: %0.3f\n", mTiltYCenter);
264665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    dump.appendFormat(INDENT4 "TiltYScale: %0.3f\n", mTiltYScale);
2647be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
2648be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "Last Button State: 0x%08x\n", mLastButtonState);
2649be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
2650be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "Last Raw Touch: pointerCount=%d\n",
2651be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mLastRawPointerData.pointerCount);
2652be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (uint32_t i = 0; i < mLastRawPointerData.pointerCount; i++) {
2653be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        const RawPointerData::Pointer& pointer = mLastRawPointerData.pointers[i];
2654be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        dump.appendFormat(INDENT4 "[%d]: id=%d, x=%d, y=%d, pressure=%d, "
2655be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                "touchMajor=%d, touchMinor=%d, toolMajor=%d, toolMinor=%d, "
265665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                "orientation=%d, tiltX=%d, tiltY=%d, distance=%d, "
265765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                "toolType=%d, isHovering=%s\n", i,
2658be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointer.id, pointer.x, pointer.y, pointer.pressure,
2659be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointer.touchMajor, pointer.touchMinor,
2660be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointer.toolMajor, pointer.toolMinor,
266165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                pointer.orientation, pointer.tiltX, pointer.tiltY, pointer.distance,
2662be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointer.toolType, toString(pointer.isHovering));
2663be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
2664be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
2665be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "Last Cooked Touch: pointerCount=%d\n",
2666be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mLastCookedPointerData.pointerCount);
2667be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (uint32_t i = 0; i < mLastCookedPointerData.pointerCount; i++) {
2668be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        const PointerProperties& pointerProperties = mLastCookedPointerData.pointerProperties[i];
2669be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        const PointerCoords& pointerCoords = mLastCookedPointerData.pointerCoords[i];
2670be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        dump.appendFormat(INDENT4 "[%d]: id=%d, x=%0.3f, y=%0.3f, pressure=%0.3f, "
2671be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                "touchMajor=%0.3f, touchMinor=%0.3f, toolMajor=%0.3f, toolMinor=%0.3f, "
267265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                "orientation=%0.3f, tilt=%0.3f, distance=%0.3f, "
267365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                "toolType=%d, isHovering=%s\n", i,
2674be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointerProperties.id,
2675be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointerCoords.getX(),
2676be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointerCoords.getY(),
2677be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2678be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2679be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2680be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2681be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2682be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
268365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TILT),
2684be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE),
2685be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointerProperties.toolType,
2686be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                toString(mLastCookedPointerData.isHovering(i)));
2687be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
2688be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
268965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mDeviceMode == DEVICE_MODE_POINTER) {
2690be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        dump.appendFormat(INDENT3 "Pointer Gesture Detector:\n");
2691be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        dump.appendFormat(INDENT4 "XMovementScale: %0.3f\n",
269265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPointerXMovementScale);
2693be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        dump.appendFormat(INDENT4 "YMovementScale: %0.3f\n",
269465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPointerYMovementScale);
2695be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        dump.appendFormat(INDENT4 "XZoomScale: %0.3f\n",
269665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPointerXZoomScale);
2697be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        dump.appendFormat(INDENT4 "YZoomScale: %0.3f\n",
269865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPointerYZoomScale);
2699be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        dump.appendFormat(INDENT4 "MaxSwipeWidth: %f\n",
2700be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mPointerGestureMaxSwipeWidth);
2701be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
2702be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
2703be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
270465fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::configure(nsecs_t when,
270565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        const InputReaderConfiguration* config, uint32_t changes) {
270665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    InputMapper::configure(when, config, changes);
270746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2708474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    mConfig = *config;
270946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2710474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    if (!changes) { // first time only
2711474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        // Configure basic parameters.
2712474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        configureParameters();
2713474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown
271465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Configure common accumulators.
271565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mCursorScrollAccumulator.configure(getDevice());
271665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mTouchButtonAccumulator.configure(getDevice());
271783c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown
2718474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        // Configure absolute axis information.
2719be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        configureRawPointerAxes();
27208d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
2721474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        // Prepare input device calibration.
2722474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        parseCalibration();
2723474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        resolveCalibration();
2724474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    }
2725474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown
2726474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
272765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Update pointer speed.
272865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerVelocityControl.setParameters(mConfig.pointerVelocityControlParameters);
272965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mWheelXVelocityControl.setParameters(mConfig.wheelVelocityControlParameters);
273065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mWheelYVelocityControl.setParameters(mConfig.wheelVelocityControlParameters);
2731474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    }
2732474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown
273365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    bool resetNeeded = false;
273465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (!changes || (changes & (InputReaderConfiguration::CHANGE_DISPLAY_INFO
2735daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown            | InputReaderConfiguration::CHANGE_POINTER_GESTURE_ENABLEMENT
2736daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown            | InputReaderConfiguration::CHANGE_SHOW_TOUCHES))) {
273765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Configure device sources, surface dimensions, orientation and
273865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // scaling factors.
273965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        configureSurface(when, &resetNeeded);
274065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
274165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
274265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (changes && resetNeeded) {
274365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Send reset, unless this is the first time the device has been configured,
274465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // in which case the reader will call reset itself after all mappers are ready.
274565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        getDevice()->notifyReset(when);
2746474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    }
27476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
274846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
27498d60866e2100db70ecf0502c14768a384514d7e9Jeff Brownvoid TouchInputMapper::configureParameters() {
2750b12682270aebc110c9518bddae7a8aecc070cad7Jeff Brown    // Use the pointer presentation mode for devices that do not support distinct
2751b12682270aebc110c9518bddae7a8aecc070cad7Jeff Brown    // multitouch.  The spot-based presentation relies on being able to accurately
2752b12682270aebc110c9518bddae7a8aecc070cad7Jeff Brown    // locate two or more fingers on the touch pad.
2753b12682270aebc110c9518bddae7a8aecc070cad7Jeff Brown    mParameters.gestureMode = getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_SEMI_MT)
2754b12682270aebc110c9518bddae7a8aecc070cad7Jeff Brown            ? Parameters::GESTURE_MODE_POINTER : Parameters::GESTURE_MODE_SPOTS;
27552352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
2756538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    String8 gestureModeString;
2757538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    if (getDevice()->getConfiguration().tryGetProperty(String8("touch.gestureMode"),
2758538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown            gestureModeString)) {
2759538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        if (gestureModeString == "pointer") {
2760538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown            mParameters.gestureMode = Parameters::GESTURE_MODE_POINTER;
2761538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        } else if (gestureModeString == "spots") {
2762538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown            mParameters.gestureMode = Parameters::GESTURE_MODE_SPOTS;
2763538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        } else if (gestureModeString != "default") {
27648564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Invalid value for touch.gestureMode: '%s'", gestureModeString.string());
2765538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        }
2766538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    }
2767538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown
2768deffe07c225c15ce780fad4a500d082f2dbdabeaJeff Brown    if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_DIRECT)) {
2769deffe07c225c15ce780fad4a500d082f2dbdabeaJeff Brown        // The device is a touch screen.
2770deffe07c225c15ce780fad4a500d082f2dbdabeaJeff Brown        mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
2771deffe07c225c15ce780fad4a500d082f2dbdabeaJeff Brown    } else if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_POINTER)) {
2772deffe07c225c15ce780fad4a500d082f2dbdabeaJeff Brown        // The device is a pointing device like a track pad.
2773deffe07c225c15ce780fad4a500d082f2dbdabeaJeff Brown        mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
2774deffe07c225c15ce780fad4a500d082f2dbdabeaJeff Brown    } else if (getEventHub()->hasRelativeAxis(getDeviceId(), REL_X)
2775ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            || getEventHub()->hasRelativeAxis(getDeviceId(), REL_Y)) {
2776ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // The device is a cursor device with a touch pad attached.
2777ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // By default don't use the touch pad to move the pointer.
2778ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
2779ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    } else {
278080fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        // The device is a touch pad of unknown purpose.
2781ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
2782ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
2783ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
278447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    String8 deviceTypeString;
278547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    if (getDevice()->getConfiguration().tryGetProperty(String8("touch.deviceType"),
278647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            deviceTypeString)) {
278758a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown        if (deviceTypeString == "touchScreen") {
278858a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown            mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
2789efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown        } else if (deviceTypeString == "touchPad") {
2790efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown            mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
2791ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        } else if (deviceTypeString == "pointer") {
2792ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
2793538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        } else if (deviceTypeString != "default") {
27948564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Invalid value for touch.deviceType: '%s'", deviceTypeString.string());
279547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        }
279647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    }
279747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
2798efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown    mParameters.orientationAware = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN;
279947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    getDevice()->getConfiguration().tryGetProperty(String8("touch.orientationAware"),
280047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            mParameters.orientationAware);
280147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
2802d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    mParameters.hasAssociatedDisplay = false;
2803bc68a59c024bdb745dac8e2ec7408a9f30595f1aJeff Brown    mParameters.associatedDisplayIsExternal = false;
2804bc68a59c024bdb745dac8e2ec7408a9f30595f1aJeff Brown    if (mParameters.orientationAware
2805efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown            || mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
2806bc68a59c024bdb745dac8e2ec7408a9f30595f1aJeff Brown            || mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) {
2807d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        mParameters.hasAssociatedDisplay = true;
2808bc68a59c024bdb745dac8e2ec7408a9f30595f1aJeff Brown        mParameters.associatedDisplayIsExternal =
2809bc68a59c024bdb745dac8e2ec7408a9f30595f1aJeff Brown                mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
2810bc68a59c024bdb745dac8e2ec7408a9f30595f1aJeff Brown                        && getDevice()->isExternal();
2811bc68a59c024bdb745dac8e2ec7408a9f30595f1aJeff Brown    }
28128d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown}
28138d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
2814ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brownvoid TouchInputMapper::dumpParameters(String8& dump) {
281547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    dump.append(INDENT3 "Parameters:\n");
281647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
2817538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    switch (mParameters.gestureMode) {
2818538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    case Parameters::GESTURE_MODE_POINTER:
2819538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        dump.append(INDENT4 "GestureMode: pointer\n");
2820538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        break;
2821538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    case Parameters::GESTURE_MODE_SPOTS:
2822538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        dump.append(INDENT4 "GestureMode: spots\n");
2823538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        break;
2824538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    default:
2825538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        assert(false);
2826538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    }
2827538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown
282847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    switch (mParameters.deviceType) {
282947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    case Parameters::DEVICE_TYPE_TOUCH_SCREEN:
283047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        dump.append(INDENT4 "DeviceType: touchScreen\n");
283147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        break;
283247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    case Parameters::DEVICE_TYPE_TOUCH_PAD:
283347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        dump.append(INDENT4 "DeviceType: touchPad\n");
283447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        break;
2835ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    case Parameters::DEVICE_TYPE_POINTER:
2836ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        dump.append(INDENT4 "DeviceType: pointer\n");
2837ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        break;
283847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    default:
2839ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block        ALOG_ASSERT(false);
284047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    }
284147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
284283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    dump.appendFormat(INDENT4 "AssociatedDisplay: hasAssociatedDisplay=%s, isExternal=%s\n",
2843d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            toString(mParameters.hasAssociatedDisplay),
2844d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            toString(mParameters.associatedDisplayIsExternal));
284547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    dump.appendFormat(INDENT4 "OrientationAware: %s\n",
284647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            toString(mParameters.orientationAware));
2847b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
2848b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
2849be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid TouchInputMapper::configureRawPointerAxes() {
2850be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mRawPointerAxes.clear();
2851be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
2852be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
2853be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid TouchInputMapper::dumpRawPointerAxes(String8& dump) {
2854be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.append(INDENT3 "Raw Touch Axes:\n");
2855be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.x, "X");
2856be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.y, "Y");
2857be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.pressure, "Pressure");
2858be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.touchMajor, "TouchMajor");
2859be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.touchMinor, "TouchMinor");
2860be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.toolMajor, "ToolMajor");
2861be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.toolMinor, "ToolMinor");
2862be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.orientation, "Orientation");
2863be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.distance, "Distance");
286465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.tiltX, "TiltX");
286565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.tiltY, "TiltY");
2866be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.trackingId, "TrackingId");
2867be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.slot, "Slot");
2868be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
2869be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
287065fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
287165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    int32_t oldDeviceMode = mDeviceMode;
287265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
287365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Determine device mode.
287465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER
287565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            && mConfig.pointerGesturesEnabled) {
287665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mSource = AINPUT_SOURCE_MOUSE;
287765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mDeviceMode = DEVICE_MODE_POINTER;
287800710e906bdafd58386ee7f81fa84addd218122fJeff Brown        if (hasStylus()) {
287900710e906bdafd58386ee7f81fa84addd218122fJeff Brown            mSource |= AINPUT_SOURCE_STYLUS;
288000710e906bdafd58386ee7f81fa84addd218122fJeff Brown        }
288165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    } else if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
2882d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            && mParameters.hasAssociatedDisplay) {
288365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mSource = AINPUT_SOURCE_TOUCHSCREEN;
288465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mDeviceMode = DEVICE_MODE_DIRECT;
288500710e906bdafd58386ee7f81fa84addd218122fJeff Brown        if (hasStylus()) {
288600710e906bdafd58386ee7f81fa84addd218122fJeff Brown            mSource |= AINPUT_SOURCE_STYLUS;
288700710e906bdafd58386ee7f81fa84addd218122fJeff Brown        }
288865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    } else {
288965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mSource = AINPUT_SOURCE_TOUCHPAD;
289065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mDeviceMode = DEVICE_MODE_UNSCALED;
289165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
289265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
28939626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown    // Ensure we have valid X and Y axes.
2894be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (!mRawPointerAxes.x.valid || !mRawPointerAxes.y.valid) {
28958564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW(INDENT "Touch device '%s' did not report support for X or Y axis!  "
28969626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                "The device will be inoperable.", getDeviceName().string());
289765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mDeviceMode = DEVICE_MODE_DISABLED;
289865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        return;
28999626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown    }
29009626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown
290183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    // Raw width and height in the natural orientation.
290283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    int32_t rawWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
290383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    int32_t rawHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
290483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown
290565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Get associated display dimensions.
290683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    bool viewportChanged = false;
290783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    DisplayViewport newViewport;
2908d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    if (mParameters.hasAssociatedDisplay) {
290983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        if (!mConfig.getDisplayInfo(mParameters.associatedDisplayIsExternal, &newViewport)) {
29106215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block            ALOGI(INDENT "Touch device '%s' could not query the properties of its associated "
2911d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                    "display.  The device will be inoperable until the display size "
291265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    "becomes available.",
2913d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                    getDeviceName().string());
291465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mDeviceMode = DEVICE_MODE_DISABLED;
291565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            return;
29166d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
291783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    } else {
291883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        newViewport.setNonDisplayViewport(rawWidth, rawHeight);
291983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    }
292083d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    if (mViewport != newViewport) {
292183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        mViewport = newViewport;
292283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        viewportChanged = true;
292383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown
292483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        if (mDeviceMode == DEVICE_MODE_DIRECT || mDeviceMode == DEVICE_MODE_POINTER) {
292583d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            // Convert rotated viewport to natural surface coordinates.
292683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            int32_t naturalLogicalWidth, naturalLogicalHeight;
292783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            int32_t naturalPhysicalWidth, naturalPhysicalHeight;
292883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            int32_t naturalPhysicalLeft, naturalPhysicalTop;
292983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            int32_t naturalDeviceWidth, naturalDeviceHeight;
293083d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            switch (mViewport.orientation) {
293183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            case DISPLAY_ORIENTATION_90:
293283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalLogicalWidth = mViewport.logicalBottom - mViewport.logicalTop;
293383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
293483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
293583d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
293683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalLeft = mViewport.deviceHeight - mViewport.physicalBottom;
293783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalTop = mViewport.physicalLeft;
293883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalDeviceWidth = mViewport.deviceHeight;
293983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalDeviceHeight = mViewport.deviceWidth;
294083d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                break;
294183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            case DISPLAY_ORIENTATION_180:
294283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalLogicalWidth = mViewport.logicalRight - mViewport.logicalLeft;
294383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalLogicalHeight = mViewport.logicalBottom - mViewport.logicalTop;
294483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft;
294583d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop;
294683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalLeft = mViewport.deviceWidth - mViewport.physicalRight;
294783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalTop = mViewport.deviceHeight - mViewport.physicalBottom;
294883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalDeviceWidth = mViewport.deviceWidth;
294983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalDeviceHeight = mViewport.deviceHeight;
295083d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                break;
295183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            case DISPLAY_ORIENTATION_270:
295283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalLogicalWidth = mViewport.logicalBottom - mViewport.logicalTop;
295383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
295483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
295583d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
295683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalLeft = mViewport.physicalTop;
295783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalTop = mViewport.deviceWidth - mViewport.physicalRight;
295883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalDeviceWidth = mViewport.deviceHeight;
295983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalDeviceHeight = mViewport.deviceWidth;
296083d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                break;
296183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            case DISPLAY_ORIENTATION_0:
296283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            default:
296383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalLogicalWidth = mViewport.logicalRight - mViewport.logicalLeft;
296483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalLogicalHeight = mViewport.logicalBottom - mViewport.logicalTop;
296583d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft;
296683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop;
296783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalLeft = mViewport.physicalLeft;
296883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalTop = mViewport.physicalTop;
296983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalDeviceWidth = mViewport.deviceWidth;
297083d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalDeviceHeight = mViewport.deviceHeight;
297183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                break;
297283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            }
297383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown
297483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mSurfaceWidth = naturalLogicalWidth * naturalDeviceWidth / naturalPhysicalWidth;
297583d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mSurfaceHeight = naturalLogicalHeight * naturalDeviceHeight / naturalPhysicalHeight;
297683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mSurfaceLeft = naturalPhysicalLeft * naturalLogicalWidth / naturalPhysicalWidth;
297783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mSurfaceTop = naturalPhysicalTop * naturalLogicalHeight / naturalPhysicalHeight;
2978efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown
297983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mSurfaceOrientation = mParameters.orientationAware ?
298083d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                    mViewport.orientation : DISPLAY_ORIENTATION_0;
298183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        } else {
298283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mSurfaceWidth = rawWidth;
298383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mSurfaceHeight = rawHeight;
298483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mSurfaceLeft = 0;
298583d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mSurfaceTop = 0;
298683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mSurfaceOrientation = DISPLAY_ORIENTATION_0;
2987d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        }
298865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
298965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
299065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // If moving between pointer modes, need to reset some state.
299165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    bool deviceModeChanged;
299265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mDeviceMode != oldDeviceMode) {
299365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        deviceModeChanged = true;
2994daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown        mOrientedRanges.clear();
2995daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown    }
2996efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown
2997daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown    // Create pointer controller if needed.
2998daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown    if (mDeviceMode == DEVICE_MODE_POINTER ||
2999daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown            (mDeviceMode == DEVICE_MODE_DIRECT && mConfig.showTouches)) {
3000daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown        if (mPointerController == NULL) {
3001daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown            mPointerController = getPolicy()->obtainPointerController(getDeviceId());
3002efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown        }
3003daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown    } else {
3004daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown        mPointerController.clear();
3005ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
3006ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
300783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    if (viewportChanged || deviceModeChanged) {
300883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        ALOGI("Device reconfigured: id=%d, name='%s', size %dx%d, orientation %d, mode %d, "
300983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                "display id %d",
301083d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                getDeviceId(), getDeviceName().string(), mSurfaceWidth, mSurfaceHeight,
301183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                mSurfaceOrientation, mDeviceMode, mViewport.displayId);
301246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
30138d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // Configure X and Y factors.
301483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        mXScale = float(mSurfaceWidth) / rawWidth;
301583d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        mYScale = float(mSurfaceHeight) / rawHeight;
301683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        mXTranslate = -mSurfaceLeft;
301783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        mYTranslate = -mSurfaceTop;
3018be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mXPrecision = 1.0f / mXScale;
3019be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mYPrecision = 1.0f / mYScale;
30209626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown
3021be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mOrientedRanges.x.axis = AMOTION_EVENT_AXIS_X;
302265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mOrientedRanges.x.source = mSource;
3023be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mOrientedRanges.y.axis = AMOTION_EVENT_AXIS_Y;
302465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mOrientedRanges.y.source = mSource;
3025efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown
3026be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        configureVirtualKeys();
30270b72e82c5f5d4ab709539c3490d6c7023f680dffJeff Brown
30288d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // Scale factor for terms that are not oriented in a particular axis.
30298d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // If the pixels are square then xScale == yScale otherwise we fake it
30308d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // by choosing an average.
3031be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mGeometricScale = avg(mXScale, mYScale);
30328d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
30338d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // Size of diagonal axis.
303483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        float diagonalSize = hypotf(mSurfaceWidth, mSurfaceHeight);
30358d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
3036a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        // Size factors.
3037a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) {
3038a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            if (mRawPointerAxes.touchMajor.valid
3039a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                    && mRawPointerAxes.touchMajor.maxValue != 0) {
3040a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                mSizeScale = 1.0f / mRawPointerAxes.touchMajor.maxValue;
3041a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            } else if (mRawPointerAxes.toolMajor.valid
3042a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                    && mRawPointerAxes.toolMajor.maxValue != 0) {
3043a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                mSizeScale = 1.0f / mRawPointerAxes.toolMajor.maxValue;
3044a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            } else {
3045a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                mSizeScale = 0.0f;
3046a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            }
3047a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown
3048be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.haveTouchSize = true;
3049a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mOrientedRanges.haveToolSize = true;
3050a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mOrientedRanges.haveSize = true;
3051efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown
3052be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.touchMajor.axis = AMOTION_EVENT_AXIS_TOUCH_MAJOR;
305365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.touchMajor.source = mSource;
3054be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.touchMajor.min = 0;
3055be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.touchMajor.max = diagonalSize;
3056be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.touchMajor.flat = 0;
3057be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.touchMajor.fuzz = 0;
3058efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown
3059be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.touchMinor = mOrientedRanges.touchMajor;
3060be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.touchMinor.axis = AMOTION_EVENT_AXIS_TOUCH_MINOR;
3061efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown
3062be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.toolMajor.axis = AMOTION_EVENT_AXIS_TOOL_MAJOR;
306365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.toolMajor.source = mSource;
3064be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.toolMajor.min = 0;
3065be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.toolMajor.max = diagonalSize;
3066be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.toolMajor.flat = 0;
3067be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.toolMajor.fuzz = 0;
3068efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown
3069be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.toolMinor = mOrientedRanges.toolMajor;
3070be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.toolMinor.axis = AMOTION_EVENT_AXIS_TOOL_MINOR;
3071a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown
3072a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mOrientedRanges.size.axis = AMOTION_EVENT_AXIS_SIZE;
307365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.size.source = mSource;
3074a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mOrientedRanges.size.min = 0;
3075a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mOrientedRanges.size.max = 1.0;
3076a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mOrientedRanges.size.flat = 0;
3077a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mOrientedRanges.size.fuzz = 0;
3078a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        } else {
3079a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mSizeScale = 0.0f;
30808d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
30818d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
30828d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // Pressure factors.
3083be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mPressureScale = 0;
308465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_PHYSICAL
308565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                || mCalibration.pressureCalibration
308665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                        == Calibration::PRESSURE_CALIBRATION_AMPLITUDE) {
308765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            if (mCalibration.havePressureScale) {
308865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPressureScale = mCalibration.pressureScale;
308965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            } else if (mRawPointerAxes.pressure.valid
309065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    && mRawPointerAxes.pressure.maxValue != 0) {
309165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPressureScale = 1.0f / mRawPointerAxes.pressure.maxValue;
30928d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
309365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
30948d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
309565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mOrientedRanges.pressure.axis = AMOTION_EVENT_AXIS_PRESSURE;
309665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mOrientedRanges.pressure.source = mSource;
309765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mOrientedRanges.pressure.min = 0;
309865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mOrientedRanges.pressure.max = 1.0;
309965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mOrientedRanges.pressure.flat = 0;
310065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mOrientedRanges.pressure.fuzz = 0;
310165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
310265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Tilt
310365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mTiltXCenter = 0;
310465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mTiltXScale = 0;
310565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mTiltYCenter = 0;
310665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mTiltYScale = 0;
310765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mHaveTilt = mRawPointerAxes.tiltX.valid && mRawPointerAxes.tiltY.valid;
310865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mHaveTilt) {
310965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mTiltXCenter = avg(mRawPointerAxes.tiltX.minValue,
311065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    mRawPointerAxes.tiltX.maxValue);
311165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mTiltYCenter = avg(mRawPointerAxes.tiltY.minValue,
311265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    mRawPointerAxes.tiltY.maxValue);
311365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mTiltXScale = M_PI / 180;
311465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mTiltYScale = M_PI / 180;
311565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
311665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.haveTilt = true;
311765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
311865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.tilt.axis = AMOTION_EVENT_AXIS_TILT;
311965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.tilt.source = mSource;
312065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.tilt.min = 0;
312165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.tilt.max = M_PI_2;
312265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.tilt.flat = 0;
312365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.tilt.fuzz = 0;
31248d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
31258d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
31268d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // Orientation
3127be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mOrientationScale = 0;
312865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mHaveTilt) {
312965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.haveOrientation = true;
313065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
313165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
313265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.orientation.source = mSource;
313365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.orientation.min = -M_PI;
313465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.orientation.max = M_PI;
313565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.orientation.flat = 0;
313665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.orientation.fuzz = 0;
313765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        } else if (mCalibration.orientationCalibration !=
313865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                Calibration::ORIENTATION_CALIBRATION_NONE) {
31398d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            if (mCalibration.orientationCalibration
31408d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    == Calibration::ORIENTATION_CALIBRATION_INTERPOLATED) {
314165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                if (mRawPointerAxes.orientation.valid) {
3142037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown                    if (mRawPointerAxes.orientation.maxValue > 0) {
3143037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown                        mOrientationScale = M_PI_2 / mRawPointerAxes.orientation.maxValue;
3144037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown                    } else if (mRawPointerAxes.orientation.minValue < 0) {
3145037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown                        mOrientationScale = -M_PI_2 / mRawPointerAxes.orientation.minValue;
3146037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown                    } else {
3147037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown                        mOrientationScale = 0;
3148037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown                    }
31498d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                }
31508d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
31516328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
3152be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.haveOrientation = true;
315380fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
3154be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
315565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.orientation.source = mSource;
315665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.orientation.min = -M_PI_2;
3157be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.orientation.max = M_PI_2;
3158be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.orientation.flat = 0;
3159be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.orientation.fuzz = 0;
31608d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
316180fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
316280fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        // Distance
3163be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mDistanceScale = 0;
316480fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        if (mCalibration.distanceCalibration != Calibration::DISTANCE_CALIBRATION_NONE) {
316580fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            if (mCalibration.distanceCalibration
316680fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                    == Calibration::DISTANCE_CALIBRATION_SCALED) {
316780fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                if (mCalibration.haveDistanceScale) {
3168be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mDistanceScale = mCalibration.distanceScale;
316980fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                } else {
3170be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mDistanceScale = 1.0f;
317180fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                }
317280fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            }
317380fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
3174be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.haveDistance = true;
317580fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
3176be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.distance.axis = AMOTION_EVENT_AXIS_DISTANCE;
317765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.distance.source = mSource;
3178be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.distance.min =
3179be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mRawPointerAxes.distance.minValue * mDistanceScale;
3180be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.distance.max =
31818239940d0efb7e536d932473c535c1d9bb0ab658Andreas Sandblad                    mRawPointerAxes.distance.maxValue * mDistanceScale;
3182be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.distance.flat = 0;
3183be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.distance.fuzz =
3184be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mRawPointerAxes.distance.fuzz * mDistanceScale;
318580fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        }
31866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
318783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        // Compute oriented precision, scales and ranges.
31889626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        // Note that the maximum value reported is an inclusive maximum value so it is one
31899626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        // unit less than the total width or height of surface.
3190be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        switch (mSurfaceOrientation) {
3191b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        case DISPLAY_ORIENTATION_90:
3192b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        case DISPLAY_ORIENTATION_270:
3193be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedXPrecision = mYPrecision;
3194be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedYPrecision = mXPrecision;
3195be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
319683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mOrientedRanges.x.min = mYTranslate;
319783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mOrientedRanges.x.max = mSurfaceHeight + mYTranslate - 1;
3198be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.x.flat = 0;
3199be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.x.fuzz = mYScale;
3200be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
320183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mOrientedRanges.y.min = mXTranslate;
320283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mOrientedRanges.y.max = mSurfaceWidth + mXTranslate - 1;
3203be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.y.flat = 0;
3204be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.y.fuzz = mXScale;
32056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
32069626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown
32076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        default:
3208be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedXPrecision = mXPrecision;
3209be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedYPrecision = mYPrecision;
3210be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
321183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mOrientedRanges.x.min = mXTranslate;
321283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mOrientedRanges.x.max = mSurfaceWidth + mXTranslate - 1;
3213be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.x.flat = 0;
3214be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.x.fuzz = mXScale;
3215be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
321683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mOrientedRanges.y.min = mYTranslate;
321783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mOrientedRanges.y.max = mSurfaceHeight + mYTranslate - 1;
3218be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.y.flat = 0;
3219be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.y.fuzz = mYScale;
32206d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
32210b72e82c5f5d4ab709539c3490d6c7023f680dffJeff Brown        }
3222ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
3223ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Compute pointer gesture detection parameters.
322465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mDeviceMode == DEVICE_MODE_POINTER) {
32252352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            float rawDiagonal = hypotf(rawWidth, rawHeight);
322683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            float displayDiagonal = hypotf(mSurfaceWidth, mSurfaceHeight);
3227ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
32282352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            // Scale movements such that one whole swipe of the touch pad covers a
322919c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            // given area relative to the diagonal size of the display when no acceleration
323019c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            // is applied.
3231ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            // Assume that the touch pad has a square aspect ratio such that movements in
3232ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            // X and Y of the same number of raw units cover the same physical distance.
323365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerXMovementScale = mConfig.pointerGestureMovementSpeedRatio
32342352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                    * displayDiagonal / rawDiagonal;
323565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerYMovementScale = mPointerXMovementScale;
3236ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
3237ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            // Scale zooms to cover a smaller range of the display than movements do.
3238ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            // This value determines the area around the pointer that is affected by freeform
3239ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            // pointer gestures.
324065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerXZoomScale = mConfig.pointerGestureZoomSpeedRatio
32412352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                    * displayDiagonal / rawDiagonal;
324265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerYZoomScale = mPointerXZoomScale;
3243ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
32442352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            // Max width between pointers to detect a swipe gesture is more than some fraction
32452352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            // of the diagonal axis of the touch pad.  Touches that are wider than this are
32462352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            // translated into freeform gestures.
3247be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mPointerGestureMaxSwipeWidth =
3248474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    mConfig.pointerGestureSwipeMaxWidthRatio * rawDiagonal;
324965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
32502352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
325165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Abort current pointer usages because the state has changed.
325265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        abortPointerUsage(when, 0 /*policyFlags*/);
32532352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
325465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Inform the dispatcher about the changes.
325565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        *outResetNeeded = true;
3256af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown        bumpGeneration();
325746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
325846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
325946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3260be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid TouchInputMapper::dumpSurface(String8& dump) {
326183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    dump.appendFormat(INDENT3 "Viewport: displayId=%d, orientation=%d, "
326283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            "logicalFrame=[%d, %d, %d, %d], "
326383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            "physicalFrame=[%d, %d, %d, %d], "
326483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            "deviceSize=[%d, %d]\n",
326583d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mViewport.displayId, mViewport.orientation,
326683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mViewport.logicalLeft, mViewport.logicalTop,
326783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mViewport.logicalRight, mViewport.logicalBottom,
326883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mViewport.physicalLeft, mViewport.physicalTop,
326983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mViewport.physicalRight, mViewport.physicalBottom,
327083d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mViewport.deviceWidth, mViewport.deviceHeight);
327183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown
3272be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mSurfaceWidth);
3273be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mSurfaceHeight);
327483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    dump.appendFormat(INDENT3 "SurfaceLeft: %d\n", mSurfaceLeft);
327583d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    dump.appendFormat(INDENT3 "SurfaceTop: %d\n", mSurfaceTop);
3276be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mSurfaceOrientation);
3277b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
3278b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
3279be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid TouchInputMapper::configureVirtualKeys() {
32808d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    Vector<VirtualKeyDefinition> virtualKeyDefinitions;
32819065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown    getEventHub()->getVirtualKeyDefinitions(getDeviceId(), virtualKeyDefinitions);
32820b72e82c5f5d4ab709539c3490d6c7023f680dffJeff Brown
3283be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mVirtualKeys.clear();
32840b72e82c5f5d4ab709539c3490d6c7023f680dffJeff Brown
32856328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    if (virtualKeyDefinitions.size() == 0) {
32866328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        return;
32876328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    }
32886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
3289be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mVirtualKeys.setCapacity(virtualKeyDefinitions.size());
32906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
3291be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t touchScreenLeft = mRawPointerAxes.x.minValue;
3292be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t touchScreenTop = mRawPointerAxes.y.minValue;
3293be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t touchScreenWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
3294be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t touchScreenHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
32956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
32966328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
32978d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        const VirtualKeyDefinition& virtualKeyDefinition =
32986328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                virtualKeyDefinitions[i];
32996d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
3300be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mVirtualKeys.add();
3301be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        VirtualKey& virtualKey = mVirtualKeys.editTop();
33020b72e82c5f5d4ab709539c3490d6c7023f680dffJeff Brown
33036328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        virtualKey.scanCode = virtualKeyDefinition.scanCode;
33046328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        int32_t keyCode;
33056328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        uint32_t flags;
330649ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode, 0, &keyCode, &flags)) {
33078564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring",
33088d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    virtualKey.scanCode);
3309be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mVirtualKeys.pop(); // drop the key
33106328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            continue;
33116328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        }
33120b72e82c5f5d4ab709539c3490d6c7023f680dffJeff Brown
33136328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        virtualKey.keyCode = keyCode;
33146328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        virtualKey.flags = flags;
33156d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
33166328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        // convert the key definition's display coordinates into touch coordinates for a hit box
33176328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        int32_t halfWidth = virtualKeyDefinition.width / 2;
33186328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        int32_t halfHeight = virtualKeyDefinition.height / 2;
33196328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
33206328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth)
3321be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
33226328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth)
3323be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
33246328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight)
3325be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                * touchScreenHeight / mSurfaceHeight + touchScreenTop;
33266328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
3327be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                * touchScreenHeight / mSurfaceHeight + touchScreenTop;
3328ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    }
3329ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown}
3330ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
3331be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid TouchInputMapper::dumpVirtualKeys(String8& dump) {
3332be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (!mVirtualKeys.isEmpty()) {
3333ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT3 "Virtual Keys:\n");
3334ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
3335be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        for (size_t i = 0; i < mVirtualKeys.size(); i++) {
3336be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const VirtualKey& virtualKey = mVirtualKeys.itemAt(i);
3337ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown            dump.appendFormat(INDENT4 "%d: scanCode=%d, keyCode=%d, "
3338ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown                    "hitLeft=%d, hitRight=%d, hitTop=%d, hitBottom=%d\n",
3339ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown                    i, virtualKey.scanCode, virtualKey.keyCode,
3340ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown                    virtualKey.hitLeft, virtualKey.hitRight,
3341ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown                    virtualKey.hitTop, virtualKey.hitBottom);
3342ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        }
33436328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    }
334446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
334546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
33468d60866e2100db70ecf0502c14768a384514d7e9Jeff Brownvoid TouchInputMapper::parseCalibration() {
334747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    const PropertyMap& in = getDevice()->getConfiguration();
33488d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    Calibration& out = mCalibration;
33498d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
3350a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    // Size
3351a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    out.sizeCalibration = Calibration::SIZE_CALIBRATION_DEFAULT;
3352a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    String8 sizeCalibrationString;
3353a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    if (in.tryGetProperty(String8("touch.size.calibration"), sizeCalibrationString)) {
3354a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        if (sizeCalibrationString == "none") {
3355a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            out.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
3356a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        } else if (sizeCalibrationString == "geometric") {
3357a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            out.sizeCalibration = Calibration::SIZE_CALIBRATION_GEOMETRIC;
3358a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        } else if (sizeCalibrationString == "diameter") {
3359a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            out.sizeCalibration = Calibration::SIZE_CALIBRATION_DIAMETER;
3360037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown        } else if (sizeCalibrationString == "box") {
3361037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown            out.sizeCalibration = Calibration::SIZE_CALIBRATION_BOX;
3362a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        } else if (sizeCalibrationString == "area") {
3363a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            out.sizeCalibration = Calibration::SIZE_CALIBRATION_AREA;
3364a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        } else if (sizeCalibrationString != "default") {
33658564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Invalid value for touch.size.calibration: '%s'",
3366a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                    sizeCalibrationString.string());
3367a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        }
3368a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    }
3369a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown
3370a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    out.haveSizeScale = in.tryGetProperty(String8("touch.size.scale"),
3371a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            out.sizeScale);
3372a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    out.haveSizeBias = in.tryGetProperty(String8("touch.size.bias"),
3373a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            out.sizeBias);
3374a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    out.haveSizeIsSummed = in.tryGetProperty(String8("touch.size.isSummed"),
3375a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            out.sizeIsSummed);
33768d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
33778d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    // Pressure
33788d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_DEFAULT;
33798d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    String8 pressureCalibrationString;
3380c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    if (in.tryGetProperty(String8("touch.pressure.calibration"), pressureCalibrationString)) {
33818d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        if (pressureCalibrationString == "none") {
33828d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
33838d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else if (pressureCalibrationString == "physical") {
33848d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
33858d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else if (pressureCalibrationString == "amplitude") {
33868d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE;
33878d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else if (pressureCalibrationString != "default") {
33888564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Invalid value for touch.pressure.calibration: '%s'",
33898d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    pressureCalibrationString.string());
33908d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
33918d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
33928d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
33938d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    out.havePressureScale = in.tryGetProperty(String8("touch.pressure.scale"),
33948d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            out.pressureScale);
33958d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
33968d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    // Orientation
33978d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_DEFAULT;
33988d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    String8 orientationCalibrationString;
3399c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    if (in.tryGetProperty(String8("touch.orientation.calibration"), orientationCalibrationString)) {
34008d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        if (orientationCalibrationString == "none") {
34018d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
34028d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else if (orientationCalibrationString == "interpolated") {
34038d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
3404517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown        } else if (orientationCalibrationString == "vector") {
3405517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_VECTOR;
34068d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else if (orientationCalibrationString != "default") {
34078564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Invalid value for touch.orientation.calibration: '%s'",
34088d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    orientationCalibrationString.string());
34098d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
34108d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
341180fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
341280fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    // Distance
341380fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_DEFAULT;
341480fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    String8 distanceCalibrationString;
341580fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    if (in.tryGetProperty(String8("touch.distance.calibration"), distanceCalibrationString)) {
341680fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        if (distanceCalibrationString == "none") {
341780fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE;
341880fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        } else if (distanceCalibrationString == "scaled") {
341980fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_SCALED;
342080fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        } else if (distanceCalibrationString != "default") {
34218564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Invalid value for touch.distance.calibration: '%s'",
342280fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                    distanceCalibrationString.string());
342380fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        }
342480fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    }
342580fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
342680fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    out.haveDistanceScale = in.tryGetProperty(String8("touch.distance.scale"),
342780fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            out.distanceScale);
34288d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown}
34298d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
34308d60866e2100db70ecf0502c14768a384514d7e9Jeff Brownvoid TouchInputMapper::resolveCalibration() {
3431a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    // Size
3432a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    if (mRawPointerAxes.touchMajor.valid || mRawPointerAxes.toolMajor.valid) {
3433a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_DEFAULT) {
3434a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_GEOMETRIC;
34358d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
3436a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    } else {
3437a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
34388d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
34398d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
3440a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    // Pressure
3441a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    if (mRawPointerAxes.pressure.valid) {
3442a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_DEFAULT) {
3443a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
34448d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
3445a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    } else {
3446a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
34478d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
34488d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
34498d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    // Orientation
3450a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    if (mRawPointerAxes.orientation.valid) {
3451a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        if (mCalibration.orientationCalibration == Calibration::ORIENTATION_CALIBRATION_DEFAULT) {
34528d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
34538d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
3454a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    } else {
3455a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
34568d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
345780fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
345880fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    // Distance
3459a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    if (mRawPointerAxes.distance.valid) {
3460a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        if (mCalibration.distanceCalibration == Calibration::DISTANCE_CALIBRATION_DEFAULT) {
346180fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_SCALED;
346280fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        }
3463a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    } else {
3464a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE;
346580fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    }
34668d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown}
34678d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
3468ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brownvoid TouchInputMapper::dumpCalibration(String8& dump) {
3469ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    dump.append(INDENT3 "Calibration:\n");
3470b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
3471a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    // Size
3472a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    switch (mCalibration.sizeCalibration) {
3473a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    case Calibration::SIZE_CALIBRATION_NONE:
3474a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        dump.append(INDENT4 "touch.size.calibration: none\n");
34758d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
3476a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    case Calibration::SIZE_CALIBRATION_GEOMETRIC:
3477a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        dump.append(INDENT4 "touch.size.calibration: geometric\n");
34788d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
3479a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    case Calibration::SIZE_CALIBRATION_DIAMETER:
3480a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        dump.append(INDENT4 "touch.size.calibration: diameter\n");
3481c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        break;
3482037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown    case Calibration::SIZE_CALIBRATION_BOX:
3483037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown        dump.append(INDENT4 "touch.size.calibration: box\n");
3484037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown        break;
3485a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    case Calibration::SIZE_CALIBRATION_AREA:
3486a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        dump.append(INDENT4 "touch.size.calibration: area\n");
34878d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
34888d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    default:
3489ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block        ALOG_ASSERT(false);
34908d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
34918d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
3492a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    if (mCalibration.haveSizeScale) {
3493a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        dump.appendFormat(INDENT4 "touch.size.scale: %0.3f\n",
3494a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                mCalibration.sizeScale);
34958d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
34968d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
3497a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    if (mCalibration.haveSizeBias) {
3498a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        dump.appendFormat(INDENT4 "touch.size.bias: %0.3f\n",
3499a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                mCalibration.sizeBias);
35008d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
35018d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
3502a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    if (mCalibration.haveSizeIsSummed) {
3503a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        dump.appendFormat(INDENT4 "touch.size.isSummed: %s\n",
3504a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                toString(mCalibration.sizeIsSummed));
35058d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
35068d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
35078d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    // Pressure
35088d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    switch (mCalibration.pressureCalibration) {
35098d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::PRESSURE_CALIBRATION_NONE:
3510ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT4 "touch.pressure.calibration: none\n");
35118d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
35128d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
3513ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT4 "touch.pressure.calibration: physical\n");
35148d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
35158d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
3516ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT4 "touch.pressure.calibration: amplitude\n");
35178d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
35188d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    default:
3519ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block        ALOG_ASSERT(false);
35208d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
35218d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
35228d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    if (mCalibration.havePressureScale) {
3523ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.appendFormat(INDENT4 "touch.pressure.scale: %0.3f\n",
3524ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown                mCalibration.pressureScale);
35258d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
35268d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
35278d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    // Orientation
35288d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    switch (mCalibration.orientationCalibration) {
35298d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::ORIENTATION_CALIBRATION_NONE:
3530ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT4 "touch.orientation.calibration: none\n");
35318d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
35328d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
3533ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT4 "touch.orientation.calibration: interpolated\n");
35348d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
3535517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown    case Calibration::ORIENTATION_CALIBRATION_VECTOR:
3536517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown        dump.append(INDENT4 "touch.orientation.calibration: vector\n");
3537517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown        break;
35388d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    default:
3539ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block        ALOG_ASSERT(false);
35408d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
354180fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
354280fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    // Distance
354380fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    switch (mCalibration.distanceCalibration) {
354480fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    case Calibration::DISTANCE_CALIBRATION_NONE:
354580fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        dump.append(INDENT4 "touch.distance.calibration: none\n");
354680fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        break;
354780fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    case Calibration::DISTANCE_CALIBRATION_SCALED:
354880fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        dump.append(INDENT4 "touch.distance.calibration: scaled\n");
354980fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        break;
355080fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    default:
3551ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block        ALOG_ASSERT(false);
355280fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    }
355380fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
355480fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    if (mCalibration.haveDistanceScale) {
355580fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        dump.appendFormat(INDENT4 "touch.distance.scale: %0.3f\n",
355680fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                mCalibration.distanceScale);
355780fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    }
35588d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown}
35598d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
356065fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::reset(nsecs_t when) {
356165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCursorButtonAccumulator.reset(getDevice());
356265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCursorScrollAccumulator.reset(getDevice());
356365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mTouchButtonAccumulator.reset(getDevice());
356465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
356565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerVelocityControl.reset();
356665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mWheelXVelocityControl.reset();
356765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mWheelYVelocityControl.reset();
356865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
3569be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mCurrentRawPointerData.clear();
357065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mLastRawPointerData.clear();
357165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentCookedPointerData.clear();
357265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mLastCookedPointerData.clear();
3573be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mCurrentButtonState = 0;
357465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mLastButtonState = 0;
357565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentRawVScroll = 0;
357665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentRawHScroll = 0;
357765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentFingerIdBits.clear();
357865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mLastFingerIdBits.clear();
357965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentStylusIdBits.clear();
358065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mLastStylusIdBits.clear();
358165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentMouseIdBits.clear();
358265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mLastMouseIdBits.clear();
358365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerUsage = POINTER_USAGE_NONE;
358465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mSentHoverEnter = false;
358565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mDownTime = 0;
35866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
358765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentVirtualKey.down = false;
358865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
358965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerGesture.reset();
359065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerSimple.reset();
35912352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
359265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mPointerController != NULL) {
3593be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
3594be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mPointerController->clearSpots();
3595be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
35966d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
359765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    InputMapper::reset(when);
35986d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
35990b72e82c5f5d4ab709539c3490d6c7023f680dffJeff Brown
360065fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::process(const RawEvent* rawEvent) {
360165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCursorButtonAccumulator.process(rawEvent);
360265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCursorScrollAccumulator.process(rawEvent);
360365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mTouchButtonAccumulator.process(rawEvent);
360465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
360549ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown    if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
360665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        sync(rawEvent->when);
360765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
360865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
360965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
361065fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::sync(nsecs_t when) {
361165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Sync button state.
361265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentButtonState = mTouchButtonAccumulator.getButtonState()
361365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            | mCursorButtonAccumulator.getButtonState();
361465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
361565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Sync scroll state.
361665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentRawVScroll = mCursorScrollAccumulator.getRelativeVWheel();
361765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentRawHScroll = mCursorScrollAccumulator.getRelativeHWheel();
361865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCursorScrollAccumulator.finishSync();
361965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
362065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Sync touch state.
362165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    bool havePointerIds = true;
362265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentRawPointerData.clear();
362365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    syncTouch(when, &havePointerIds);
362465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
3625aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown#if DEBUG_RAW_EVENTS
3626aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown    if (!havePointerIds) {
36275baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("syncTouch: pointerCount %d -> %d, no pointer ids",
3628be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mLastRawPointerData.pointerCount,
3629be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentRawPointerData.pointerCount);
3630aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown    } else {
36315baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("syncTouch: pointerCount %d -> %d, touching ids 0x%08x -> 0x%08x, "
3632be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                "hovering ids 0x%08x -> 0x%08x",
3633be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mLastRawPointerData.pointerCount,
3634be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentRawPointerData.pointerCount,
3635be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mLastRawPointerData.touchingIdBits.value,
3636be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentRawPointerData.touchingIdBits.value,
3637be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mLastRawPointerData.hoveringIdBits.value,
3638be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentRawPointerData.hoveringIdBits.value);
3639aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown    }
3640aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown#endif
3641aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown
364265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Reset state that we will compute below.
364365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentFingerIdBits.clear();
364465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentStylusIdBits.clear();
364565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentMouseIdBits.clear();
364665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentCookedPointerData.clear();
3647be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
364865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mDeviceMode == DEVICE_MODE_DISABLED) {
364965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Drop all input if the device is disabled.
365065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mCurrentRawPointerData.clear();
365165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mCurrentButtonState = 0;
365265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    } else {
365365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Preprocess pointer data.
365465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (!havePointerIds) {
365565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            assignPointerIds();
365665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
365746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
365865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Handle policy on initial down or hover events.
365965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        uint32_t policyFlags = 0;
3660c28306ad4ac9ce7a7d5f10c2e38d422ffc309a1fJeff Brown        bool initialDown = mLastRawPointerData.pointerCount == 0
3661c28306ad4ac9ce7a7d5f10c2e38d422ffc309a1fJeff Brown                && mCurrentRawPointerData.pointerCount != 0;
3662c28306ad4ac9ce7a7d5f10c2e38d422ffc309a1fJeff Brown        bool buttonsPressed = mCurrentButtonState & ~mLastButtonState;
3663c28306ad4ac9ce7a7d5f10c2e38d422ffc309a1fJeff Brown        if (initialDown || buttonsPressed) {
3664c28306ad4ac9ce7a7d5f10c2e38d422ffc309a1fJeff Brown            // If this is a touch screen, hide the pointer on an initial down.
366565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            if (mDeviceMode == DEVICE_MODE_DIRECT) {
366665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                getContext()->fadePointer();
366765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            }
366865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
366965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            // Initial downs on external touch devices should wake the device.
367065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            // We don't do this for internal touch screens to prevent them from waking
367165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            // up in your pocket.
367265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            // TODO: Use the input device configuration to control this behavior more finely.
367365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            if (getDevice()->isExternal()) {
367465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                policyFlags |= POLICY_FLAG_WAKE_DROPPED;
367565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            }
3676efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown        }
367756194ebec6212e229f4ccdaa4b187166d20013efJeff Brown
367865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Synthesize key down from raw buttons if needed.
367965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mSource,
368065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                policyFlags, mLastButtonState, mCurrentButtonState);
368165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
368265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Consume raw off-screen touches before cooking pointer data.
368365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // If touches are consumed, subsequent code will not receive any pointer data.
368465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (consumeRawTouches(when, policyFlags)) {
368565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mCurrentRawPointerData.clear();
368656194ebec6212e229f4ccdaa4b187166d20013efJeff Brown        }
368746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
368865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Cook pointer data.  This call populates the mCurrentCookedPointerData structure
368965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // with cooked pointer data that has the same ids and indices as the raw data.
369065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // The following code can use either the raw or cooked data, as needed.
369165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        cookPointerData();
3692be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
369365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Dispatch the touches either directly or by translation through a pointer on screen.
3694daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown        if (mDeviceMode == DEVICE_MODE_POINTER) {
369565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            for (BitSet32 idBits(mCurrentRawPointerData.touchingIdBits); !idBits.isEmpty(); ) {
369665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                uint32_t id = idBits.clearFirstMarkedBit();
369765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
369865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS
369965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                        || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_ERASER) {
370065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    mCurrentStylusIdBits.markBit(id);
370165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                } else if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_FINGER
370265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                        || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
370365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    mCurrentFingerIdBits.markBit(id);
370465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                } else if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_MOUSE) {
370565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    mCurrentMouseIdBits.markBit(id);
370665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                }
370765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            }
370865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            for (BitSet32 idBits(mCurrentRawPointerData.hoveringIdBits); !idBits.isEmpty(); ) {
370965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                uint32_t id = idBits.clearFirstMarkedBit();
371065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
371165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS
371265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                        || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_ERASER) {
371365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    mCurrentStylusIdBits.markBit(id);
371465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                }
371565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            }
371646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
371765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            // Stylus takes precedence over all tools, then mouse, then finger.
371865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            PointerUsage pointerUsage = mPointerUsage;
371965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            if (!mCurrentStylusIdBits.isEmpty()) {
372065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mCurrentMouseIdBits.clear();
372165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mCurrentFingerIdBits.clear();
372265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                pointerUsage = POINTER_USAGE_STYLUS;
372365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            } else if (!mCurrentMouseIdBits.isEmpty()) {
372465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mCurrentFingerIdBits.clear();
372565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                pointerUsage = POINTER_USAGE_MOUSE;
372665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            } else if (!mCurrentFingerIdBits.isEmpty() || isPointerDown(mCurrentButtonState)) {
372765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                pointerUsage = POINTER_USAGE_GESTURES;
372865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            }
3729be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
373065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            dispatchPointerUsage(when, policyFlags, pointerUsage);
373165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        } else {
3732daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown            if (mDeviceMode == DEVICE_MODE_DIRECT
3733daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown                    && mConfig.showTouches && mPointerController != NULL) {
3734daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown                mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_SPOT);
3735daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown                mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
3736daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown
3737daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown                mPointerController->setButtonState(mCurrentButtonState);
3738daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown                mPointerController->setSpots(mCurrentCookedPointerData.pointerCoords,
3739daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown                        mCurrentCookedPointerData.idToIndex,
3740daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown                        mCurrentCookedPointerData.touchingIdBits);
3741daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown            }
3742daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown
374365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            dispatchHoverExit(when, policyFlags);
374465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            dispatchTouches(when, policyFlags);
374565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            dispatchHoverEnterAndMove(when, policyFlags);
374665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
3747be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
374865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Synthesize key up from raw buttons if needed.
374965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mSource,
375065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                policyFlags, mLastButtonState, mCurrentButtonState);
375165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
3752fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
37536328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    // Copy current touch to last touch in preparation for the next cycle.
3754be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mLastRawPointerData.copyFrom(mCurrentRawPointerData);
3755be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mLastCookedPointerData.copyFrom(mCurrentCookedPointerData);
3756be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mLastButtonState = mCurrentButtonState;
375765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mLastFingerIdBits = mCurrentFingerIdBits;
375865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mLastStylusIdBits = mCurrentStylusIdBits;
375965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mLastMouseIdBits = mCurrentMouseIdBits;
376065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
376165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Clear some transient state.
376265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentRawVScroll = 0;
376365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentRawHScroll = 0;
37649c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown}
37659c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
376679ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brownvoid TouchInputMapper::timeoutExpired(nsecs_t when) {
3767daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown    if (mDeviceMode == DEVICE_MODE_POINTER) {
376865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mPointerUsage == POINTER_USAGE_GESTURES) {
376965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            dispatchPointerGestures(when, 0 /*policyFlags*/, true /*isTimeout*/);
377065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
377179ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown    }
377279ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown}
377379ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown
3774be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownbool TouchInputMapper::consumeRawTouches(nsecs_t when, uint32_t policyFlags) {
3775be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // Check for release of a virtual key.
3776be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (mCurrentVirtualKey.down) {
3777be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (mCurrentRawPointerData.touchingIdBits.isEmpty()) {
3778be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            // Pointer went up while virtual key was down.
3779be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mCurrentVirtualKey.down = false;
3780be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (!mCurrentVirtualKey.ignored) {
37816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_VIRTUAL_KEYS
37825baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
3783be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
37846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
3785be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                dispatchVirtualKey(when, policyFlags,
3786be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        AKEY_EVENT_ACTION_UP,
3787be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
37886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
3789be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            return true;
3790be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
37916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
3792be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (mCurrentRawPointerData.touchingIdBits.count() == 1) {
3793be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t id = mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
3794be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
3795be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
3796be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (virtualKey && virtualKey->keyCode == mCurrentVirtualKey.keyCode) {
3797be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                // Pointer is still within the space of the virtual key.
3798be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                return true;
37996d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
3800be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
38016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
3802be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        // Pointer left virtual key area or another pointer also went down.
3803be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        // Send key cancellation but do not consume the touch yet.
3804be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        // This is useful when the user swipes through from the virtual key area
3805be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        // into the main display surface.
3806be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mCurrentVirtualKey.down = false;
3807be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (!mCurrentVirtualKey.ignored) {
38086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_VIRTUAL_KEYS
38095baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
3810be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
38116d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
3812be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            dispatchVirtualKey(when, policyFlags,
3813be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    AKEY_EVENT_ACTION_UP,
3814be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
3815be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            | AKEY_EVENT_FLAG_CANCELED);
3816be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
3817be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
3818be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
3819be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (mLastRawPointerData.touchingIdBits.isEmpty()
3820be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            && !mCurrentRawPointerData.touchingIdBits.isEmpty()) {
3821be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        // Pointer just went down.  Check for virtual key press or off-screen touches.
3822be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        uint32_t id = mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
3823be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
3824be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (!isPointInsideSurface(pointer.x, pointer.y)) {
3825be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            // If exactly one pointer went down, check for virtual key hit.
3826be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            // Otherwise we will drop the entire stroke.
3827be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (mCurrentRawPointerData.touchingIdBits.count() == 1) {
3828be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
3829be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                if (virtualKey) {
3830be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentVirtualKey.down = true;
3831be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentVirtualKey.downTime = when;
3832be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentVirtualKey.keyCode = virtualKey->keyCode;
3833be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentVirtualKey.scanCode = virtualKey->scanCode;
3834be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentVirtualKey.ignored = mContext->shouldDropVirtualKey(
3835be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            when, getDevice(), virtualKey->keyCode, virtualKey->scanCode);
3836be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
3837be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    if (!mCurrentVirtualKey.ignored) {
38386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_VIRTUAL_KEYS
38395baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                        ALOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
3840be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                mCurrentVirtualKey.keyCode,
3841be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                mCurrentVirtualKey.scanCode);
38426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
3843be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        dispatchVirtualKey(when, policyFlags,
3844be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                AKEY_EVENT_ACTION_DOWN,
3845be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
38466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    }
38476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
384846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            }
3849be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            return true;
385046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
3851be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
38526d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
3853fe50892af3b365806a767298dfd8e86447682581Jeff Brown    // Disable all virtual key touches that happen within a short time interval of the
3854be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // most recent touch within the screen area.  The idea is to filter out stray
3855be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // virtual key presses when interacting with the touch screen.
3856fe50892af3b365806a767298dfd8e86447682581Jeff Brown    //
3857fe50892af3b365806a767298dfd8e86447682581Jeff Brown    // Problems we're trying to solve:
3858fe50892af3b365806a767298dfd8e86447682581Jeff Brown    //
3859fe50892af3b365806a767298dfd8e86447682581Jeff Brown    // 1. While scrolling a list or dragging the window shade, the user swipes down into a
3860fe50892af3b365806a767298dfd8e86447682581Jeff Brown    //    virtual key area that is implemented by a separate touch panel and accidentally
3861fe50892af3b365806a767298dfd8e86447682581Jeff Brown    //    triggers a virtual key.
3862fe50892af3b365806a767298dfd8e86447682581Jeff Brown    //
3863fe50892af3b365806a767298dfd8e86447682581Jeff Brown    // 2. While typing in the on screen keyboard, the user taps slightly outside the screen
3864fe50892af3b365806a767298dfd8e86447682581Jeff Brown    //    area and accidentally triggers a virtual key.  This often happens when virtual keys
3865fe50892af3b365806a767298dfd8e86447682581Jeff Brown    //    are layed out below the screen near to where the on screen keyboard's space bar
3866fe50892af3b365806a767298dfd8e86447682581Jeff Brown    //    is displayed.
3867be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (mConfig.virtualKeyQuietTime > 0 && !mCurrentRawPointerData.touchingIdBits.isEmpty()) {
3868474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        mContext->disableVirtualKeysUntil(when + mConfig.virtualKeyQuietTime);
3869fe50892af3b365806a767298dfd8e86447682581Jeff Brown    }
3870be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return false;
3871fe50892af3b365806a767298dfd8e86447682581Jeff Brown}
3872fe50892af3b365806a767298dfd8e86447682581Jeff Brown
3873be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid TouchInputMapper::dispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
3874be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        int32_t keyEventAction, int32_t keyEventFlags) {
3875be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t keyCode = mCurrentVirtualKey.keyCode;
3876be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t scanCode = mCurrentVirtualKey.scanCode;
3877be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    nsecs_t downTime = mCurrentVirtualKey.downTime;
3878be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t metaState = mContext->getGlobalMetaState();
3879be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    policyFlags |= POLICY_FLAG_VIRTUAL;
38806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
3881be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    NotifyKeyArgs args(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
3882be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
3883be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getListener()->notifyKey(&args);
3884be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
3885ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
3886be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
3887be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    BitSet32 currentIdBits = mCurrentCookedPointerData.touchingIdBits;
3888be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    BitSet32 lastIdBits = mLastCookedPointerData.touchingIdBits;
3889fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    int32_t metaState = getContext()->getGlobalMetaState();
3890be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t buttonState = mCurrentButtonState;
389146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
38926d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (currentIdBits == lastIdBits) {
3893be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (!currentIdBits.isEmpty()) {
3894be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            // No pointer id changes so this is a move event.
3895be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            // The listener takes care of batching moves so we don't have to deal with that here.
389665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            dispatchMotion(when, policyFlags, mSource,
3897be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState,
3898be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    AMOTION_EVENT_EDGE_FLAG_NONE,
3899be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.pointerProperties,
3900be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.pointerCoords,
3901be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.idToIndex,
3902be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    currentIdBits, -1,
3903be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
3904be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
39056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    } else {
3906c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        // There may be pointers going up and pointers going down and pointers moving
3907c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        // all at the same time.
3908ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        BitSet32 upIdBits(lastIdBits.value & ~currentIdBits.value);
3909ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        BitSet32 downIdBits(currentIdBits.value & ~lastIdBits.value);
3910c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        BitSet32 moveIdBits(lastIdBits.value & currentIdBits.value);
3911ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        BitSet32 dispatchedIdBits(lastIdBits.value);
3912c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown
3913ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Update last coordinates of pointers that have moved so that we observe the new
3914ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // pointer positions at the same time as other pointers that have just gone up.
3915fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        bool moveNeeded = updateMovedPointers(
3916be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentCookedPointerData.pointerProperties,
3917be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentCookedPointerData.pointerCoords,
3918be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentCookedPointerData.idToIndex,
3919be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mLastCookedPointerData.pointerProperties,
3920be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mLastCookedPointerData.pointerCoords,
3921be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mLastCookedPointerData.idToIndex,
3922ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                moveIdBits);
3923be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (buttonState != mLastButtonState) {
3924fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            moveNeeded = true;
3925fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        }
3926c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown
3927ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Dispatch pointer up events.
3928c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        while (!upIdBits.isEmpty()) {
3929be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t upId = upIdBits.clearFirstMarkedBit();
39306d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
393165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            dispatchMotion(when, policyFlags, mSource,
3932fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    AMOTION_EVENT_ACTION_POINTER_UP, 0, metaState, buttonState, 0,
3933be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mLastCookedPointerData.pointerProperties,
3934be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mLastCookedPointerData.pointerCoords,
3935be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mLastCookedPointerData.idToIndex,
3936be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    dispatchedIdBits, upId,
3937be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
3938ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            dispatchedIdBits.clearBit(upId);
393946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
394046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3941c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        // Dispatch move events if any of the remaining pointers moved from their old locations.
3942c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        // Although applications receive new locations as part of individual pointer up
3943c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        // events, they do not generally handle them except when presented in a move event.
3944c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        if (moveNeeded) {
3945ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block            ALOG_ASSERT(moveIdBits.value == dispatchedIdBits.value);
394665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            dispatchMotion(when, policyFlags, mSource,
3947fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, 0,
3948be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.pointerProperties,
3949be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.pointerCoords,
3950be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.idToIndex,
3951be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    dispatchedIdBits, -1,
3952be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
3953c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        }
3954c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown
3955c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        // Dispatch pointer down events using the new pointer locations.
3956c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        while (!downIdBits.isEmpty()) {
3957be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t downId = downIdBits.clearFirstMarkedBit();
3958ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            dispatchedIdBits.markBit(downId);
39596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
3960ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            if (dispatchedIdBits.count() == 1) {
3961ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                // First pointer is going down.  Set down time.
39626d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                mDownTime = when;
39636d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
396446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
396565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            dispatchMotion(when, policyFlags, mSource,
3966a6111377e1edbc5d63fc2a7205d58b2d9c21d978Jeff Brown                    AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, 0,
3967be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.pointerProperties,
3968be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.pointerCoords,
3969be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.idToIndex,
3970be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    dispatchedIdBits, downId,
3971be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
39726d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
39736d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
3974be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
397546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3976be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid TouchInputMapper::dispatchHoverExit(nsecs_t when, uint32_t policyFlags) {
3977be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (mSentHoverEnter &&
3978be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            (mCurrentCookedPointerData.hoveringIdBits.isEmpty()
3979be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    || !mCurrentCookedPointerData.touchingIdBits.isEmpty())) {
3980be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        int32_t metaState = getContext()->getGlobalMetaState();
398165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        dispatchMotion(when, policyFlags, mSource,
3982be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                AMOTION_EVENT_ACTION_HOVER_EXIT, 0, metaState, mLastButtonState, 0,
3983be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mLastCookedPointerData.pointerProperties,
3984be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mLastCookedPointerData.pointerCoords,
3985be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mLastCookedPointerData.idToIndex,
3986be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mLastCookedPointerData.hoveringIdBits, -1,
3987be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mOrientedXPrecision, mOrientedYPrecision, mDownTime);
3988be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mSentHoverEnter = false;
3989be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
3990be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
3991be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
3992be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid TouchInputMapper::dispatchHoverEnterAndMove(nsecs_t when, uint32_t policyFlags) {
3993be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (mCurrentCookedPointerData.touchingIdBits.isEmpty()
3994be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            && !mCurrentCookedPointerData.hoveringIdBits.isEmpty()) {
3995be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        int32_t metaState = getContext()->getGlobalMetaState();
3996be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (!mSentHoverEnter) {
399765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            dispatchMotion(when, policyFlags, mSource,
3998be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    AMOTION_EVENT_ACTION_HOVER_ENTER, 0, metaState, mCurrentButtonState, 0,
3999be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.pointerProperties,
4000be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.pointerCoords,
4001be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.idToIndex,
4002be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.hoveringIdBits, -1,
4003be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
4004be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mSentHoverEnter = true;
4005be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
4006be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
400765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        dispatchMotion(when, policyFlags, mSource,
4008be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                AMOTION_EVENT_ACTION_HOVER_MOVE, 0, metaState, mCurrentButtonState, 0,
4009be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentCookedPointerData.pointerProperties,
4010be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentCookedPointerData.pointerCoords,
4011be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentCookedPointerData.idToIndex,
4012be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentCookedPointerData.hoveringIdBits, -1,
4013be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mOrientedXPrecision, mOrientedYPrecision, mDownTime);
4014ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
4015ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown}
40166328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
4017be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid TouchInputMapper::cookPointerData() {
4018be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    uint32_t currentPointerCount = mCurrentRawPointerData.pointerCount;
40196328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
4020be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mCurrentCookedPointerData.clear();
4021be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mCurrentCookedPointerData.pointerCount = currentPointerCount;
4022be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mCurrentCookedPointerData.hoveringIdBits = mCurrentRawPointerData.hoveringIdBits;
4023be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mCurrentCookedPointerData.touchingIdBits = mCurrentRawPointerData.touchingIdBits;
40248d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
4025be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // Walk through the the active pointers and map device coordinates onto
4026be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // surface coordinates and adjust for display orientation.
4027ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    for (uint32_t i = 0; i < currentPointerCount; i++) {
4028be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        const RawPointerData::Pointer& in = mCurrentRawPointerData.pointers[i];
40298d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
4030a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        // Size
4031a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        float touchMajor, touchMinor, toolMajor, toolMinor, size;
4032a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        switch (mCalibration.sizeCalibration) {
4033a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        case Calibration::SIZE_CALIBRATION_GEOMETRIC:
4034a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        case Calibration::SIZE_CALIBRATION_DIAMETER:
4035037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown        case Calibration::SIZE_CALIBRATION_BOX:
4036a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        case Calibration::SIZE_CALIBRATION_AREA:
4037a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            if (mRawPointerAxes.touchMajor.valid && mRawPointerAxes.toolMajor.valid) {
4038a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                touchMajor = in.touchMajor;
4039a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                touchMinor = mRawPointerAxes.touchMinor.valid ? in.touchMinor : in.touchMajor;
4040a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                toolMajor = in.toolMajor;
4041a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                toolMinor = mRawPointerAxes.toolMinor.valid ? in.toolMinor : in.toolMajor;
4042a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                size = mRawPointerAxes.touchMinor.valid
4043a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                        ? avg(in.touchMajor, in.touchMinor) : in.touchMajor;
4044a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            } else if (mRawPointerAxes.touchMajor.valid) {
4045a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                toolMajor = touchMajor = in.touchMajor;
4046a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                toolMinor = touchMinor = mRawPointerAxes.touchMinor.valid
4047a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                        ? in.touchMinor : in.touchMajor;
4048a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                size = mRawPointerAxes.touchMinor.valid
4049a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                        ? avg(in.touchMajor, in.touchMinor) : in.touchMajor;
4050a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            } else if (mRawPointerAxes.toolMajor.valid) {
4051a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                touchMajor = toolMajor = in.toolMajor;
4052a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                touchMinor = toolMinor = mRawPointerAxes.toolMinor.valid
4053a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                        ? in.toolMinor : in.toolMajor;
4054a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                size = mRawPointerAxes.toolMinor.valid
4055a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                        ? avg(in.toolMajor, in.toolMinor) : in.toolMajor;
4056ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            } else {
4057ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block                ALOG_ASSERT(false, "No touch or tool axes.  "
4058a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                        "Size calibration should have been resolved to NONE.");
4059a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                touchMajor = 0;
4060a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                touchMinor = 0;
4061a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                toolMajor = 0;
4062a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                toolMinor = 0;
4063a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                size = 0;
4064ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            }
4065a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown
4066a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            if (mCalibration.haveSizeIsSummed && mCalibration.sizeIsSummed) {
4067a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                uint32_t touchingCount = mCurrentRawPointerData.touchingIdBits.count();
4068a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                if (touchingCount > 1) {
4069a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                    touchMajor /= touchingCount;
4070a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                    touchMinor /= touchingCount;
4071a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                    toolMajor /= touchingCount;
4072a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                    toolMinor /= touchingCount;
4073a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                    size /= touchingCount;
4074a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                }
4075ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            }
4076a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown
4077a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_GEOMETRIC) {
4078a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                touchMajor *= mGeometricScale;
4079a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                touchMinor *= mGeometricScale;
4080a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                toolMajor *= mGeometricScale;
4081a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                toolMinor *= mGeometricScale;
4082a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            } else if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_AREA) {
4083a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                touchMajor = touchMajor > 0 ? sqrtf(touchMajor) : 0;
4084a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                touchMinor = touchMajor;
4085a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                toolMajor = toolMajor > 0 ? sqrtf(toolMajor) : 0;
4086a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                toolMinor = toolMajor;
4087a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            } else if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_DIAMETER) {
4088a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                touchMinor = touchMajor;
4089a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                toolMinor = toolMajor;
40908d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
4091a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown
4092a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mCalibration.applySizeScaleAndBias(&touchMajor);
4093a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mCalibration.applySizeScaleAndBias(&touchMinor);
4094a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mCalibration.applySizeScaleAndBias(&toolMajor);
4095a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mCalibration.applySizeScaleAndBias(&toolMinor);
4096a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            size *= mSizeScale;
4097ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            break;
4098ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        default:
4099a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            touchMajor = 0;
4100a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            touchMinor = 0;
4101ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            toolMajor = 0;
4102ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            toolMinor = 0;
4103a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            size = 0;
4104ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            break;
4105ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
4106ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4107ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Pressure
4108ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        float pressure;
4109ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        switch (mCalibration.pressureCalibration) {
4110ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
4111ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
4112a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            pressure = in.pressure * mPressureScale;
4113ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            break;
4114ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        default:
4115be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            pressure = in.isHovering ? 0 : 1;
4116ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            break;
4117ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
4118ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
411965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Tilt and Orientation
412065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        float tilt;
4121ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        float orientation;
412265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mHaveTilt) {
412365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            float tiltXAngle = (in.tiltX - mTiltXCenter) * mTiltXScale;
412465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            float tiltYAngle = (in.tiltY - mTiltYCenter) * mTiltYScale;
412565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            orientation = atan2f(-sinf(tiltXAngle), sinf(tiltYAngle));
412665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            tilt = acosf(cosf(tiltXAngle) * cosf(tiltYAngle));
412765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        } else {
412865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            tilt = 0;
412965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
413065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            switch (mCalibration.orientationCalibration) {
413165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
4132037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown                orientation = in.orientation * mOrientationScale;
413365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                break;
413465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            case Calibration::ORIENTATION_CALIBRATION_VECTOR: {
413565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                int32_t c1 = signExtendNybble((in.orientation & 0xf0) >> 4);
413665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                int32_t c2 = signExtendNybble(in.orientation & 0x0f);
413765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                if (c1 != 0 || c2 != 0) {
413865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    orientation = atan2f(c1, c2) * 0.5f;
413965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    float confidence = hypotf(c1, c2);
414065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    float scale = 1.0f + confidence / 16.0f;
414165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    touchMajor *= scale;
414265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    touchMinor /= scale;
414365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    toolMajor *= scale;
414465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    toolMinor /= scale;
414565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                } else {
414665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    orientation = 0;
414765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                }
414865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                break;
414965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            }
415065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            default:
4151ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                orientation = 0;
41528d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
4153ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
41548d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
415580fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        // Distance
415680fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        float distance;
415780fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        switch (mCalibration.distanceCalibration) {
415880fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        case Calibration::DISTANCE_CALIBRATION_SCALED:
4159be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            distance = in.distance * mDistanceScale;
416080fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            break;
416180fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        default:
416280fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            distance = 0;
416380fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        }
416480fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
4165ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // X and Y
4166ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Adjust coords for surface orientation.
4167ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        float x, y;
4168be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        switch (mSurfaceOrientation) {
4169ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        case DISPLAY_ORIENTATION_90:
417083d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            x = float(in.y - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
417183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            y = float(mRawPointerAxes.x.maxValue - in.x) * mXScale + mXTranslate;
4172ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            orientation -= M_PI_2;
4173ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            if (orientation < - M_PI_2) {
4174ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                orientation += M_PI;
4175ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            }
4176ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            break;
4177ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        case DISPLAY_ORIENTATION_180:
417883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            x = float(mRawPointerAxes.x.maxValue - in.x) * mXScale + mXTranslate;
417983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            y = float(mRawPointerAxes.y.maxValue - in.y) * mYScale + mYTranslate;
4180ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            break;
4181ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        case DISPLAY_ORIENTATION_270:
418283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            x = float(mRawPointerAxes.y.maxValue - in.y) * mYScale + mYTranslate;
418383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            y = float(in.x - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
4184ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            orientation += M_PI_2;
4185ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            if (orientation > M_PI_2) {
4186ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                orientation -= M_PI;
41878d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
4188ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            break;
4189ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        default:
419083d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            x = float(in.x - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
419183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            y = float(in.y - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
4192ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            break;
4193ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
41948d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
4195ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Write output coords.
4196be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        PointerCoords& out = mCurrentCookedPointerData.pointerCoords[i];
4197ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        out.clear();
4198ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        out.setAxisValue(AMOTION_EVENT_AXIS_X, x);
4199ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        out.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
4200ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        out.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure);
4201ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        out.setAxisValue(AMOTION_EVENT_AXIS_SIZE, size);
4202ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, touchMajor);
4203ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, touchMinor);
4204ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, toolMajor);
4205ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, toolMinor);
4206ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, orientation);
420765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        out.setAxisValue(AMOTION_EVENT_AXIS_TILT, tilt);
4208be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        out.setAxisValue(AMOTION_EVENT_AXIS_DISTANCE, distance);
4209fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
4210fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        // Write output properties.
4211be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        PointerProperties& properties = mCurrentCookedPointerData.pointerProperties[i];
4212be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        uint32_t id = in.id;
4213fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        properties.clear();
4214be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        properties.id = id;
4215be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        properties.toolType = in.toolType;
4216ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4217be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        // Write id index.
4218be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mCurrentCookedPointerData.idToIndex[id] = i;
4219be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
4220ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown}
4221ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
422265fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::dispatchPointerUsage(nsecs_t when, uint32_t policyFlags,
422365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        PointerUsage pointerUsage) {
422465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (pointerUsage != mPointerUsage) {
422565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        abortPointerUsage(when, policyFlags);
422665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerUsage = pointerUsage;
422765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
422865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
422965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    switch (mPointerUsage) {
423065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    case POINTER_USAGE_GESTURES:
423165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        dispatchPointerGestures(when, policyFlags, false /*isTimeout*/);
423265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        break;
423365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    case POINTER_USAGE_STYLUS:
423465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        dispatchPointerStylus(when, policyFlags);
423565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        break;
423665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    case POINTER_USAGE_MOUSE:
423765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        dispatchPointerMouse(when, policyFlags);
423865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        break;
423965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    default:
424065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        break;
424165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
424265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
424365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
424465fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::abortPointerUsage(nsecs_t when, uint32_t policyFlags) {
424565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    switch (mPointerUsage) {
424665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    case POINTER_USAGE_GESTURES:
424765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        abortPointerGestures(when, policyFlags);
424865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        break;
424965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    case POINTER_USAGE_STYLUS:
425065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        abortPointerStylus(when, policyFlags);
425165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        break;
425265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    case POINTER_USAGE_MOUSE:
425365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        abortPointerMouse(when, policyFlags);
425465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        break;
425565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    default:
425665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        break;
425765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
425865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
425965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerUsage = POINTER_USAGE_NONE;
426065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
426165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
426279ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brownvoid TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlags,
426379ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        bool isTimeout) {
4264ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Update current gesture coordinates.
4265ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    bool cancelPreviousGesture, finishPreviousGesture;
426679ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown    bool sendEvents = preparePointerGestures(when,
426779ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            &cancelPreviousGesture, &finishPreviousGesture, isTimeout);
426879ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown    if (!sendEvents) {
426979ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        return;
427079ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown    }
427119c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown    if (finishPreviousGesture) {
427219c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown        cancelPreviousGesture = false;
427319c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown    }
4274ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4275bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown    // Update the pointer presentation and spots.
4276bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown    if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
4277bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_SPOT);
4278bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        if (finishPreviousGesture || cancelPreviousGesture) {
4279bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            mPointerController->clearSpots();
4280bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        }
4281cb5ffcf0e41d2597401208221c61589547a00f3dJeff Brown        mPointerController->setSpots(mPointerGesture.currentGestureCoords,
4282cb5ffcf0e41d2597401208221c61589547a00f3dJeff Brown                mPointerGesture.currentGestureIdToIndex,
4283cb5ffcf0e41d2597401208221c61589547a00f3dJeff Brown                mPointerGesture.currentGestureIdBits);
4284bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown    } else {
4285bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
4286bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown    }
4287214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown
4288538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    // Show or hide the pointer if needed.
4289538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    switch (mPointerGesture.currentGestureMode) {
4290538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    case PointerGesture::NEUTRAL:
4291538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    case PointerGesture::QUIET:
4292538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS
4293538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown                && (mPointerGesture.lastGestureMode == PointerGesture::SWIPE
4294538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown                        || mPointerGesture.lastGestureMode == PointerGesture::FREEFORM)) {
4295538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown            // Remind the user of where the pointer is after finishing a gesture with spots.
4296538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown            mPointerController->unfade(PointerControllerInterface::TRANSITION_GRADUAL);
4297538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        }
4298538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        break;
4299538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    case PointerGesture::TAP:
4300538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    case PointerGesture::TAP_DRAG:
4301538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    case PointerGesture::BUTTON_CLICK_OR_DRAG:
4302538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    case PointerGesture::HOVER:
4303538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    case PointerGesture::PRESS:
4304538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        // Unfade the pointer when the current gesture manipulates the
4305538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        // area directly under the pointer.
4306538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
4307538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        break;
4308538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    case PointerGesture::SWIPE:
4309538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    case PointerGesture::FREEFORM:
4310538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        // Fade the pointer when the current gesture manipulates a different
4311538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        // area and there are spots to guide the user experience.
4312538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
4313538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown            mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
4314538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        } else {
4315538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown            mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
4316538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        }
4317538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        break;
43182352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    }
43192352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
4320ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Send events!
4321fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    int32_t metaState = getContext()->getGlobalMetaState();
4322be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t buttonState = mCurrentButtonState;
4323ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4324ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Update last coordinates of pointers that have moved so that we observe the new
4325ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // pointer positions at the same time as other pointers that have just gone up.
432679ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown    bool down = mPointerGesture.currentGestureMode == PointerGesture::TAP
432779ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            || mPointerGesture.currentGestureMode == PointerGesture::TAP_DRAG
432879ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            || mPointerGesture.currentGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG
43292352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            || mPointerGesture.currentGestureMode == PointerGesture::PRESS
4330ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            || mPointerGesture.currentGestureMode == PointerGesture::SWIPE
4331ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            || mPointerGesture.currentGestureMode == PointerGesture::FREEFORM;
4332ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    bool moveNeeded = false;
4333ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    if (down && !cancelPreviousGesture && !finishPreviousGesture
43342352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            && !mPointerGesture.lastGestureIdBits.isEmpty()
43352352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            && !mPointerGesture.currentGestureIdBits.isEmpty()) {
4336ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        BitSet32 movedGestureIdBits(mPointerGesture.currentGestureIdBits.value
4337ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                & mPointerGesture.lastGestureIdBits.value);
4338fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        moveNeeded = updateMovedPointers(mPointerGesture.currentGestureProperties,
4339ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
4340fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                mPointerGesture.lastGestureProperties,
4341ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
4342ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                movedGestureIdBits);
4343be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (buttonState != mLastButtonState) {
4344fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            moveNeeded = true;
4345fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        }
4346ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
4347ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4348ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Send motion events for all pointers that went up or were canceled.
4349ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    BitSet32 dispatchedGestureIdBits(mPointerGesture.lastGestureIdBits);
4350ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    if (!dispatchedGestureIdBits.isEmpty()) {
4351ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        if (cancelPreviousGesture) {
435265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            dispatchMotion(when, policyFlags, mSource,
4353fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    AMOTION_EVENT_ACTION_CANCEL, 0, metaState, buttonState,
4354fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    AMOTION_EVENT_EDGE_FLAG_NONE,
4355fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    mPointerGesture.lastGestureProperties,
4356ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
4357ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    dispatchedGestureIdBits, -1,
4358ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    0, 0, mPointerGesture.downTime);
4359ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4360ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            dispatchedGestureIdBits.clear();
4361ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        } else {
4362ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            BitSet32 upGestureIdBits;
4363ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            if (finishPreviousGesture) {
4364ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                upGestureIdBits = dispatchedGestureIdBits;
4365ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            } else {
4366ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                upGestureIdBits.value = dispatchedGestureIdBits.value
4367ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                        & ~mPointerGesture.currentGestureIdBits.value;
43688d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
4369ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            while (!upGestureIdBits.isEmpty()) {
4370be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                uint32_t id = upGestureIdBits.clearFirstMarkedBit();
4371ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
437265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                dispatchMotion(when, policyFlags, mSource,
4373ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                        AMOTION_EVENT_ACTION_POINTER_UP, 0,
4374fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                        metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
4375fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                        mPointerGesture.lastGestureProperties,
4376ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                        mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
4377ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                        dispatchedGestureIdBits, id,
4378ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                        0, 0, mPointerGesture.downTime);
4379ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4380ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                dispatchedGestureIdBits.clearBit(id);
4381ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            }
4382ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
4383ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
4384ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4385ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Send motion events for all pointers that moved.
4386ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    if (moveNeeded) {
438765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        dispatchMotion(when, policyFlags, mSource,
4388fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
4389fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                mPointerGesture.currentGestureProperties,
4390ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
4391ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                dispatchedGestureIdBits, -1,
4392ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                0, 0, mPointerGesture.downTime);
4393ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
43948d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
4395ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Send motion events for all pointers that went down.
4396ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    if (down) {
4397ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        BitSet32 downGestureIdBits(mPointerGesture.currentGestureIdBits.value
4398ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                & ~dispatchedGestureIdBits.value);
4399ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        while (!downGestureIdBits.isEmpty()) {
4400be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t id = downGestureIdBits.clearFirstMarkedBit();
4401ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            dispatchedGestureIdBits.markBit(id);
4402ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4403ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            if (dispatchedGestureIdBits.count() == 1) {
4404ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.downTime = when;
44058d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
4406ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
440765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            dispatchMotion(when, policyFlags, mSource,
4408a6111377e1edbc5d63fc2a7205d58b2d9c21d978Jeff Brown                    AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, 0,
4409fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    mPointerGesture.currentGestureProperties,
4410ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
4411ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    dispatchedGestureIdBits, id,
4412ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    0, 0, mPointerGesture.downTime);
4413ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
4414ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
4415ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4416ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Send motion events for hover.
4417ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    if (mPointerGesture.currentGestureMode == PointerGesture::HOVER) {
441865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        dispatchMotion(when, policyFlags, mSource,
4419fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
4420fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
4421fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                mPointerGesture.currentGestureProperties,
4422ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
4423ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.currentGestureIdBits, -1,
4424ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                0, 0, mPointerGesture.downTime);
44258134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    } else if (dispatchedGestureIdBits.isEmpty()
44268134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            && !mPointerGesture.lastGestureIdBits.isEmpty()) {
44278134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        // Synthesize a hover move event after all pointers go up to indicate that
44288134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        // the pointer is hovering again even if the user is not currently touching
44298134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        // the touch pad.  This ensures that a view will receive a fresh hover enter
44308134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        // event after a tap.
44318134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        float x, y;
44328134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        mPointerController->getPosition(&x, &y);
44338134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown
44348134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        PointerProperties pointerProperties;
44358134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        pointerProperties.clear();
44368134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        pointerProperties.id = 0;
443749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
44388134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown
44398134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        PointerCoords pointerCoords;
44408134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        pointerCoords.clear();
44418134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
44428134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
44438134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown
444465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
44458134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
44468134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
444783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                mViewport.displayId, 1, &pointerProperties, &pointerCoords,
444883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                0, 0, mPointerGesture.downTime);
4449be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        getListener()->notifyMotion(&args);
4450ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
4451ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4452ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Update state.
4453ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    mPointerGesture.lastGestureMode = mPointerGesture.currentGestureMode;
4454ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    if (!down) {
4455ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.lastGestureIdBits.clear();
4456ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    } else {
4457ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.lastGestureIdBits = mPointerGesture.currentGestureIdBits;
4458ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        for (BitSet32 idBits(mPointerGesture.currentGestureIdBits); !idBits.isEmpty(); ) {
4459be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t id = idBits.clearFirstMarkedBit();
4460ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
4461fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            mPointerGesture.lastGestureProperties[index].copyFrom(
4462fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    mPointerGesture.currentGestureProperties[index]);
4463ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerGesture.lastGestureCoords[index].copyFrom(
4464ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.currentGestureCoords[index]);
4465ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerGesture.lastGestureIdToIndex[id] = index;
4466ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
4467ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
4468ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown}
4469ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
447065fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::abortPointerGestures(nsecs_t when, uint32_t policyFlags) {
447165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Cancel previously dispatches pointers.
447265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (!mPointerGesture.lastGestureIdBits.isEmpty()) {
447365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        int32_t metaState = getContext()->getGlobalMetaState();
447465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        int32_t buttonState = mCurrentButtonState;
447565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        dispatchMotion(when, policyFlags, mSource,
447665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                AMOTION_EVENT_ACTION_CANCEL, 0, metaState, buttonState,
447765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                AMOTION_EVENT_EDGE_FLAG_NONE,
447865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPointerGesture.lastGestureProperties,
447965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
448065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPointerGesture.lastGestureIdBits, -1,
448165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                0, 0, mPointerGesture.downTime);
448265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
448365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
448465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Reset the current pointer gesture.
448565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerGesture.reset();
448665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerVelocityControl.reset();
448765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
448865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Remove any current spots.
448965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mPointerController != NULL) {
449065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
449165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerController->clearSpots();
449265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
449365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
449465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
449579ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brownbool TouchInputMapper::preparePointerGestures(nsecs_t when,
449679ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        bool* outCancelPreviousGesture, bool* outFinishPreviousGesture, bool isTimeout) {
4497ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    *outCancelPreviousGesture = false;
4498ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    *outFinishPreviousGesture = false;
4499ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
450079ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown    // Handle TAP timeout.
450179ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown    if (isTimeout) {
450279ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown#if DEBUG_GESTURES
45035baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("Gestures: Processing timeout");
450479ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown#endif
450579ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown
450679ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        if (mPointerGesture.lastGestureMode == PointerGesture::TAP) {
4507474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) {
450879ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                // The tap/drag timeout has not yet expired.
4509214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown                getContext()->requestTimeoutAtTime(mPointerGesture.tapUpTime
4510474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                        + mConfig.pointerGestureTapDragInterval);
451179ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            } else {
451279ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                // The tap is finished.
451379ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown#if DEBUG_GESTURES
45145baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Gestures: TAP finished");
451579ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown#endif
451679ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                *outFinishPreviousGesture = true;
451779ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown
451879ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                mPointerGesture.activeGestureId = -1;
451979ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
452079ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                mPointerGesture.currentGestureIdBits.clear();
452179ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown
452265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPointerVelocityControl.reset();
452379ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                return true;
452479ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            }
452579ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        }
452679ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown
452779ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        // We did not handle this timeout.
452879ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        return false;
452979ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown    }
453079ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown
453165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    const uint32_t currentFingerCount = mCurrentFingerIdBits.count();
453265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    const uint32_t lastFingerCount = mLastFingerIdBits.count();
453365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
4534ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Update the velocity tracker.
4535ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    {
4536ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        VelocityTracker::Position positions[MAX_POINTERS];
4537ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        uint32_t count = 0;
453865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        for (BitSet32 idBits(mCurrentFingerIdBits); !idBits.isEmpty(); count++) {
4539be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t id = idBits.clearFirstMarkedBit();
4540be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
454165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            positions[count].x = pointer.x * mPointerXMovementScale;
454265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            positions[count].y = pointer.y * mPointerYMovementScale;
4543ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
4544be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mPointerGesture.velocityTracker.addMovement(when,
454565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mCurrentFingerIdBits, positions);
4546ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
4547ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4548ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Pick a new active touch id if needed.
4549ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Choose an arbitrary pointer that just went down, if there is one.
4550ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Otherwise choose an arbitrary remaining pointer.
4551ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // This guarantees we always have an active touch id when there is at least one pointer.
45522352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    // We keep the same active touch id for as long as possible.
45532352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    bool activeTouchChanged = false;
45542352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    int32_t lastActiveTouchId = mPointerGesture.activeTouchId;
45552352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    int32_t activeTouchId = lastActiveTouchId;
45562352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    if (activeTouchId < 0) {
455765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (!mCurrentFingerIdBits.isEmpty()) {
45582352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            activeTouchChanged = true;
4559be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            activeTouchId = mPointerGesture.activeTouchId =
456065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    mCurrentFingerIdBits.firstMarkedBit();
45612352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            mPointerGesture.firstTouchTime = when;
4562ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
456365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    } else if (!mCurrentFingerIdBits.hasBit(activeTouchId)) {
45642352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        activeTouchChanged = true;
456565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (!mCurrentFingerIdBits.isEmpty()) {
4566be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            activeTouchId = mPointerGesture.activeTouchId =
456765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    mCurrentFingerIdBits.firstMarkedBit();
45682352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        } else {
45692352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            activeTouchId = mPointerGesture.activeTouchId = -1;
4570ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
4571ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
4572ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4573ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Determine whether we are in quiet time.
45742352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    bool isQuietTime = false;
45752352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    if (activeTouchId < 0) {
45762352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        mPointerGesture.resetQuietTime();
45772352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    } else {
4578474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        isQuietTime = when < mPointerGesture.quietTime + mConfig.pointerGestureQuietInterval;
45792352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        if (!isQuietTime) {
45802352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            if ((mPointerGesture.lastGestureMode == PointerGesture::PRESS
45812352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                    || mPointerGesture.lastGestureMode == PointerGesture::SWIPE
45822352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                    || mPointerGesture.lastGestureMode == PointerGesture::FREEFORM)
458365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    && currentFingerCount < 2) {
45842352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                // Enter quiet time when exiting swipe or freeform state.
45852352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                // This is to prevent accidentally entering the hover state and flinging the
45862352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                // pointer when finishing a swipe and there is still one pointer left onscreen.
45872352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                isQuietTime = true;
458879ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            } else if (mPointerGesture.lastGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG
458965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    && currentFingerCount >= 2
4590be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    && !isPointerDown(mCurrentButtonState)) {
45912352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                // Enter quiet time when releasing the button and there are still two or more
45922352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                // fingers down.  This may indicate that one finger was used to press the button
45932352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                // but it has not gone up yet.
45942352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                isQuietTime = true;
45952352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            }
45962352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            if (isQuietTime) {
45972352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                mPointerGesture.quietTime = when;
45982352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            }
4599ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
4600ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
4601ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4602ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Switch states based on button and pointer state.
4603ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    if (isQuietTime) {
4604ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Case 1: Quiet time. (QUIET)
4605ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
46065baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("Gestures: QUIET for next %0.3fms", (mPointerGesture.quietTime
4607474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                + mConfig.pointerGestureQuietInterval - when) * 0.000001f);
4608ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
4609bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        if (mPointerGesture.lastGestureMode != PointerGesture::QUIET) {
4610bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            *outFinishPreviousGesture = true;
4611bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        }
4612ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4613ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.activeGestureId = -1;
4614ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureMode = PointerGesture::QUIET;
4615ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureIdBits.clear();
46162352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
461765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerVelocityControl.reset();
4618be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    } else if (isPointerDown(mCurrentButtonState)) {
461979ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        // Case 2: Button is pressed. (BUTTON_CLICK_OR_DRAG)
4620ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // The pointer follows the active touch point.
4621ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Emit DOWN, MOVE, UP events at the pointer location.
4622ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        //
4623ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Only the active touch matters; other fingers are ignored.  This policy helps
4624ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // to handle the case where the user places a second finger on the touch pad
4625ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // to apply the necessary force to depress an integrated button below the surface.
4626ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // We don't want the second finger to be delivered to applications.
4627ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        //
4628ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // For this to work well, we need to make sure to track the pointer that is really
4629ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // active.  If the user first puts one finger down to click then adds another
4630ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // finger to drag then the active pointer should switch to the finger that is
4631ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // being dragged.
4632ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
46335baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("Gestures: BUTTON_CLICK_OR_DRAG activeTouchId=%d, "
463465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                "currentFingerCount=%d", activeTouchId, currentFingerCount);
4635ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
4636ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Reset state when just starting.
463779ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        if (mPointerGesture.lastGestureMode != PointerGesture::BUTTON_CLICK_OR_DRAG) {
4638ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            *outFinishPreviousGesture = true;
4639ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerGesture.activeGestureId = 0;
4640ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
4641ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4642ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Switch pointers if needed.
4643ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Find the fastest pointer and follow it.
464465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (activeTouchId >= 0 && currentFingerCount > 1) {
464519c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            int32_t bestId = -1;
4646474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            float bestSpeed = mConfig.pointerGestureDragMinSwitchSpeed;
464765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            for (BitSet32 idBits(mCurrentFingerIdBits); !idBits.isEmpty(); ) {
4648be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                uint32_t id = idBits.clearFirstMarkedBit();
464919c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown                float vx, vy;
465019c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown                if (mPointerGesture.velocityTracker.getVelocity(id, &vx, &vy)) {
465119c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown                    float speed = hypotf(vx, vy);
465219c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown                    if (speed > bestSpeed) {
465319c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown                        bestId = id;
465419c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown                        bestSpeed = speed;
4655ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    }
4656ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                }
465719c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            }
465819c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            if (bestId >= 0 && bestId != activeTouchId) {
465919c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown                mPointerGesture.activeTouchId = activeTouchId = bestId;
466019c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown                activeTouchChanged = true;
4661ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
46625baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Gestures: BUTTON_CLICK_OR_DRAG switched pointers, "
466319c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown                        "bestId=%d, bestSpeed=%0.3f", bestId, bestSpeed);
4664ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
46656328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            }
466619c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown        }
46679c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
466865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (activeTouchId >= 0 && mLastFingerIdBits.hasBit(activeTouchId)) {
4669be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const RawPointerData::Pointer& currentPointer =
4670be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentRawPointerData.pointerForId(activeTouchId);
4671be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const RawPointerData::Pointer& lastPointer =
4672be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mLastRawPointerData.pointerForId(activeTouchId);
467365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            float deltaX = (currentPointer.x - lastPointer.x) * mPointerXMovementScale;
467465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            float deltaY = (currentPointer.y - lastPointer.y) * mPointerYMovementScale;
467519c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown
4676be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
467765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerVelocityControl.move(when, &deltaX, &deltaY);
467819c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown
467919c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            // Move the pointer using a relative motion.
468019c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            // When using spots, the click will occur at the position of the anchor
468119c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            // spot and all other spots will move there.
468219c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            mPointerController->move(deltaX, deltaY);
468319c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown        } else {
468465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerVelocityControl.reset();
4685ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
4686ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4687ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        float x, y;
4688ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerController->getPosition(&x, &y);
4689ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
469079ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        mPointerGesture.currentGestureMode = PointerGesture::BUTTON_CLICK_OR_DRAG;
4691ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureIdBits.clear();
4692ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
4693ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
4694fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        mPointerGesture.currentGestureProperties[0].clear();
4695fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
469649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        mPointerGesture.currentGestureProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
4697ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureCoords[0].clear();
4698ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
4699ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
4700ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
470165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    } else if (currentFingerCount == 0) {
4702ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Case 3. No fingers down and button is not pressed. (NEUTRAL)
4703bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        if (mPointerGesture.lastGestureMode != PointerGesture::NEUTRAL) {
4704bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            *outFinishPreviousGesture = true;
4705bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        }
4706ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
470779ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        // Watch for taps coming out of HOVER or TAP_DRAG mode.
4708214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown        // Checking for taps after TAP_DRAG allows us to detect double-taps.
4709ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        bool tapped = false;
471079ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        if ((mPointerGesture.lastGestureMode == PointerGesture::HOVER
471179ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                || mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG)
471265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                && lastFingerCount == 1) {
4713474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            if (when <= mPointerGesture.tapDownTime + mConfig.pointerGestureTapInterval) {
4714ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                float x, y;
4715ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerController->getPosition(&x, &y);
4716474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop
4717474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                        && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) {
4718ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
47195baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                    ALOGD("Gestures: TAP");
4720ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
472179ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown
472279ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                    mPointerGesture.tapUpTime = when;
4723214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown                    getContext()->requestTimeoutAtTime(when
4724474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                            + mConfig.pointerGestureTapDragInterval);
472579ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown
4726ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.activeGestureId = 0;
4727ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.currentGestureMode = PointerGesture::TAP;
4728ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.currentGestureIdBits.clear();
4729ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.currentGestureIdBits.markBit(
4730ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                            mPointerGesture.activeGestureId);
4731ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.currentGestureIdToIndex[
4732ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                            mPointerGesture.activeGestureId] = 0;
4733fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    mPointerGesture.currentGestureProperties[0].clear();
4734fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    mPointerGesture.currentGestureProperties[0].id =
4735fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                            mPointerGesture.activeGestureId;
4736fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    mPointerGesture.currentGestureProperties[0].toolType =
473749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                            AMOTION_EVENT_TOOL_TYPE_FINGER;
4738ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.currentGestureCoords[0].clear();
4739ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.currentGestureCoords[0].setAxisValue(
47402352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                            AMOTION_EVENT_AXIS_X, mPointerGesture.tapX);
4741ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.currentGestureCoords[0].setAxisValue(
47422352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                            AMOTION_EVENT_AXIS_Y, mPointerGesture.tapY);
4743ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.currentGestureCoords[0].setAxisValue(
4744ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                            AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
47452352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
4746ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    tapped = true;
4747517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown                } else {
4748ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
47495baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                    ALOGD("Gestures: Not a TAP, deltaX=%f, deltaY=%f",
47502352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                            x - mPointerGesture.tapX,
47512352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                            y - mPointerGesture.tapY);
4752ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
4753517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown                }
4754ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            } else {
4755ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
47565baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Gestures: Not a TAP, %0.3fms since down",
475779ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                        (when - mPointerGesture.tapDownTime) * 0.000001f);
4758ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
4759517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown            }
4760ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
47612352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
476265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerVelocityControl.reset();
476319c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown
4764ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        if (!tapped) {
4765ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
47665baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Gestures: NEUTRAL");
4767ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
4768ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerGesture.activeGestureId = -1;
4769ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
4770ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerGesture.currentGestureIdBits.clear();
4771ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
477265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    } else if (currentFingerCount == 1) {
477379ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        // Case 4. Exactly one finger down, button is not pressed. (HOVER or TAP_DRAG)
4774ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // The pointer follows the active touch point.
477579ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        // When in HOVER, emit HOVER_MOVE events at the pointer location.
477679ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        // When in TAP_DRAG, emit MOVE events at the pointer location.
4777ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block        ALOG_ASSERT(activeTouchId >= 0);
4778ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
477979ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        mPointerGesture.currentGestureMode = PointerGesture::HOVER;
478079ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        if (mPointerGesture.lastGestureMode == PointerGesture::TAP) {
4781474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) {
478279ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                float x, y;
478379ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                mPointerController->getPosition(&x, &y);
4784474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop
4785474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                        && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) {
478679ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                    mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG;
478779ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                } else {
478879ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown#if DEBUG_GESTURES
47895baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                    ALOGD("Gestures: Not a TAP_DRAG, deltaX=%f, deltaY=%f",
479079ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                            x - mPointerGesture.tapX,
479179ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                            y - mPointerGesture.tapY);
479279ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown#endif
479379ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                }
479479ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            } else {
4795ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
47965baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Gestures: Not a TAP_DRAG, %0.3fms time since up",
479779ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                        (when - mPointerGesture.tapUpTime) * 0.000001f);
4798ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
479979ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            }
480079ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        } else if (mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG) {
480179ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG;
480279ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        }
4803ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
480465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mLastFingerIdBits.hasBit(activeTouchId)) {
4805be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const RawPointerData::Pointer& currentPointer =
4806be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentRawPointerData.pointerForId(activeTouchId);
4807be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const RawPointerData::Pointer& lastPointer =
4808be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mLastRawPointerData.pointerForId(activeTouchId);
4809ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            float deltaX = (currentPointer.x - lastPointer.x)
481065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    * mPointerXMovementScale;
4811ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            float deltaY = (currentPointer.y - lastPointer.y)
481265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    * mPointerYMovementScale;
48132352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
4814be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
481565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerVelocityControl.move(when, &deltaX, &deltaY);
481619c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown
48172352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            // Move the pointer using a relative motion.
481879ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            // When using spots, the hover or drag will occur at the position of the anchor spot.
4819ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerController->move(deltaX, deltaY);
482019c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown        } else {
482165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerVelocityControl.reset();
4822ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
4823ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
482479ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        bool down;
482579ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        if (mPointerGesture.currentGestureMode == PointerGesture::TAP_DRAG) {
482679ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown#if DEBUG_GESTURES
48275baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Gestures: TAP_DRAG");
482879ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown#endif
482979ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            down = true;
483079ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        } else {
483179ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown#if DEBUG_GESTURES
48325baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Gestures: HOVER");
483379ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown#endif
4834bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            if (mPointerGesture.lastGestureMode != PointerGesture::HOVER) {
4835bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                *outFinishPreviousGesture = true;
4836bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            }
483779ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            mPointerGesture.activeGestureId = 0;
483879ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            down = false;
483979ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        }
4840ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4841ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        float x, y;
4842ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerController->getPosition(&x, &y);
4843ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4844ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureIdBits.clear();
4845ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
4846ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
4847fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        mPointerGesture.currentGestureProperties[0].clear();
4848fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
4849fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        mPointerGesture.currentGestureProperties[0].toolType =
485049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                AMOTION_EVENT_TOOL_TYPE_FINGER;
4851ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureCoords[0].clear();
4852ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
4853ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
485479ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
485579ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                down ? 1.0f : 0.0f);
485679ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown
485765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (lastFingerCount == 0 && currentFingerCount != 0) {
485879ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            mPointerGesture.resetTap();
485979ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            mPointerGesture.tapDownTime = when;
48602352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            mPointerGesture.tapX = x;
48612352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            mPointerGesture.tapY = y;
48622352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        }
4863ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    } else {
48642352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        // Case 5. At least two fingers down, button is not pressed. (PRESS, SWIPE or FREEFORM)
48652352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        // We need to provide feedback for each finger that goes down so we cannot wait
48662352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        // for the fingers to move before deciding what to do.
4867ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        //
48682352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        // The ambiguous case is deciding what to do when there are two fingers down but they
48692352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        // have not moved enough to determine whether they are part of a drag or part of a
48702352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        // freeform gesture, or just a press or long-press at the pointer location.
48712352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        //
48722352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        // When there are two fingers we start with the PRESS hypothesis and we generate a
48732352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        // down at the pointer location.
48742352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        //
48752352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        // When the two fingers move enough or when additional fingers are added, we make
48762352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        // a decision to transition into SWIPE or FREEFORM mode accordingly.
4877ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block        ALOG_ASSERT(activeTouchId >= 0);
4878ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4879214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown        bool settled = when >= mPointerGesture.firstTouchTime
4880474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                + mConfig.pointerGestureMultitouchSettleInterval;
48812352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        if (mPointerGesture.lastGestureMode != PointerGesture::PRESS
4882ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                && mPointerGesture.lastGestureMode != PointerGesture::SWIPE
4883ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                && mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) {
4884ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            *outFinishPreviousGesture = true;
488565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        } else if (!settled && currentFingerCount > lastFingerCount) {
488619c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            // Additional pointers have gone down but not yet settled.
488719c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            // Reset the gesture.
488819c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown#if DEBUG_GESTURES
48895baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Gestures: Resetting gesture since additional pointers went down for MULTITOUCH, "
4890bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                    "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime
4891474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                            + mConfig.pointerGestureMultitouchSettleInterval - when)
489219c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown                            * 0.000001f);
489319c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown#endif
489419c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            *outCancelPreviousGesture = true;
489519c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown        } else {
489619c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            // Continue previous gesture.
489719c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            mPointerGesture.currentGestureMode = mPointerGesture.lastGestureMode;
489819c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown        }
489919c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown
490019c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown        if (*outFinishPreviousGesture || *outCancelPreviousGesture) {
49012352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            mPointerGesture.currentGestureMode = PointerGesture::PRESS;
49022352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            mPointerGesture.activeGestureId = 0;
4903538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown            mPointerGesture.referenceIdBits.clear();
490465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerVelocityControl.reset();
4905ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4906cb5ffcf0e41d2597401208221c61589547a00f3dJeff Brown            // Use the centroid and pointer location as the reference points for the gesture.
49072352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#if DEBUG_GESTURES
49085baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Gestures: Using centroid as reference for MULTITOUCH, "
4909cb5ffcf0e41d2597401208221c61589547a00f3dJeff Brown                    "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime
4910474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                            + mConfig.pointerGestureMultitouchSettleInterval - when)
4911cb5ffcf0e41d2597401208221c61589547a00f3dJeff Brown                            * 0.000001f);
49122352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#endif
4913be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mCurrentRawPointerData.getCentroidOfTouchingPointers(
4914be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    &mPointerGesture.referenceTouchX,
4915cb5ffcf0e41d2597401208221c61589547a00f3dJeff Brown                    &mPointerGesture.referenceTouchY);
4916cb5ffcf0e41d2597401208221c61589547a00f3dJeff Brown            mPointerController->getPosition(&mPointerGesture.referenceGestureX,
4917cb5ffcf0e41d2597401208221c61589547a00f3dJeff Brown                    &mPointerGesture.referenceGestureY);
49182352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        }
49196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
4920bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        // Clear the reference deltas for fingers not yet included in the reference calculation.
492165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        for (BitSet32 idBits(mCurrentFingerIdBits.value
4922be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                & ~mPointerGesture.referenceIdBits.value); !idBits.isEmpty(); ) {
4923be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t id = idBits.clearFirstMarkedBit();
4924bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            mPointerGesture.referenceDeltas[id].dx = 0;
4925bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            mPointerGesture.referenceDeltas[id].dy = 0;
4926bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        }
492765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerGesture.referenceIdBits = mCurrentFingerIdBits;
4928bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown
4929bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        // Add delta for all fingers and calculate a common movement delta.
4930bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        float commonDeltaX = 0, commonDeltaY = 0;
493165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        BitSet32 commonIdBits(mLastFingerIdBits.value
493265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                & mCurrentFingerIdBits.value);
4933bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        for (BitSet32 idBits(commonIdBits); !idBits.isEmpty(); ) {
4934bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            bool first = (idBits == commonIdBits);
4935be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t id = idBits.clearFirstMarkedBit();
4936be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const RawPointerData::Pointer& cpd = mCurrentRawPointerData.pointerForId(id);
4937be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const RawPointerData::Pointer& lpd = mLastRawPointerData.pointerForId(id);
4938bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
4939bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            delta.dx += cpd.x - lpd.x;
4940bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            delta.dy += cpd.y - lpd.y;
4941bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown
4942bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            if (first) {
4943bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                commonDeltaX = delta.dx;
4944bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                commonDeltaY = delta.dy;
4945bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            } else {
4946bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                commonDeltaX = calculateCommonVector(commonDeltaX, delta.dx);
4947bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                commonDeltaY = calculateCommonVector(commonDeltaY, delta.dy);
4948bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            }
4949bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        }
4950bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown
4951bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        // Consider transitions from PRESS to SWIPE or MULTITOUCH.
49522352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        if (mPointerGesture.currentGestureMode == PointerGesture::PRESS) {
4953bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            float dist[MAX_POINTER_ID + 1];
4954bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            int32_t distOverThreshold = 0;
4955bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
4956be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                uint32_t id = idBits.clearFirstMarkedBit();
4957bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
495865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                dist[id] = hypotf(delta.dx * mPointerXZoomScale,
495965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                        delta.dy * mPointerYZoomScale);
4960474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                if (dist[id] > mConfig.pointerGestureMultitouchMinDistance) {
4961bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                    distOverThreshold += 1;
4962bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                }
4963bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            }
4964bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown
4965bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            // Only transition when at least two pointers have moved further than
4966bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            // the minimum distance threshold.
4967bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            if (distOverThreshold >= 2) {
496865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                if (currentFingerCount > 2) {
4969bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                    // There are more than two pointers, switch to FREEFORM.
49702352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#if DEBUG_GESTURES
49715baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                    ALOGD("Gestures: PRESS transitioned to FREEFORM, number of pointers %d > 2",
497265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                            currentFingerCount);
49732352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#endif
4974bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                    *outCancelPreviousGesture = true;
4975bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                    mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
4976be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                } else {
4977be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    // There are exactly two pointers.
497865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    BitSet32 idBits(mCurrentFingerIdBits);
4979be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    uint32_t id1 = idBits.clearFirstMarkedBit();
4980be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    uint32_t id2 = idBits.firstMarkedBit();
4981be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    const RawPointerData::Pointer& p1 = mCurrentRawPointerData.pointerForId(id1);
4982be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    const RawPointerData::Pointer& p2 = mCurrentRawPointerData.pointerForId(id2);
4983be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    float mutualDistance = distance(p1.x, p1.y, p2.x, p2.y);
4984be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    if (mutualDistance > mPointerGestureMaxSwipeWidth) {
4985be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        // There are two pointers but they are too far apart for a SWIPE,
4986be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        // switch to FREEFORM.
49872352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#if DEBUG_GESTURES
49885baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                        ALOGD("Gestures: PRESS transitioned to FREEFORM, distance %0.3f > %0.3f",
4989be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                mutualDistance, mPointerGestureMaxSwipeWidth);
49902352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#endif
4991be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        *outCancelPreviousGesture = true;
4992be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
4993be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    } else {
4994be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        // There are two pointers.  Wait for both pointers to start moving
4995be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        // before deciding whether this is a SWIPE or FREEFORM gesture.
4996be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        float dist1 = dist[id1];
4997be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        float dist2 = dist[id2];
4998be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        if (dist1 >= mConfig.pointerGestureMultitouchMinDistance
4999be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                && dist2 >= mConfig.pointerGestureMultitouchMinDistance) {
5000be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            // Calculate the dot product of the displacement vectors.
5001be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            // When the vectors are oriented in approximately the same direction,
5002be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            // the angle betweeen them is near zero and the cosine of the angle
5003be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            // approches 1.0.  Recall that dot(v1, v2) = cos(angle) * mag(v1) * mag(v2).
5004be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            PointerGesture::Delta& delta1 = mPointerGesture.referenceDeltas[id1];
5005be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            PointerGesture::Delta& delta2 = mPointerGesture.referenceDeltas[id2];
500665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                            float dx1 = delta1.dx * mPointerXZoomScale;
500765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                            float dy1 = delta1.dy * mPointerYZoomScale;
500865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                            float dx2 = delta2.dx * mPointerXZoomScale;
500965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                            float dy2 = delta2.dy * mPointerYZoomScale;
5010be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            float dot = dx1 * dx2 + dy1 * dy2;
5011be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            float cosine = dot / (dist1 * dist2); // denominator always > 0
5012be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            if (cosine >= mConfig.pointerGestureSwipeTransitionAngleCosine) {
5013be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                // Pointers are moving in the same direction.  Switch to SWIPE.
50142352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#if DEBUG_GESTURES
50155baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                                ALOGD("Gestures: PRESS transitioned to SWIPE, "
5016be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                        "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
5017be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                        "cosine %0.3f >= %0.3f",
5018be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                        dist1, mConfig.pointerGestureMultitouchMinDistance,
5019be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                        dist2, mConfig.pointerGestureMultitouchMinDistance,
5020be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                        cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
50212352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#endif
5022be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                mPointerGesture.currentGestureMode = PointerGesture::SWIPE;
5023be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            } else {
5024be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                // Pointers are moving in different directions.  Switch to FREEFORM.
50252352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#if DEBUG_GESTURES
50265baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                                ALOGD("Gestures: PRESS transitioned to FREEFORM, "
5027be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                        "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
5028be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                        "cosine %0.3f < %0.3f",
5029be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                        dist1, mConfig.pointerGestureMultitouchMinDistance,
5030be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                        dist2, mConfig.pointerGestureMultitouchMinDistance,
5031be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                        cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
50322352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#endif
5033be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                *outCancelPreviousGesture = true;
5034be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
5035be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            }
5036bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                        }
5037ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    }
5038ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                }
5039ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            }
5040ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        } else if (mPointerGesture.currentGestureMode == PointerGesture::SWIPE) {
50412352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            // Switch from SWIPE to FREEFORM if additional pointers go down.
50422352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            // Cancel previous gesture.
504365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            if (currentFingerCount > 2) {
50442352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#if DEBUG_GESTURES
50455baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Gestures: SWIPE transitioned to FREEFORM, number of pointers %d > 2",
504665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                        currentFingerCount);
50472352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#endif
5048ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                *outCancelPreviousGesture = true;
5049ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
50506328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            }
50516d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
50526328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
5053bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        // Move the reference points based on the overall group motion of the fingers
5054bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        // except in PRESS mode while waiting for a transition to occur.
5055bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        if (mPointerGesture.currentGestureMode != PointerGesture::PRESS
5056bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                && (commonDeltaX || commonDeltaY)) {
5057bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
5058be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                uint32_t id = idBits.clearFirstMarkedBit();
5059538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown                PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
5060bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                delta.dx = 0;
5061bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                delta.dy = 0;
50622352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            }
50632352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
5064bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            mPointerGesture.referenceTouchX += commonDeltaX;
5065bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            mPointerGesture.referenceTouchY += commonDeltaY;
506619c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown
506765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            commonDeltaX *= mPointerXMovementScale;
506865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            commonDeltaY *= mPointerYMovementScale;
5069612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown
5070be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            rotateDelta(mSurfaceOrientation, &commonDeltaX, &commonDeltaY);
507165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerVelocityControl.move(when, &commonDeltaX, &commonDeltaY);
507219c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown
5073bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            mPointerGesture.referenceGestureX += commonDeltaX;
5074bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            mPointerGesture.referenceGestureY += commonDeltaY;
50752352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        }
50762352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
50772352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        // Report gestures.
5078612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown        if (mPointerGesture.currentGestureMode == PointerGesture::PRESS
5079612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown                || mPointerGesture.currentGestureMode == PointerGesture::SWIPE) {
5080612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown            // PRESS or SWIPE mode.
5081ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
50825baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Gestures: PRESS or SWIPE activeTouchId=%d,"
5083ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    "activeGestureId=%d, currentTouchPointerCount=%d",
508465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    activeTouchId, mPointerGesture.activeGestureId, currentFingerCount);
5085ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
5086ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block            ALOG_ASSERT(mPointerGesture.activeGestureId >= 0);
5087ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5088ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerGesture.currentGestureIdBits.clear();
5089ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
5090ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
5091fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            mPointerGesture.currentGestureProperties[0].clear();
5092fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
5093fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            mPointerGesture.currentGestureProperties[0].toolType =
509449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                    AMOTION_EVENT_TOOL_TYPE_FINGER;
5095ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerGesture.currentGestureCoords[0].clear();
50962352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X,
50972352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                    mPointerGesture.referenceGestureX);
50982352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y,
50992352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                    mPointerGesture.referenceGestureY);
5100ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
5101ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        } else if (mPointerGesture.currentGestureMode == PointerGesture::FREEFORM) {
5102ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            // FREEFORM mode.
5103ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
51045baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Gestures: FREEFORM activeTouchId=%d,"
5105ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    "activeGestureId=%d, currentTouchPointerCount=%d",
510665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    activeTouchId, mPointerGesture.activeGestureId, currentFingerCount);
5107ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
5108ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block            ALOG_ASSERT(mPointerGesture.activeGestureId >= 0);
5109ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5110ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerGesture.currentGestureIdBits.clear();
5111ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5112ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            BitSet32 mappedTouchIdBits;
5113ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            BitSet32 usedGestureIdBits;
5114ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            if (mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) {
5115ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                // Initially, assign the active gesture id to the active touch point
5116ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                // if there is one.  No other touch id bits are mapped yet.
5117ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                if (!*outCancelPreviousGesture) {
5118ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mappedTouchIdBits.markBit(activeTouchId);
5119ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    usedGestureIdBits.markBit(mPointerGesture.activeGestureId);
5120ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.freeformTouchToGestureIdMap[activeTouchId] =
5121ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                            mPointerGesture.activeGestureId;
5122ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                } else {
5123ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.activeGestureId = -1;
5124ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                }
5125ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            } else {
5126ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                // Otherwise, assume we mapped all touches from the previous frame.
5127ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                // Reuse all mappings that are still applicable.
512865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mappedTouchIdBits.value = mLastFingerIdBits.value
512965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                        & mCurrentFingerIdBits.value;
5130ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                usedGestureIdBits = mPointerGesture.lastGestureIdBits;
5131ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5132ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                // Check whether we need to choose a new active gesture id because the
5133ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                // current went went up.
513465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                for (BitSet32 upTouchIdBits(mLastFingerIdBits.value
513565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                        & ~mCurrentFingerIdBits.value);
5136ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                        !upTouchIdBits.isEmpty(); ) {
5137be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    uint32_t upTouchId = upTouchIdBits.clearFirstMarkedBit();
5138ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    uint32_t upGestureId = mPointerGesture.freeformTouchToGestureIdMap[upTouchId];
5139ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    if (upGestureId == uint32_t(mPointerGesture.activeGestureId)) {
5140ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                        mPointerGesture.activeGestureId = -1;
5141ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                        break;
5142ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    }
5143ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                }
5144ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            }
5145ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5146ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
51475baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Gestures: FREEFORM follow up "
5148ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    "mappedTouchIdBits=0x%08x, usedGestureIdBits=0x%08x, "
5149ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    "activeGestureId=%d",
5150ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mappedTouchIdBits.value, usedGestureIdBits.value,
5151ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.activeGestureId);
5152ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
515391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
515465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            BitSet32 idBits(mCurrentFingerIdBits);
515565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            for (uint32_t i = 0; i < currentFingerCount; i++) {
5156be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                uint32_t touchId = idBits.clearFirstMarkedBit();
5157ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                uint32_t gestureId;
5158ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                if (!mappedTouchIdBits.hasBit(touchId)) {
5159be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    gestureId = usedGestureIdBits.markFirstUnmarkedBit();
5160ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.freeformTouchToGestureIdMap[touchId] = gestureId;
5161ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
51625baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                    ALOGD("Gestures: FREEFORM "
5163ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                            "new mapping for touch id %d -> gesture id %d",
5164ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                            touchId, gestureId);
5165ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
5166ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                } else {
5167ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    gestureId = mPointerGesture.freeformTouchToGestureIdMap[touchId];
5168ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
51695baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                    ALOGD("Gestures: FREEFORM "
5170ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                            "existing mapping for touch id %d -> gesture id %d",
5171ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                            touchId, gestureId);
5172ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
5173ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                }
5174ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.currentGestureIdBits.markBit(gestureId);
5175ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.currentGestureIdToIndex[gestureId] = i;
5176ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5177be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                const RawPointerData::Pointer& pointer =
5178be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        mCurrentRawPointerData.pointerForId(touchId);
5179be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                float deltaX = (pointer.x - mPointerGesture.referenceTouchX)
518065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                        * mPointerXZoomScale;
5181be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                float deltaY = (pointer.y - mPointerGesture.referenceTouchY)
518265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                        * mPointerYZoomScale;
5183be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
5184ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5185fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                mPointerGesture.currentGestureProperties[i].clear();
5186fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                mPointerGesture.currentGestureProperties[i].id = gestureId;
5187fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                mPointerGesture.currentGestureProperties[i].toolType =
518849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                        AMOTION_EVENT_TOOL_TYPE_FINGER;
5189ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.currentGestureCoords[i].clear();
5190ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.currentGestureCoords[i].setAxisValue(
5191612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown                        AMOTION_EVENT_AXIS_X, mPointerGesture.referenceGestureX + deltaX);
5192ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.currentGestureCoords[i].setAxisValue(
5193612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown                        AMOTION_EVENT_AXIS_Y, mPointerGesture.referenceGestureY + deltaY);
5194ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.currentGestureCoords[i].setAxisValue(
5195ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                        AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
51966328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            }
5197ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5198ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            if (mPointerGesture.activeGestureId < 0) {
5199ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.activeGestureId =
5200ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                        mPointerGesture.currentGestureIdBits.firstMarkedBit();
5201ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
52025baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Gestures: FREEFORM new "
5203ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                        "activeGestureId=%d", mPointerGesture.activeGestureId);
5204ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
52056328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            }
52062352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        }
5207ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
52089c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
5209be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mPointerController->setButtonState(mCurrentButtonState);
5210fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
5211ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
52125baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("Gestures: finishPreviousGesture=%s, cancelPreviousGesture=%s, "
52132352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            "currentGestureMode=%d, currentGestureIdBits=0x%08x, "
52142352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            "lastGestureMode=%d, lastGestureIdBits=0x%08x",
5215ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            toString(*outFinishPreviousGesture), toString(*outCancelPreviousGesture),
52162352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            mPointerGesture.currentGestureMode, mPointerGesture.currentGestureIdBits.value,
52172352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            mPointerGesture.lastGestureMode, mPointerGesture.lastGestureIdBits.value);
5218ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    for (BitSet32 idBits = mPointerGesture.currentGestureIdBits; !idBits.isEmpty(); ) {
5219be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        uint32_t id = idBits.clearFirstMarkedBit();
5220ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
5221fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        const PointerProperties& properties = mPointerGesture.currentGestureProperties[index];
5222ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        const PointerCoords& coords = mPointerGesture.currentGestureCoords[index];
52235baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("  currentGesture[%d]: index=%d, toolType=%d, "
5224fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                "x=%0.3f, y=%0.3f, pressure=%0.3f",
5225fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                id, index, properties.toolType,
5226fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                coords.getAxisValue(AMOTION_EVENT_AXIS_X),
5227ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                coords.getAxisValue(AMOTION_EVENT_AXIS_Y),
5228ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
5229ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
5230ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    for (BitSet32 idBits = mPointerGesture.lastGestureIdBits; !idBits.isEmpty(); ) {
5231be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        uint32_t id = idBits.clearFirstMarkedBit();
5232ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        uint32_t index = mPointerGesture.lastGestureIdToIndex[id];
5233fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        const PointerProperties& properties = mPointerGesture.lastGestureProperties[index];
5234ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        const PointerCoords& coords = mPointerGesture.lastGestureCoords[index];
52355baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("  lastGesture[%d]: index=%d, toolType=%d, "
5236fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                "x=%0.3f, y=%0.3f, pressure=%0.3f",
5237fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                id, index, properties.toolType,
5238fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                coords.getAxisValue(AMOTION_EVENT_AXIS_X),
5239ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                coords.getAxisValue(AMOTION_EVENT_AXIS_Y),
5240ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
5241ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
5242ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
524379ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown    return true;
5244ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown}
5245ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
524665fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::dispatchPointerStylus(nsecs_t when, uint32_t policyFlags) {
524765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerSimple.currentCoords.clear();
524865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerSimple.currentProperties.clear();
524965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
525065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    bool down, hovering;
525165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (!mCurrentStylusIdBits.isEmpty()) {
525265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        uint32_t id = mCurrentStylusIdBits.firstMarkedBit();
525365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        uint32_t index = mCurrentCookedPointerData.idToIndex[id];
525465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        float x = mCurrentCookedPointerData.pointerCoords[index].getX();
525565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        float y = mCurrentCookedPointerData.pointerCoords[index].getY();
525665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerController->setPosition(x, y);
525765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
525865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        hovering = mCurrentCookedPointerData.hoveringIdBits.hasBit(id);
525965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        down = !hovering;
526065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
526165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerController->getPosition(&x, &y);
526265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.currentCoords.copyFrom(mCurrentCookedPointerData.pointerCoords[index]);
526365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
526465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
526565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.currentProperties.id = 0;
526665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.currentProperties.toolType =
526765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mCurrentCookedPointerData.pointerProperties[index].toolType;
526865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    } else {
526965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        down = false;
527065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        hovering = false;
527165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
527265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
527365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    dispatchPointerSimple(when, policyFlags, down, hovering);
527465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
527565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
527665fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::abortPointerStylus(nsecs_t when, uint32_t policyFlags) {
527765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    abortPointerSimple(when, policyFlags);
527865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
527965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
528065fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::dispatchPointerMouse(nsecs_t when, uint32_t policyFlags) {
528165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerSimple.currentCoords.clear();
528265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerSimple.currentProperties.clear();
528365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
528465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    bool down, hovering;
528565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (!mCurrentMouseIdBits.isEmpty()) {
528665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        uint32_t id = mCurrentMouseIdBits.firstMarkedBit();
528765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        uint32_t currentIndex = mCurrentRawPointerData.idToIndex[id];
528865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mLastMouseIdBits.hasBit(id)) {
528965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            uint32_t lastIndex = mCurrentRawPointerData.idToIndex[id];
529065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            float deltaX = (mCurrentRawPointerData.pointers[currentIndex].x
529165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    - mLastRawPointerData.pointers[lastIndex].x)
529265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    * mPointerXMovementScale;
529365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            float deltaY = (mCurrentRawPointerData.pointers[currentIndex].y
529465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    - mLastRawPointerData.pointers[lastIndex].y)
529565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    * mPointerYMovementScale;
529665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
529765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
529865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerVelocityControl.move(when, &deltaX, &deltaY);
529965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
530065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerController->move(deltaX, deltaY);
530165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        } else {
530265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerVelocityControl.reset();
530365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
530465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
530565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        down = isPointerDown(mCurrentButtonState);
530665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        hovering = !down;
530765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
530865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        float x, y;
530965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerController->getPosition(&x, &y);
531065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.currentCoords.copyFrom(
531165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mCurrentCookedPointerData.pointerCoords[currentIndex]);
531265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
531365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
531465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
531565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                hovering ? 0.0f : 1.0f);
531665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.currentProperties.id = 0;
531765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.currentProperties.toolType =
531865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mCurrentCookedPointerData.pointerProperties[currentIndex].toolType;
531965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    } else {
532065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerVelocityControl.reset();
532165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
532265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        down = false;
532365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        hovering = false;
532465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
532565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
532665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    dispatchPointerSimple(when, policyFlags, down, hovering);
532765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
532865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
532965fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::abortPointerMouse(nsecs_t when, uint32_t policyFlags) {
533065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    abortPointerSimple(when, policyFlags);
533165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
533265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerVelocityControl.reset();
533365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
533465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
533565fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::dispatchPointerSimple(nsecs_t when, uint32_t policyFlags,
533665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        bool down, bool hovering) {
533765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    int32_t metaState = getContext()->getGlobalMetaState();
533865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
533965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mPointerController != NULL) {
534065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (down || hovering) {
534165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
534265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerController->clearSpots();
534365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerController->setButtonState(mCurrentButtonState);
534465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
534565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        } else if (!down && !hovering && (mPointerSimple.down || mPointerSimple.hovering)) {
534665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
534765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
534865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
534965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
535065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mPointerSimple.down && !down) {
535165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.down = false;
535265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
535365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Send up.
535465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
535565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                 AMOTION_EVENT_ACTION_UP, 0, metaState, mLastButtonState, 0,
535683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                 mViewport.displayId,
535765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                 1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
535865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                 mOrientedXPrecision, mOrientedYPrecision,
535965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                 mPointerSimple.downTime);
536065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        getListener()->notifyMotion(&args);
536165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
536265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
536365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mPointerSimple.hovering && !hovering) {
536465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.hovering = false;
536565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
536665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Send hover exit.
536765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
536865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                AMOTION_EVENT_ACTION_HOVER_EXIT, 0, metaState, mLastButtonState, 0,
536983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                mViewport.displayId,
537065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
537165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mOrientedXPrecision, mOrientedYPrecision,
537265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPointerSimple.downTime);
537365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        getListener()->notifyMotion(&args);
537465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
537565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
537665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (down) {
537765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (!mPointerSimple.down) {
537865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerSimple.down = true;
537965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerSimple.downTime = when;
538065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
538165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            // Send down.
538265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
538365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    AMOTION_EVENT_ACTION_DOWN, 0, metaState, mCurrentButtonState, 0,
538483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                    mViewport.displayId,
538565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
538665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    mOrientedXPrecision, mOrientedYPrecision,
538765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    mPointerSimple.downTime);
538865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            getListener()->notifyMotion(&args);
538965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
539065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
539165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Send move.
539265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
539365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                AMOTION_EVENT_ACTION_MOVE, 0, metaState, mCurrentButtonState, 0,
539483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                mViewport.displayId,
539565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
539665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mOrientedXPrecision, mOrientedYPrecision,
539765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPointerSimple.downTime);
539865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        getListener()->notifyMotion(&args);
539965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
540065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
540165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (hovering) {
540265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (!mPointerSimple.hovering) {
540365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerSimple.hovering = true;
540465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
540565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            // Send hover enter.
540665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
540765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    AMOTION_EVENT_ACTION_HOVER_ENTER, 0, metaState, mCurrentButtonState, 0,
540883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                    mViewport.displayId,
540965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
541065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    mOrientedXPrecision, mOrientedYPrecision,
541165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    mPointerSimple.downTime);
541265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            getListener()->notifyMotion(&args);
541365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
541465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
541565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Send hover move.
541665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
541765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                AMOTION_EVENT_ACTION_HOVER_MOVE, 0, metaState, mCurrentButtonState, 0,
541883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                mViewport.displayId,
541965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
542065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mOrientedXPrecision, mOrientedYPrecision,
542165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPointerSimple.downTime);
542265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        getListener()->notifyMotion(&args);
542365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
542465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
542565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mCurrentRawVScroll || mCurrentRawHScroll) {
542665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        float vscroll = mCurrentRawVScroll;
542765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        float hscroll = mCurrentRawHScroll;
542865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mWheelYVelocityControl.move(when, NULL, &vscroll);
542965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mWheelXVelocityControl.move(when, &hscroll, NULL);
543065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
543165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Send scroll.
543265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        PointerCoords pointerCoords;
543365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        pointerCoords.copyFrom(mPointerSimple.currentCoords);
543465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
543565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
543665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
543765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
543865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                AMOTION_EVENT_ACTION_SCROLL, 0, metaState, mCurrentButtonState, 0,
543983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                mViewport.displayId,
544065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                1, &mPointerSimple.currentProperties, &pointerCoords,
544165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mOrientedXPrecision, mOrientedYPrecision,
544265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPointerSimple.downTime);
544365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        getListener()->notifyMotion(&args);
544465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
544565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
544665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Save state.
544765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (down || hovering) {
544865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.lastCoords.copyFrom(mPointerSimple.currentCoords);
544965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.lastProperties.copyFrom(mPointerSimple.currentProperties);
545065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    } else {
545165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.reset();
545265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
545365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
545465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
545565fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::abortPointerSimple(nsecs_t when, uint32_t policyFlags) {
545665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerSimple.currentCoords.clear();
545765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerSimple.currentProperties.clear();
545865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
545965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    dispatchPointerSimple(when, policyFlags, false, false);
546065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
546165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
5462ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brownvoid TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source,
5463fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        int32_t action, int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags,
5464fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        const PointerProperties* properties, const PointerCoords* coords,
5465fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        const uint32_t* idToIndex, BitSet32 idBits,
5466ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        int32_t changedId, float xPrecision, float yPrecision, nsecs_t downTime) {
5467ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    PointerCoords pointerCoords[MAX_POINTERS];
5468fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    PointerProperties pointerProperties[MAX_POINTERS];
5469ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    uint32_t pointerCount = 0;
5470ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    while (!idBits.isEmpty()) {
5471be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        uint32_t id = idBits.clearFirstMarkedBit();
5472ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        uint32_t index = idToIndex[id];
5473fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        pointerProperties[pointerCount].copyFrom(properties[index]);
5474ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        pointerCoords[pointerCount].copyFrom(coords[index]);
5475ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5476ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        if (changedId >= 0 && id == uint32_t(changedId)) {
5477ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            action |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
5478ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
5479ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5480ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        pointerCount += 1;
5481ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
5482ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5483ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block    ALOG_ASSERT(pointerCount != 0);
5484ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5485ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    if (changedId >= 0 && pointerCount == 1) {
5486ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Replace initial down and final up action.
5487ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // We can compare the action without masking off the changed pointer index
5488ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // because we know the index is 0.
5489ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        if (action == AMOTION_EVENT_ACTION_POINTER_DOWN) {
5490ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            action = AMOTION_EVENT_ACTION_DOWN;
5491ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        } else if (action == AMOTION_EVENT_ACTION_POINTER_UP) {
5492ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            action = AMOTION_EVENT_ACTION_UP;
5493ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        } else {
5494ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            // Can't happen.
5495ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block            ALOG_ASSERT(false);
5496ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
5497ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
5498ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5499be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    NotifyMotionArgs args(when, getDeviceId(), source, policyFlags,
5500fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            action, flags, metaState, buttonState, edgeFlags,
550183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mViewport.displayId, pointerCount, pointerProperties, pointerCoords,
550283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            xPrecision, yPrecision, downTime);
5503be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getListener()->notifyMotion(&args);
5504ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown}
5505ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5506fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownbool TouchInputMapper::updateMovedPointers(const PointerProperties* inProperties,
5507ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        const PointerCoords* inCoords, const uint32_t* inIdToIndex,
5508fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        PointerProperties* outProperties, PointerCoords* outCoords, const uint32_t* outIdToIndex,
5509fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        BitSet32 idBits) const {
5510ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    bool changed = false;
5511ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    while (!idBits.isEmpty()) {
5512be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        uint32_t id = idBits.clearFirstMarkedBit();
5513ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        uint32_t inIndex = inIdToIndex[id];
5514ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        uint32_t outIndex = outIdToIndex[id];
5515fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
5516fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        const PointerProperties& curInProperties = inProperties[inIndex];
5517ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        const PointerCoords& curInCoords = inCoords[inIndex];
5518fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        PointerProperties& curOutProperties = outProperties[outIndex];
5519ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        PointerCoords& curOutCoords = outCoords[outIndex];
5520ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5521fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        if (curInProperties != curOutProperties) {
5522fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            curOutProperties.copyFrom(curInProperties);
5523fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            changed = true;
5524fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        }
5525fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
5526ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        if (curInCoords != curOutCoords) {
5527ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            curOutCoords.copyFrom(curInCoords);
5528ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            changed = true;
5529ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
5530ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
5531ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    return changed;
5532ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown}
5533ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5534ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brownvoid TouchInputMapper::fadePointer() {
5535be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (mPointerController != NULL) {
5536be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
5537be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
55389c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown}
55399c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
5540be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownbool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) {
5541be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return x >= mRawPointerAxes.x.minValue && x <= mRawPointerAxes.x.maxValue
5542be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            && y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue;
55439c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown}
55449c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
5545be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownconst TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHit(
55466328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        int32_t x, int32_t y) {
5547be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    size_t numVirtualKeys = mVirtualKeys.size();
55486328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    for (size_t i = 0; i < numVirtualKeys; i++) {
5549be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        const VirtualKey& virtualKey = mVirtualKeys[i];
55509c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
55516d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_VIRTUAL_KEYS
55525baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, "
55536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                "left=%d, top=%d, right=%d, bottom=%d",
55546d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                x, y,
55556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                virtualKey.keyCode, virtualKey.scanCode,
55566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                virtualKey.hitLeft, virtualKey.hitTop,
55576d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                virtualKey.hitRight, virtualKey.hitBottom);
55586d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
55596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
55606d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (virtualKey.isHit(x, y)) {
55616d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            return & virtualKey;
55629c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown        }
55636d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
55649c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
55656d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return NULL;
55669c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown}
55679c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
5568be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid TouchInputMapper::assignPointerIds() {
5569be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    uint32_t currentPointerCount = mCurrentRawPointerData.pointerCount;
5570be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    uint32_t lastPointerCount = mLastRawPointerData.pointerCount;
5571be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
5572be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mCurrentRawPointerData.clearIdBits();
55736d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
55746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (currentPointerCount == 0) {
55756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // No pointers to assign.
5576be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        return;
5577be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
5578be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
5579be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (lastPointerCount == 0) {
55806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // All pointers are new.
55816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        for (uint32_t i = 0; i < currentPointerCount; i++) {
5582be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t id = i;
5583be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mCurrentRawPointerData.pointers[i].id = id;
5584be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mCurrentRawPointerData.idToIndex[id] = i;
5585be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mCurrentRawPointerData.markIdBit(id, mCurrentRawPointerData.isHovering(i));
55866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
5587be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        return;
5588be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
5589be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
5590be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (currentPointerCount == 1 && lastPointerCount == 1
5591be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            && mCurrentRawPointerData.pointers[0].toolType
5592be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    == mLastRawPointerData.pointers[0].toolType) {
55936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // Only one pointer and no change in count so it must have the same id as before.
5594be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        uint32_t id = mLastRawPointerData.pointers[0].id;
5595be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mCurrentRawPointerData.pointers[0].id = id;
5596be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mCurrentRawPointerData.idToIndex[id] = 0;
5597be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mCurrentRawPointerData.markIdBit(id, mCurrentRawPointerData.isHovering(0));
5598be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        return;
5599be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
5600be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
5601be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // General case.
5602be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // We build a heap of squared euclidean distances between current and last pointers
5603be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // associated with the current and last pointer indices.  Then, we find the best
5604be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // match (by distance) for each current pointer.
5605be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // The pointers must have the same tool type but it is possible for them to
5606be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // transition from hovering to touching or vice-versa while retaining the same id.
5607be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    PointerDistanceHeapElement heap[MAX_POINTERS * MAX_POINTERS];
5608be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
5609be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    uint32_t heapSize = 0;
5610be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (uint32_t currentPointerIndex = 0; currentPointerIndex < currentPointerCount;
5611be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            currentPointerIndex++) {
5612be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        for (uint32_t lastPointerIndex = 0; lastPointerIndex < lastPointerCount;
5613be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                lastPointerIndex++) {
5614be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const RawPointerData::Pointer& currentPointer =
5615be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentRawPointerData.pointers[currentPointerIndex];
5616be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const RawPointerData::Pointer& lastPointer =
5617be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mLastRawPointerData.pointers[lastPointerIndex];
5618be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (currentPointer.toolType == lastPointer.toolType) {
5619be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                int64_t deltaX = currentPointer.x - lastPointer.x;
5620be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                int64_t deltaY = currentPointer.y - lastPointer.y;
56216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
56226d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY);
56236d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
56246d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                // Insert new element into the heap (sift up).
56256d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                heap[heapSize].currentPointerIndex = currentPointerIndex;
56266d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                heap[heapSize].lastPointerIndex = lastPointerIndex;
56276d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                heap[heapSize].distance = distance;
56286d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                heapSize += 1;
56296d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
56306d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
5631be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
56329c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
5633be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // Heapify
5634be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (uint32_t startIndex = heapSize / 2; startIndex != 0; ) {
5635be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        startIndex -= 1;
5636be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        for (uint32_t parentIndex = startIndex; ;) {
5637be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t childIndex = parentIndex * 2 + 1;
5638be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (childIndex >= heapSize) {
5639be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                break;
5640be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            }
56416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5642be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (childIndex + 1 < heapSize
5643be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    && heap[childIndex + 1].distance < heap[childIndex].distance) {
5644be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                childIndex += 1;
5645be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            }
56466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5647be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (heap[parentIndex].distance <= heap[childIndex].distance) {
5648be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                break;
56496d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
5650be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
5651be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            swap(heap[parentIndex], heap[childIndex]);
5652be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            parentIndex = childIndex;
56539c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown        }
5654be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
56559c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
56566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_POINTER_ASSIGNMENT
56575baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("assignPointerIds - initial distance min-heap: size=%d", heapSize);
5658be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (size_t i = 0; i < heapSize; i++) {
56595baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("  heap[%d]: cur=%d, last=%d, distance=%lld",
5660be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
5661be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                heap[i].distance);
5662be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
56636d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
56649c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
5665be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // Pull matches out by increasing order of distance.
5666be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // To avoid reassigning pointers that have already been matched, the loop keeps track
5667be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // of which last and current pointers have been matched using the matchedXXXBits variables.
5668be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // It also tracks the used pointer id bits.
5669be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    BitSet32 matchedLastBits(0);
5670be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    BitSet32 matchedCurrentBits(0);
5671be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    BitSet32 usedIdBits(0);
5672be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    bool first = true;
5673be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (uint32_t i = min(currentPointerCount, lastPointerCount); heapSize > 0 && i > 0; i--) {
5674be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        while (heapSize > 0) {
5675be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (first) {
5676be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                // The first time through the loop, we just consume the root element of
5677be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                // the heap (the one with smallest distance).
5678be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                first = false;
5679be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            } else {
5680be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                // Previous iterations consumed the root element of the heap.
5681be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                // Pop root element off of the heap (sift down).
5682be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                heap[0] = heap[heapSize];
5683be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                for (uint32_t parentIndex = 0; ;) {
5684be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    uint32_t childIndex = parentIndex * 2 + 1;
5685be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    if (childIndex >= heapSize) {
5686be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        break;
5687be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    }
56886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5689be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    if (childIndex + 1 < heapSize
5690be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            && heap[childIndex + 1].distance < heap[childIndex].distance) {
5691be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        childIndex += 1;
5692be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    }
56936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5694be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    if (heap[parentIndex].distance <= heap[childIndex].distance) {
5695be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        break;
56966d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    }
56976d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5698be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    swap(heap[parentIndex], heap[childIndex]);
5699be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    parentIndex = childIndex;
5700be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                }
5701be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
57026d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_POINTER_ASSIGNMENT
57035baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("assignPointerIds - reduced distance min-heap: size=%d", heapSize);
5704be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                for (size_t i = 0; i < heapSize; i++) {
57055baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                    ALOGD("  heap[%d]: cur=%d, last=%d, distance=%lld",
5706be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
5707be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            heap[i].distance);
57086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
5709be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown#endif
5710be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            }
571146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5712be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            heapSize -= 1;
571346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5714be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t currentPointerIndex = heap[0].currentPointerIndex;
5715be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (matchedCurrentBits.hasBit(currentPointerIndex)) continue; // already matched
571646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5717be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t lastPointerIndex = heap[0].lastPointerIndex;
5718be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (matchedLastBits.hasBit(lastPointerIndex)) continue; // already matched
571946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5720be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            matchedCurrentBits.markBit(currentPointerIndex);
5721be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            matchedLastBits.markBit(lastPointerIndex);
5722be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
5723be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t id = mLastRawPointerData.pointers[lastPointerIndex].id;
5724be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mCurrentRawPointerData.pointers[currentPointerIndex].id = id;
5725be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mCurrentRawPointerData.idToIndex[id] = currentPointerIndex;
5726be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mCurrentRawPointerData.markIdBit(id,
5727be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentRawPointerData.isHovering(currentPointerIndex));
5728be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            usedIdBits.markBit(id);
572946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
57306d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_POINTER_ASSIGNMENT
57315baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("assignPointerIds - matched: cur=%d, last=%d, id=%d, distance=%lld",
5732be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    lastPointerIndex, currentPointerIndex, id, heap[0].distance);
57336d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
5734be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            break;
57356d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
5736be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
573746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5738be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // Assign fresh ids to pointers that were not matched in the process.
5739be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (uint32_t i = currentPointerCount - matchedCurrentBits.count(); i != 0; i--) {
5740be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        uint32_t currentPointerIndex = matchedCurrentBits.markFirstUnmarkedBit();
5741be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        uint32_t id = usedIdBits.markFirstUnmarkedBit();
57426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5743be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mCurrentRawPointerData.pointers[currentPointerIndex].id = id;
5744be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mCurrentRawPointerData.idToIndex[id] = currentPointerIndex;
5745be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mCurrentRawPointerData.markIdBit(id,
5746be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentRawPointerData.isHovering(currentPointerIndex));
57476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
57486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_POINTER_ASSIGNMENT
57495baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("assignPointerIds - assigned: cur=%d, id=%d",
5750be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                currentPointerIndex, id);
57516d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
57526d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
575346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
575446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
57556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
5756be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (mCurrentVirtualKey.down && mCurrentVirtualKey.keyCode == keyCode) {
5757be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        return AKEY_STATE_VIRTUAL;
5758be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
57596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5760be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    size_t numVirtualKeys = mVirtualKeys.size();
5761be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (size_t i = 0; i < numVirtualKeys; i++) {
5762be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        const VirtualKey& virtualKey = mVirtualKeys[i];
5763be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (virtualKey.keyCode == keyCode) {
5764be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            return AKEY_STATE_UP;
57656d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
5766be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
57676d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
57686d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return AKEY_STATE_UNKNOWN;
57696d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
57706d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
57716d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
5772be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (mCurrentVirtualKey.down && mCurrentVirtualKey.scanCode == scanCode) {
5773be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        return AKEY_STATE_VIRTUAL;
5774be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
57756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5776be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    size_t numVirtualKeys = mVirtualKeys.size();
5777be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (size_t i = 0; i < numVirtualKeys; i++) {
5778be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        const VirtualKey& virtualKey = mVirtualKeys[i];
5779be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (virtualKey.scanCode == scanCode) {
5780be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            return AKEY_STATE_UP;
57816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
5782be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
57836d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
57846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return AKEY_STATE_UNKNOWN;
57856d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
57866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
57876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownbool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
57886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        const int32_t* keyCodes, uint8_t* outFlags) {
5789be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    size_t numVirtualKeys = mVirtualKeys.size();
5790be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (size_t i = 0; i < numVirtualKeys; i++) {
5791be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        const VirtualKey& virtualKey = mVirtualKeys[i];
57926d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5793be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        for (size_t i = 0; i < numCodes; i++) {
5794be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (virtualKey.keyCode == keyCodes[i]) {
5795be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                outFlags[i] = 1;
57966d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
57976d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
5798be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
57996d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
58006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return true;
58016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
58026d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
58036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
58046d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown// --- SingleTouchInputMapper ---
58056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
580647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff BrownSingleTouchInputMapper::SingleTouchInputMapper(InputDevice* device) :
580747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        TouchInputMapper(device) {
58086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
58096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
58106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownSingleTouchInputMapper::~SingleTouchInputMapper() {
58116d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
58126d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
581365fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid SingleTouchInputMapper::reset(nsecs_t when) {
581465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mSingleTouchMotionAccumulator.reset(getDevice());
58156d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
581665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    TouchInputMapper::reset(when);
581765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
58186d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
58196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid SingleTouchInputMapper::process(const RawEvent* rawEvent) {
582065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    TouchInputMapper::process(rawEvent);
58216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
582265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mSingleTouchMotionAccumulator.process(rawEvent);
58236d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
58246d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
582565fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid SingleTouchInputMapper::syncTouch(nsecs_t when, bool* outHavePointerIds) {
5826d87c6d5fd5e620ecb1a7a401d2b31c6cf2e1a851Jeff Brown    if (mTouchButtonAccumulator.isToolActive()) {
5827be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mCurrentRawPointerData.pointerCount = 1;
5828be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mCurrentRawPointerData.idToIndex[0] = 0;
582949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
583065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        bool isHovering = mTouchButtonAccumulator.getToolType() != AMOTION_EVENT_TOOL_TYPE_MOUSE
583165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                && (mTouchButtonAccumulator.isHovering()
583265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                        || (mRawPointerAxes.pressure.valid
583365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                                && mSingleTouchMotionAccumulator.getAbsolutePressure() <= 0));
5834be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mCurrentRawPointerData.markIdBit(0, isHovering);
583549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
5836be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        RawPointerData::Pointer& outPointer = mCurrentRawPointerData.pointers[0];
583749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.id = 0;
583849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.x = mSingleTouchMotionAccumulator.getAbsoluteX();
583949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.y = mSingleTouchMotionAccumulator.getAbsoluteY();
584049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.pressure = mSingleTouchMotionAccumulator.getAbsolutePressure();
584149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.touchMajor = 0;
584249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.touchMinor = 0;
584349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.toolMajor = mSingleTouchMotionAccumulator.getAbsoluteToolWidth();
584449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.toolMinor = mSingleTouchMotionAccumulator.getAbsoluteToolWidth();
584549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.orientation = 0;
584649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.distance = mSingleTouchMotionAccumulator.getAbsoluteDistance();
584765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        outPointer.tiltX = mSingleTouchMotionAccumulator.getAbsoluteTiltX();
584865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        outPointer.tiltY = mSingleTouchMotionAccumulator.getAbsoluteTiltY();
584949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.toolType = mTouchButtonAccumulator.getToolType();
585049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
585149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
585249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        }
585349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.isHovering = isHovering;
58546d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
58556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
58566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5857be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid SingleTouchInputMapper::configureRawPointerAxes() {
5858be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    TouchInputMapper::configureRawPointerAxes();
58596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5860be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_X, &mRawPointerAxes.x);
5861be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_Y, &mRawPointerAxes.y);
5862be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_PRESSURE, &mRawPointerAxes.pressure);
5863be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_TOOL_WIDTH, &mRawPointerAxes.toolMajor);
5864be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_DISTANCE, &mRawPointerAxes.distance);
586565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    getAbsoluteAxisInfo(ABS_TILT_X, &mRawPointerAxes.tiltX);
586665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    getAbsoluteAxisInfo(ABS_TILT_Y, &mRawPointerAxes.tiltY);
58676d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
58686d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
586900710e906bdafd58386ee7f81fa84addd218122fJeff Brownbool SingleTouchInputMapper::hasStylus() const {
587000710e906bdafd58386ee7f81fa84addd218122fJeff Brown    return mTouchButtonAccumulator.hasStylus();
587100710e906bdafd58386ee7f81fa84addd218122fJeff Brown}
587200710e906bdafd58386ee7f81fa84addd218122fJeff Brown
58736d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
58746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown// --- MultiTouchInputMapper ---
58756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
587647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff BrownMultiTouchInputMapper::MultiTouchInputMapper(InputDevice* device) :
587749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        TouchInputMapper(device) {
58786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
58796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
58806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownMultiTouchInputMapper::~MultiTouchInputMapper() {
58816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
58826d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
588365fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid MultiTouchInputMapper::reset(nsecs_t when) {
588465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mMultiTouchMotionAccumulator.reset(getDevice());
58852717eff2ac04bed60e5fd577bcb8ec1ea7c2ccdeJeff Brown
588665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerIdBits.clear();
58876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
588865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    TouchInputMapper::reset(when);
58896d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
58906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
58916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid MultiTouchInputMapper::process(const RawEvent* rawEvent) {
589265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    TouchInputMapper::process(rawEvent);
58936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
589465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mMultiTouchMotionAccumulator.process(rawEvent);
58956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
58966d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
589765fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid MultiTouchInputMapper::syncTouch(nsecs_t when, bool* outHavePointerIds) {
589849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    size_t inCount = mMultiTouchMotionAccumulator.getSlotCount();
589980fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    size_t outCount = 0;
5900be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    BitSet32 newPointerIdBits;
59016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
590280fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    for (size_t inIndex = 0; inIndex < inCount; inIndex++) {
590349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        const MultiTouchMotionAccumulator::Slot* inSlot =
590449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                mMultiTouchMotionAccumulator.getSlot(inIndex);
590549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        if (!inSlot->isInUse()) {
59066d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            continue;
59076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
59086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
590980fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        if (outCount >= MAX_POINTERS) {
591080fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown#if DEBUG_POINTERS
59115baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("MultiTouch device %s emitted more than maximum of %d pointers; "
591280fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                    "ignoring the rest.",
591380fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                    getDeviceName().string(), MAX_POINTERS);
591480fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown#endif
591580fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            break; // too many fingers!
591680fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        }
591780fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
5918be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        RawPointerData::Pointer& outPointer = mCurrentRawPointerData.pointers[outCount];
591949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.x = inSlot->getX();
592049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.y = inSlot->getY();
592149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.pressure = inSlot->getPressure();
592249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.touchMajor = inSlot->getTouchMajor();
592349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.touchMinor = inSlot->getTouchMinor();
592449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.toolMajor = inSlot->getToolMajor();
592549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.toolMinor = inSlot->getToolMinor();
592649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.orientation = inSlot->getOrientation();
592749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.distance = inSlot->getDistance();
592865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        outPointer.tiltX = 0;
592965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        outPointer.tiltY = 0;
593049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
593149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.toolType = inSlot->getToolType();
593249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
593349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            outPointer.toolType = mTouchButtonAccumulator.getToolType();
593449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
593549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
593649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            }
593780fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        }
593880fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
593965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        bool isHovering = mTouchButtonAccumulator.getToolType() != AMOTION_EVENT_TOOL_TYPE_MOUSE
594065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                && (mTouchButtonAccumulator.isHovering()
594165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                        || (mRawPointerAxes.pressure.valid && inSlot->getPressure() <= 0));
5942be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        outPointer.isHovering = isHovering;
5943fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
59448d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // Assign pointer id using tracking id if available.
594565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (*outHavePointerIds) {
594649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            int32_t trackingId = inSlot->getTrackingId();
59476894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown            int32_t id = -1;
594849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            if (trackingId >= 0) {
59496894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown                for (BitSet32 idBits(mPointerIdBits); !idBits.isEmpty(); ) {
5950be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    uint32_t n = idBits.clearFirstMarkedBit();
59516894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown                    if (mPointerTrackingIdMap[n] == trackingId) {
59526894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown                        id = n;
59536894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown                    }
59546894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown                }
59556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
59566894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown                if (id < 0 && !mPointerIdBits.isFull()) {
5957be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    id = mPointerIdBits.markFirstUnmarkedBit();
59586894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown                    mPointerTrackingIdMap[id] = trackingId;
59596894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown                }
59606894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown            }
59616894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown            if (id < 0) {
596265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                *outHavePointerIds = false;
5963be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentRawPointerData.clearIdBits();
5964be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                newPointerIdBits.clear();
59656894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown            } else {
596680fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                outPointer.id = id;
5967be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentRawPointerData.idToIndex[id] = outCount;
5968be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentRawPointerData.markIdBit(id, isHovering);
5969be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                newPointerIdBits.markBit(id);
59706d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
59716d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
59726d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
59736d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        outCount += 1;
59746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
59756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5976be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mCurrentRawPointerData.pointerCount = outCount;
5977be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mPointerIdBits = newPointerIdBits;
59786894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown
597965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mMultiTouchMotionAccumulator.finishSync();
59806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
59816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5982be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid MultiTouchInputMapper::configureRawPointerAxes() {
5983be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    TouchInputMapper::configureRawPointerAxes();
59842dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown
5985be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_MT_POSITION_X, &mRawPointerAxes.x);
5986be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_MT_POSITION_Y, &mRawPointerAxes.y);
5987be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_MT_TOUCH_MAJOR, &mRawPointerAxes.touchMajor);
5988be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_MT_TOUCH_MINOR, &mRawPointerAxes.touchMinor);
5989be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_MT_WIDTH_MAJOR, &mRawPointerAxes.toolMajor);
5990be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_MT_WIDTH_MINOR, &mRawPointerAxes.toolMinor);
5991be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_MT_ORIENTATION, &mRawPointerAxes.orientation);
5992be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_MT_PRESSURE, &mRawPointerAxes.pressure);
5993be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_MT_DISTANCE, &mRawPointerAxes.distance);
5994be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_MT_TRACKING_ID, &mRawPointerAxes.trackingId);
5995be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_MT_SLOT, &mRawPointerAxes.slot);
5996be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
5997be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (mRawPointerAxes.trackingId.valid
5998be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            && mRawPointerAxes.slot.valid
5999be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            && mRawPointerAxes.slot.minValue == 0 && mRawPointerAxes.slot.maxValue > 0) {
6000be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        size_t slotCount = mRawPointerAxes.slot.maxValue + 1;
600149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        if (slotCount > MAX_SLOTS) {
60028564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("MultiTouch Device %s reported %d slots but the framework "
600380fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                    "only supports a maximum of %d slots at this time.",
600449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                    getDeviceName().string(), slotCount, MAX_SLOTS);
600549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            slotCount = MAX_SLOTS;
600680fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        }
600700710e906bdafd58386ee7f81fa84addd218122fJeff Brown        mMultiTouchMotionAccumulator.configure(getDevice(),
600800710e906bdafd58386ee7f81fa84addd218122fJeff Brown                slotCount, true /*usingSlotsProtocol*/);
600980fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    } else {
601000710e906bdafd58386ee7f81fa84addd218122fJeff Brown        mMultiTouchMotionAccumulator.configure(getDevice(),
601100710e906bdafd58386ee7f81fa84addd218122fJeff Brown                MAX_POINTERS, false /*usingSlotsProtocol*/);
601280fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    }
60136d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
60146d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
601500710e906bdafd58386ee7f81fa84addd218122fJeff Brownbool MultiTouchInputMapper::hasStylus() const {
601600710e906bdafd58386ee7f81fa84addd218122fJeff Brown    return mMultiTouchMotionAccumulator.hasStylus()
601700710e906bdafd58386ee7f81fa84addd218122fJeff Brown            || mTouchButtonAccumulator.hasStylus();
601800710e906bdafd58386ee7f81fa84addd218122fJeff Brown}
601900710e906bdafd58386ee7f81fa84addd218122fJeff Brown
60206d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
6021cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown// --- JoystickInputMapper ---
6022cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
6023cb1404e45639d20439d7700b06d57ca1a1aad1faJeff BrownJoystickInputMapper::JoystickInputMapper(InputDevice* device) :
6024cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        InputMapper(device) {
6025cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
6026cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
6027cb1404e45639d20439d7700b06d57ca1a1aad1faJeff BrownJoystickInputMapper::~JoystickInputMapper() {
6028cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
6029cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
6030cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brownuint32_t JoystickInputMapper::getSources() {
6031cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    return AINPUT_SOURCE_JOYSTICK;
6032cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
6033cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
6034cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brownvoid JoystickInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
6035cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    InputMapper::populateDeviceInfo(info);
6036cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
60376f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    for (size_t i = 0; i < mAxes.size(); i++) {
60386f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        const Axis& axis = mAxes.valueAt(i);
6039efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown        info->addMotionRange(axis.axisInfo.axis, AINPUT_SOURCE_JOYSTICK,
6040efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown                axis.min, axis.max, axis.flat, axis.fuzz);
60418529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
6042efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown            info->addMotionRange(axis.axisInfo.highAxis, AINPUT_SOURCE_JOYSTICK,
6043efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown                    axis.min, axis.max, axis.flat, axis.fuzz);
60448529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        }
6045cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
6046cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
6047cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
6048cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brownvoid JoystickInputMapper::dump(String8& dump) {
6049cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    dump.append(INDENT2 "Joystick Input Mapper:\n");
6050cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
60516f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    dump.append(INDENT3 "Axes:\n");
60526f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    size_t numAxes = mAxes.size();
60536f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    for (size_t i = 0; i < numAxes; i++) {
60546f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        const Axis& axis = mAxes.valueAt(i);
60558529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        const char* label = getAxisLabel(axis.axisInfo.axis);
60566f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        if (label) {
60578529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            dump.appendFormat(INDENT4 "%s", label);
60586f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        } else {
60598529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            dump.appendFormat(INDENT4 "%d", axis.axisInfo.axis);
60608529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        }
60618529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
60628529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            label = getAxisLabel(axis.axisInfo.highAxis);
60638529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            if (label) {
60648529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                dump.appendFormat(" / %s (split at %d)", label, axis.axisInfo.splitValue);
60658529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            } else {
60668529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                dump.appendFormat(" / %d (split at %d)", axis.axisInfo.highAxis,
60678529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                        axis.axisInfo.splitValue);
60688529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            }
60698529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        } else if (axis.axisInfo.mode == AxisInfo::MODE_INVERT) {
60708529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            dump.append(" (invert)");
60716f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        }
60728529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown
60738529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        dump.appendFormat(": min=%0.5f, max=%0.5f, flat=%0.5f, fuzz=%0.5f\n",
60748529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                axis.min, axis.max, axis.flat, axis.fuzz);
60758529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        dump.appendFormat(INDENT4 "  scale=%0.5f, offset=%0.5f, "
60768529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                "highScale=%0.5f, highOffset=%0.5f\n",
60778529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                axis.scale, axis.offset, axis.highScale, axis.highOffset);
6078b3a2d1330716812784aee91b6d6275764b5e4210Jeff Brown        dump.appendFormat(INDENT4 "  rawAxis=%d, rawMin=%d, rawMax=%d, "
6079b3a2d1330716812784aee91b6d6275764b5e4210Jeff Brown                "rawFlat=%d, rawFuzz=%d, rawResolution=%d\n",
60806f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown                mAxes.keyAt(i), axis.rawAxisInfo.minValue, axis.rawAxisInfo.maxValue,
6081b3a2d1330716812784aee91b6d6275764b5e4210Jeff Brown                axis.rawAxisInfo.flat, axis.rawAxisInfo.fuzz, axis.rawAxisInfo.resolution);
6082cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
6083cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
6084cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
608565fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid JoystickInputMapper::configure(nsecs_t when,
608665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        const InputReaderConfiguration* config, uint32_t changes) {
608765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    InputMapper::configure(when, config, changes);
6088cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
6089474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    if (!changes) { // first time only
6090474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        // Collect all axes.
6091474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        for (int32_t abs = 0; abs <= ABS_MAX; abs++) {
60929ee285afe740ff13d176c9d8430979dfd9575a23Jeff Brown            if (!(getAbsAxisUsage(abs, getDevice()->getClasses())
60939ee285afe740ff13d176c9d8430979dfd9575a23Jeff Brown                    & INPUT_DEVICE_CLASS_JOYSTICK)) {
60949ee285afe740ff13d176c9d8430979dfd9575a23Jeff Brown                continue; // axis must be claimed by a different device
60959ee285afe740ff13d176c9d8430979dfd9575a23Jeff Brown            }
60969ee285afe740ff13d176c9d8430979dfd9575a23Jeff Brown
6097474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            RawAbsoluteAxisInfo rawAxisInfo;
6098be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            getAbsoluteAxisInfo(abs, &rawAxisInfo);
6099474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            if (rawAxisInfo.valid) {
6100474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                // Map axis.
6101474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                AxisInfo axisInfo;
6102474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                bool explicitlyMapped = !getEventHub()->mapAxis(getDeviceId(), abs, &axisInfo);
6103474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                if (!explicitlyMapped) {
6104474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    // Axis is not explicitly mapped, will choose a generic axis later.
6105474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    axisInfo.mode = AxisInfo::MODE_NORMAL;
6106474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    axisInfo.axis = -1;
6107474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                }
61086f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
6109474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                // Apply flat override.
6110474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                int32_t rawFlat = axisInfo.flatOverride < 0
6111474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                        ? rawAxisInfo.flat : axisInfo.flatOverride;
6112474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown
6113474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                // Calculate scaling factors and limits.
6114474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                Axis axis;
6115474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                if (axisInfo.mode == AxisInfo::MODE_SPLIT) {
6116474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    float scale = 1.0f / (axisInfo.splitValue - rawAxisInfo.minValue);
6117474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    float highScale = 1.0f / (rawAxisInfo.maxValue - axisInfo.splitValue);
6118474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
6119474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                            scale, 0.0f, highScale, 0.0f,
6120474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                            0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale);
6121474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                } else if (isCenteredAxis(axisInfo.axis)) {
6122474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    float scale = 2.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
6123474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    float offset = avg(rawAxisInfo.minValue, rawAxisInfo.maxValue) * -scale;
6124474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
6125474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                            scale, offset, scale, offset,
6126474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                            -1.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale);
6127474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                } else {
6128474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    float scale = 1.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
6129474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
6130474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                            scale, 0.0f, scale, 0.0f,
6131474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                            0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale);
6132474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                }
61336f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
6134474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                // To eliminate noise while the joystick is at rest, filter out small variations
6135474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                // in axis values up front.
6136474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                axis.filter = axis.flat * 0.25f;
61376f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
6138474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                mAxes.add(abs, axis);
6139474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            }
61406f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        }
6141cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
6142474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        // If there are too many axes, start dropping them.
6143474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        // Prefer to keep explicitly mapped axes.
6144474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        if (mAxes.size() > PointerCoords::MAX_AXES) {
61456215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block            ALOGI("Joystick '%s' has %d axes but the framework only supports a maximum of %d.",
6146474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    getDeviceName().string(), mAxes.size(), PointerCoords::MAX_AXES);
6147474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            pruneAxes(true);
6148474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            pruneAxes(false);
6149474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        }
6150474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown
6151474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        // Assign generic axis ids to remaining axes.
6152474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        int32_t nextGenericAxisId = AMOTION_EVENT_AXIS_GENERIC_1;
6153474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        size_t numAxes = mAxes.size();
6154474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        for (size_t i = 0; i < numAxes; i++) {
6155474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            Axis& axis = mAxes.editValueAt(i);
6156474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            if (axis.axisInfo.axis < 0) {
6157474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                while (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16
6158474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                        && haveAxis(nextGenericAxisId)) {
6159474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    nextGenericAxisId += 1;
6160474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                }
61616f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
6162474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                if (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16) {
6163474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    axis.axisInfo.axis = nextGenericAxisId;
6164474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    nextGenericAxisId += 1;
6165474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                } else {
61666215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block                    ALOGI("Ignoring joystick '%s' axis %d because all of the generic axis ids "
6167474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                            "have already been assigned to other axes.",
6168474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                            getDeviceName().string(), mAxes.keyAt(i));
6169474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    mAxes.removeItemsAt(i--);
6170474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    numAxes -= 1;
6171474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                }
61726f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            }
61736f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        }
61746f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
6175cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
6176cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
61778529745b27877d98a0c76692295a3fcac238b1e6Jeff Brownbool JoystickInputMapper::haveAxis(int32_t axisId) {
61786f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    size_t numAxes = mAxes.size();
61796f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    for (size_t i = 0; i < numAxes; i++) {
61808529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        const Axis& axis = mAxes.valueAt(i);
61818529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        if (axis.axisInfo.axis == axisId
61828529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                || (axis.axisInfo.mode == AxisInfo::MODE_SPLIT
61838529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                        && axis.axisInfo.highAxis == axisId)) {
61846f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            return true;
61856f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        }
61866f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
61876f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    return false;
61886f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown}
6189cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
61906f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brownvoid JoystickInputMapper::pruneAxes(bool ignoreExplicitlyMappedAxes) {
61916f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    size_t i = mAxes.size();
61926f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    while (mAxes.size() > PointerCoords::MAX_AXES && i-- > 0) {
61936f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        if (ignoreExplicitlyMappedAxes && mAxes.valueAt(i).explicitlyMapped) {
61946f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            continue;
61956f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        }
61966215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block        ALOGI("Discarding joystick '%s' axis %d because there are too many axes.",
61976f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown                getDeviceName().string(), mAxes.keyAt(i));
61986f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        mAxes.removeItemsAt(i);
61996f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
62006f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown}
62016f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
62026f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brownbool JoystickInputMapper::isCenteredAxis(int32_t axis) {
62036f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    switch (axis) {
62046f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_X:
62056f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_Y:
62066f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_Z:
62076f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_RX:
62086f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_RY:
62096f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_RZ:
62106f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_HAT_X:
62116f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_HAT_Y:
62126f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_ORIENTATION:
62138529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    case AMOTION_EVENT_AXIS_RUDDER:
62148529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    case AMOTION_EVENT_AXIS_WHEEL:
62156f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        return true;
62166f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    default:
62176f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        return false;
62186f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
6219cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
6220cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
622165fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid JoystickInputMapper::reset(nsecs_t when) {
6222cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    // Recenter all axes.
62236f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    size_t numAxes = mAxes.size();
62246f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    for (size_t i = 0; i < numAxes; i++) {
62256f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        Axis& axis = mAxes.editValueAt(i);
62268529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        axis.resetValue();
62276f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
62286f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
622965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    InputMapper::reset(when);
6230cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
6231cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
6232cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brownvoid JoystickInputMapper::process(const RawEvent* rawEvent) {
6233cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    switch (rawEvent->type) {
62346f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case EV_ABS: {
623549ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        ssize_t index = mAxes.indexOfKey(rawEvent->code);
62366f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        if (index >= 0) {
62376f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            Axis& axis = mAxes.editValueAt(index);
62388529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            float newValue, highNewValue;
62398529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            switch (axis.axisInfo.mode) {
62408529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            case AxisInfo::MODE_INVERT:
62418529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                newValue = (axis.rawAxisInfo.maxValue - rawEvent->value)
62428529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                        * axis.scale + axis.offset;
62438529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                highNewValue = 0.0f;
62448529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                break;
62458529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            case AxisInfo::MODE_SPLIT:
62468529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                if (rawEvent->value < axis.axisInfo.splitValue) {
62478529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                    newValue = (axis.axisInfo.splitValue - rawEvent->value)
62488529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                            * axis.scale + axis.offset;
62498529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                    highNewValue = 0.0f;
62508529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                } else if (rawEvent->value > axis.axisInfo.splitValue) {
62518529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                    newValue = 0.0f;
62528529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                    highNewValue = (rawEvent->value - axis.axisInfo.splitValue)
62538529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                            * axis.highScale + axis.highOffset;
62548529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                } else {
62558529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                    newValue = 0.0f;
62568529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                    highNewValue = 0.0f;
62578529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                }
62588529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                break;
62598529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            default:
62608529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                newValue = rawEvent->value * axis.scale + axis.offset;
62618529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                highNewValue = 0.0f;
62628529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                break;
62636f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            }
62648529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            axis.newValue = newValue;
62658529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            axis.highNewValue = highNewValue;
6266cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        }
6267cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        break;
62686f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
6269cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
6270cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    case EV_SYN:
627149ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        switch (rawEvent->code) {
6272cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        case SYN_REPORT:
62736f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            sync(rawEvent->when, false /*force*/);
6274cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown            break;
6275cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        }
6276cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        break;
6277cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
6278cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
6279cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
62806f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brownvoid JoystickInputMapper::sync(nsecs_t when, bool force) {
62818529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    if (!filterAxes(force)) {
62826f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        return;
6283cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
6284cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
6285cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    int32_t metaState = mContext->getGlobalMetaState();
6286fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    int32_t buttonState = 0;
6287fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
6288fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    PointerProperties pointerProperties;
6289fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    pointerProperties.clear();
6290fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    pointerProperties.id = 0;
6291fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
6292cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
62936f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    PointerCoords pointerCoords;
62946f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    pointerCoords.clear();
6295cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
62966f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    size_t numAxes = mAxes.size();
62976f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    for (size_t i = 0; i < numAxes; i++) {
62988529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        const Axis& axis = mAxes.valueAt(i);
62998529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        pointerCoords.setAxisValue(axis.axisInfo.axis, axis.currentValue);
63008529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
63018529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            pointerCoords.setAxisValue(axis.axisInfo.highAxis, axis.highCurrentValue);
63028529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        }
6303cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
6304cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
630583d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    // Moving a joystick axis should not wake the device because joysticks can
630656194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // be fairly noisy even when not in use.  On the other hand, pushing a gamepad
630756194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // button will likely wake the device.
630856194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // TODO: Use the input device configuration to control this behavior more finely.
630956194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    uint32_t policyFlags = 0;
631056194ebec6212e229f4ccdaa4b187166d20013efJeff Brown
6311be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    NotifyMotionArgs args(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, policyFlags,
6312fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
631383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            ADISPLAY_ID_NONE, 1, &pointerProperties, &pointerCoords, 0, 0, 0);
6314be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getListener()->notifyMotion(&args);
6315cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
6316cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
63178529745b27877d98a0c76692295a3fcac238b1e6Jeff Brownbool JoystickInputMapper::filterAxes(bool force) {
63188529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    bool atLeastOneSignificantChange = force;
63196f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    size_t numAxes = mAxes.size();
63206f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    for (size_t i = 0; i < numAxes; i++) {
63218529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        Axis& axis = mAxes.editValueAt(i);
63228529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        if (force || hasValueChangedSignificantly(axis.filter,
63238529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                axis.newValue, axis.currentValue, axis.min, axis.max)) {
63248529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            axis.currentValue = axis.newValue;
63258529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            atLeastOneSignificantChange = true;
63268529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        }
63278529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
63288529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            if (force || hasValueChangedSignificantly(axis.filter,
63298529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                    axis.highNewValue, axis.highCurrentValue, axis.min, axis.max)) {
63308529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                axis.highCurrentValue = axis.highNewValue;
63318529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                atLeastOneSignificantChange = true;
63328529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            }
63338529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        }
63348529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    }
63358529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    return atLeastOneSignificantChange;
63368529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown}
63378529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown
63388529745b27877d98a0c76692295a3fcac238b1e6Jeff Brownbool JoystickInputMapper::hasValueChangedSignificantly(
63398529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        float filter, float newValue, float currentValue, float min, float max) {
63408529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    if (newValue != currentValue) {
63418529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        // Filter out small changes in value unless the value is converging on the axis
63428529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        // bounds or center point.  This is intended to reduce the amount of information
63438529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        // sent to applications by particularly noisy joysticks (such as PS3).
63448529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        if (fabs(newValue - currentValue) > filter
63458529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, min)
63468529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, max)
63478529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, 0)) {
63488529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            return true;
63498529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        }
63508529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    }
63518529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    return false;
63528529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown}
63538529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown
63548529745b27877d98a0c76692295a3fcac238b1e6Jeff Brownbool JoystickInputMapper::hasMovedNearerToValueWithinFilteredRange(
63558529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        float filter, float newValue, float currentValue, float thresholdValue) {
63568529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    float newDistance = fabs(newValue - thresholdValue);
63578529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    if (newDistance < filter) {
63588529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        float oldDistance = fabs(currentValue - thresholdValue);
63598529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        if (newDistance < oldDistance) {
63606f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            return true;
63616f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        }
6362cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
63636f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    return false;
6364cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
6365cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
636646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} // namespace android
6367