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>
459d3b1a424c5c61e24e9659d15fb353026a00d925Jeff Brown#include <input/Keyboard.h>
469d3b1a424c5c61e24e9659d15fb353026a00d925Jeff Brown#include <input/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);
357ac6c78b6eef49f5c1ab2a346d90ccb99ccec18f4Michael Wright    int32_t controllerNumber = mEventHub->getDeviceControllerNumber(deviceId);
35846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
359ac6c78b6eef49f5c1ab2a346d90ccb99ccec18f4Michael Wright    InputDevice* device = createDeviceLocked(deviceId, controllerNumber, identifier, classes);
36065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    device->configure(when, &mConfig, 0);
36165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    device->reset(when);
36246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3638d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    if (device->isIgnored()) {
364e38fdfae9196afd1bdc14c5ec6c12793af1e2550Jeff Brown        ALOGI("Device added: id=%d, name='%s' (ignored non-input device)", deviceId,
365e38fdfae9196afd1bdc14c5ec6c12793af1e2550Jeff Brown                identifier.name.string());
3668d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    } else {
367e38fdfae9196afd1bdc14c5ec6c12793af1e2550Jeff Brown        ALOGI("Device added: id=%d, name='%s', sources=0x%08x", deviceId,
368e38fdfae9196afd1bdc14c5ec6c12793af1e2550Jeff Brown                identifier.name.string(), device->getSources());
3698d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
3708d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
371af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    mDevices.add(deviceId, device);
372af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    bumpGenerationLocked();
37346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
37446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
37565fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid InputReader::removeDeviceLocked(nsecs_t when, int32_t deviceId) {
3766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    InputDevice* device = NULL;
377be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
378af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    if (deviceIndex < 0) {
3798564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("Ignoring spurious device removed event for deviceId %d.", deviceId);
3806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        return;
3816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
38246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
383af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    device = mDevices.valueAt(deviceIndex);
384af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    mDevices.removeItemsAt(deviceIndex, 1);
385af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    bumpGenerationLocked();
386af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown
3876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (device->isIgnored()) {
3886215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block        ALOGI("Device removed: id=%d, name='%s' (ignored non-input device)",
3896d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                device->getId(), device->getName().string());
3906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    } else {
3916215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block        ALOGI("Device removed: id=%d, name='%s', sources=0x%08x",
3926d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                device->getId(), device->getName().string(), device->getSources());
39346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
3946d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
39565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    device->reset(when);
3966d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    delete device;
39746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
39846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
399ac6c78b6eef49f5c1ab2a346d90ccb99ccec18f4Michael WrightInputDevice* InputReader::createDeviceLocked(int32_t deviceId, int32_t controllerNumber,
400e38fdfae9196afd1bdc14c5ec6c12793af1e2550Jeff Brown        const InputDeviceIdentifier& identifier, uint32_t classes) {
401af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    InputDevice* device = new InputDevice(&mContext, deviceId, bumpGenerationLocked(),
402ac6c78b6eef49f5c1ab2a346d90ccb99ccec18f4Michael Wright            controllerNumber, identifier, classes);
40346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
40456194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // External devices.
40556194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    if (classes & INPUT_DEVICE_CLASS_EXTERNAL) {
40656194ebec6212e229f4ccdaa4b187166d20013efJeff Brown        device->setExternal(true);
40756194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    }
40856194ebec6212e229f4ccdaa4b187166d20013efJeff Brown
4096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // Switch-like devices.
4106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (classes & INPUT_DEVICE_CLASS_SWITCH) {
4116d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        device->addMapper(new SwitchInputMapper(device));
412fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown    }
413fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown
414a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    // Vibrator-like devices.
415a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    if (classes & INPUT_DEVICE_CLASS_VIBRATOR) {
416a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        device->addMapper(new VibratorInputMapper(device));
417a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    }
418a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
4196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // Keyboard-like devices.
420efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown    uint32_t keyboardSource = 0;
4216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
4226d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (classes & INPUT_DEVICE_CLASS_KEYBOARD) {
423efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown        keyboardSource |= AINPUT_SOURCE_KEYBOARD;
4246d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
4256d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (classes & INPUT_DEVICE_CLASS_ALPHAKEY) {
4266d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC;
4276d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
4286d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (classes & INPUT_DEVICE_CLASS_DPAD) {
429efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown        keyboardSource |= AINPUT_SOURCE_DPAD;
4306d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
431cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    if (classes & INPUT_DEVICE_CLASS_GAMEPAD) {
432efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown        keyboardSource |= AINPUT_SOURCE_GAMEPAD;
433cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
434fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown
435efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown    if (keyboardSource != 0) {
436efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown        device->addMapper(new KeyboardInputMapper(device, keyboardSource, keyboardType));
437fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown    }
43846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
43983c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    // Cursor-like devices.
44083c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    if (classes & INPUT_DEVICE_CLASS_CURSOR) {
44183c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        device->addMapper(new CursorInputMapper(device));
4426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
44346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
44458a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown    // Touchscreens and touchpad devices.
44558a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown    if (classes & INPUT_DEVICE_CLASS_TOUCH_MT) {
44647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        device->addMapper(new MultiTouchInputMapper(device));
44758a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown    } else if (classes & INPUT_DEVICE_CLASS_TOUCH) {
44847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        device->addMapper(new SingleTouchInputMapper(device));
44946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
4506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
451cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    // Joystick-like devices.
452cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    if (classes & INPUT_DEVICE_CLASS_JOYSTICK) {
453cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        device->addMapper(new JoystickInputMapper(device));
454cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
455cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
4566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return device;
45746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
45846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
459be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputReader::processEventsForDeviceLocked(int32_t deviceId,
460b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown        const RawEvent* rawEvents, size_t count) {
461be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
462be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (deviceIndex < 0) {
4638564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("Discarding event for unknown deviceId %d.", deviceId);
464be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        return;
465be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
4666d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
467be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    InputDevice* device = mDevices.valueAt(deviceIndex);
468be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (device->isIgnored()) {
4695baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        //ALOGD("Discarding event for ignored deviceId %d.", deviceId);
470be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        return;
471be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
4726d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
473be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    device->process(rawEvents, count);
47446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
47546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
476be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputReader::timeoutExpiredLocked(nsecs_t when) {
477be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (size_t i = 0; i < mDevices.size(); i++) {
478be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        InputDevice* device = mDevices.valueAt(i);
479be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (!device->isIgnored()) {
480be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            device->timeoutExpired(when);
481aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown        }
482be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
483aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown}
484aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown
485be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputReader::handleConfigurationChangedLocked(nsecs_t when) {
4866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // Reset global meta state because it depends on the list of all configured devices.
487be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    updateGlobalMetaStateLocked();
4886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
4896d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // Enqueue configuration changed.
490be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    NotifyConfigurationChangedArgs args(when);
491be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mQueuedListener->notifyConfigurationChanged(&args);
49246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
49346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
494be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputReader::refreshConfigurationLocked(uint32_t changes) {
4951a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown    mPolicy->getReaderConfiguration(&mConfig);
4961a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown    mEventHub->setExcludedDevices(mConfig.excludedDeviceNames);
4971a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown
498474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    if (changes) {
4996215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block        ALOGI("Reconfiguring input devices.  changes=0x%08x", changes);
50065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
501474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown
502474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        if (changes & InputReaderConfiguration::CHANGE_MUST_REOPEN) {
503474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mEventHub->requestReopenDevices();
504474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        } else {
5056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            for (size_t i = 0; i < mDevices.size(); i++) {
5066d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                InputDevice* device = mDevices.valueAt(i);
50765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                device->configure(now, &mConfig, changes);
5086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
509be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
510be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
5116d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
51246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
513be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputReader::updateGlobalMetaStateLocked() {
514be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mGlobalMetaState = 0;
51546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
516be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (size_t i = 0; i < mDevices.size(); i++) {
517be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        InputDevice* device = mDevices.valueAt(i);
518be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mGlobalMetaState |= device->getMetaState();
519be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
5206d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
52146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
522be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownint32_t InputReader::getGlobalMetaStateLocked() {
523be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return mGlobalMetaState;
524be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
52546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
526be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputReader::disableVirtualKeysUntilLocked(nsecs_t time) {
527fe50892af3b365806a767298dfd8e86447682581Jeff Brown    mDisableVirtualKeysTimeout = time;
528fe50892af3b365806a767298dfd8e86447682581Jeff Brown}
529fe50892af3b365806a767298dfd8e86447682581Jeff Brown
530be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownbool InputReader::shouldDropVirtualKeyLocked(nsecs_t now,
531fe50892af3b365806a767298dfd8e86447682581Jeff Brown        InputDevice* device, int32_t keyCode, int32_t scanCode) {
532fe50892af3b365806a767298dfd8e86447682581Jeff Brown    if (now < mDisableVirtualKeysTimeout) {
5336215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block        ALOGI("Dropping virtual key from device %s because virtual keys are "
534fe50892af3b365806a767298dfd8e86447682581Jeff Brown                "temporarily disabled for the next %0.3fms.  keyCode=%d, scanCode=%d",
535fe50892af3b365806a767298dfd8e86447682581Jeff Brown                device->getName().string(),
536fe50892af3b365806a767298dfd8e86447682581Jeff Brown                (mDisableVirtualKeysTimeout - now) * 0.000001,
537fe50892af3b365806a767298dfd8e86447682581Jeff Brown                keyCode, scanCode);
538fe50892af3b365806a767298dfd8e86447682581Jeff Brown        return true;
539fe50892af3b365806a767298dfd8e86447682581Jeff Brown    } else {
540fe50892af3b365806a767298dfd8e86447682581Jeff Brown        return false;
541fe50892af3b365806a767298dfd8e86447682581Jeff Brown    }
542fe50892af3b365806a767298dfd8e86447682581Jeff Brown}
543fe50892af3b365806a767298dfd8e86447682581Jeff Brown
544be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputReader::fadePointerLocked() {
545be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (size_t i = 0; i < mDevices.size(); i++) {
546be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        InputDevice* device = mDevices.valueAt(i);
547be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        device->fadePointer();
548be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
54905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown}
55005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
551be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputReader::requestTimeoutAtTimeLocked(nsecs_t when) {
552aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown    if (when < mNextTimeout) {
553aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown        mNextTimeout = when;
554a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        mEventHub->wake();
555aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown    }
556aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown}
557aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown
558af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownint32_t InputReader::bumpGenerationLocked() {
559af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    return ++mGeneration;
560af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown}
561af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown
562af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownvoid InputReader::getInputDevices(Vector<InputDeviceInfo>& outInputDevices) {
563be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    AutoMutex _l(mLock);
564af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    getInputDevicesLocked(outInputDevices);
5656d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
56646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
567af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownvoid InputReader::getInputDevicesLocked(Vector<InputDeviceInfo>& outInputDevices) {
568af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    outInputDevices.clear();
56946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
570be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    size_t numDevices = mDevices.size();
571be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (size_t i = 0; i < numDevices; i++) {
572be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        InputDevice* device = mDevices.valueAt(i);
573be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (!device->isIgnored()) {
574af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown            outInputDevices.push();
575af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown            device->getDeviceInfo(&outInputDevices.editTop());
57646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
577be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
5786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
57946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
5816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        int32_t keyCode) {
582be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    AutoMutex _l(mLock);
583be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
584be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return getStateLocked(deviceId, sourceMask, keyCode, &InputDevice::getKeyCodeState);
5856d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
586c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown
5876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputReader::getScanCodeState(int32_t deviceId, uint32_t sourceMask,
5886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        int32_t scanCode) {
589be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    AutoMutex _l(mLock);
590be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
591be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return getStateLocked(deviceId, sourceMask, scanCode, &InputDevice::getScanCodeState);
5926d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
593c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown
5946d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputReader::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t switchCode) {
595be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    AutoMutex _l(mLock);
596be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
597be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return getStateLocked(deviceId, sourceMask, switchCode, &InputDevice::getSwitchState);
5986d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
599c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown
600be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownint32_t InputReader::getStateLocked(int32_t deviceId, uint32_t sourceMask, int32_t code,
6016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        GetStateFunc getStateFunc) {
602be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t result = AKEY_STATE_UNKNOWN;
603be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (deviceId >= 0) {
604be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
605be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (deviceIndex >= 0) {
606be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            InputDevice* device = mDevices.valueAt(deviceIndex);
607be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
608be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                result = (device->*getStateFunc)(sourceMask, code);
6096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
610be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
611be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    } else {
612be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        size_t numDevices = mDevices.size();
613be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        for (size_t i = 0; i < numDevices; i++) {
614be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            InputDevice* device = mDevices.valueAt(i);
615be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
616fbca596721ea19daa2972639095898ce62100490David Deephanphongs                // If any device reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
617fbca596721ea19daa2972639095898ce62100490David Deephanphongs                // value.  Otherwise, return AKEY_STATE_UP as long as one device reports it.
618fbca596721ea19daa2972639095898ce62100490David Deephanphongs                int32_t currentResult = (device->*getStateFunc)(sourceMask, code);
619fbca596721ea19daa2972639095898ce62100490David Deephanphongs                if (currentResult >= AKEY_STATE_DOWN) {
620fbca596721ea19daa2972639095898ce62100490David Deephanphongs                    return currentResult;
621fbca596721ea19daa2972639095898ce62100490David Deephanphongs                } else if (currentResult == AKEY_STATE_UP) {
622fbca596721ea19daa2972639095898ce62100490David Deephanphongs                    result = currentResult;
6236d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
6246d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
6256d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
626be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
627be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return result;
6286d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
62946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
6306d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownbool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask,
6316d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
632be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    AutoMutex _l(mLock);
633be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
6346d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    memset(outFlags, 0, numCodes);
635be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return markSupportedKeyCodesLocked(deviceId, sourceMask, numCodes, keyCodes, outFlags);
6366d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
63746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
638be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownbool InputReader::markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask,
639be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
640be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    bool result = false;
641be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (deviceId >= 0) {
642be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
643be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (deviceIndex >= 0) {
644be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            InputDevice* device = mDevices.valueAt(deviceIndex);
645be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
646be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                result = device->markSupportedKeyCodes(sourceMask,
647be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        numCodes, keyCodes, outFlags);
6486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
649be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
650be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    } else {
651be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        size_t numDevices = mDevices.size();
652be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        for (size_t i = 0; i < numDevices; i++) {
653be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            InputDevice* device = mDevices.valueAt(i);
654be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
655be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                result |= device->markSupportedKeyCodes(sourceMask,
656be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        numCodes, keyCodes, outFlags);
65746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            }
65846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
659be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
660be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return result;
6616d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
66246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
663474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brownvoid InputReader::requestRefreshConfiguration(uint32_t changes) {
664be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    AutoMutex _l(mLock);
665474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown
666be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (changes) {
667be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        bool needWake = !mConfigurationChangesToRefresh;
668be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mConfigurationChangesToRefresh |= changes;
66993fa9b30b91f75ee161d0791ff17f98d1a603812Jeff Brown
670474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        if (needWake) {
671474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mEventHub->wake();
672474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        }
673474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    }
6741a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown}
6751a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown
676a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid InputReader::vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
677a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        ssize_t repeat, int32_t token) {
678a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    AutoMutex _l(mLock);
679a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
680a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
681a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    if (deviceIndex >= 0) {
682a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        InputDevice* device = mDevices.valueAt(deviceIndex);
683a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        device->vibrate(pattern, patternSize, repeat, token);
684a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    }
685a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
686a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
687a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid InputReader::cancelVibrate(int32_t deviceId, int32_t token) {
688a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    AutoMutex _l(mLock);
689a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
690a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
691a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    if (deviceIndex >= 0) {
692a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        InputDevice* device = mDevices.valueAt(deviceIndex);
693a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        device->cancelVibrate(token);
694a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    }
695a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
696a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
697b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownvoid InputReader::dump(String8& dump) {
698be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    AutoMutex _l(mLock);
699be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
700f2f487183052865d50c004a835360be1728b5a52Jeff Brown    mEventHub->dump(dump);
701f2f487183052865d50c004a835360be1728b5a52Jeff Brown    dump.append("\n");
702f2f487183052865d50c004a835360be1728b5a52Jeff Brown
703f2f487183052865d50c004a835360be1728b5a52Jeff Brown    dump.append("Input Reader State:\n");
704f2f487183052865d50c004a835360be1728b5a52Jeff Brown
705be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (size_t i = 0; i < mDevices.size(); i++) {
706be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mDevices.valueAt(i)->dump(dump);
707be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
708214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown
709214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.append(INDENT "Configuration:\n");
710214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.append(INDENT2 "ExcludedDeviceNames: [");
711214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    for (size_t i = 0; i < mConfig.excludedDeviceNames.size(); i++) {
712214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown        if (i != 0) {
713214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown            dump.append(", ");
714214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown        }
715214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown        dump.append(mConfig.excludedDeviceNames.itemAt(i).string());
716214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    }
717214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.append("]\n");
718214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT2 "VirtualKeyQuietTime: %0.1fms\n",
719214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown            mConfig.virtualKeyQuietTime * 0.000001f);
720214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown
72119c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown    dump.appendFormat(INDENT2 "PointerVelocityControlParameters: "
72219c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, acceleration=%0.3f\n",
72319c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            mConfig.pointerVelocityControlParameters.scale,
72419c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            mConfig.pointerVelocityControlParameters.lowThreshold,
72519c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            mConfig.pointerVelocityControlParameters.highThreshold,
72619c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            mConfig.pointerVelocityControlParameters.acceleration);
72719c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown
72819c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown    dump.appendFormat(INDENT2 "WheelVelocityControlParameters: "
72919c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, acceleration=%0.3f\n",
73019c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            mConfig.wheelVelocityControlParameters.scale,
73119c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            mConfig.wheelVelocityControlParameters.lowThreshold,
73219c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            mConfig.wheelVelocityControlParameters.highThreshold,
73319c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            mConfig.wheelVelocityControlParameters.acceleration);
73419c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown
735214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT2 "PointerGesture:\n");
736474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    dump.appendFormat(INDENT3 "Enabled: %s\n",
737474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            toString(mConfig.pointerGesturesEnabled));
738214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT3 "QuietInterval: %0.1fms\n",
739214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown            mConfig.pointerGestureQuietInterval * 0.000001f);
740214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT3 "DragMinSwitchSpeed: %0.1fpx/s\n",
741214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown            mConfig.pointerGestureDragMinSwitchSpeed);
742214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT3 "TapInterval: %0.1fms\n",
743214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown            mConfig.pointerGestureTapInterval * 0.000001f);
744214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT3 "TapDragInterval: %0.1fms\n",
745214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown            mConfig.pointerGestureTapDragInterval * 0.000001f);
746214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT3 "TapSlop: %0.1fpx\n",
747214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown            mConfig.pointerGestureTapSlop);
748214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT3 "MultitouchSettleInterval: %0.1fms\n",
749214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown            mConfig.pointerGestureMultitouchSettleInterval * 0.000001f);
750bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown    dump.appendFormat(INDENT3 "MultitouchMinDistance: %0.1fpx\n",
751bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            mConfig.pointerGestureMultitouchMinDistance);
752214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT3 "SwipeTransitionAngleCosine: %0.1f\n",
753214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown            mConfig.pointerGestureSwipeTransitionAngleCosine);
754214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT3 "SwipeMaxWidthRatio: %0.1f\n",
755214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown            mConfig.pointerGestureSwipeMaxWidthRatio);
756214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT3 "MovementSpeedRatio: %0.1f\n",
757214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown            mConfig.pointerGestureMovementSpeedRatio);
758214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT3 "ZoomSpeedRatio: %0.1f\n",
759214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown            mConfig.pointerGestureZoomSpeedRatio);
760b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
761b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
76289ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brownvoid InputReader::monitor() {
76389ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown    // Acquire and release the lock to ensure that the reader has not deadlocked.
76489ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown    mLock.lock();
765112b5f52c5a4b6743eeb7b26a8896c7636c74455Jeff Brown    mEventHub->wake();
766112b5f52c5a4b6743eeb7b26a8896c7636c74455Jeff Brown    mReaderIsAliveCondition.wait(mLock);
76789ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown    mLock.unlock();
76889ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown
76989ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown    // Check the EventHub
77089ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown    mEventHub->monitor();
77189ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown}
77289ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown
77346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
774be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown// --- InputReader::ContextImpl ---
775be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
776be1aa8250cee7819c49741e819e81659d1d03823Jeff BrownInputReader::ContextImpl::ContextImpl(InputReader* reader) :
777be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mReader(reader) {
778be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
779be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
780be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputReader::ContextImpl::updateGlobalMetaState() {
781be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // lock is already held by the input loop
782be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mReader->updateGlobalMetaStateLocked();
783be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
784be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
785be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownint32_t InputReader::ContextImpl::getGlobalMetaState() {
786be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // lock is already held by the input loop
787be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return mReader->getGlobalMetaStateLocked();
788be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
789be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
790be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputReader::ContextImpl::disableVirtualKeysUntil(nsecs_t time) {
791be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // lock is already held by the input loop
792be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mReader->disableVirtualKeysUntilLocked(time);
793be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
794be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
795be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownbool InputReader::ContextImpl::shouldDropVirtualKey(nsecs_t now,
796be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        InputDevice* device, int32_t keyCode, int32_t scanCode) {
797be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // lock is already held by the input loop
798be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return mReader->shouldDropVirtualKeyLocked(now, device, keyCode, scanCode);
799be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
800be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
801be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputReader::ContextImpl::fadePointer() {
802be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // lock is already held by the input loop
803be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mReader->fadePointerLocked();
804be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
805be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
806be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputReader::ContextImpl::requestTimeoutAtTime(nsecs_t when) {
807be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // lock is already held by the input loop
808be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mReader->requestTimeoutAtTimeLocked(when);
809be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
810be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
811af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownint32_t InputReader::ContextImpl::bumpGeneration() {
812af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    // lock is already held by the input loop
813af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    return mReader->bumpGenerationLocked();
814af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown}
815af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown
816be1aa8250cee7819c49741e819e81659d1d03823Jeff BrownInputReaderPolicyInterface* InputReader::ContextImpl::getPolicy() {
817be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return mReader->mPolicy.get();
818be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
819be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
820be1aa8250cee7819c49741e819e81659d1d03823Jeff BrownInputListenerInterface* InputReader::ContextImpl::getListener() {
821be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return mReader->mQueuedListener.get();
822be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
823be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
824be1aa8250cee7819c49741e819e81659d1d03823Jeff BrownEventHubInterface* InputReader::ContextImpl::getEventHub() {
825be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return mReader->mEventHub.get();
826be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
827be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
828be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
8296d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown// --- InputReaderThread ---
83046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
8316d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownInputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) :
8326d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        Thread(/*canCallJava*/ true), mReader(reader) {
83346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
83446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
8356d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownInputReaderThread::~InputReaderThread() {
8366d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
83746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
8386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownbool InputReaderThread::threadLoop() {
8396d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mReader->loopOnce();
8406d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return true;
8416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
84246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
84346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
8446d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown// --- InputDevice ---
84546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
846af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff BrownInputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
847ac6c78b6eef49f5c1ab2a346d90ccb99ccec18f4Michael Wright        int32_t controllerNumber, const InputDeviceIdentifier& identifier, uint32_t classes) :
848ac6c78b6eef49f5c1ab2a346d90ccb99ccec18f4Michael Wright        mContext(context), mId(id), mGeneration(generation), mControllerNumber(controllerNumber),
849af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown        mIdentifier(identifier), mClasses(classes),
8509ee285afe740ff13d176c9d8430979dfd9575a23Jeff Brown        mSources(0), mIsExternal(false), mDropUntilNextSync(false) {
8516d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
85246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
8536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownInputDevice::~InputDevice() {
8546d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    size_t numMappers = mMappers.size();
8556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
8566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        delete mMappers[i];
85746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
8586d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mMappers.clear();
8596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
86046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
861ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brownvoid InputDevice::dump(String8& dump) {
862ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    InputDeviceInfo deviceInfo;
863ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    getDeviceInfo(& deviceInfo);
864ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
8659065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown    dump.appendFormat(INDENT "Device %d: %s\n", deviceInfo.getId(),
8665bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown            deviceInfo.getDisplayName().string());
867af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    dump.appendFormat(INDENT2 "Generation: %d\n", mGeneration);
86856194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    dump.appendFormat(INDENT2 "IsExternal: %s\n", toString(mIsExternal));
869ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
870ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    dump.appendFormat(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
871cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown
872efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown    const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
873cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown    if (!ranges.isEmpty()) {
874ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT2 "Motion Ranges:\n");
875cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown        for (size_t i = 0; i < ranges.size(); i++) {
876efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown            const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
877efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown            const char* label = getAxisLabel(range.axis);
878cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown            char name[32];
879cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown            if (label) {
880cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown                strncpy(name, label, sizeof(name));
881cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown                name[sizeof(name) - 1] = '\0';
882cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown            } else {
883efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown                snprintf(name, sizeof(name), "%d", range.axis);
884cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown            }
885efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown            dump.appendFormat(INDENT3 "%s: source=0x%08x, "
886c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright                    "min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f, resolution=%0.3f\n",
887c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright                    name, range.source, range.min, range.max, range.flat, range.fuzz,
888c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright                    range.resolution);
889cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown        }
890ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    }
891ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
892ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    size_t numMappers = mMappers.size();
893ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
894ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        InputMapper* mapper = mMappers[i];
895ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        mapper->dump(dump);
896ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    }
897ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown}
898ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
8996d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid InputDevice::addMapper(InputMapper* mapper) {
9006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mMappers.add(mapper);
9016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
902349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown
90365fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes) {
9046d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mSources = 0;
9056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
906474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    if (!isIgnored()) {
907474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        if (!changes) { // first time only
908474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mContext->getEventHub()->getConfiguration(mId, &mConfiguration);
909474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        }
910474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown
9116ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown        if (!changes || (changes & InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS)) {
91261c08240585a6186b4bd879d87f238b3efc368f8Jeff Brown            if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
91361c08240585a6186b4bd879d87f238b3efc368f8Jeff Brown                sp<KeyCharacterMap> keyboardLayout =
91461c08240585a6186b4bd879d87f238b3efc368f8Jeff Brown                        mContext->getPolicy()->getKeyboardLayoutOverlay(mIdentifier.descriptor);
91561c08240585a6186b4bd879d87f238b3efc368f8Jeff Brown                if (mContext->getEventHub()->setKeyboardLayoutOverlay(mId, keyboardLayout)) {
91661c08240585a6186b4bd879d87f238b3efc368f8Jeff Brown                    bumpGeneration();
91761c08240585a6186b4bd879d87f238b3efc368f8Jeff Brown                }
9186ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown            }
9196ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown        }
9206ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown
9215bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown        if (!changes || (changes & InputReaderConfiguration::CHANGE_DEVICE_ALIAS)) {
9225bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown            if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
9235bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown                String8 alias = mContext->getPolicy()->getDeviceAlias(mIdentifier);
9245bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown                if (mAlias != alias) {
9255bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown                    mAlias = alias;
9265bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown                    bumpGeneration();
9275bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown                }
9285bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown            }
9295bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown        }
9305bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown
931474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        size_t numMappers = mMappers.size();
932474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        for (size_t i = 0; i < numMappers; i++) {
933474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            InputMapper* mapper = mMappers[i];
93465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mapper->configure(when, config, changes);
935474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mSources |= mapper->getSources();
936474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        }
937349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown    }
9386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
939349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown
94065fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid InputDevice::reset(nsecs_t when) {
9416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    size_t numMappers = mMappers.size();
9426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
9436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        InputMapper* mapper = mMappers[i];
94465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mapper->reset(when);
945349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown    }
94665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
94765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mContext->updateGlobalMetaState();
94865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
94965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    notifyReset(when);
9506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
951349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown
952b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brownvoid InputDevice::process(const RawEvent* rawEvents, size_t count) {
953b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown    // Process all of the events in order for each mapper.
954b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown    // We cannot simply ask each mapper to process them in bulk because mappers may
955b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown    // have side-effects that must be interleaved.  For example, joystick movement events and
956b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown    // gamepad button presses are handled by different mappers but they should be dispatched
957b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown    // in the order received.
9586d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    size_t numMappers = mMappers.size();
959b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown    for (const RawEvent* rawEvent = rawEvents; count--; rawEvent++) {
960b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown#if DEBUG_RAW_EVENTS
961f33b2b2b2483fa824c650b281159ca62e1d0123aJeff Brown        ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%lld",
962f33b2b2b2483fa824c650b281159ca62e1d0123aJeff Brown                rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value,
963f33b2b2b2483fa824c650b281159ca62e1d0123aJeff Brown                rawEvent->when);
964b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown#endif
965b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown
96680fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        if (mDropUntilNextSync) {
96749ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown            if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
96880fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                mDropUntilNextSync = false;
96980fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown#if DEBUG_RAW_EVENTS
9705baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Recovered from input event buffer overrun.");
97180fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown#endif
97280fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            } else {
97380fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown#if DEBUG_RAW_EVENTS
9745baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Dropped input event while waiting for next input sync.");
97580fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown#endif
97680fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            }
97749ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
978e38fdfae9196afd1bdc14c5ec6c12793af1e2550Jeff Brown            ALOGI("Detected input event buffer overrun for device %s.", getName().string());
97980fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            mDropUntilNextSync = true;
98065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            reset(rawEvent->when);
98180fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        } else {
98280fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            for (size_t i = 0; i < numMappers; i++) {
98380fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                InputMapper* mapper = mMappers[i];
98480fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                mapper->process(rawEvent);
98580fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            }
986b7198743ab3976b30d4655c1e065ca33e372b6afJeff Brown        }
98746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
9886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
98946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
990aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brownvoid InputDevice::timeoutExpired(nsecs_t when) {
991aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown    size_t numMappers = mMappers.size();
992aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown    for (size_t i = 0; i < numMappers; i++) {
993aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown        InputMapper* mapper = mMappers[i];
994aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown        mapper->timeoutExpired(when);
995aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown    }
996aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown}
997aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown
9986d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
999ac6c78b6eef49f5c1ab2a346d90ccb99ccec18f4Michael Wright    outDeviceInfo->initialize(mId, mGeneration, mControllerNumber, mIdentifier, mAlias,
1000ac6c78b6eef49f5c1ab2a346d90ccb99ccec18f4Michael Wright            mIsExternal);
100146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
10026d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    size_t numMappers = mMappers.size();
10036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
10046d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        InputMapper* mapper = mMappers[i];
10056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mapper->populateDeviceInfo(outDeviceInfo);
100646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
100746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
100846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
10096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputDevice::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
10106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return getState(sourceMask, keyCode, & InputMapper::getKeyCodeState);
10116d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
101246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
10136d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputDevice::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
10146d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return getState(sourceMask, scanCode, & InputMapper::getScanCodeState);
10156d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
101646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
10176d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputDevice::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
10186d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return getState(sourceMask, switchCode, & InputMapper::getSwitchState);
10196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
102046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
10216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) {
10226d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    int32_t result = AKEY_STATE_UNKNOWN;
10236d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    size_t numMappers = mMappers.size();
10246d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
10256d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        InputMapper* mapper = mMappers[i];
10266d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
1027fbca596721ea19daa2972639095898ce62100490David Deephanphongs            // If any mapper reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
1028fbca596721ea19daa2972639095898ce62100490David Deephanphongs            // value.  Otherwise, return AKEY_STATE_UP as long as one mapper reports it.
1029fbca596721ea19daa2972639095898ce62100490David Deephanphongs            int32_t currentResult = (mapper->*getStateFunc)(sourceMask, code);
1030fbca596721ea19daa2972639095898ce62100490David Deephanphongs            if (currentResult >= AKEY_STATE_DOWN) {
1031fbca596721ea19daa2972639095898ce62100490David Deephanphongs                return currentResult;
1032fbca596721ea19daa2972639095898ce62100490David Deephanphongs            } else if (currentResult == AKEY_STATE_UP) {
1033fbca596721ea19daa2972639095898ce62100490David Deephanphongs                result = currentResult;
10346d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
103546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
103646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
10376d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return result;
10386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
103946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
10406d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownbool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
10416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        const int32_t* keyCodes, uint8_t* outFlags) {
10426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    bool result = false;
10436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    size_t numMappers = mMappers.size();
10446d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
10456d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        InputMapper* mapper = mMappers[i];
10466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
10476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            result |= mapper->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
104846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
104946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
10506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return result;
10516d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
105246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1053a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid InputDevice::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
1054a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        int32_t token) {
1055a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    size_t numMappers = mMappers.size();
1056a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
1057a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        InputMapper* mapper = mMappers[i];
1058a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        mapper->vibrate(pattern, patternSize, repeat, token);
1059a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    }
1060a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1061a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1062a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid InputDevice::cancelVibrate(int32_t token) {
1063a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    size_t numMappers = mMappers.size();
1064a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
1065a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        InputMapper* mapper = mMappers[i];
1066a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        mapper->cancelVibrate(token);
1067a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    }
1068a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1069a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
10706d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputDevice::getMetaState() {
10716d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    int32_t result = 0;
10726d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    size_t numMappers = mMappers.size();
10736d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
10746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        InputMapper* mapper = mMappers[i];
10756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        result |= mapper->getMetaState();
107646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
10776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return result;
10786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
107946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
108005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownvoid InputDevice::fadePointer() {
108105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    size_t numMappers = mMappers.size();
108205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    for (size_t i = 0; i < numMappers; i++) {
108305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        InputMapper* mapper = mMappers[i];
108405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        mapper->fadePointer();
108505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    }
108605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown}
108705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
1088af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownvoid InputDevice::bumpGeneration() {
1089af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    mGeneration = mContext->bumpGeneration();
1090af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown}
1091af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown
109265fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid InputDevice::notifyReset(nsecs_t when) {
109365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    NotifyDeviceResetArgs args(when, mId);
109465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mContext->getListener()->notifyDeviceReset(&args);
109565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
109665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
109746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
109849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown// --- CursorButtonAccumulator ---
109949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
110049754db5a304d995c1cc108ff6f19e4ba4265572Jeff BrownCursorButtonAccumulator::CursorButtonAccumulator() {
110149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    clearButtons();
110249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
110349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
110465fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid CursorButtonAccumulator::reset(InputDevice* device) {
110565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnLeft = device->isKeyPressed(BTN_LEFT);
110665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnRight = device->isKeyPressed(BTN_RIGHT);
110765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnMiddle = device->isKeyPressed(BTN_MIDDLE);
110865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnBack = device->isKeyPressed(BTN_BACK);
110965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnSide = device->isKeyPressed(BTN_SIDE);
111065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnForward = device->isKeyPressed(BTN_FORWARD);
111165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnExtra = device->isKeyPressed(BTN_EXTRA);
111265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnTask = device->isKeyPressed(BTN_TASK);
111365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
111465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
111549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownvoid CursorButtonAccumulator::clearButtons() {
111649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnLeft = 0;
111749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnRight = 0;
111849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnMiddle = 0;
111949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnBack = 0;
112049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnSide = 0;
112149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnForward = 0;
112249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnExtra = 0;
112349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnTask = 0;
112449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
112549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
112649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownvoid CursorButtonAccumulator::process(const RawEvent* rawEvent) {
112749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (rawEvent->type == EV_KEY) {
112849ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        switch (rawEvent->code) {
112949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_LEFT:
113049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnLeft = rawEvent->value;
113149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
113249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_RIGHT:
113349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnRight = rawEvent->value;
113449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
113549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_MIDDLE:
113649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnMiddle = rawEvent->value;
113749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
113849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_BACK:
113949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnBack = rawEvent->value;
114049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
114149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_SIDE:
114249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnSide = rawEvent->value;
114349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
114449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_FORWARD:
114549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnForward = rawEvent->value;
114649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
114749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_EXTRA:
114849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnExtra = rawEvent->value;
114949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
115049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_TASK:
115149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnTask = rawEvent->value;
115249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
115349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        }
115449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
115549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
115649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
115749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownuint32_t CursorButtonAccumulator::getButtonState() const {
115849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    uint32_t result = 0;
115949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (mBtnLeft) {
116049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        result |= AMOTION_EVENT_BUTTON_PRIMARY;
116149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
116249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (mBtnRight) {
116349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        result |= AMOTION_EVENT_BUTTON_SECONDARY;
116449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
116549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (mBtnMiddle) {
116649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        result |= AMOTION_EVENT_BUTTON_TERTIARY;
116749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
116849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (mBtnBack || mBtnSide) {
116949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        result |= AMOTION_EVENT_BUTTON_BACK;
117049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
117149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (mBtnForward || mBtnExtra) {
117249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        result |= AMOTION_EVENT_BUTTON_FORWARD;
117349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
117449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    return result;
117549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
117649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
117749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
117849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown// --- CursorMotionAccumulator ---
117949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
118065fd251c3913fc921468a3dad190810db19eb9dfJeff BrownCursorMotionAccumulator::CursorMotionAccumulator() {
118149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    clearRelativeAxes();
118249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
118349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
118465fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid CursorMotionAccumulator::reset(InputDevice* device) {
118565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    clearRelativeAxes();
118649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
118749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
118849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownvoid CursorMotionAccumulator::clearRelativeAxes() {
118949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mRelX = 0;
119049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mRelY = 0;
119149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
119249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
119349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownvoid CursorMotionAccumulator::process(const RawEvent* rawEvent) {
119449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (rawEvent->type == EV_REL) {
119549ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        switch (rawEvent->code) {
119649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case REL_X:
119749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mRelX = rawEvent->value;
119849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
119949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case REL_Y:
120049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mRelY = rawEvent->value;
120149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
120265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
120365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
120465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
120565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
120665fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid CursorMotionAccumulator::finishSync() {
120765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    clearRelativeAxes();
120865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
120965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
121065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
121165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown// --- CursorScrollAccumulator ---
121265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
121365fd251c3913fc921468a3dad190810db19eb9dfJeff BrownCursorScrollAccumulator::CursorScrollAccumulator() :
121465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mHaveRelWheel(false), mHaveRelHWheel(false) {
121565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    clearRelativeAxes();
121665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
121765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
121865fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid CursorScrollAccumulator::configure(InputDevice* device) {
121965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mHaveRelWheel = device->getEventHub()->hasRelativeAxis(device->getId(), REL_WHEEL);
122065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mHaveRelHWheel = device->getEventHub()->hasRelativeAxis(device->getId(), REL_HWHEEL);
122165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
122265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
122365fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid CursorScrollAccumulator::reset(InputDevice* device) {
122465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    clearRelativeAxes();
122565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
122665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
122765fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid CursorScrollAccumulator::clearRelativeAxes() {
122865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mRelWheel = 0;
122965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mRelHWheel = 0;
123065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
123165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
123265fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid CursorScrollAccumulator::process(const RawEvent* rawEvent) {
123365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (rawEvent->type == EV_REL) {
123449ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        switch (rawEvent->code) {
123549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case REL_WHEEL:
123649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mRelWheel = rawEvent->value;
123749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
123849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case REL_HWHEEL:
123949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mRelHWheel = rawEvent->value;
124049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
124149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        }
124249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
124349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
124449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
124565fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid CursorScrollAccumulator::finishSync() {
124665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    clearRelativeAxes();
124765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
124865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
124949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
125049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown// --- TouchButtonAccumulator ---
125149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
125249754db5a304d995c1cc108ff6f19e4ba4265572Jeff BrownTouchButtonAccumulator::TouchButtonAccumulator() :
125300710e906bdafd58386ee7f81fa84addd218122fJeff Brown        mHaveBtnTouch(false), mHaveStylus(false) {
125449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    clearButtons();
125549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
125649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
125749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownvoid TouchButtonAccumulator::configure(InputDevice* device) {
125865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mHaveBtnTouch = device->hasKey(BTN_TOUCH);
125900710e906bdafd58386ee7f81fa84addd218122fJeff Brown    mHaveStylus = device->hasKey(BTN_TOOL_PEN)
126000710e906bdafd58386ee7f81fa84addd218122fJeff Brown            || device->hasKey(BTN_TOOL_RUBBER)
126100710e906bdafd58386ee7f81fa84addd218122fJeff Brown            || device->hasKey(BTN_TOOL_BRUSH)
126200710e906bdafd58386ee7f81fa84addd218122fJeff Brown            || device->hasKey(BTN_TOOL_PENCIL)
126300710e906bdafd58386ee7f81fa84addd218122fJeff Brown            || device->hasKey(BTN_TOOL_AIRBRUSH);
126465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
126565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
126665fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchButtonAccumulator::reset(InputDevice* device) {
126765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnTouch = device->isKeyPressed(BTN_TOUCH);
126865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnStylus = device->isKeyPressed(BTN_STYLUS);
126965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnStylus2 = device->isKeyPressed(BTN_STYLUS);
127065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolFinger = device->isKeyPressed(BTN_TOOL_FINGER);
127165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolPen = device->isKeyPressed(BTN_TOOL_PEN);
127265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolRubber = device->isKeyPressed(BTN_TOOL_RUBBER);
127365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolBrush = device->isKeyPressed(BTN_TOOL_BRUSH);
127465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolPencil = device->isKeyPressed(BTN_TOOL_PENCIL);
127565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolAirbrush = device->isKeyPressed(BTN_TOOL_AIRBRUSH);
127665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolMouse = device->isKeyPressed(BTN_TOOL_MOUSE);
127765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolLens = device->isKeyPressed(BTN_TOOL_LENS);
1278ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown    mBtnToolDoubleTap = device->isKeyPressed(BTN_TOOL_DOUBLETAP);
1279ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown    mBtnToolTripleTap = device->isKeyPressed(BTN_TOOL_TRIPLETAP);
1280ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown    mBtnToolQuadTap = device->isKeyPressed(BTN_TOOL_QUADTAP);
128149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
128249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
128349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownvoid TouchButtonAccumulator::clearButtons() {
128449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnTouch = 0;
128549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnStylus = 0;
128649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnStylus2 = 0;
128749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnToolFinger = 0;
128849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnToolPen = 0;
128949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mBtnToolRubber = 0;
129065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolBrush = 0;
129165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolPencil = 0;
129265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolAirbrush = 0;
129365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolMouse = 0;
129465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mBtnToolLens = 0;
1295ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown    mBtnToolDoubleTap = 0;
1296ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown    mBtnToolTripleTap = 0;
1297ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown    mBtnToolQuadTap = 0;
129849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
129949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
130049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownvoid TouchButtonAccumulator::process(const RawEvent* rawEvent) {
130149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (rawEvent->type == EV_KEY) {
130249ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        switch (rawEvent->code) {
130349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_TOUCH:
130449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnTouch = rawEvent->value;
130549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
130649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_STYLUS:
130749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnStylus = rawEvent->value;
130849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
130949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_STYLUS2:
131049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnStylus2 = rawEvent->value;
131149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
131249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_TOOL_FINGER:
131349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnToolFinger = rawEvent->value;
131449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
131549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_TOOL_PEN:
131649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnToolPen = rawEvent->value;
131749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
131849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case BTN_TOOL_RUBBER:
131949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mBtnToolRubber = rawEvent->value;
132049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
132165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        case BTN_TOOL_BRUSH:
132265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mBtnToolBrush = rawEvent->value;
132365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            break;
132465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        case BTN_TOOL_PENCIL:
132565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mBtnToolPencil = rawEvent->value;
132665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            break;
132765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        case BTN_TOOL_AIRBRUSH:
132865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mBtnToolAirbrush = rawEvent->value;
132965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            break;
133065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        case BTN_TOOL_MOUSE:
133165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mBtnToolMouse = rawEvent->value;
133265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            break;
133365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        case BTN_TOOL_LENS:
133465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mBtnToolLens = rawEvent->value;
133565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            break;
1336ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown        case BTN_TOOL_DOUBLETAP:
1337ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown            mBtnToolDoubleTap = rawEvent->value;
1338ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown            break;
1339ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown        case BTN_TOOL_TRIPLETAP:
1340ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown            mBtnToolTripleTap = rawEvent->value;
1341ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown            break;
1342ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown        case BTN_TOOL_QUADTAP:
1343ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown            mBtnToolQuadTap = rawEvent->value;
1344ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown            break;
134549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        }
134649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
134749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
134849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
134949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownuint32_t TouchButtonAccumulator::getButtonState() const {
135049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    uint32_t result = 0;
135149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (mBtnStylus) {
135249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        result |= AMOTION_EVENT_BUTTON_SECONDARY;
135349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
135449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (mBtnStylus2) {
135549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        result |= AMOTION_EVENT_BUTTON_TERTIARY;
135649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
135749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    return result;
135849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
135949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
136049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownint32_t TouchButtonAccumulator::getToolType() const {
136165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mBtnToolMouse || mBtnToolLens) {
136265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        return AMOTION_EVENT_TOOL_TYPE_MOUSE;
136365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
136449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (mBtnToolRubber) {
136549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        return AMOTION_EVENT_TOOL_TYPE_ERASER;
136649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
136765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mBtnToolPen || mBtnToolBrush || mBtnToolPencil || mBtnToolAirbrush) {
136849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        return AMOTION_EVENT_TOOL_TYPE_STYLUS;
136949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
1370ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown    if (mBtnToolFinger || mBtnToolDoubleTap || mBtnToolTripleTap || mBtnToolQuadTap) {
137149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        return AMOTION_EVENT_TOOL_TYPE_FINGER;
137249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
137349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    return AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
137449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
137549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
1376d87c6d5fd5e620ecb1a7a401d2b31c6cf2e1a851Jeff Brownbool TouchButtonAccumulator::isToolActive() const {
137765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    return mBtnTouch || mBtnToolFinger || mBtnToolPen || mBtnToolRubber
137865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            || mBtnToolBrush || mBtnToolPencil || mBtnToolAirbrush
1379ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown            || mBtnToolMouse || mBtnToolLens
1380ea6892e02e10a57673a42f0922ad28694595dcaaJeff Brown            || mBtnToolDoubleTap || mBtnToolTripleTap || mBtnToolQuadTap;
138149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
138249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
138349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownbool TouchButtonAccumulator::isHovering() const {
138449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    return mHaveBtnTouch && !mBtnTouch;
138549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
138649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
138700710e906bdafd58386ee7f81fa84addd218122fJeff Brownbool TouchButtonAccumulator::hasStylus() const {
138800710e906bdafd58386ee7f81fa84addd218122fJeff Brown    return mHaveStylus;
138900710e906bdafd58386ee7f81fa84addd218122fJeff Brown}
139000710e906bdafd58386ee7f81fa84addd218122fJeff Brown
139149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
1392be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown// --- RawPointerAxes ---
1393be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1394be1aa8250cee7819c49741e819e81659d1d03823Jeff BrownRawPointerAxes::RawPointerAxes() {
1395be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    clear();
1396be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
1397be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1398be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid RawPointerAxes::clear() {
1399be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    x.clear();
1400be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    y.clear();
1401be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    pressure.clear();
1402be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    touchMajor.clear();
1403be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    touchMinor.clear();
1404be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    toolMajor.clear();
1405be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    toolMinor.clear();
1406be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    orientation.clear();
1407be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    distance.clear();
140865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    tiltX.clear();
140965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    tiltY.clear();
1410be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    trackingId.clear();
1411be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    slot.clear();
1412be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
1413be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1414be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1415be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown// --- RawPointerData ---
1416be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1417be1aa8250cee7819c49741e819e81659d1d03823Jeff BrownRawPointerData::RawPointerData() {
1418be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    clear();
1419be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
1420be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1421be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid RawPointerData::clear() {
1422be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    pointerCount = 0;
1423be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    clearIdBits();
1424be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
1425be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1426be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid RawPointerData::copyFrom(const RawPointerData& other) {
1427be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    pointerCount = other.pointerCount;
1428be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    hoveringIdBits = other.hoveringIdBits;
1429be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    touchingIdBits = other.touchingIdBits;
1430be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1431be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (uint32_t i = 0; i < pointerCount; i++) {
1432be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        pointers[i] = other.pointers[i];
1433be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1434be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        int id = pointers[i].id;
1435be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        idToIndex[id] = other.idToIndex[id];
1436be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
1437be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
1438be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1439be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid RawPointerData::getCentroidOfTouchingPointers(float* outX, float* outY) const {
1440be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    float x = 0, y = 0;
1441be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    uint32_t count = touchingIdBits.count();
1442be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (count) {
1443be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        for (BitSet32 idBits(touchingIdBits); !idBits.isEmpty(); ) {
1444be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t id = idBits.clearFirstMarkedBit();
1445be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const Pointer& pointer = pointerForId(id);
1446be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            x += pointer.x;
1447be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            y += pointer.y;
1448be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
1449be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        x /= count;
1450be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        y /= count;
1451be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
1452be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    *outX = x;
1453be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    *outY = y;
1454be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
1455be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1456be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1457be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown// --- CookedPointerData ---
1458be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1459be1aa8250cee7819c49741e819e81659d1d03823Jeff BrownCookedPointerData::CookedPointerData() {
1460be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    clear();
1461be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
1462be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1463be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid CookedPointerData::clear() {
1464be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    pointerCount = 0;
1465be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    hoveringIdBits.clear();
1466be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    touchingIdBits.clear();
1467be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
1468be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1469be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid CookedPointerData::copyFrom(const CookedPointerData& other) {
1470be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    pointerCount = other.pointerCount;
1471be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    hoveringIdBits = other.hoveringIdBits;
1472be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    touchingIdBits = other.touchingIdBits;
1473be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1474be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (uint32_t i = 0; i < pointerCount; i++) {
1475be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        pointerProperties[i].copyFrom(other.pointerProperties[i]);
1476be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        pointerCoords[i].copyFrom(other.pointerCoords[i]);
1477be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1478be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        int id = pointerProperties[i].id;
1479be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        idToIndex[id] = other.idToIndex[id];
1480be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
1481be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
1482be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1483be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
148449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown// --- SingleTouchMotionAccumulator ---
148549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
148649754db5a304d995c1cc108ff6f19e4ba4265572Jeff BrownSingleTouchMotionAccumulator::SingleTouchMotionAccumulator() {
148749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    clearAbsoluteAxes();
148849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
148949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
149065fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid SingleTouchMotionAccumulator::reset(InputDevice* device) {
149165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mAbsX = device->getAbsoluteAxisValue(ABS_X);
149265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mAbsY = device->getAbsoluteAxisValue(ABS_Y);
149365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mAbsPressure = device->getAbsoluteAxisValue(ABS_PRESSURE);
149465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mAbsToolWidth = device->getAbsoluteAxisValue(ABS_TOOL_WIDTH);
149565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mAbsDistance = device->getAbsoluteAxisValue(ABS_DISTANCE);
149665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mAbsTiltX = device->getAbsoluteAxisValue(ABS_TILT_X);
149765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mAbsTiltY = device->getAbsoluteAxisValue(ABS_TILT_Y);
149865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
149965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
150049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownvoid SingleTouchMotionAccumulator::clearAbsoluteAxes() {
150149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsX = 0;
150249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsY = 0;
150349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsPressure = 0;
150449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsToolWidth = 0;
150549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsDistance = 0;
150665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mAbsTiltX = 0;
150765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mAbsTiltY = 0;
150849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
150949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
151049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownvoid SingleTouchMotionAccumulator::process(const RawEvent* rawEvent) {
151149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (rawEvent->type == EV_ABS) {
151249ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        switch (rawEvent->code) {
151349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case ABS_X:
151449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mAbsX = rawEvent->value;
151549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
151649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case ABS_Y:
151749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mAbsY = rawEvent->value;
151849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
151949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case ABS_PRESSURE:
152049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mAbsPressure = rawEvent->value;
152149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
152249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case ABS_TOOL_WIDTH:
152349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mAbsToolWidth = rawEvent->value;
152449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
152549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case ABS_DISTANCE:
152649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mAbsDistance = rawEvent->value;
152749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            break;
152865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        case ABS_TILT_X:
152965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mAbsTiltX = rawEvent->value;
153065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            break;
153165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        case ABS_TILT_Y:
153265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mAbsTiltY = rawEvent->value;
153365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            break;
153449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        }
153549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
153649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
153749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
153849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
153949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown// --- MultiTouchMotionAccumulator ---
154049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
154149754db5a304d995c1cc108ff6f19e4ba4265572Jeff BrownMultiTouchMotionAccumulator::MultiTouchMotionAccumulator() :
154200710e906bdafd58386ee7f81fa84addd218122fJeff Brown        mCurrentSlot(-1), mSlots(NULL), mSlotCount(0), mUsingSlotsProtocol(false),
154300710e906bdafd58386ee7f81fa84addd218122fJeff Brown        mHaveStylus(false) {
154449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
154549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
154649754db5a304d995c1cc108ff6f19e4ba4265572Jeff BrownMultiTouchMotionAccumulator::~MultiTouchMotionAccumulator() {
154749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    delete[] mSlots;
154849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
154949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
155000710e906bdafd58386ee7f81fa84addd218122fJeff Brownvoid MultiTouchMotionAccumulator::configure(InputDevice* device,
155100710e906bdafd58386ee7f81fa84addd218122fJeff Brown        size_t slotCount, bool usingSlotsProtocol) {
155249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mSlotCount = slotCount;
155349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mUsingSlotsProtocol = usingSlotsProtocol;
155400710e906bdafd58386ee7f81fa84addd218122fJeff Brown    mHaveStylus = device->hasAbsoluteAxis(ABS_MT_TOOL_TYPE);
155549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
155649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    delete[] mSlots;
155749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mSlots = new Slot[slotCount];
155849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
155949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
156065fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid MultiTouchMotionAccumulator::reset(InputDevice* device) {
156165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Unfortunately there is no way to read the initial contents of the slots.
156265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // So when we reset the accumulator, we must assume they are all zeroes.
156365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mUsingSlotsProtocol) {
156465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Query the driver for the current slot index and use it as the initial slot
156565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // before we start reading events from the device.  It is possible that the
156665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // current slot index will not be the same as it was when the first event was
156765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // written into the evdev buffer, which means the input mapper could start
156865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // out of sync with the initial state of the events in the evdev buffer.
156965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // In the extremely unlikely case that this happens, the data from
157065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // two slots will be confused until the next ABS_MT_SLOT event is received.
157165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // This can cause the touch point to "jump", but at least there will be
157265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // no stuck touches.
157365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        int32_t initialSlot;
157465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        status_t status = device->getEventHub()->getAbsoluteAxisValue(device->getId(),
157565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                ABS_MT_SLOT, &initialSlot);
157665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (status) {
15775baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Could not retrieve current multitouch slot index.  status=%d", status);
157865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            initialSlot = -1;
157965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
158065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        clearSlots(initialSlot);
158165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    } else {
158265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        clearSlots(-1);
158365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
158465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
158565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
158649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownvoid MultiTouchMotionAccumulator::clearSlots(int32_t initialSlot) {
158765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mSlots) {
158865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        for (size_t i = 0; i < mSlotCount; i++) {
158965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mSlots[i].clear();
159065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
159149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
159249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mCurrentSlot = initialSlot;
159349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
159449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
159549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownvoid MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
159649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (rawEvent->type == EV_ABS) {
159749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        bool newSlot = false;
159849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        if (mUsingSlotsProtocol) {
159949ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown            if (rawEvent->code == ABS_MT_SLOT) {
160049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                mCurrentSlot = rawEvent->value;
160149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                newSlot = true;
160249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            }
160349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        } else if (mCurrentSlot < 0) {
160449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            mCurrentSlot = 0;
160549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        }
160649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
160749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        if (mCurrentSlot < 0 || size_t(mCurrentSlot) >= mSlotCount) {
160849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown#if DEBUG_POINTERS
160949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            if (newSlot) {
16108564c8da817a845353d213acd8636b76f567b234Steve Block                ALOGW("MultiTouch device emitted invalid slot index %d but it "
161149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                        "should be between 0 and %d; ignoring this slot.",
161249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                        mCurrentSlot, mSlotCount - 1);
161349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            }
161449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown#endif
161549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        } else {
161649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            Slot* slot = &mSlots[mCurrentSlot];
161749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
161849ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown            switch (rawEvent->code) {
161949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            case ABS_MT_POSITION_X:
162049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mInUse = true;
162149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mAbsMTPositionX = rawEvent->value;
162249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                break;
162349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            case ABS_MT_POSITION_Y:
162449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mInUse = true;
162549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mAbsMTPositionY = rawEvent->value;
162649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                break;
162749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            case ABS_MT_TOUCH_MAJOR:
162849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mInUse = true;
162949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mAbsMTTouchMajor = rawEvent->value;
163049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                break;
163149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            case ABS_MT_TOUCH_MINOR:
163249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mInUse = true;
163349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mAbsMTTouchMinor = rawEvent->value;
163449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mHaveAbsMTTouchMinor = true;
163549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                break;
163649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            case ABS_MT_WIDTH_MAJOR:
163749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mInUse = true;
163849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mAbsMTWidthMajor = rawEvent->value;
163949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                break;
164049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            case ABS_MT_WIDTH_MINOR:
164149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mInUse = true;
164249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mAbsMTWidthMinor = rawEvent->value;
164349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mHaveAbsMTWidthMinor = true;
164449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                break;
164549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            case ABS_MT_ORIENTATION:
164649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mInUse = true;
164749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mAbsMTOrientation = rawEvent->value;
164849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                break;
164949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            case ABS_MT_TRACKING_ID:
165049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                if (mUsingSlotsProtocol && rawEvent->value < 0) {
16518bcbbefa3b4e149099b2057547543ea95a7be400Jeff Brown                    // The slot is no longer in use but it retains its previous contents,
16528bcbbefa3b4e149099b2057547543ea95a7be400Jeff Brown                    // which may be reused for subsequent touches.
16538bcbbefa3b4e149099b2057547543ea95a7be400Jeff Brown                    slot->mInUse = false;
165449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                } else {
165549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                    slot->mInUse = true;
165649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                    slot->mAbsMTTrackingId = rawEvent->value;
165749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                }
165849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                break;
165949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            case ABS_MT_PRESSURE:
166049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mInUse = true;
166149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mAbsMTPressure = rawEvent->value;
166249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                break;
1663be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            case ABS_MT_DISTANCE:
1664be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                slot->mInUse = true;
1665be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                slot->mAbsMTDistance = rawEvent->value;
1666be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                break;
166749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            case ABS_MT_TOOL_TYPE:
166849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mInUse = true;
166949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mAbsMTToolType = rawEvent->value;
167049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                slot->mHaveAbsMTToolType = true;
167149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                break;
167249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            }
167349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        }
167449ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown    } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_MT_REPORT) {
167549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        // MultiTouch Sync: The driver has returned all data for *one* of the pointers.
167649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        mCurrentSlot += 1;
167749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
167849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
167949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
168065fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid MultiTouchMotionAccumulator::finishSync() {
168165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (!mUsingSlotsProtocol) {
168265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        clearSlots(-1);
168365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
168465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
168565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
168600710e906bdafd58386ee7f81fa84addd218122fJeff Brownbool MultiTouchMotionAccumulator::hasStylus() const {
168700710e906bdafd58386ee7f81fa84addd218122fJeff Brown    return mHaveStylus;
168800710e906bdafd58386ee7f81fa84addd218122fJeff Brown}
168900710e906bdafd58386ee7f81fa84addd218122fJeff Brown
169049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
169149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown// --- MultiTouchMotionAccumulator::Slot ---
169249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
169349754db5a304d995c1cc108ff6f19e4ba4265572Jeff BrownMultiTouchMotionAccumulator::Slot::Slot() {
169449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    clear();
169549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
169649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
169749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownvoid MultiTouchMotionAccumulator::Slot::clear() {
169849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mInUse = false;
169949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mHaveAbsMTTouchMinor = false;
170049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mHaveAbsMTWidthMinor = false;
170149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mHaveAbsMTToolType = false;
170249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsMTPositionX = 0;
170349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsMTPositionY = 0;
170449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsMTTouchMajor = 0;
170549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsMTTouchMinor = 0;
170649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsMTWidthMajor = 0;
170749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsMTWidthMinor = 0;
170849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsMTOrientation = 0;
170949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsMTTrackingId = -1;
171049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsMTPressure = 0;
171149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mAbsMTDistance = 0;
1712be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mAbsMTToolType = 0;
171349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
171449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
171549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brownint32_t MultiTouchMotionAccumulator::Slot::getToolType() const {
171649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    if (mHaveAbsMTToolType) {
171749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        switch (mAbsMTToolType) {
171849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case MT_TOOL_FINGER:
171949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            return AMOTION_EVENT_TOOL_TYPE_FINGER;
172049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        case MT_TOOL_PEN:
172149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            return AMOTION_EVENT_TOOL_TYPE_STYLUS;
172249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        }
172349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    }
172449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    return AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
172549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown}
172649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
172749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
17286d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown// --- InputMapper ---
172946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
17306d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownInputMapper::InputMapper(InputDevice* device) :
17316d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mDevice(device), mContext(device->getContext()) {
17326d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
173346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
17346d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownInputMapper::~InputMapper() {
17356d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
173646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
17376d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid InputMapper::populateDeviceInfo(InputDeviceInfo* info) {
17386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    info->addSource(getSources());
173946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
174046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1741ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brownvoid InputMapper::dump(String8& dump) {
1742ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown}
1743ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
174465fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid InputMapper::configure(nsecs_t when,
174565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        const InputReaderConfiguration* config, uint32_t changes) {
17466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
174746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
174865fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid InputMapper::reset(nsecs_t when) {
17496d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
175046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1751aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brownvoid InputMapper::timeoutExpired(nsecs_t when) {
1752aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown}
1753aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown
17546d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
17556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return AKEY_STATE_UNKNOWN;
17566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
175746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
17586d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
17596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return AKEY_STATE_UNKNOWN;
17606d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
176146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
17626d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
17636d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return AKEY_STATE_UNKNOWN;
176446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
176546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
17666d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownbool InputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
17676d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        const int32_t* keyCodes, uint8_t* outFlags) {
17686d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return false;
17696d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
1770349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown
1771a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid InputMapper::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
1772a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        int32_t token) {
1773a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1774a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1775a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid InputMapper::cancelVibrate(int32_t token) {
1776a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1777a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
17786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputMapper::getMetaState() {
17796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return 0;
17806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
178146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
178205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownvoid InputMapper::fadePointer() {
178305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown}
178405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
1785be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownstatus_t InputMapper::getAbsoluteAxisInfo(int32_t axis, RawAbsoluteAxisInfo* axisInfo) {
1786be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return getEventHub()->getAbsoluteAxisInfo(getDeviceId(), axis, axisInfo);
1787be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
1788be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
1789af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownvoid InputMapper::bumpGeneration() {
1790af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown    mDevice->bumpGeneration();
1791af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown}
1792af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown
1793cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brownvoid InputMapper::dumpRawAbsoluteAxisInfo(String8& dump,
1794cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        const RawAbsoluteAxisInfo& axis, const char* name) {
1795cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    if (axis.valid) {
1796b3a2d1330716812784aee91b6d6275764b5e4210Jeff Brown        dump.appendFormat(INDENT4 "%s: min=%d, max=%d, flat=%d, fuzz=%d, resolution=%d\n",
1797b3a2d1330716812784aee91b6d6275764b5e4210Jeff Brown                name, axis.minValue, axis.maxValue, axis.flat, axis.fuzz, axis.resolution);
1798cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    } else {
1799cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        dump.appendFormat(INDENT4 "%s: unknown range\n", name);
1800cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
1801cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
1802cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
18036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
18046d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown// --- SwitchInputMapper ---
18056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
18066d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownSwitchInputMapper::SwitchInputMapper(InputDevice* device) :
1807bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown        InputMapper(device), mUpdatedSwitchValues(0), mUpdatedSwitchMask(0) {
180846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
180946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
18106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownSwitchInputMapper::~SwitchInputMapper() {
18116d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
18126d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
18136d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownuint32_t SwitchInputMapper::getSources() {
181489de57a8d252a25ef2412a11a66089a9ff6ffe29Jeff Brown    return AINPUT_SOURCE_SWITCH;
18156d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
18166d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
18176d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid SwitchInputMapper::process(const RawEvent* rawEvent) {
18186d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    switch (rawEvent->type) {
18196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    case EV_SW:
1820bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown        processSwitch(rawEvent->code, rawEvent->value);
18216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        break;
1822bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown
1823bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown    case EV_SYN:
1824bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown        if (rawEvent->code == SYN_REPORT) {
1825bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown            sync(rawEvent->when);
1826bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown        }
1827bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown    }
1828bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown}
1829bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown
1830bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brownvoid SwitchInputMapper::processSwitch(int32_t switchCode, int32_t switchValue) {
1831bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown    if (switchCode >= 0 && switchCode < 32) {
1832bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown        if (switchValue) {
1833bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown            mUpdatedSwitchValues |= 1 << switchCode;
1834bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown        }
1835bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown        mUpdatedSwitchMask |= 1 << switchCode;
183646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
18376d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
183846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1839bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brownvoid SwitchInputMapper::sync(nsecs_t when) {
1840bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown    if (mUpdatedSwitchMask) {
1841bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown        NotifySwitchArgs args(when, 0, mUpdatedSwitchValues, mUpdatedSwitchMask);
1842bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown        getListener()->notifySwitch(&args);
1843bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown
1844bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown        mUpdatedSwitchValues = 0;
1845bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown        mUpdatedSwitchMask = 0;
1846bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown    }
18476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
184846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
18496d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
18506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return getEventHub()->getSwitchState(getDeviceId(), switchCode);
18516d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
185246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
185346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1854a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown// --- VibratorInputMapper ---
1855a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1856a47425a13c19f95057df78b8bb65bb25657e8753Jeff BrownVibratorInputMapper::VibratorInputMapper(InputDevice* device) :
1857a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        InputMapper(device), mVibrating(false) {
1858a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1859a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1860a47425a13c19f95057df78b8bb65bb25657e8753Jeff BrownVibratorInputMapper::~VibratorInputMapper() {
1861a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1862a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1863a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownuint32_t VibratorInputMapper::getSources() {
1864a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    return 0;
1865a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1866a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1867a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid VibratorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
1868a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    InputMapper::populateDeviceInfo(info);
1869a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1870a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    info->setVibrator(true);
1871a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1872a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1873a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid VibratorInputMapper::process(const RawEvent* rawEvent) {
1874a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    // TODO: Handle FF_STATUS, although it does not seem to be widely supported.
1875a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1876a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1877a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid VibratorInputMapper::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
1878a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        int32_t token) {
1879a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown#if DEBUG_VIBRATOR
1880a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    String8 patternStr;
1881a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    for (size_t i = 0; i < patternSize; i++) {
1882a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        if (i != 0) {
1883a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown            patternStr.append(", ");
1884a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        }
1885a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        patternStr.appendFormat("%lld", pattern[i]);
1886a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    }
1887a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    ALOGD("vibrate: deviceId=%d, pattern=[%s], repeat=%ld, token=%d",
1888a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown            getDeviceId(), patternStr.string(), repeat, token);
1889a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown#endif
1890a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1891a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    mVibrating = true;
1892a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    memcpy(mPattern, pattern, patternSize * sizeof(nsecs_t));
1893a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    mPatternSize = patternSize;
1894a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    mRepeat = repeat;
1895a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    mToken = token;
1896a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    mIndex = -1;
1897a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1898a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    nextStep();
1899a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1900a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1901a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid VibratorInputMapper::cancelVibrate(int32_t token) {
1902a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown#if DEBUG_VIBRATOR
1903a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    ALOGD("cancelVibrate: deviceId=%d, token=%d", getDeviceId(), token);
1904a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown#endif
1905a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1906a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    if (mVibrating && mToken == token) {
1907a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        stopVibrating();
1908a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    }
1909a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1910a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1911a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid VibratorInputMapper::timeoutExpired(nsecs_t when) {
1912a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    if (mVibrating) {
1913a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        if (when >= mNextStepTime) {
1914a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown            nextStep();
1915a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        } else {
1916a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown            getContext()->requestTimeoutAtTime(mNextStepTime);
1917a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        }
1918a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    }
1919a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1920a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1921a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid VibratorInputMapper::nextStep() {
1922a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    mIndex += 1;
1923a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    if (size_t(mIndex) >= mPatternSize) {
1924a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        if (mRepeat < 0) {
1925a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown            // We are done.
1926a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown            stopVibrating();
1927a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown            return;
1928a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        }
1929a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        mIndex = mRepeat;
1930a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    }
1931a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1932a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    bool vibratorOn = mIndex & 1;
1933a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    nsecs_t duration = mPattern[mIndex];
1934a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    if (vibratorOn) {
1935a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown#if DEBUG_VIBRATOR
1936a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        ALOGD("nextStep: sending vibrate deviceId=%d, duration=%lld",
1937a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown                getDeviceId(), duration);
1938a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown#endif
1939a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        getEventHub()->vibrate(getDeviceId(), duration);
1940a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    } else {
1941a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown#if DEBUG_VIBRATOR
1942a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        ALOGD("nextStep: sending cancel vibrate deviceId=%d", getDeviceId());
1943a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown#endif
1944a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown        getEventHub()->cancelVibrate(getDeviceId());
1945a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    }
1946a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
1947a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    mNextStepTime = now + duration;
1948a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    getContext()->requestTimeoutAtTime(mNextStepTime);
1949a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown#if DEBUG_VIBRATOR
1950a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    ALOGD("nextStep: scheduled timeout in %0.3fms", duration * 0.000001f);
1951a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown#endif
1952a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1953a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1954a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid VibratorInputMapper::stopVibrating() {
1955a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    mVibrating = false;
1956a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown#if DEBUG_VIBRATOR
1957a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    ALOGD("stopVibrating: sending cancel vibrate deviceId=%d", getDeviceId());
1958a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown#endif
1959a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    getEventHub()->cancelVibrate(getDeviceId());
1960a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1961a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1962a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownvoid VibratorInputMapper::dump(String8& dump) {
1963a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    dump.append(INDENT2 "Vibrator Input Mapper:\n");
1964a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown    dump.appendFormat(INDENT3 "Vibrating: %s\n", toString(mVibrating));
1965a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown}
1966a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
1967a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown
19686d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown// --- KeyboardInputMapper ---
19696d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
197047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff BrownKeyboardInputMapper::KeyboardInputMapper(InputDevice* device,
1971efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown        uint32_t source, int32_t keyboardType) :
1972efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown        InputMapper(device), mSource(source),
19736d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mKeyboardType(keyboardType) {
19746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
19756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
19766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownKeyboardInputMapper::~KeyboardInputMapper() {
19776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
19786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
19796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownuint32_t KeyboardInputMapper::getSources() {
1980efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown    return mSource;
19816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
19826d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
19836d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
19846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    InputMapper::populateDeviceInfo(info);
19856d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
19866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    info->setKeyboardType(mKeyboardType);
19879f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown    info->setKeyCharacterMap(getEventHub()->getKeyCharacterMap(getDeviceId()));
19886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
19896d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
1990ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brownvoid KeyboardInputMapper::dump(String8& dump) {
1991be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.append(INDENT2 "Keyboard Input Mapper:\n");
1992be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpParameters(dump);
1993be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "KeyboardType: %d\n", mKeyboardType);
199465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    dump.appendFormat(INDENT3 "Orientation: %d\n", mOrientation);
1995be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "KeyDowns: %d keys currently down\n", mKeyDowns.size());
1996be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "MetaState: 0x%0x\n", mMetaState);
1997be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "DownTime: %lld\n", mDownTime);
1998ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown}
1999ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
200047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
200165fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid KeyboardInputMapper::configure(nsecs_t when,
200265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        const InputReaderConfiguration* config, uint32_t changes) {
200365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    InputMapper::configure(when, config, changes);
200447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
2005474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    if (!changes) { // first time only
2006474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        // Configure basic parameters.
2007474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        configureParameters();
200865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
200949ed71db425c5054e3ad9526496a7e116c89556bJeff Brown
201065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
2011d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
2012d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            DisplayViewport v;
2013d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            if (config->getDisplayInfo(false /*external*/, &v)) {
2014d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                mOrientation = v.orientation;
2015d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            } else {
201665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mOrientation = DISPLAY_ORIENTATION_0;
201765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            }
201865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        } else {
201965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientation = DISPLAY_ORIENTATION_0;
202065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
202149ed71db425c5054e3ad9526496a7e116c89556bJeff Brown    }
202247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown}
202347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
202447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brownvoid KeyboardInputMapper::configureParameters() {
202547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    mParameters.orientationAware = false;
202647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    getDevice()->getConfiguration().tryGetProperty(String8("keyboard.orientationAware"),
202747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            mParameters.orientationAware);
202847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
2029d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    mParameters.hasAssociatedDisplay = false;
2030bc68a59c024bdb745dac8e2ec7408a9f30595f1aJeff Brown    if (mParameters.orientationAware) {
2031d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        mParameters.hasAssociatedDisplay = true;
2032bc68a59c024bdb745dac8e2ec7408a9f30595f1aJeff Brown    }
203347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown}
203447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
203547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brownvoid KeyboardInputMapper::dumpParameters(String8& dump) {
203647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    dump.append(INDENT3 "Parameters:\n");
2037d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    dump.appendFormat(INDENT4 "HasAssociatedDisplay: %s\n",
2038d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            toString(mParameters.hasAssociatedDisplay));
203947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    dump.appendFormat(INDENT4 "OrientationAware: %s\n",
204047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            toString(mParameters.orientationAware));
204147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown}
204247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
204365fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid KeyboardInputMapper::reset(nsecs_t when) {
204465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mMetaState = AMETA_NONE;
204565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mDownTime = 0;
204665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mKeyDowns.clear();
204749ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown    mCurrentHidUsage = 0;
20486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
2049be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    resetLedState();
2050be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
205165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    InputMapper::reset(when);
20526d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
20536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
20546d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid KeyboardInputMapper::process(const RawEvent* rawEvent) {
20556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    switch (rawEvent->type) {
20566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    case EV_KEY: {
205749ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        int32_t scanCode = rawEvent->code;
205849ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        int32_t usageCode = mCurrentHidUsage;
205949ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        mCurrentHidUsage = 0;
206049ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown
20616d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (isKeyboardOrGamepadKey(scanCode)) {
206249ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown            int32_t keyCode;
206349ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown            uint32_t flags;
206449ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown            if (getEventHub()->mapKey(getDeviceId(), scanCode, usageCode, &keyCode, &flags)) {
206549ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown                keyCode = AKEYCODE_UNKNOWN;
206649ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown                flags = 0;
206749ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown            }
206849ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown            processKey(rawEvent->when, rawEvent->value != 0, keyCode, scanCode, flags);
206946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
20706d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        break;
20716d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
207249ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown    case EV_MSC: {
207349ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        if (rawEvent->code == MSC_SCAN) {
207449ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown            mCurrentHidUsage = rawEvent->value;
207549ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        }
207649ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        break;
207749ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown    }
207849ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown    case EV_SYN: {
207949ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        if (rawEvent->code == SYN_REPORT) {
208049ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown            mCurrentHidUsage = 0;
208149ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        }
208249ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown    }
20836d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
20846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
208546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
20866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownbool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) {
20876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return scanCode < BTN_MOUSE
20886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        || scanCode >= KEY_OK
20899e8e40cb5f8aeb0702002eee60d1ce394bf699eeJeff Brown        || (scanCode >= BTN_MISC && scanCode < BTN_MOUSE)
2090cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        || (scanCode >= BTN_JOYSTICK && scanCode < BTN_DIGI);
20916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
209246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
20936328cdc89e099806a1893b89e4c724d596272d9eJeff Brownvoid KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
20946328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        int32_t scanCode, uint32_t policyFlags) {
20956328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
2096be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (down) {
2097be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        // Rotate key codes according to orientation if needed.
2098d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
209965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            keyCode = rotateKeyCode(keyCode, mOrientation);
2100be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
21016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
2102be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        // Add key down.
2103be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        ssize_t keyDownIndex = findKeyDown(scanCode);
2104be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (keyDownIndex >= 0) {
2105be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            // key repeat, be sure to use same keycode as before in case of rotation
2106be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
21076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        } else {
2108be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            // key down
2109be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if ((policyFlags & POLICY_FLAG_VIRTUAL)
2110be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    && mContext->shouldDropVirtualKey(when,
2111be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            getDevice(), keyCode, scanCode)) {
21126328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                return;
21136328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            }
2114be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
2115be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mKeyDowns.push();
2116be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            KeyDown& keyDown = mKeyDowns.editTop();
2117be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            keyDown.keyCode = keyCode;
2118be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            keyDown.scanCode = scanCode;
21196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
21206328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
2121be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mDownTime = when;
2122be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    } else {
2123be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        // Remove key down.
2124be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        ssize_t keyDownIndex = findKeyDown(scanCode);
2125be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (keyDownIndex >= 0) {
2126be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            // key up, be sure to use same keycode as before in case of rotation
2127be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
2128be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mKeyDowns.removeAt(size_t(keyDownIndex));
2129be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        } else {
2130be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            // key was not actually down
21316215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block            ALOGI("Dropping key up from device %s because the key was not down.  "
2132be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    "keyCode=%d, scanCode=%d",
2133be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    getDeviceName().string(), keyCode, scanCode);
2134be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            return;
213546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
2136be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
213746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2138be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t oldMetaState = mMetaState;
2139be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t newMetaState = updateMetaState(keyCode, down, oldMetaState);
2140f583d0dcc6e5c1968c472c844f6c8fbbe036ad78Michael Wright    bool metaStateChanged = oldMetaState != newMetaState;
2141f583d0dcc6e5c1968c472c844f6c8fbbe036ad78Michael Wright    if (metaStateChanged) {
2142be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mMetaState = newMetaState;
2143be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        updateLedState(false);
2144be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
2145be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
2146be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    nsecs_t downTime = mDownTime;
21476328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
214856194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // Key down on external an keyboard should wake the device.
214956194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // We don't do this for internal keyboards to prevent them from waking up in your pocket.
215056194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // For internal keyboards, the key layout file should specify the policy flags for
215156194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // each wake key individually.
215256194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // TODO: Use the input device configuration to control this behavior more finely.
215356194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    if (down && getDevice()->isExternal()
215456194ebec6212e229f4ccdaa4b187166d20013efJeff Brown            && !(policyFlags & (POLICY_FLAG_WAKE | POLICY_FLAG_WAKE_DROPPED))) {
215556194ebec6212e229f4ccdaa4b187166d20013efJeff Brown        policyFlags |= POLICY_FLAG_WAKE_DROPPED;
215656194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    }
215756194ebec6212e229f4ccdaa4b187166d20013efJeff Brown
21586328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    if (metaStateChanged) {
21596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        getContext()->updateGlobalMetaState();
216046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
216146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
216205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    if (down && !isMetaKey(keyCode)) {
216305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        getContext()->fadePointer();
216405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    }
216505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
2166be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
2167b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
2168b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
2169be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getListener()->notifyKey(&args);
21706d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
2171c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown
2172be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownssize_t KeyboardInputMapper::findKeyDown(int32_t scanCode) {
2173be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    size_t n = mKeyDowns.size();
21746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (size_t i = 0; i < n; i++) {
2175be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (mKeyDowns[i].scanCode == scanCode) {
21766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            return i;
217746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
21786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
21796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return -1;
21806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
218146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
21826d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t KeyboardInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
21836d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return getEventHub()->getKeyCodeState(getDeviceId(), keyCode);
21846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
2185c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown
21866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t KeyboardInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
21876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
21886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
218946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
21906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownbool KeyboardInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
21916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        const int32_t* keyCodes, uint8_t* outFlags) {
21926d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return getEventHub()->markSupportedKeyCodes(getDeviceId(), numCodes, keyCodes, outFlags);
21936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
219446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
21956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t KeyboardInputMapper::getMetaState() {
2196be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return mMetaState;
21976d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
219800ba884436dc8b222ad850c73c936d87bf4e84deJeff Brown
2199be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid KeyboardInputMapper::resetLedState() {
2200be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    initializeLedState(mCapsLockLedState, LED_CAPSL);
2201be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    initializeLedState(mNumLockLedState, LED_NUML);
2202be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    initializeLedState(mScrollLockLedState, LED_SCROLLL);
220349ed71db425c5054e3ad9526496a7e116c89556bJeff Brown
2204be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    updateLedState(true);
220549ed71db425c5054e3ad9526496a7e116c89556bJeff Brown}
220649ed71db425c5054e3ad9526496a7e116c89556bJeff Brown
2207be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid KeyboardInputMapper::initializeLedState(LedState& ledState, int32_t led) {
220849ed71db425c5054e3ad9526496a7e116c89556bJeff Brown    ledState.avail = getEventHub()->hasLed(getDeviceId(), led);
220949ed71db425c5054e3ad9526496a7e116c89556bJeff Brown    ledState.on = false;
221049ed71db425c5054e3ad9526496a7e116c89556bJeff Brown}
221149ed71db425c5054e3ad9526496a7e116c89556bJeff Brown
2212be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid KeyboardInputMapper::updateLedState(bool reset) {
2213be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    updateLedStateForModifier(mCapsLockLedState, LED_CAPSL,
221451e7fe7545e3509ebb5c31c10440acd31cec89a2Jeff Brown            AMETA_CAPS_LOCK_ON, reset);
2215be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    updateLedStateForModifier(mNumLockLedState, LED_NUML,
221651e7fe7545e3509ebb5c31c10440acd31cec89a2Jeff Brown            AMETA_NUM_LOCK_ON, reset);
2217be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    updateLedStateForModifier(mScrollLockLedState, LED_SCROLLL,
221851e7fe7545e3509ebb5c31c10440acd31cec89a2Jeff Brown            AMETA_SCROLL_LOCK_ON, reset);
2219497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown}
2220497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown
2221be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid KeyboardInputMapper::updateLedStateForModifier(LedState& ledState,
2222497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown        int32_t led, int32_t modifier, bool reset) {
2223497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown    if (ledState.avail) {
2224be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        bool desiredState = (mMetaState & modifier) != 0;
222549ed71db425c5054e3ad9526496a7e116c89556bJeff Brown        if (reset || ledState.on != desiredState) {
2226497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown            getEventHub()->setLedState(getDeviceId(), led, desiredState);
2227497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown            ledState.on = desiredState;
2228497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown        }
2229497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown    }
2230497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown}
2231497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown
22326d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
223383c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown// --- CursorInputMapper ---
22346d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
223583c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff BrownCursorInputMapper::CursorInputMapper(InputDevice* device) :
223647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        InputMapper(device) {
22376d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
22386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
223983c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff BrownCursorInputMapper::~CursorInputMapper() {
22406d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
22416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
224283c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownuint32_t CursorInputMapper::getSources() {
2243efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown    return mSource;
22446d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
22456d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
224683c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownvoid CursorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
22476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    InputMapper::populateDeviceInfo(info);
22486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
224983c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    if (mParameters.mode == Parameters::MODE_POINTER) {
225083c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        float minX, minY, maxX, maxY;
225183c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
2252c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright            info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, minX, maxX, 0.0f, 0.0f, 0.0f);
2253c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright            info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, minY, maxY, 0.0f, 0.0f, 0.0f);
225483c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        }
225583c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    } else {
2256c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright        info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, -1.0f, 1.0f, 0.0f, mXScale, 0.0f);
2257c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright        info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, -1.0f, 1.0f, 0.0f, mYScale, 0.0f);
22586f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
2259c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright    info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mSource, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
22606f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
226165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mCursorScrollAccumulator.haveRelativeVWheel()) {
2262c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright        info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
22636f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
226465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mCursorScrollAccumulator.haveRelativeHWheel()) {
2265c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright        info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
226683c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    }
22676d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
22686d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
226983c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownvoid CursorInputMapper::dump(String8& dump) {
2270be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.append(INDENT2 "Cursor Input Mapper:\n");
2271be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpParameters(dump);
2272be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "XScale: %0.3f\n", mXScale);
2273be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "YScale: %0.3f\n", mYScale);
2274be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision);
2275be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision);
2276be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "HaveVWheel: %s\n",
227765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            toString(mCursorScrollAccumulator.haveRelativeVWheel()));
2278be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "HaveHWheel: %s\n",
227965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            toString(mCursorScrollAccumulator.haveRelativeHWheel()));
2280be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale);
2281be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale);
228265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    dump.appendFormat(INDENT3 "Orientation: %d\n", mOrientation);
2283be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "ButtonState: 0x%08x\n", mButtonState);
2284be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "Down: %s\n", toString(isPointerDown(mButtonState)));
2285be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "DownTime: %lld\n", mDownTime);
2286ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown}
2287ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
228865fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid CursorInputMapper::configure(nsecs_t when,
228965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        const InputReaderConfiguration* config, uint32_t changes) {
229065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    InputMapper::configure(when, config, changes);
229147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
2292474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    if (!changes) { // first time only
229365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mCursorScrollAccumulator.configure(getDevice());
229449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
2295474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        // Configure basic parameters.
2296474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        configureParameters();
229783c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown
2298474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        // Configure device mode.
2299474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        switch (mParameters.mode) {
2300474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        case Parameters::MODE_POINTER:
2301474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mSource = AINPUT_SOURCE_MOUSE;
2302474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mXPrecision = 1.0f;
2303474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mYPrecision = 1.0f;
2304474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mXScale = 1.0f;
2305474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mYScale = 1.0f;
2306474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mPointerController = getPolicy()->obtainPointerController(getDeviceId());
2307474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            break;
2308474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        case Parameters::MODE_NAVIGATION:
2309474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mSource = AINPUT_SOURCE_TRACKBALL;
2310474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
2311474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
2312474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
2313474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
2314474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            break;
2315474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        }
23166f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
2317474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        mVWheelScale = 1.0f;
2318474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        mHWheelScale = 1.0f;
2319474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    }
232019c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown
2321474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
2322474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        mPointerVelocityControl.setParameters(config->pointerVelocityControlParameters);
2323474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        mWheelXVelocityControl.setParameters(config->wheelVelocityControlParameters);
2324474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        mWheelYVelocityControl.setParameters(config->wheelVelocityControlParameters);
2325474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    }
232665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
232765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
2328d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
2329d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            DisplayViewport v;
2330d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            if (config->getDisplayInfo(false /*external*/, &v)) {
2331d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                mOrientation = v.orientation;
2332d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            } else {
233365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mOrientation = DISPLAY_ORIENTATION_0;
233465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            }
233565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        } else {
233665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientation = DISPLAY_ORIENTATION_0;
233765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
2338af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown        bumpGeneration();
233965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
234047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown}
234147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
234283c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownvoid CursorInputMapper::configureParameters() {
234383c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    mParameters.mode = Parameters::MODE_POINTER;
234483c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    String8 cursorModeString;
234583c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    if (getDevice()->getConfiguration().tryGetProperty(String8("cursor.mode"), cursorModeString)) {
234683c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        if (cursorModeString == "navigation") {
234783c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown            mParameters.mode = Parameters::MODE_NAVIGATION;
234883c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        } else if (cursorModeString != "pointer" && cursorModeString != "default") {
23498564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Invalid value for cursor.mode: '%s'", cursorModeString.string());
235083c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        }
235183c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    }
235283c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown
235347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    mParameters.orientationAware = false;
235483c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    getDevice()->getConfiguration().tryGetProperty(String8("cursor.orientationAware"),
235547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            mParameters.orientationAware);
235647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
2357d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    mParameters.hasAssociatedDisplay = false;
2358bc68a59c024bdb745dac8e2ec7408a9f30595f1aJeff Brown    if (mParameters.mode == Parameters::MODE_POINTER || mParameters.orientationAware) {
2359d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        mParameters.hasAssociatedDisplay = true;
2360bc68a59c024bdb745dac8e2ec7408a9f30595f1aJeff Brown    }
236147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown}
236247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
236383c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownvoid CursorInputMapper::dumpParameters(String8& dump) {
236447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    dump.append(INDENT3 "Parameters:\n");
2365d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    dump.appendFormat(INDENT4 "HasAssociatedDisplay: %s\n",
2366d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            toString(mParameters.hasAssociatedDisplay));
236783c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown
236883c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    switch (mParameters.mode) {
236983c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    case Parameters::MODE_POINTER:
237083c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        dump.append(INDENT4 "Mode: pointer\n");
237183c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        break;
237283c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    case Parameters::MODE_NAVIGATION:
237383c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        dump.append(INDENT4 "Mode: navigation\n");
237483c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        break;
237583c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    default:
2376ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block        ALOG_ASSERT(false);
237783c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    }
237883c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown
237947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    dump.appendFormat(INDENT4 "OrientationAware: %s\n",
238047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            toString(mParameters.orientationAware));
238147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown}
238247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
238365fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid CursorInputMapper::reset(nsecs_t when) {
2384be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mButtonState = 0;
2385be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mDownTime = 0;
23866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
2387be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mPointerVelocityControl.reset();
2388be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mWheelXVelocityControl.reset();
2389be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mWheelYVelocityControl.reset();
23906328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
239165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCursorButtonAccumulator.reset(getDevice());
239265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCursorMotionAccumulator.reset(getDevice());
239365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCursorScrollAccumulator.reset(getDevice());
239446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
239565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    InputMapper::reset(when);
23966d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
23976d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
239883c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownvoid CursorInputMapper::process(const RawEvent* rawEvent) {
239949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mCursorButtonAccumulator.process(rawEvent);
240049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    mCursorMotionAccumulator.process(rawEvent);
240165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCursorScrollAccumulator.process(rawEvent);
24026d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
240349ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown    if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
240449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        sync(rawEvent->when);
24056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
240646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
240746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
240883c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownvoid CursorInputMapper::sync(nsecs_t when) {
2409be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t lastButtonState = mButtonState;
2410be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t currentButtonState = mCursorButtonAccumulator.getButtonState();
2411be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mButtonState = currentButtonState;
2412be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
2413be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    bool wasDown = isPointerDown(lastButtonState);
2414be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    bool down = isPointerDown(currentButtonState);
2415be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    bool downChanged;
2416be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (!wasDown && down) {
2417be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mDownTime = when;
2418be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        downChanged = true;
2419be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    } else if (wasDown && !down) {
2420be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        downChanged = true;
2421be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    } else {
2422be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        downChanged = false;
2423be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
2424be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    nsecs_t downTime = mDownTime;
2425be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    bool buttonsChanged = currentButtonState != lastButtonState;
2426c28306ad4ac9ce7a7d5f10c2e38d422ffc309a1fJeff Brown    bool buttonsPressed = currentButtonState & ~lastButtonState;
242749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
2428be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    float deltaX = mCursorMotionAccumulator.getRelativeX() * mXScale;
2429be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    float deltaY = mCursorMotionAccumulator.getRelativeY() * mYScale;
2430be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    bool moved = deltaX != 0 || deltaY != 0;
24316328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
243265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Rotate delta according to orientation if needed.
2433d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    if (mParameters.orientationAware && mParameters.hasAssociatedDisplay
2434be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            && (deltaX != 0.0f || deltaY != 0.0f)) {
243565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        rotateDelta(mOrientation, &deltaX, &deltaY);
2436be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
2437fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
243865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Move the pointer.
2439be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    PointerProperties pointerProperties;
2440be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    pointerProperties.clear();
2441be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    pointerProperties.id = 0;
2442be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;
2443fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
2444be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    PointerCoords pointerCoords;
2445be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    pointerCoords.clear();
244619c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown
244765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    float vscroll = mCursorScrollAccumulator.getRelativeVWheel();
244865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    float hscroll = mCursorScrollAccumulator.getRelativeHWheel();
2449be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    bool scrolled = vscroll != 0 || hscroll != 0;
245019c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown
2451be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mWheelYVelocityControl.move(when, NULL, &vscroll);
2452be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mWheelXVelocityControl.move(when, &hscroll, NULL);
24532352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
2454be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mPointerVelocityControl.move(when, &deltaX, &deltaY);
24552352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
245683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    int32_t displayId;
2457be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (mPointerController != NULL) {
2458be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (moved || scrolled || buttonsChanged) {
2459be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mPointerController->setPresentation(
2460be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    PointerControllerInterface::PRESENTATION_POINTER);
24612352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
2462be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (moved) {
2463be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mPointerController->move(deltaX, deltaY);
2464be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            }
24652352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
2466be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (buttonsChanged) {
2467be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mPointerController->setButtonState(currentButtonState);
246883c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown            }
2469efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown
2470be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
247183c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        }
247283c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown
2473be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        float x, y;
2474be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mPointerController->getPosition(&x, &y);
2475be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
2476be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
247783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        displayId = ADISPLAY_ID_DEFAULT;
2478be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    } else {
2479be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
2480be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
248183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        displayId = ADISPLAY_ID_NONE;
2482be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
2483be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
2484be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);
248546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
248656194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // Moving an external trackball or mouse should wake the device.
248756194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // We don't do this for internal cursor devices to prevent them from waking up
248856194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // the device in your pocket.
248956194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // TODO: Use the input device configuration to control this behavior more finely.
249056194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    uint32_t policyFlags = 0;
2491c28306ad4ac9ce7a7d5f10c2e38d422ffc309a1fJeff Brown    if ((buttonsPressed || moved || scrolled) && getDevice()->isExternal()) {
249256194ebec6212e229f4ccdaa4b187166d20013efJeff Brown        policyFlags |= POLICY_FLAG_WAKE_DROPPED;
249356194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    }
249456194ebec6212e229f4ccdaa4b187166d20013efJeff Brown
2495fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    // Synthesize key down from buttons if needed.
2496fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mSource,
2497fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            policyFlags, lastButtonState, currentButtonState);
2498fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
2499fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    // Send motion event.
2500be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (downChanged || moved || scrolled || buttonsChanged) {
2501be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        int32_t metaState = mContext->getGlobalMetaState();
2502be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        int32_t motionEventAction;
2503be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (downChanged) {
2504be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
2505be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        } else if (down || mPointerController == NULL) {
2506be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            motionEventAction = AMOTION_EVENT_ACTION_MOVE;
2507be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        } else {
2508be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
2509be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
2510be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
2511be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
2512be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                motionEventAction, 0, metaState, currentButtonState, 0,
251383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                displayId, 1, &pointerProperties, &pointerCoords,
251483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                mXPrecision, mYPrecision, downTime);
2515be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        getListener()->notifyMotion(&args);
2516be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
2517be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        // Send hover move after UP to tell the application that the mouse is hovering now.
2518be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (motionEventAction == AMOTION_EVENT_ACTION_UP
2519be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                && mPointerController != NULL) {
2520be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            NotifyMotionArgs hoverArgs(when, getDeviceId(), mSource, policyFlags,
2521be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
2522be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    metaState, currentButtonState, AMOTION_EVENT_EDGE_FLAG_NONE,
252383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                    displayId, 1, &pointerProperties, &pointerCoords,
252483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                    mXPrecision, mYPrecision, downTime);
2525be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            getListener()->notifyMotion(&hoverArgs);
2526be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
252733bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown
2528be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        // Send scroll events.
2529be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (scrolled) {
2530be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
2531be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
253233bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown
2533be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, policyFlags,
2534be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    AMOTION_EVENT_ACTION_SCROLL, 0, metaState, currentButtonState,
2535be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    AMOTION_EVENT_EDGE_FLAG_NONE,
253683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                    displayId, 1, &pointerProperties, &pointerCoords,
253783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                    mXPrecision, mYPrecision, downTime);
2538be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            getListener()->notifyMotion(&scrollArgs);
2539be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
254033bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown    }
2541a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
2542fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    // Synthesize key up from buttons if needed.
2543fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mSource,
2544fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            policyFlags, lastButtonState, currentButtonState);
2545fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
254665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCursorMotionAccumulator.finishSync();
254765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCursorScrollAccumulator.finishSync();
254846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
254946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
255083c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownint32_t CursorInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
2551c3fc2d03d58a258c53c9265a70143d4af076b764Jeff Brown    if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) {
2552c3fc2d03d58a258c53c9265a70143d4af076b764Jeff Brown        return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
2553c3fc2d03d58a258c53c9265a70143d4af076b764Jeff Brown    } else {
2554c3fc2d03d58a258c53c9265a70143d4af076b764Jeff Brown        return AKEY_STATE_UNKNOWN;
2555c3fc2d03d58a258c53c9265a70143d4af076b764Jeff Brown    }
2556c3fc2d03d58a258c53c9265a70143d4af076b764Jeff Brown}
2557c3fc2d03d58a258c53c9265a70143d4af076b764Jeff Brown
255805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownvoid CursorInputMapper::fadePointer() {
2559be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (mPointerController != NULL) {
2560be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
2561be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
256205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown}
256305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
256446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
25656d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown// --- TouchInputMapper ---
256646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
256747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff BrownTouchInputMapper::TouchInputMapper(InputDevice* device) :
2568be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        InputMapper(device),
256965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mSource(0), mDeviceMode(DEVICE_MODE_DISABLED),
257083d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        mSurfaceWidth(-1), mSurfaceHeight(-1), mSurfaceLeft(0), mSurfaceTop(0),
257183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        mSurfaceOrientation(DISPLAY_ORIENTATION_0) {
25726d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
257346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
25746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownTouchInputMapper::~TouchInputMapper() {
257546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
257646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
25776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownuint32_t TouchInputMapper::getSources() {
257865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    return mSource;
25796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
258046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
25816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
25826d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    InputMapper::populateDeviceInfo(info);
25836d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
258465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mDeviceMode != DEVICE_MODE_DISABLED) {
258565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        info->addMotionRange(mOrientedRanges.x);
258665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        info->addMotionRange(mOrientedRanges.y);
2587be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        info->addMotionRange(mOrientedRanges.pressure);
25888d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
258965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mOrientedRanges.haveSize) {
259065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            info->addMotionRange(mOrientedRanges.size);
259165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
25928d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
259365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mOrientedRanges.haveTouchSize) {
259465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            info->addMotionRange(mOrientedRanges.touchMajor);
259565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            info->addMotionRange(mOrientedRanges.touchMinor);
259665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
25978d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
259865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mOrientedRanges.haveToolSize) {
259965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            info->addMotionRange(mOrientedRanges.toolMajor);
260065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            info->addMotionRange(mOrientedRanges.toolMinor);
260165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
26028d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
260365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mOrientedRanges.haveOrientation) {
260465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            info->addMotionRange(mOrientedRanges.orientation);
260565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
2606ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
260765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mOrientedRanges.haveDistance) {
260865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            info->addMotionRange(mOrientedRanges.distance);
260965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
261080fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
261165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mOrientedRanges.haveTilt) {
261265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            info->addMotionRange(mOrientedRanges.tilt);
261365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
261465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
261565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mCursorScrollAccumulator.haveRelativeVWheel()) {
2616c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright            info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f,
2617c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright                    0.0f);
261865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
261965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mCursorScrollAccumulator.haveRelativeHWheel()) {
2620c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright            info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f,
2621c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright                    0.0f);
2622ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
26235e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright        if (mCalibration.coverageCalibration == Calibration::COVERAGE_CALIBRATION_BOX) {
26245e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            const InputDeviceInfo::MotionRange& x = mOrientedRanges.x;
26255e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            const InputDeviceInfo::MotionRange& y = mOrientedRanges.y;
26265e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_1, mSource, x.min, x.max, x.flat,
26275e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright                    x.fuzz, x.resolution);
26285e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_2, mSource, y.min, y.max, y.flat,
26295e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright                    y.fuzz, y.resolution);
26305e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_3, mSource, x.min, x.max, x.flat,
26315e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright                    x.fuzz, x.resolution);
26325e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_4, mSource, y.min, y.max, y.flat,
26335e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright                    y.fuzz, y.resolution);
26345e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright        }
26357ddd11035b25b0a2dbf09f9d9efd3fca701f0a79Michael Wright        info->setButtonUnderPad(mParameters.hasButtonUnderPad);
2636be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
26376d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
26386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
2639ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brownvoid TouchInputMapper::dump(String8& dump) {
2640be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.append(INDENT2 "Touch Input Mapper:\n");
2641be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpParameters(dump);
2642be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpVirtualKeys(dump);
2643be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpRawPointerAxes(dump);
2644be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpCalibration(dump);
2645be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpSurface(dump);
2646be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
2647be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n");
264883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    dump.appendFormat(INDENT4 "XTranslate: %0.3f\n", mXTranslate);
264983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    dump.appendFormat(INDENT4 "YTranslate: %0.3f\n", mYTranslate);
2650be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT4 "XScale: %0.3f\n", mXScale);
2651be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT4 "YScale: %0.3f\n", mYScale);
2652be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mXPrecision);
2653be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT4 "YPrecision: %0.3f\n", mYPrecision);
2654be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT4 "GeometricScale: %0.3f\n", mGeometricScale);
2655be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mPressureScale);
2656be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mSizeScale);
2657be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT4 "OrientationScale: %0.3f\n", mOrientationScale);
2658be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT4 "DistanceScale: %0.3f\n", mDistanceScale);
265965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    dump.appendFormat(INDENT4 "HaveTilt: %s\n", toString(mHaveTilt));
266065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    dump.appendFormat(INDENT4 "TiltXCenter: %0.3f\n", mTiltXCenter);
266165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    dump.appendFormat(INDENT4 "TiltXScale: %0.3f\n", mTiltXScale);
266265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    dump.appendFormat(INDENT4 "TiltYCenter: %0.3f\n", mTiltYCenter);
266365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    dump.appendFormat(INDENT4 "TiltYScale: %0.3f\n", mTiltYScale);
2664be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
2665be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "Last Button State: 0x%08x\n", mLastButtonState);
2666be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
2667be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "Last Raw Touch: pointerCount=%d\n",
2668be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mLastRawPointerData.pointerCount);
2669be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (uint32_t i = 0; i < mLastRawPointerData.pointerCount; i++) {
2670be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        const RawPointerData::Pointer& pointer = mLastRawPointerData.pointers[i];
2671be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        dump.appendFormat(INDENT4 "[%d]: id=%d, x=%d, y=%d, pressure=%d, "
2672be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                "touchMajor=%d, touchMinor=%d, toolMajor=%d, toolMinor=%d, "
267365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                "orientation=%d, tiltX=%d, tiltY=%d, distance=%d, "
267465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                "toolType=%d, isHovering=%s\n", i,
2675be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointer.id, pointer.x, pointer.y, pointer.pressure,
2676be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointer.touchMajor, pointer.touchMinor,
2677be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointer.toolMajor, pointer.toolMinor,
267865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                pointer.orientation, pointer.tiltX, pointer.tiltY, pointer.distance,
2679be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointer.toolType, toString(pointer.isHovering));
2680be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
2681be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
2682be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "Last Cooked Touch: pointerCount=%d\n",
2683be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mLastCookedPointerData.pointerCount);
2684be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (uint32_t i = 0; i < mLastCookedPointerData.pointerCount; i++) {
2685be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        const PointerProperties& pointerProperties = mLastCookedPointerData.pointerProperties[i];
2686be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        const PointerCoords& pointerCoords = mLastCookedPointerData.pointerCoords[i];
2687be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        dump.appendFormat(INDENT4 "[%d]: id=%d, x=%0.3f, y=%0.3f, pressure=%0.3f, "
2688be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                "touchMajor=%0.3f, touchMinor=%0.3f, toolMajor=%0.3f, toolMinor=%0.3f, "
268965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                "orientation=%0.3f, tilt=%0.3f, distance=%0.3f, "
269065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                "toolType=%d, isHovering=%s\n", i,
2691be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointerProperties.id,
2692be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointerCoords.getX(),
2693be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointerCoords.getY(),
2694be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2695be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2696be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2697be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2698be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2699be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
270065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TILT),
2701be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE),
2702be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                pointerProperties.toolType,
2703be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                toString(mLastCookedPointerData.isHovering(i)));
2704be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
2705be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
270665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mDeviceMode == DEVICE_MODE_POINTER) {
2707be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        dump.appendFormat(INDENT3 "Pointer Gesture Detector:\n");
2708be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        dump.appendFormat(INDENT4 "XMovementScale: %0.3f\n",
270965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPointerXMovementScale);
2710be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        dump.appendFormat(INDENT4 "YMovementScale: %0.3f\n",
271165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPointerYMovementScale);
2712be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        dump.appendFormat(INDENT4 "XZoomScale: %0.3f\n",
271365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPointerXZoomScale);
2714be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        dump.appendFormat(INDENT4 "YZoomScale: %0.3f\n",
271565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPointerYZoomScale);
2716be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        dump.appendFormat(INDENT4 "MaxSwipeWidth: %f\n",
2717be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mPointerGestureMaxSwipeWidth);
2718be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
2719be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
2720be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
272165fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::configure(nsecs_t when,
272265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        const InputReaderConfiguration* config, uint32_t changes) {
272365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    InputMapper::configure(when, config, changes);
272446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2725474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    mConfig = *config;
272646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2727474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    if (!changes) { // first time only
2728474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        // Configure basic parameters.
2729474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        configureParameters();
2730474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown
273165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Configure common accumulators.
273265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mCursorScrollAccumulator.configure(getDevice());
273365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mTouchButtonAccumulator.configure(getDevice());
273483c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown
2735474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        // Configure absolute axis information.
2736be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        configureRawPointerAxes();
27378d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
2738474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        // Prepare input device calibration.
2739474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        parseCalibration();
2740474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        resolveCalibration();
2741474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    }
2742474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown
2743474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
274465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Update pointer speed.
274565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerVelocityControl.setParameters(mConfig.pointerVelocityControlParameters);
274665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mWheelXVelocityControl.setParameters(mConfig.wheelVelocityControlParameters);
274765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mWheelYVelocityControl.setParameters(mConfig.wheelVelocityControlParameters);
2748474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    }
2749474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown
275065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    bool resetNeeded = false;
275165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (!changes || (changes & (InputReaderConfiguration::CHANGE_DISPLAY_INFO
2752daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown            | InputReaderConfiguration::CHANGE_POINTER_GESTURE_ENABLEMENT
2753daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown            | InputReaderConfiguration::CHANGE_SHOW_TOUCHES))) {
275465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Configure device sources, surface dimensions, orientation and
275565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // scaling factors.
275665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        configureSurface(when, &resetNeeded);
275765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
275865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
275965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (changes && resetNeeded) {
276065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Send reset, unless this is the first time the device has been configured,
276165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // in which case the reader will call reset itself after all mappers are ready.
276265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        getDevice()->notifyReset(when);
2763474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    }
27646d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
276546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
27668d60866e2100db70ecf0502c14768a384514d7e9Jeff Brownvoid TouchInputMapper::configureParameters() {
2767b12682270aebc110c9518bddae7a8aecc070cad7Jeff Brown    // Use the pointer presentation mode for devices that do not support distinct
2768b12682270aebc110c9518bddae7a8aecc070cad7Jeff Brown    // multitouch.  The spot-based presentation relies on being able to accurately
2769b12682270aebc110c9518bddae7a8aecc070cad7Jeff Brown    // locate two or more fingers on the touch pad.
2770b12682270aebc110c9518bddae7a8aecc070cad7Jeff Brown    mParameters.gestureMode = getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_SEMI_MT)
2771b12682270aebc110c9518bddae7a8aecc070cad7Jeff Brown            ? Parameters::GESTURE_MODE_POINTER : Parameters::GESTURE_MODE_SPOTS;
27722352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
2773538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    String8 gestureModeString;
2774538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    if (getDevice()->getConfiguration().tryGetProperty(String8("touch.gestureMode"),
2775538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown            gestureModeString)) {
2776538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        if (gestureModeString == "pointer") {
2777538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown            mParameters.gestureMode = Parameters::GESTURE_MODE_POINTER;
2778538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        } else if (gestureModeString == "spots") {
2779538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown            mParameters.gestureMode = Parameters::GESTURE_MODE_SPOTS;
2780538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        } else if (gestureModeString != "default") {
27818564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Invalid value for touch.gestureMode: '%s'", gestureModeString.string());
2782538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        }
2783538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    }
2784538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown
2785deffe07c225c15ce780fad4a500d082f2dbdabeaJeff Brown    if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_DIRECT)) {
2786deffe07c225c15ce780fad4a500d082f2dbdabeaJeff Brown        // The device is a touch screen.
2787deffe07c225c15ce780fad4a500d082f2dbdabeaJeff Brown        mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
2788deffe07c225c15ce780fad4a500d082f2dbdabeaJeff Brown    } else if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_POINTER)) {
2789deffe07c225c15ce780fad4a500d082f2dbdabeaJeff Brown        // The device is a pointing device like a track pad.
2790deffe07c225c15ce780fad4a500d082f2dbdabeaJeff Brown        mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
2791deffe07c225c15ce780fad4a500d082f2dbdabeaJeff Brown    } else if (getEventHub()->hasRelativeAxis(getDeviceId(), REL_X)
2792ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            || getEventHub()->hasRelativeAxis(getDeviceId(), REL_Y)) {
2793ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // The device is a cursor device with a touch pad attached.
2794ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // By default don't use the touch pad to move the pointer.
2795ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
2796ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    } else {
279780fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        // The device is a touch pad of unknown purpose.
2798ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
2799ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
2800ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
28017ddd11035b25b0a2dbf09f9d9efd3fca701f0a79Michael Wright    mParameters.hasButtonUnderPad=
28027ddd11035b25b0a2dbf09f9d9efd3fca701f0a79Michael Wright            getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_BUTTONPAD);
28037ddd11035b25b0a2dbf09f9d9efd3fca701f0a79Michael Wright
280447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    String8 deviceTypeString;
280547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    if (getDevice()->getConfiguration().tryGetProperty(String8("touch.deviceType"),
280647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            deviceTypeString)) {
280758a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown        if (deviceTypeString == "touchScreen") {
280858a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown            mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
2809efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown        } else if (deviceTypeString == "touchPad") {
2810efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown            mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
2811e7a9ae8ba0fb7fc61960e3facd0c5534e9ffce1eMichael Wright        } else if (deviceTypeString == "touchNavigation") {
2812e7a9ae8ba0fb7fc61960e3facd0c5534e9ffce1eMichael Wright            mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_NAVIGATION;
2813ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        } else if (deviceTypeString == "pointer") {
2814ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
2815538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        } else if (deviceTypeString != "default") {
28168564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Invalid value for touch.deviceType: '%s'", deviceTypeString.string());
281747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        }
281847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    }
281947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
2820efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown    mParameters.orientationAware = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN;
282147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    getDevice()->getConfiguration().tryGetProperty(String8("touch.orientationAware"),
282247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            mParameters.orientationAware);
282347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
2824d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    mParameters.hasAssociatedDisplay = false;
2825bc68a59c024bdb745dac8e2ec7408a9f30595f1aJeff Brown    mParameters.associatedDisplayIsExternal = false;
2826bc68a59c024bdb745dac8e2ec7408a9f30595f1aJeff Brown    if (mParameters.orientationAware
2827efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown            || mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
2828bc68a59c024bdb745dac8e2ec7408a9f30595f1aJeff Brown            || mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) {
2829d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        mParameters.hasAssociatedDisplay = true;
2830bc68a59c024bdb745dac8e2ec7408a9f30595f1aJeff Brown        mParameters.associatedDisplayIsExternal =
2831bc68a59c024bdb745dac8e2ec7408a9f30595f1aJeff Brown                mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
2832bc68a59c024bdb745dac8e2ec7408a9f30595f1aJeff Brown                        && getDevice()->isExternal();
2833bc68a59c024bdb745dac8e2ec7408a9f30595f1aJeff Brown    }
28348d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown}
28358d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
2836ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brownvoid TouchInputMapper::dumpParameters(String8& dump) {
283747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    dump.append(INDENT3 "Parameters:\n");
283847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
2839538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    switch (mParameters.gestureMode) {
2840538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    case Parameters::GESTURE_MODE_POINTER:
2841538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        dump.append(INDENT4 "GestureMode: pointer\n");
2842538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        break;
2843538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    case Parameters::GESTURE_MODE_SPOTS:
2844538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        dump.append(INDENT4 "GestureMode: spots\n");
2845538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        break;
2846538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    default:
2847538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        assert(false);
2848538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    }
2849538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown
285047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    switch (mParameters.deviceType) {
285147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    case Parameters::DEVICE_TYPE_TOUCH_SCREEN:
285247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        dump.append(INDENT4 "DeviceType: touchScreen\n");
285347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        break;
285447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    case Parameters::DEVICE_TYPE_TOUCH_PAD:
285547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        dump.append(INDENT4 "DeviceType: touchPad\n");
285647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        break;
2857e7a9ae8ba0fb7fc61960e3facd0c5534e9ffce1eMichael Wright    case Parameters::DEVICE_TYPE_TOUCH_NAVIGATION:
2858e7a9ae8ba0fb7fc61960e3facd0c5534e9ffce1eMichael Wright        dump.append(INDENT4 "DeviceType: touchNavigation\n");
2859e7a9ae8ba0fb7fc61960e3facd0c5534e9ffce1eMichael Wright        break;
2860ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    case Parameters::DEVICE_TYPE_POINTER:
2861ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        dump.append(INDENT4 "DeviceType: pointer\n");
2862ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        break;
286347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    default:
2864ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block        ALOG_ASSERT(false);
286547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    }
286647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
286783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    dump.appendFormat(INDENT4 "AssociatedDisplay: hasAssociatedDisplay=%s, isExternal=%s\n",
2868d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            toString(mParameters.hasAssociatedDisplay),
2869d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            toString(mParameters.associatedDisplayIsExternal));
287047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    dump.appendFormat(INDENT4 "OrientationAware: %s\n",
287147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            toString(mParameters.orientationAware));
2872b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
2873b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
2874be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid TouchInputMapper::configureRawPointerAxes() {
2875be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mRawPointerAxes.clear();
2876be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
2877be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
2878be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid TouchInputMapper::dumpRawPointerAxes(String8& dump) {
2879be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.append(INDENT3 "Raw Touch Axes:\n");
2880be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.x, "X");
2881be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.y, "Y");
2882be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.pressure, "Pressure");
2883be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.touchMajor, "TouchMajor");
2884be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.touchMinor, "TouchMinor");
2885be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.toolMajor, "ToolMajor");
2886be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.toolMinor, "ToolMinor");
2887be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.orientation, "Orientation");
2888be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.distance, "Distance");
288965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.tiltX, "TiltX");
289065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.tiltY, "TiltY");
2891be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.trackingId, "TrackingId");
2892be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.slot, "Slot");
2893be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
2894be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
289565fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
289665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    int32_t oldDeviceMode = mDeviceMode;
289765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
289865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Determine device mode.
289965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER
290065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            && mConfig.pointerGesturesEnabled) {
290165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mSource = AINPUT_SOURCE_MOUSE;
290265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mDeviceMode = DEVICE_MODE_POINTER;
290300710e906bdafd58386ee7f81fa84addd218122fJeff Brown        if (hasStylus()) {
290400710e906bdafd58386ee7f81fa84addd218122fJeff Brown            mSource |= AINPUT_SOURCE_STYLUS;
290500710e906bdafd58386ee7f81fa84addd218122fJeff Brown        }
290665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    } else if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
2907d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown            && mParameters.hasAssociatedDisplay) {
290865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mSource = AINPUT_SOURCE_TOUCHSCREEN;
290965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mDeviceMode = DEVICE_MODE_DIRECT;
291000710e906bdafd58386ee7f81fa84addd218122fJeff Brown        if (hasStylus()) {
291100710e906bdafd58386ee7f81fa84addd218122fJeff Brown            mSource |= AINPUT_SOURCE_STYLUS;
291200710e906bdafd58386ee7f81fa84addd218122fJeff Brown        }
2913e7a9ae8ba0fb7fc61960e3facd0c5534e9ffce1eMichael Wright    } else if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_NAVIGATION) {
2914e7a9ae8ba0fb7fc61960e3facd0c5534e9ffce1eMichael Wright        mSource = AINPUT_SOURCE_TOUCH_NAVIGATION;
29154dac901f011e7c15882e260441225633a6435e49Jeff Brown        mDeviceMode = DEVICE_MODE_NAVIGATION;
291665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    } else {
291765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mSource = AINPUT_SOURCE_TOUCHPAD;
291865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mDeviceMode = DEVICE_MODE_UNSCALED;
291965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
292065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
29219626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown    // Ensure we have valid X and Y axes.
2922be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (!mRawPointerAxes.x.valid || !mRawPointerAxes.y.valid) {
29238564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW(INDENT "Touch device '%s' did not report support for X or Y axis!  "
29249626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                "The device will be inoperable.", getDeviceName().string());
292565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mDeviceMode = DEVICE_MODE_DISABLED;
292665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        return;
29279626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown    }
29289626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown
292983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    // Raw width and height in the natural orientation.
293083d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    int32_t rawWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
293183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    int32_t rawHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
293283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown
293365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Get associated display dimensions.
293483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    DisplayViewport newViewport;
2935d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown    if (mParameters.hasAssociatedDisplay) {
293683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        if (!mConfig.getDisplayInfo(mParameters.associatedDisplayIsExternal, &newViewport)) {
29376215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block            ALOGI(INDENT "Touch device '%s' could not query the properties of its associated "
2938d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                    "display.  The device will be inoperable until the display size "
293965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    "becomes available.",
2940d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown                    getDeviceName().string());
294165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mDeviceMode = DEVICE_MODE_DISABLED;
294265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            return;
29436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
294483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    } else {
294583d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        newViewport.setNonDisplayViewport(rawWidth, rawHeight);
294683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    }
2947f583d0dcc6e5c1968c472c844f6c8fbbe036ad78Michael Wright    bool viewportChanged = mViewport != newViewport;
2948f583d0dcc6e5c1968c472c844f6c8fbbe036ad78Michael Wright    if (viewportChanged) {
294983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        mViewport = newViewport;
295083d616a9c7b9505153d258511eb5c16b552e268dJeff Brown
295183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        if (mDeviceMode == DEVICE_MODE_DIRECT || mDeviceMode == DEVICE_MODE_POINTER) {
295283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            // Convert rotated viewport to natural surface coordinates.
295383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            int32_t naturalLogicalWidth, naturalLogicalHeight;
295483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            int32_t naturalPhysicalWidth, naturalPhysicalHeight;
295583d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            int32_t naturalPhysicalLeft, naturalPhysicalTop;
295683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            int32_t naturalDeviceWidth, naturalDeviceHeight;
295783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            switch (mViewport.orientation) {
295883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            case DISPLAY_ORIENTATION_90:
295983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalLogicalWidth = mViewport.logicalBottom - mViewport.logicalTop;
296083d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
296183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
296283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
296383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalLeft = mViewport.deviceHeight - mViewport.physicalBottom;
296483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalTop = mViewport.physicalLeft;
296583d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalDeviceWidth = mViewport.deviceHeight;
296683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalDeviceHeight = mViewport.deviceWidth;
296783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                break;
296883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            case DISPLAY_ORIENTATION_180:
296983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalLogicalWidth = mViewport.logicalRight - mViewport.logicalLeft;
297083d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalLogicalHeight = mViewport.logicalBottom - mViewport.logicalTop;
297183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft;
297283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop;
297383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalLeft = mViewport.deviceWidth - mViewport.physicalRight;
297483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalTop = mViewport.deviceHeight - mViewport.physicalBottom;
297583d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalDeviceWidth = mViewport.deviceWidth;
297683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalDeviceHeight = mViewport.deviceHeight;
297783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                break;
297883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            case DISPLAY_ORIENTATION_270:
297983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalLogicalWidth = mViewport.logicalBottom - mViewport.logicalTop;
298083d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
298183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
298283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
298383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalLeft = mViewport.physicalTop;
298483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalTop = mViewport.deviceWidth - mViewport.physicalRight;
298583d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalDeviceWidth = mViewport.deviceHeight;
298683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalDeviceHeight = mViewport.deviceWidth;
298783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                break;
298883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            case DISPLAY_ORIENTATION_0:
298983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            default:
299083d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalLogicalWidth = mViewport.logicalRight - mViewport.logicalLeft;
299183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalLogicalHeight = mViewport.logicalBottom - mViewport.logicalTop;
299283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft;
299383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop;
299483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalLeft = mViewport.physicalLeft;
299583d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalPhysicalTop = mViewport.physicalTop;
299683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalDeviceWidth = mViewport.deviceWidth;
299783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                naturalDeviceHeight = mViewport.deviceHeight;
299883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                break;
299983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            }
300083d616a9c7b9505153d258511eb5c16b552e268dJeff Brown
300183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mSurfaceWidth = naturalLogicalWidth * naturalDeviceWidth / naturalPhysicalWidth;
300283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mSurfaceHeight = naturalLogicalHeight * naturalDeviceHeight / naturalPhysicalHeight;
300383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mSurfaceLeft = naturalPhysicalLeft * naturalLogicalWidth / naturalPhysicalWidth;
300483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mSurfaceTop = naturalPhysicalTop * naturalLogicalHeight / naturalPhysicalHeight;
3005efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown
300683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mSurfaceOrientation = mParameters.orientationAware ?
300783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                    mViewport.orientation : DISPLAY_ORIENTATION_0;
300883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        } else {
300983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mSurfaceWidth = rawWidth;
301083d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mSurfaceHeight = rawHeight;
301183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mSurfaceLeft = 0;
301283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mSurfaceTop = 0;
301383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mSurfaceOrientation = DISPLAY_ORIENTATION_0;
3014d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown        }
301565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
301665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
301765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // If moving between pointer modes, need to reset some state.
3018f583d0dcc6e5c1968c472c844f6c8fbbe036ad78Michael Wright    bool deviceModeChanged = mDeviceMode != oldDeviceMode;
3019f583d0dcc6e5c1968c472c844f6c8fbbe036ad78Michael Wright    if (deviceModeChanged) {
3020daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown        mOrientedRanges.clear();
3021daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown    }
3022efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown
3023daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown    // Create pointer controller if needed.
3024daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown    if (mDeviceMode == DEVICE_MODE_POINTER ||
3025daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown            (mDeviceMode == DEVICE_MODE_DIRECT && mConfig.showTouches)) {
3026daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown        if (mPointerController == NULL) {
3027daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown            mPointerController = getPolicy()->obtainPointerController(getDeviceId());
3028efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown        }
3029daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown    } else {
3030daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown        mPointerController.clear();
3031ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
3032ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
303383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    if (viewportChanged || deviceModeChanged) {
303483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        ALOGI("Device reconfigured: id=%d, name='%s', size %dx%d, orientation %d, mode %d, "
303583d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                "display id %d",
303683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                getDeviceId(), getDeviceName().string(), mSurfaceWidth, mSurfaceHeight,
303783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                mSurfaceOrientation, mDeviceMode, mViewport.displayId);
303846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
30398d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // Configure X and Y factors.
304083d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        mXScale = float(mSurfaceWidth) / rawWidth;
304183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        mYScale = float(mSurfaceHeight) / rawHeight;
304283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        mXTranslate = -mSurfaceLeft;
304383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        mYTranslate = -mSurfaceTop;
3044be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mXPrecision = 1.0f / mXScale;
3045be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mYPrecision = 1.0f / mYScale;
30469626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown
3047be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mOrientedRanges.x.axis = AMOTION_EVENT_AXIS_X;
304865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mOrientedRanges.x.source = mSource;
3049be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mOrientedRanges.y.axis = AMOTION_EVENT_AXIS_Y;
305065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mOrientedRanges.y.source = mSource;
3051efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown
3052be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        configureVirtualKeys();
30530b72e82c5f5d4ab709539c3490d6c7023f680dffJeff Brown
30548d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // Scale factor for terms that are not oriented in a particular axis.
30558d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // If the pixels are square then xScale == yScale otherwise we fake it
30568d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // by choosing an average.
3057be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mGeometricScale = avg(mXScale, mYScale);
30588d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
30598d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // Size of diagonal axis.
306083d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        float diagonalSize = hypotf(mSurfaceWidth, mSurfaceHeight);
30618d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
3062a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        // Size factors.
3063a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) {
3064a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            if (mRawPointerAxes.touchMajor.valid
3065a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                    && mRawPointerAxes.touchMajor.maxValue != 0) {
3066a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                mSizeScale = 1.0f / mRawPointerAxes.touchMajor.maxValue;
3067a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            } else if (mRawPointerAxes.toolMajor.valid
3068a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                    && mRawPointerAxes.toolMajor.maxValue != 0) {
3069a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                mSizeScale = 1.0f / mRawPointerAxes.toolMajor.maxValue;
3070a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            } else {
3071a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                mSizeScale = 0.0f;
3072a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            }
3073a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown
3074be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.haveTouchSize = true;
3075a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mOrientedRanges.haveToolSize = true;
3076a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mOrientedRanges.haveSize = true;
3077efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown
3078be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.touchMajor.axis = AMOTION_EVENT_AXIS_TOUCH_MAJOR;
307965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.touchMajor.source = mSource;
3080be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.touchMajor.min = 0;
3081be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.touchMajor.max = diagonalSize;
3082be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.touchMajor.flat = 0;
3083be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.touchMajor.fuzz = 0;
3084c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright            mOrientedRanges.touchMajor.resolution = 0;
3085efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown
3086be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.touchMinor = mOrientedRanges.touchMajor;
3087be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.touchMinor.axis = AMOTION_EVENT_AXIS_TOUCH_MINOR;
3088efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown
3089be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.toolMajor.axis = AMOTION_EVENT_AXIS_TOOL_MAJOR;
309065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.toolMajor.source = mSource;
3091be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.toolMajor.min = 0;
3092be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.toolMajor.max = diagonalSize;
3093be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.toolMajor.flat = 0;
3094be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.toolMajor.fuzz = 0;
3095c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright            mOrientedRanges.toolMajor.resolution = 0;
3096efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown
3097be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.toolMinor = mOrientedRanges.toolMajor;
3098be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.toolMinor.axis = AMOTION_EVENT_AXIS_TOOL_MINOR;
3099a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown
3100a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mOrientedRanges.size.axis = AMOTION_EVENT_AXIS_SIZE;
310165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.size.source = mSource;
3102a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mOrientedRanges.size.min = 0;
3103a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mOrientedRanges.size.max = 1.0;
3104a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mOrientedRanges.size.flat = 0;
3105a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mOrientedRanges.size.fuzz = 0;
3106c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright            mOrientedRanges.size.resolution = 0;
3107a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        } else {
3108a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mSizeScale = 0.0f;
31098d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
31108d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
31118d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // Pressure factors.
3112be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mPressureScale = 0;
311365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_PHYSICAL
311465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                || mCalibration.pressureCalibration
311565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                        == Calibration::PRESSURE_CALIBRATION_AMPLITUDE) {
311665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            if (mCalibration.havePressureScale) {
311765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPressureScale = mCalibration.pressureScale;
311865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            } else if (mRawPointerAxes.pressure.valid
311965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    && mRawPointerAxes.pressure.maxValue != 0) {
312065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPressureScale = 1.0f / mRawPointerAxes.pressure.maxValue;
31218d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
312265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
31238d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
312465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mOrientedRanges.pressure.axis = AMOTION_EVENT_AXIS_PRESSURE;
312565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mOrientedRanges.pressure.source = mSource;
312665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mOrientedRanges.pressure.min = 0;
312765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mOrientedRanges.pressure.max = 1.0;
312865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mOrientedRanges.pressure.flat = 0;
312965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mOrientedRanges.pressure.fuzz = 0;
3130c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright        mOrientedRanges.pressure.resolution = 0;
313165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
313265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Tilt
313365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mTiltXCenter = 0;
313465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mTiltXScale = 0;
313565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mTiltYCenter = 0;
313665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mTiltYScale = 0;
313765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mHaveTilt = mRawPointerAxes.tiltX.valid && mRawPointerAxes.tiltY.valid;
313865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mHaveTilt) {
313965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mTiltXCenter = avg(mRawPointerAxes.tiltX.minValue,
314065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    mRawPointerAxes.tiltX.maxValue);
314165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mTiltYCenter = avg(mRawPointerAxes.tiltY.minValue,
314265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    mRawPointerAxes.tiltY.maxValue);
314365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mTiltXScale = M_PI / 180;
314465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mTiltYScale = M_PI / 180;
314565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
314665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.haveTilt = true;
314765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
314865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.tilt.axis = AMOTION_EVENT_AXIS_TILT;
314965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.tilt.source = mSource;
315065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.tilt.min = 0;
315165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.tilt.max = M_PI_2;
315265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.tilt.flat = 0;
315365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.tilt.fuzz = 0;
3154c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright            mOrientedRanges.tilt.resolution = 0;
31558d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
31568d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
31578d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // Orientation
3158be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mOrientationScale = 0;
315965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mHaveTilt) {
316065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.haveOrientation = true;
316165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
316265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
316365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.orientation.source = mSource;
316465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.orientation.min = -M_PI;
316565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.orientation.max = M_PI;
316665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.orientation.flat = 0;
316765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.orientation.fuzz = 0;
3168c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright            mOrientedRanges.orientation.resolution = 0;
316965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        } else if (mCalibration.orientationCalibration !=
317065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                Calibration::ORIENTATION_CALIBRATION_NONE) {
31718d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            if (mCalibration.orientationCalibration
31728d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    == Calibration::ORIENTATION_CALIBRATION_INTERPOLATED) {
317365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                if (mRawPointerAxes.orientation.valid) {
3174037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown                    if (mRawPointerAxes.orientation.maxValue > 0) {
3175037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown                        mOrientationScale = M_PI_2 / mRawPointerAxes.orientation.maxValue;
3176037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown                    } else if (mRawPointerAxes.orientation.minValue < 0) {
3177037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown                        mOrientationScale = -M_PI_2 / mRawPointerAxes.orientation.minValue;
3178037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown                    } else {
3179037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown                        mOrientationScale = 0;
3180037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown                    }
31818d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                }
31828d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
31836328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
3184be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.haveOrientation = true;
318580fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
3186be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
318765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.orientation.source = mSource;
318865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.orientation.min = -M_PI_2;
3189be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.orientation.max = M_PI_2;
3190be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.orientation.flat = 0;
3191be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.orientation.fuzz = 0;
3192c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright            mOrientedRanges.orientation.resolution = 0;
31938d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
319480fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
319580fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        // Distance
3196be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mDistanceScale = 0;
319780fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        if (mCalibration.distanceCalibration != Calibration::DISTANCE_CALIBRATION_NONE) {
319880fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            if (mCalibration.distanceCalibration
319980fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                    == Calibration::DISTANCE_CALIBRATION_SCALED) {
320080fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                if (mCalibration.haveDistanceScale) {
3201be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mDistanceScale = mCalibration.distanceScale;
320280fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                } else {
3203be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mDistanceScale = 1.0f;
320480fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                }
320580fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            }
320680fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
3207be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.haveDistance = true;
320880fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
3209be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.distance.axis = AMOTION_EVENT_AXIS_DISTANCE;
321065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mOrientedRanges.distance.source = mSource;
3211be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.distance.min =
3212be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mRawPointerAxes.distance.minValue * mDistanceScale;
3213be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.distance.max =
32148239940d0efb7e536d932473c535c1d9bb0ab658Andreas Sandblad                    mRawPointerAxes.distance.maxValue * mDistanceScale;
3215be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.distance.flat = 0;
3216be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.distance.fuzz =
3217be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mRawPointerAxes.distance.fuzz * mDistanceScale;
3218c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright            mOrientedRanges.distance.resolution = 0;
321980fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        }
32206d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
322183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown        // Compute oriented precision, scales and ranges.
32229626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        // Note that the maximum value reported is an inclusive maximum value so it is one
32239626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        // unit less than the total width or height of surface.
3224be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        switch (mSurfaceOrientation) {
3225b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        case DISPLAY_ORIENTATION_90:
3226b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        case DISPLAY_ORIENTATION_270:
3227be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedXPrecision = mYPrecision;
3228be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedYPrecision = mXPrecision;
3229be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
323083d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mOrientedRanges.x.min = mYTranslate;
323183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mOrientedRanges.x.max = mSurfaceHeight + mYTranslate - 1;
3232be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.x.flat = 0;
3233c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright            mOrientedRanges.x.fuzz = 0;
3234c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright            mOrientedRanges.x.resolution = mRawPointerAxes.y.resolution * mYScale;
3235be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
323683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mOrientedRanges.y.min = mXTranslate;
323783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mOrientedRanges.y.max = mSurfaceWidth + mXTranslate - 1;
3238be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.y.flat = 0;
3239c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright            mOrientedRanges.y.fuzz = 0;
3240c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright            mOrientedRanges.y.resolution = mRawPointerAxes.x.resolution * mXScale;
32416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
32429626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown
32436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        default:
3244be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedXPrecision = mXPrecision;
3245be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedYPrecision = mYPrecision;
3246be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
324783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mOrientedRanges.x.min = mXTranslate;
324883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mOrientedRanges.x.max = mSurfaceWidth + mXTranslate - 1;
3249be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.x.flat = 0;
3250c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright            mOrientedRanges.x.fuzz = 0;
3251c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright            mOrientedRanges.x.resolution = mRawPointerAxes.x.resolution * mXScale;
3252be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
325383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mOrientedRanges.y.min = mYTranslate;
325483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mOrientedRanges.y.max = mSurfaceHeight + mYTranslate - 1;
3255be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mOrientedRanges.y.flat = 0;
3256c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright            mOrientedRanges.y.fuzz = 0;
3257c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright            mOrientedRanges.y.resolution = mRawPointerAxes.y.resolution * mYScale;
32586d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
32590b72e82c5f5d4ab709539c3490d6c7023f680dffJeff Brown        }
3260ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
326165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mDeviceMode == DEVICE_MODE_POINTER) {
32624dac901f011e7c15882e260441225633a6435e49Jeff Brown            // Compute pointer gesture detection parameters.
32632352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            float rawDiagonal = hypotf(rawWidth, rawHeight);
326483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            float displayDiagonal = hypotf(mSurfaceWidth, mSurfaceHeight);
3265ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
32662352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            // Scale movements such that one whole swipe of the touch pad covers a
326719c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            // given area relative to the diagonal size of the display when no acceleration
326819c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            // is applied.
3269ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            // Assume that the touch pad has a square aspect ratio such that movements in
3270ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            // X and Y of the same number of raw units cover the same physical distance.
327165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerXMovementScale = mConfig.pointerGestureMovementSpeedRatio
32722352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                    * displayDiagonal / rawDiagonal;
327365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerYMovementScale = mPointerXMovementScale;
3274ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
3275ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            // Scale zooms to cover a smaller range of the display than movements do.
3276ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            // This value determines the area around the pointer that is affected by freeform
3277ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            // pointer gestures.
327865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerXZoomScale = mConfig.pointerGestureZoomSpeedRatio
32792352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                    * displayDiagonal / rawDiagonal;
328065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerYZoomScale = mPointerXZoomScale;
3281ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
32822352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            // Max width between pointers to detect a swipe gesture is more than some fraction
32832352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            // of the diagonal axis of the touch pad.  Touches that are wider than this are
32842352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            // translated into freeform gestures.
3285be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mPointerGestureMaxSwipeWidth =
3286474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    mConfig.pointerGestureSwipeMaxWidthRatio * rawDiagonal;
32872352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
32884dac901f011e7c15882e260441225633a6435e49Jeff Brown            // Abort current pointer usages because the state has changed.
32894dac901f011e7c15882e260441225633a6435e49Jeff Brown            abortPointerUsage(when, 0 /*policyFlags*/);
32904dac901f011e7c15882e260441225633a6435e49Jeff Brown        }
32912352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
329265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Inform the dispatcher about the changes.
329365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        *outResetNeeded = true;
3294af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown        bumpGeneration();
329546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
329646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
329746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3298be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid TouchInputMapper::dumpSurface(String8& dump) {
329983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    dump.appendFormat(INDENT3 "Viewport: displayId=%d, orientation=%d, "
330083d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            "logicalFrame=[%d, %d, %d, %d], "
330183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            "physicalFrame=[%d, %d, %d, %d], "
330283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            "deviceSize=[%d, %d]\n",
330383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mViewport.displayId, mViewport.orientation,
330483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mViewport.logicalLeft, mViewport.logicalTop,
330583d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mViewport.logicalRight, mViewport.logicalBottom,
330683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mViewport.physicalLeft, mViewport.physicalTop,
330783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mViewport.physicalRight, mViewport.physicalBottom,
330883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mViewport.deviceWidth, mViewport.deviceHeight);
330983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown
3310be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mSurfaceWidth);
3311be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mSurfaceHeight);
331283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    dump.appendFormat(INDENT3 "SurfaceLeft: %d\n", mSurfaceLeft);
331383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    dump.appendFormat(INDENT3 "SurfaceTop: %d\n", mSurfaceTop);
3314be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mSurfaceOrientation);
3315b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
3316b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
3317be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid TouchInputMapper::configureVirtualKeys() {
33188d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    Vector<VirtualKeyDefinition> virtualKeyDefinitions;
33199065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown    getEventHub()->getVirtualKeyDefinitions(getDeviceId(), virtualKeyDefinitions);
33200b72e82c5f5d4ab709539c3490d6c7023f680dffJeff Brown
3321be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mVirtualKeys.clear();
33220b72e82c5f5d4ab709539c3490d6c7023f680dffJeff Brown
33236328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    if (virtualKeyDefinitions.size() == 0) {
33246328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        return;
33256328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    }
33266d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
3327be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mVirtualKeys.setCapacity(virtualKeyDefinitions.size());
33286d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
3329be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t touchScreenLeft = mRawPointerAxes.x.minValue;
3330be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t touchScreenTop = mRawPointerAxes.y.minValue;
3331be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t touchScreenWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
3332be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t touchScreenHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
33336d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
33346328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
33358d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        const VirtualKeyDefinition& virtualKeyDefinition =
33366328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                virtualKeyDefinitions[i];
33376d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
3338be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mVirtualKeys.add();
3339be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        VirtualKey& virtualKey = mVirtualKeys.editTop();
33400b72e82c5f5d4ab709539c3490d6c7023f680dffJeff Brown
33416328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        virtualKey.scanCode = virtualKeyDefinition.scanCode;
33426328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        int32_t keyCode;
33436328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        uint32_t flags;
334449ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode, 0, &keyCode, &flags)) {
33458564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring",
33468d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    virtualKey.scanCode);
3347be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mVirtualKeys.pop(); // drop the key
33486328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            continue;
33496328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        }
33500b72e82c5f5d4ab709539c3490d6c7023f680dffJeff Brown
33516328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        virtualKey.keyCode = keyCode;
33526328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        virtualKey.flags = flags;
33536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
33546328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        // convert the key definition's display coordinates into touch coordinates for a hit box
33556328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        int32_t halfWidth = virtualKeyDefinition.width / 2;
33566328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        int32_t halfHeight = virtualKeyDefinition.height / 2;
33576328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
33586328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth)
3359be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
33606328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth)
3361be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
33626328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight)
3363be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                * touchScreenHeight / mSurfaceHeight + touchScreenTop;
33646328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
3365be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                * touchScreenHeight / mSurfaceHeight + touchScreenTop;
3366ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    }
3367ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown}
3368ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
3369be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid TouchInputMapper::dumpVirtualKeys(String8& dump) {
3370be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (!mVirtualKeys.isEmpty()) {
3371ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT3 "Virtual Keys:\n");
3372ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
3373be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        for (size_t i = 0; i < mVirtualKeys.size(); i++) {
3374be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const VirtualKey& virtualKey = mVirtualKeys.itemAt(i);
3375ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown            dump.appendFormat(INDENT4 "%d: scanCode=%d, keyCode=%d, "
3376ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown                    "hitLeft=%d, hitRight=%d, hitTop=%d, hitBottom=%d\n",
3377ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown                    i, virtualKey.scanCode, virtualKey.keyCode,
3378ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown                    virtualKey.hitLeft, virtualKey.hitRight,
3379ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown                    virtualKey.hitTop, virtualKey.hitBottom);
3380ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        }
33816328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    }
338246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
338346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
33848d60866e2100db70ecf0502c14768a384514d7e9Jeff Brownvoid TouchInputMapper::parseCalibration() {
338547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    const PropertyMap& in = getDevice()->getConfiguration();
33868d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    Calibration& out = mCalibration;
33878d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
3388a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    // Size
3389a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    out.sizeCalibration = Calibration::SIZE_CALIBRATION_DEFAULT;
3390a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    String8 sizeCalibrationString;
3391a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    if (in.tryGetProperty(String8("touch.size.calibration"), sizeCalibrationString)) {
3392a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        if (sizeCalibrationString == "none") {
3393a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            out.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
3394a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        } else if (sizeCalibrationString == "geometric") {
3395a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            out.sizeCalibration = Calibration::SIZE_CALIBRATION_GEOMETRIC;
3396a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        } else if (sizeCalibrationString == "diameter") {
3397a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            out.sizeCalibration = Calibration::SIZE_CALIBRATION_DIAMETER;
3398037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown        } else if (sizeCalibrationString == "box") {
3399037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown            out.sizeCalibration = Calibration::SIZE_CALIBRATION_BOX;
3400a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        } else if (sizeCalibrationString == "area") {
3401a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            out.sizeCalibration = Calibration::SIZE_CALIBRATION_AREA;
3402a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        } else if (sizeCalibrationString != "default") {
34038564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Invalid value for touch.size.calibration: '%s'",
3404a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                    sizeCalibrationString.string());
3405a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        }
3406a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    }
3407a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown
3408a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    out.haveSizeScale = in.tryGetProperty(String8("touch.size.scale"),
3409a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            out.sizeScale);
3410a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    out.haveSizeBias = in.tryGetProperty(String8("touch.size.bias"),
3411a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            out.sizeBias);
3412a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    out.haveSizeIsSummed = in.tryGetProperty(String8("touch.size.isSummed"),
3413a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            out.sizeIsSummed);
34148d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
34158d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    // Pressure
34168d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_DEFAULT;
34178d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    String8 pressureCalibrationString;
3418c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    if (in.tryGetProperty(String8("touch.pressure.calibration"), pressureCalibrationString)) {
34198d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        if (pressureCalibrationString == "none") {
34208d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
34218d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else if (pressureCalibrationString == "physical") {
34228d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
34238d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else if (pressureCalibrationString == "amplitude") {
34248d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE;
34258d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else if (pressureCalibrationString != "default") {
34268564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Invalid value for touch.pressure.calibration: '%s'",
34278d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    pressureCalibrationString.string());
34288d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
34298d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
34308d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
34318d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    out.havePressureScale = in.tryGetProperty(String8("touch.pressure.scale"),
34328d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            out.pressureScale);
34338d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
34348d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    // Orientation
34358d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_DEFAULT;
34368d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    String8 orientationCalibrationString;
3437c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    if (in.tryGetProperty(String8("touch.orientation.calibration"), orientationCalibrationString)) {
34388d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        if (orientationCalibrationString == "none") {
34398d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
34408d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else if (orientationCalibrationString == "interpolated") {
34418d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
3442517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown        } else if (orientationCalibrationString == "vector") {
3443517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_VECTOR;
34448d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else if (orientationCalibrationString != "default") {
34458564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Invalid value for touch.orientation.calibration: '%s'",
34468d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    orientationCalibrationString.string());
34478d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
34488d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
344980fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
345080fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    // Distance
345180fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_DEFAULT;
345280fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    String8 distanceCalibrationString;
345380fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    if (in.tryGetProperty(String8("touch.distance.calibration"), distanceCalibrationString)) {
345480fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        if (distanceCalibrationString == "none") {
345580fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE;
345680fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        } else if (distanceCalibrationString == "scaled") {
345780fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_SCALED;
345880fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        } else if (distanceCalibrationString != "default") {
34598564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Invalid value for touch.distance.calibration: '%s'",
346080fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                    distanceCalibrationString.string());
346180fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        }
346280fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    }
346380fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
346480fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    out.haveDistanceScale = in.tryGetProperty(String8("touch.distance.scale"),
346580fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            out.distanceScale);
34665e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright
34675e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright    out.coverageCalibration = Calibration::COVERAGE_CALIBRATION_DEFAULT;
34685e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright    String8 coverageCalibrationString;
34695e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright    if (in.tryGetProperty(String8("touch.coverage.calibration"), coverageCalibrationString)) {
34705e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright        if (coverageCalibrationString == "none") {
34715e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            out.coverageCalibration = Calibration::COVERAGE_CALIBRATION_NONE;
34725e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright        } else if (coverageCalibrationString == "box") {
34735e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            out.coverageCalibration = Calibration::COVERAGE_CALIBRATION_BOX;
34745e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright        } else if (coverageCalibrationString != "default") {
34755e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            ALOGW("Invalid value for touch.coverage.calibration: '%s'",
34765e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright                    coverageCalibrationString.string());
34775e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright        }
34785e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright    }
34798d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown}
34808d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
34818d60866e2100db70ecf0502c14768a384514d7e9Jeff Brownvoid TouchInputMapper::resolveCalibration() {
3482a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    // Size
3483a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    if (mRawPointerAxes.touchMajor.valid || mRawPointerAxes.toolMajor.valid) {
3484a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_DEFAULT) {
3485a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_GEOMETRIC;
34868d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
3487a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    } else {
3488a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
34898d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
34908d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
3491a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    // Pressure
3492a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    if (mRawPointerAxes.pressure.valid) {
3493a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_DEFAULT) {
3494a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
34958d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
3496a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    } else {
3497a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
34988d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
34998d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
35008d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    // Orientation
3501a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    if (mRawPointerAxes.orientation.valid) {
3502a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        if (mCalibration.orientationCalibration == Calibration::ORIENTATION_CALIBRATION_DEFAULT) {
35038d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
35048d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
3505a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    } else {
3506a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
35078d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
350880fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
350980fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    // Distance
3510a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    if (mRawPointerAxes.distance.valid) {
3511a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        if (mCalibration.distanceCalibration == Calibration::DISTANCE_CALIBRATION_DEFAULT) {
351280fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_SCALED;
351380fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        }
3514a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    } else {
3515a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE;
351680fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    }
35175e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright
35185e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright    // Coverage
35195e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright    if (mCalibration.coverageCalibration == Calibration::COVERAGE_CALIBRATION_DEFAULT) {
35205e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright        mCalibration.coverageCalibration = Calibration::COVERAGE_CALIBRATION_NONE;
35215e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright    }
35228d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown}
35238d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
3524ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brownvoid TouchInputMapper::dumpCalibration(String8& dump) {
3525ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    dump.append(INDENT3 "Calibration:\n");
3526b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
3527a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    // Size
3528a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    switch (mCalibration.sizeCalibration) {
3529a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    case Calibration::SIZE_CALIBRATION_NONE:
3530a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        dump.append(INDENT4 "touch.size.calibration: none\n");
35318d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
3532a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    case Calibration::SIZE_CALIBRATION_GEOMETRIC:
3533a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        dump.append(INDENT4 "touch.size.calibration: geometric\n");
35348d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
3535a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    case Calibration::SIZE_CALIBRATION_DIAMETER:
3536a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        dump.append(INDENT4 "touch.size.calibration: diameter\n");
3537c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        break;
3538037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown    case Calibration::SIZE_CALIBRATION_BOX:
3539037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown        dump.append(INDENT4 "touch.size.calibration: box\n");
3540037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown        break;
3541a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    case Calibration::SIZE_CALIBRATION_AREA:
3542a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        dump.append(INDENT4 "touch.size.calibration: area\n");
35438d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
35448d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    default:
3545ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block        ALOG_ASSERT(false);
35468d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
35478d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
3548a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    if (mCalibration.haveSizeScale) {
3549a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        dump.appendFormat(INDENT4 "touch.size.scale: %0.3f\n",
3550a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                mCalibration.sizeScale);
35518d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
35528d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
3553a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    if (mCalibration.haveSizeBias) {
3554a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        dump.appendFormat(INDENT4 "touch.size.bias: %0.3f\n",
3555a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                mCalibration.sizeBias);
35568d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
35578d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
3558a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown    if (mCalibration.haveSizeIsSummed) {
3559a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        dump.appendFormat(INDENT4 "touch.size.isSummed: %s\n",
3560a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                toString(mCalibration.sizeIsSummed));
35618d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
35628d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
35638d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    // Pressure
35648d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    switch (mCalibration.pressureCalibration) {
35658d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::PRESSURE_CALIBRATION_NONE:
3566ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT4 "touch.pressure.calibration: none\n");
35678d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
35688d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
3569ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT4 "touch.pressure.calibration: physical\n");
35708d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
35718d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
3572ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT4 "touch.pressure.calibration: amplitude\n");
35738d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
35748d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    default:
3575ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block        ALOG_ASSERT(false);
35768d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
35778d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
35788d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    if (mCalibration.havePressureScale) {
3579ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.appendFormat(INDENT4 "touch.pressure.scale: %0.3f\n",
3580ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown                mCalibration.pressureScale);
35818d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
35828d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
35838d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    // Orientation
35848d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    switch (mCalibration.orientationCalibration) {
35858d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::ORIENTATION_CALIBRATION_NONE:
3586ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT4 "touch.orientation.calibration: none\n");
35878d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
35888d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
3589ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT4 "touch.orientation.calibration: interpolated\n");
35908d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
3591517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown    case Calibration::ORIENTATION_CALIBRATION_VECTOR:
3592517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown        dump.append(INDENT4 "touch.orientation.calibration: vector\n");
3593517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown        break;
35948d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    default:
3595ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block        ALOG_ASSERT(false);
35968d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
359780fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
359880fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    // Distance
359980fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    switch (mCalibration.distanceCalibration) {
360080fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    case Calibration::DISTANCE_CALIBRATION_NONE:
360180fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        dump.append(INDENT4 "touch.distance.calibration: none\n");
360280fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        break;
360380fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    case Calibration::DISTANCE_CALIBRATION_SCALED:
360480fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        dump.append(INDENT4 "touch.distance.calibration: scaled\n");
360580fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        break;
360680fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    default:
3607ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block        ALOG_ASSERT(false);
360880fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    }
360980fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
361080fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    if (mCalibration.haveDistanceScale) {
361180fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        dump.appendFormat(INDENT4 "touch.distance.scale: %0.3f\n",
361280fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                mCalibration.distanceScale);
361380fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    }
36145e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright
36155e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright    switch (mCalibration.coverageCalibration) {
36165e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright    case Calibration::COVERAGE_CALIBRATION_NONE:
36175e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright        dump.append(INDENT4 "touch.coverage.calibration: none\n");
36185e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright        break;
36195e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright    case Calibration::COVERAGE_CALIBRATION_BOX:
36205e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright        dump.append(INDENT4 "touch.coverage.calibration: box\n");
36215e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright        break;
36225e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright    default:
36235e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright        ALOG_ASSERT(false);
36245e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright    }
36258d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown}
36268d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
362765fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::reset(nsecs_t when) {
362865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCursorButtonAccumulator.reset(getDevice());
362965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCursorScrollAccumulator.reset(getDevice());
363065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mTouchButtonAccumulator.reset(getDevice());
363165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
363265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerVelocityControl.reset();
363365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mWheelXVelocityControl.reset();
363465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mWheelYVelocityControl.reset();
363565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
3636be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mCurrentRawPointerData.clear();
363765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mLastRawPointerData.clear();
363865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentCookedPointerData.clear();
363965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mLastCookedPointerData.clear();
3640be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mCurrentButtonState = 0;
364165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mLastButtonState = 0;
364265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentRawVScroll = 0;
364365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentRawHScroll = 0;
364465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentFingerIdBits.clear();
364565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mLastFingerIdBits.clear();
364665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentStylusIdBits.clear();
364765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mLastStylusIdBits.clear();
364865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentMouseIdBits.clear();
364965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mLastMouseIdBits.clear();
365065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerUsage = POINTER_USAGE_NONE;
365165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mSentHoverEnter = false;
365265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mDownTime = 0;
36536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
365465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentVirtualKey.down = false;
365565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
365665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerGesture.reset();
365765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerSimple.reset();
36582352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
365965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mPointerController != NULL) {
3660be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
3661be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mPointerController->clearSpots();
3662be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
36636d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
366465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    InputMapper::reset(when);
36656d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
36660b72e82c5f5d4ab709539c3490d6c7023f680dffJeff Brown
366765fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::process(const RawEvent* rawEvent) {
366865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCursorButtonAccumulator.process(rawEvent);
366965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCursorScrollAccumulator.process(rawEvent);
367065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mTouchButtonAccumulator.process(rawEvent);
367165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
367249ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown    if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
367365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        sync(rawEvent->when);
367465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
367565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
367665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
367765fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::sync(nsecs_t when) {
367865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Sync button state.
367965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentButtonState = mTouchButtonAccumulator.getButtonState()
368065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            | mCursorButtonAccumulator.getButtonState();
368165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
368265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Sync scroll state.
368365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentRawVScroll = mCursorScrollAccumulator.getRelativeVWheel();
368465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentRawHScroll = mCursorScrollAccumulator.getRelativeHWheel();
368565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCursorScrollAccumulator.finishSync();
368665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
368765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Sync touch state.
368865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    bool havePointerIds = true;
368965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentRawPointerData.clear();
369065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    syncTouch(when, &havePointerIds);
369165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
3692aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown#if DEBUG_RAW_EVENTS
3693aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown    if (!havePointerIds) {
36945baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("syncTouch: pointerCount %d -> %d, no pointer ids",
3695be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mLastRawPointerData.pointerCount,
3696be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentRawPointerData.pointerCount);
3697aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown    } else {
36985baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("syncTouch: pointerCount %d -> %d, touching ids 0x%08x -> 0x%08x, "
3699be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                "hovering ids 0x%08x -> 0x%08x",
3700be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mLastRawPointerData.pointerCount,
3701be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentRawPointerData.pointerCount,
3702be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mLastRawPointerData.touchingIdBits.value,
3703be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentRawPointerData.touchingIdBits.value,
3704be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mLastRawPointerData.hoveringIdBits.value,
3705be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentRawPointerData.hoveringIdBits.value);
3706aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown    }
3707aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown#endif
3708aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown
370965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Reset state that we will compute below.
371065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentFingerIdBits.clear();
371165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentStylusIdBits.clear();
371265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentMouseIdBits.clear();
371365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentCookedPointerData.clear();
3714be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
371565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mDeviceMode == DEVICE_MODE_DISABLED) {
371665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Drop all input if the device is disabled.
371765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mCurrentRawPointerData.clear();
371865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mCurrentButtonState = 0;
371965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    } else {
372065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Preprocess pointer data.
372165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (!havePointerIds) {
372265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            assignPointerIds();
372365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
372446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
372565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Handle policy on initial down or hover events.
372665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        uint32_t policyFlags = 0;
3727c28306ad4ac9ce7a7d5f10c2e38d422ffc309a1fJeff Brown        bool initialDown = mLastRawPointerData.pointerCount == 0
3728c28306ad4ac9ce7a7d5f10c2e38d422ffc309a1fJeff Brown                && mCurrentRawPointerData.pointerCount != 0;
3729c28306ad4ac9ce7a7d5f10c2e38d422ffc309a1fJeff Brown        bool buttonsPressed = mCurrentButtonState & ~mLastButtonState;
3730c28306ad4ac9ce7a7d5f10c2e38d422ffc309a1fJeff Brown        if (initialDown || buttonsPressed) {
3731c28306ad4ac9ce7a7d5f10c2e38d422ffc309a1fJeff Brown            // If this is a touch screen, hide the pointer on an initial down.
373265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            if (mDeviceMode == DEVICE_MODE_DIRECT) {
373365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                getContext()->fadePointer();
373465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            }
373565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
373665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            // Initial downs on external touch devices should wake the device.
373765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            // We don't do this for internal touch screens to prevent them from waking
373865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            // up in your pocket.
373965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            // TODO: Use the input device configuration to control this behavior more finely.
374065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            if (getDevice()->isExternal()) {
374165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                policyFlags |= POLICY_FLAG_WAKE_DROPPED;
374265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            }
3743efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown        }
374456194ebec6212e229f4ccdaa4b187166d20013efJeff Brown
374565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Synthesize key down from raw buttons if needed.
374665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mSource,
374765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                policyFlags, mLastButtonState, mCurrentButtonState);
374865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
374965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Consume raw off-screen touches before cooking pointer data.
375065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // If touches are consumed, subsequent code will not receive any pointer data.
375165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (consumeRawTouches(when, policyFlags)) {
375265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mCurrentRawPointerData.clear();
375356194ebec6212e229f4ccdaa4b187166d20013efJeff Brown        }
375446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
375565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Cook pointer data.  This call populates the mCurrentCookedPointerData structure
375665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // with cooked pointer data that has the same ids and indices as the raw data.
375765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // The following code can use either the raw or cooked data, as needed.
375865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        cookPointerData();
3759be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
376065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Dispatch the touches either directly or by translation through a pointer on screen.
3761daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown        if (mDeviceMode == DEVICE_MODE_POINTER) {
376265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            for (BitSet32 idBits(mCurrentRawPointerData.touchingIdBits); !idBits.isEmpty(); ) {
376365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                uint32_t id = idBits.clearFirstMarkedBit();
376465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
376565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS
376665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                        || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_ERASER) {
376765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    mCurrentStylusIdBits.markBit(id);
376865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                } else if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_FINGER
376965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                        || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
377065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    mCurrentFingerIdBits.markBit(id);
377165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                } else if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_MOUSE) {
377265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    mCurrentMouseIdBits.markBit(id);
377365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                }
377465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            }
377565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            for (BitSet32 idBits(mCurrentRawPointerData.hoveringIdBits); !idBits.isEmpty(); ) {
377665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                uint32_t id = idBits.clearFirstMarkedBit();
377765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
377865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS
377965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                        || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_ERASER) {
378065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    mCurrentStylusIdBits.markBit(id);
378165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                }
378265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            }
378346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
378465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            // Stylus takes precedence over all tools, then mouse, then finger.
378565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            PointerUsage pointerUsage = mPointerUsage;
378665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            if (!mCurrentStylusIdBits.isEmpty()) {
378765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mCurrentMouseIdBits.clear();
378865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mCurrentFingerIdBits.clear();
378965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                pointerUsage = POINTER_USAGE_STYLUS;
379065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            } else if (!mCurrentMouseIdBits.isEmpty()) {
379165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mCurrentFingerIdBits.clear();
379265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                pointerUsage = POINTER_USAGE_MOUSE;
379365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            } else if (!mCurrentFingerIdBits.isEmpty() || isPointerDown(mCurrentButtonState)) {
379465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                pointerUsage = POINTER_USAGE_GESTURES;
379565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            }
3796be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
379765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            dispatchPointerUsage(when, policyFlags, pointerUsage);
379865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        } else {
3799daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown            if (mDeviceMode == DEVICE_MODE_DIRECT
3800daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown                    && mConfig.showTouches && mPointerController != NULL) {
3801daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown                mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_SPOT);
3802daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown                mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
3803daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown
3804daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown                mPointerController->setButtonState(mCurrentButtonState);
3805daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown                mPointerController->setSpots(mCurrentCookedPointerData.pointerCoords,
3806daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown                        mCurrentCookedPointerData.idToIndex,
3807daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown                        mCurrentCookedPointerData.touchingIdBits);
3808daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown            }
3809daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown
381065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            dispatchHoverExit(when, policyFlags);
381165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            dispatchTouches(when, policyFlags);
381265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            dispatchHoverEnterAndMove(when, policyFlags);
381365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
3814be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
381565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Synthesize key up from raw buttons if needed.
381665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mSource,
381765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                policyFlags, mLastButtonState, mCurrentButtonState);
381865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
3819fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
38206328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    // Copy current touch to last touch in preparation for the next cycle.
3821be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mLastRawPointerData.copyFrom(mCurrentRawPointerData);
3822be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mLastCookedPointerData.copyFrom(mCurrentCookedPointerData);
3823be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mLastButtonState = mCurrentButtonState;
382465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mLastFingerIdBits = mCurrentFingerIdBits;
382565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mLastStylusIdBits = mCurrentStylusIdBits;
382665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mLastMouseIdBits = mCurrentMouseIdBits;
382765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
382865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Clear some transient state.
382965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentRawVScroll = 0;
383065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mCurrentRawHScroll = 0;
38319c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown}
38329c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
383379ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brownvoid TouchInputMapper::timeoutExpired(nsecs_t when) {
3834daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown    if (mDeviceMode == DEVICE_MODE_POINTER) {
383565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mPointerUsage == POINTER_USAGE_GESTURES) {
383665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            dispatchPointerGestures(when, 0 /*policyFlags*/, true /*isTimeout*/);
383765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
383879ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown    }
383979ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown}
384079ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown
3841be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownbool TouchInputMapper::consumeRawTouches(nsecs_t when, uint32_t policyFlags) {
3842be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // Check for release of a virtual key.
3843be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (mCurrentVirtualKey.down) {
3844be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (mCurrentRawPointerData.touchingIdBits.isEmpty()) {
3845be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            // Pointer went up while virtual key was down.
3846be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mCurrentVirtualKey.down = false;
3847be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (!mCurrentVirtualKey.ignored) {
38486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_VIRTUAL_KEYS
38495baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
3850be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
38516d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
3852be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                dispatchVirtualKey(when, policyFlags,
3853be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        AKEY_EVENT_ACTION_UP,
3854be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
38556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
3856be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            return true;
3857be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
38586d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
3859be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (mCurrentRawPointerData.touchingIdBits.count() == 1) {
3860be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t id = mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
3861be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
3862be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
3863be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (virtualKey && virtualKey->keyCode == mCurrentVirtualKey.keyCode) {
3864be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                // Pointer is still within the space of the virtual key.
3865be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                return true;
38666d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
3867be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
38686d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
3869be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        // Pointer left virtual key area or another pointer also went down.
3870be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        // Send key cancellation but do not consume the touch yet.
3871be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        // This is useful when the user swipes through from the virtual key area
3872be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        // into the main display surface.
3873be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mCurrentVirtualKey.down = false;
3874be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (!mCurrentVirtualKey.ignored) {
38756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_VIRTUAL_KEYS
38765baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
3877be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
38786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
3879be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            dispatchVirtualKey(when, policyFlags,
3880be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    AKEY_EVENT_ACTION_UP,
3881be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
3882be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            | AKEY_EVENT_FLAG_CANCELED);
3883be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
3884be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
3885be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
3886be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (mLastRawPointerData.touchingIdBits.isEmpty()
3887be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            && !mCurrentRawPointerData.touchingIdBits.isEmpty()) {
3888be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        // Pointer just went down.  Check for virtual key press or off-screen touches.
3889be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        uint32_t id = mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
3890be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
3891be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (!isPointInsideSurface(pointer.x, pointer.y)) {
3892be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            // If exactly one pointer went down, check for virtual key hit.
3893be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            // Otherwise we will drop the entire stroke.
3894be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (mCurrentRawPointerData.touchingIdBits.count() == 1) {
3895be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
3896be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                if (virtualKey) {
3897be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentVirtualKey.down = true;
3898be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentVirtualKey.downTime = when;
3899be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentVirtualKey.keyCode = virtualKey->keyCode;
3900be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentVirtualKey.scanCode = virtualKey->scanCode;
3901be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentVirtualKey.ignored = mContext->shouldDropVirtualKey(
3902be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            when, getDevice(), virtualKey->keyCode, virtualKey->scanCode);
3903be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
3904be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    if (!mCurrentVirtualKey.ignored) {
39056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_VIRTUAL_KEYS
39065baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                        ALOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
3907be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                mCurrentVirtualKey.keyCode,
3908be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                mCurrentVirtualKey.scanCode);
39096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
3910be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        dispatchVirtualKey(when, policyFlags,
3911be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                AKEY_EVENT_ACTION_DOWN,
3912be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
39136d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    }
39146d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
391546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            }
3916be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            return true;
391746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
3918be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
39196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
3920fe50892af3b365806a767298dfd8e86447682581Jeff Brown    // Disable all virtual key touches that happen within a short time interval of the
3921be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // most recent touch within the screen area.  The idea is to filter out stray
3922be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // virtual key presses when interacting with the touch screen.
3923fe50892af3b365806a767298dfd8e86447682581Jeff Brown    //
3924fe50892af3b365806a767298dfd8e86447682581Jeff Brown    // Problems we're trying to solve:
3925fe50892af3b365806a767298dfd8e86447682581Jeff Brown    //
3926fe50892af3b365806a767298dfd8e86447682581Jeff Brown    // 1. While scrolling a list or dragging the window shade, the user swipes down into a
3927fe50892af3b365806a767298dfd8e86447682581Jeff Brown    //    virtual key area that is implemented by a separate touch panel and accidentally
3928fe50892af3b365806a767298dfd8e86447682581Jeff Brown    //    triggers a virtual key.
3929fe50892af3b365806a767298dfd8e86447682581Jeff Brown    //
3930fe50892af3b365806a767298dfd8e86447682581Jeff Brown    // 2. While typing in the on screen keyboard, the user taps slightly outside the screen
3931fe50892af3b365806a767298dfd8e86447682581Jeff Brown    //    area and accidentally triggers a virtual key.  This often happens when virtual keys
3932fe50892af3b365806a767298dfd8e86447682581Jeff Brown    //    are layed out below the screen near to where the on screen keyboard's space bar
3933fe50892af3b365806a767298dfd8e86447682581Jeff Brown    //    is displayed.
3934be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (mConfig.virtualKeyQuietTime > 0 && !mCurrentRawPointerData.touchingIdBits.isEmpty()) {
3935474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        mContext->disableVirtualKeysUntil(when + mConfig.virtualKeyQuietTime);
3936fe50892af3b365806a767298dfd8e86447682581Jeff Brown    }
3937be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return false;
3938fe50892af3b365806a767298dfd8e86447682581Jeff Brown}
3939fe50892af3b365806a767298dfd8e86447682581Jeff Brown
3940be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid TouchInputMapper::dispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
3941be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        int32_t keyEventAction, int32_t keyEventFlags) {
3942be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t keyCode = mCurrentVirtualKey.keyCode;
3943be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t scanCode = mCurrentVirtualKey.scanCode;
3944be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    nsecs_t downTime = mCurrentVirtualKey.downTime;
3945be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t metaState = mContext->getGlobalMetaState();
3946be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    policyFlags |= POLICY_FLAG_VIRTUAL;
39476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
3948be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    NotifyKeyArgs args(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
3949be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
3950be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getListener()->notifyKey(&args);
3951be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
3952ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
3953be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
3954be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    BitSet32 currentIdBits = mCurrentCookedPointerData.touchingIdBits;
3955be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    BitSet32 lastIdBits = mLastCookedPointerData.touchingIdBits;
3956fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    int32_t metaState = getContext()->getGlobalMetaState();
3957be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t buttonState = mCurrentButtonState;
395846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
39596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (currentIdBits == lastIdBits) {
3960be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (!currentIdBits.isEmpty()) {
3961be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            // No pointer id changes so this is a move event.
3962be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            // The listener takes care of batching moves so we don't have to deal with that here.
396365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            dispatchMotion(when, policyFlags, mSource,
3964be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState,
3965be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    AMOTION_EVENT_EDGE_FLAG_NONE,
3966be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.pointerProperties,
3967be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.pointerCoords,
3968be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.idToIndex,
3969be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    currentIdBits, -1,
3970be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
3971be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
39726d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    } else {
3973c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        // There may be pointers going up and pointers going down and pointers moving
3974c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        // all at the same time.
3975ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        BitSet32 upIdBits(lastIdBits.value & ~currentIdBits.value);
3976ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        BitSet32 downIdBits(currentIdBits.value & ~lastIdBits.value);
3977c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        BitSet32 moveIdBits(lastIdBits.value & currentIdBits.value);
3978ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        BitSet32 dispatchedIdBits(lastIdBits.value);
3979c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown
3980ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Update last coordinates of pointers that have moved so that we observe the new
3981ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // pointer positions at the same time as other pointers that have just gone up.
3982fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        bool moveNeeded = updateMovedPointers(
3983be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentCookedPointerData.pointerProperties,
3984be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentCookedPointerData.pointerCoords,
3985be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentCookedPointerData.idToIndex,
3986be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mLastCookedPointerData.pointerProperties,
3987be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mLastCookedPointerData.pointerCoords,
3988be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mLastCookedPointerData.idToIndex,
3989ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                moveIdBits);
3990be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (buttonState != mLastButtonState) {
3991fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            moveNeeded = true;
3992fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        }
3993c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown
3994ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Dispatch pointer up events.
3995c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        while (!upIdBits.isEmpty()) {
3996be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t upId = upIdBits.clearFirstMarkedBit();
39976d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
399865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            dispatchMotion(when, policyFlags, mSource,
3999fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    AMOTION_EVENT_ACTION_POINTER_UP, 0, metaState, buttonState, 0,
4000be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mLastCookedPointerData.pointerProperties,
4001be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mLastCookedPointerData.pointerCoords,
4002be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mLastCookedPointerData.idToIndex,
4003be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    dispatchedIdBits, upId,
4004be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
4005ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            dispatchedIdBits.clearBit(upId);
400646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
400746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4008c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        // Dispatch move events if any of the remaining pointers moved from their old locations.
4009c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        // Although applications receive new locations as part of individual pointer up
4010c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        // events, they do not generally handle them except when presented in a move event.
4011c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        if (moveNeeded) {
4012ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block            ALOG_ASSERT(moveIdBits.value == dispatchedIdBits.value);
401365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            dispatchMotion(when, policyFlags, mSource,
4014fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, 0,
4015be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.pointerProperties,
4016be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.pointerCoords,
4017be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.idToIndex,
4018be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    dispatchedIdBits, -1,
4019be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
4020c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        }
4021c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown
4022c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        // Dispatch pointer down events using the new pointer locations.
4023c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        while (!downIdBits.isEmpty()) {
4024be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t downId = downIdBits.clearFirstMarkedBit();
4025ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            dispatchedIdBits.markBit(downId);
40266d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
4027ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            if (dispatchedIdBits.count() == 1) {
4028ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                // First pointer is going down.  Set down time.
40296d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                mDownTime = when;
40306d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
403146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
403265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            dispatchMotion(when, policyFlags, mSource,
4033a6111377e1edbc5d63fc2a7205d58b2d9c21d978Jeff Brown                    AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, 0,
4034be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.pointerProperties,
4035be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.pointerCoords,
4036be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.idToIndex,
4037be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    dispatchedIdBits, downId,
4038be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
40396d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
40406d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
4041be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
404246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4043be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid TouchInputMapper::dispatchHoverExit(nsecs_t when, uint32_t policyFlags) {
4044be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (mSentHoverEnter &&
4045be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            (mCurrentCookedPointerData.hoveringIdBits.isEmpty()
4046be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    || !mCurrentCookedPointerData.touchingIdBits.isEmpty())) {
4047be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        int32_t metaState = getContext()->getGlobalMetaState();
404865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        dispatchMotion(when, policyFlags, mSource,
4049be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                AMOTION_EVENT_ACTION_HOVER_EXIT, 0, metaState, mLastButtonState, 0,
4050be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mLastCookedPointerData.pointerProperties,
4051be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mLastCookedPointerData.pointerCoords,
4052be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mLastCookedPointerData.idToIndex,
4053be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mLastCookedPointerData.hoveringIdBits, -1,
4054be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mOrientedXPrecision, mOrientedYPrecision, mDownTime);
4055be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mSentHoverEnter = false;
4056be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
4057be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown}
4058be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
4059be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid TouchInputMapper::dispatchHoverEnterAndMove(nsecs_t when, uint32_t policyFlags) {
4060be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (mCurrentCookedPointerData.touchingIdBits.isEmpty()
4061be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            && !mCurrentCookedPointerData.hoveringIdBits.isEmpty()) {
4062be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        int32_t metaState = getContext()->getGlobalMetaState();
4063be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (!mSentHoverEnter) {
406465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            dispatchMotion(when, policyFlags, mSource,
4065be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    AMOTION_EVENT_ACTION_HOVER_ENTER, 0, metaState, mCurrentButtonState, 0,
4066be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.pointerProperties,
4067be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.pointerCoords,
4068be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.idToIndex,
4069be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentCookedPointerData.hoveringIdBits, -1,
4070be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
4071be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mSentHoverEnter = true;
4072be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        }
4073be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
407465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        dispatchMotion(when, policyFlags, mSource,
4075be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                AMOTION_EVENT_ACTION_HOVER_MOVE, 0, metaState, mCurrentButtonState, 0,
4076be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentCookedPointerData.pointerProperties,
4077be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentCookedPointerData.pointerCoords,
4078be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentCookedPointerData.idToIndex,
4079be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentCookedPointerData.hoveringIdBits, -1,
4080be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mOrientedXPrecision, mOrientedYPrecision, mDownTime);
4081ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
4082ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown}
40836328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
4084be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid TouchInputMapper::cookPointerData() {
4085be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    uint32_t currentPointerCount = mCurrentRawPointerData.pointerCount;
40866328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
4087be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mCurrentCookedPointerData.clear();
4088be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mCurrentCookedPointerData.pointerCount = currentPointerCount;
4089be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mCurrentCookedPointerData.hoveringIdBits = mCurrentRawPointerData.hoveringIdBits;
4090be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mCurrentCookedPointerData.touchingIdBits = mCurrentRawPointerData.touchingIdBits;
40918d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
4092be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // Walk through the the active pointers and map device coordinates onto
4093be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // surface coordinates and adjust for display orientation.
4094ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    for (uint32_t i = 0; i < currentPointerCount; i++) {
4095be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        const RawPointerData::Pointer& in = mCurrentRawPointerData.pointers[i];
40968d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
4097a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        // Size
4098a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        float touchMajor, touchMinor, toolMajor, toolMinor, size;
4099a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        switch (mCalibration.sizeCalibration) {
4100a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        case Calibration::SIZE_CALIBRATION_GEOMETRIC:
4101a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        case Calibration::SIZE_CALIBRATION_DIAMETER:
4102037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown        case Calibration::SIZE_CALIBRATION_BOX:
4103a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown        case Calibration::SIZE_CALIBRATION_AREA:
4104a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            if (mRawPointerAxes.touchMajor.valid && mRawPointerAxes.toolMajor.valid) {
4105a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                touchMajor = in.touchMajor;
4106a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                touchMinor = mRawPointerAxes.touchMinor.valid ? in.touchMinor : in.touchMajor;
4107a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                toolMajor = in.toolMajor;
4108a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                toolMinor = mRawPointerAxes.toolMinor.valid ? in.toolMinor : in.toolMajor;
4109a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                size = mRawPointerAxes.touchMinor.valid
4110a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                        ? avg(in.touchMajor, in.touchMinor) : in.touchMajor;
4111a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            } else if (mRawPointerAxes.touchMajor.valid) {
4112a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                toolMajor = touchMajor = in.touchMajor;
4113a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                toolMinor = touchMinor = mRawPointerAxes.touchMinor.valid
4114a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                        ? in.touchMinor : in.touchMajor;
4115a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                size = mRawPointerAxes.touchMinor.valid
4116a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                        ? avg(in.touchMajor, in.touchMinor) : in.touchMajor;
4117a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            } else if (mRawPointerAxes.toolMajor.valid) {
4118a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                touchMajor = toolMajor = in.toolMajor;
4119a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                touchMinor = toolMinor = mRawPointerAxes.toolMinor.valid
4120a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                        ? in.toolMinor : in.toolMajor;
4121a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                size = mRawPointerAxes.toolMinor.valid
4122a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                        ? avg(in.toolMajor, in.toolMinor) : in.toolMajor;
4123ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            } else {
4124ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block                ALOG_ASSERT(false, "No touch or tool axes.  "
4125a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                        "Size calibration should have been resolved to NONE.");
4126a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                touchMajor = 0;
4127a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                touchMinor = 0;
4128a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                toolMajor = 0;
4129a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                toolMinor = 0;
4130a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                size = 0;
4131ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            }
4132a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown
4133a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            if (mCalibration.haveSizeIsSummed && mCalibration.sizeIsSummed) {
4134a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                uint32_t touchingCount = mCurrentRawPointerData.touchingIdBits.count();
4135a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                if (touchingCount > 1) {
4136a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                    touchMajor /= touchingCount;
4137a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                    touchMinor /= touchingCount;
4138a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                    toolMajor /= touchingCount;
4139a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                    toolMinor /= touchingCount;
4140a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                    size /= touchingCount;
4141a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                }
4142ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            }
4143a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown
4144a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_GEOMETRIC) {
4145a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                touchMajor *= mGeometricScale;
4146a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                touchMinor *= mGeometricScale;
4147a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                toolMajor *= mGeometricScale;
4148a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                toolMinor *= mGeometricScale;
4149a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            } else if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_AREA) {
4150a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                touchMajor = touchMajor > 0 ? sqrtf(touchMajor) : 0;
4151a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                touchMinor = touchMajor;
4152a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                toolMajor = toolMajor > 0 ? sqrtf(toolMajor) : 0;
4153a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                toolMinor = toolMajor;
4154a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            } else if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_DIAMETER) {
4155a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                touchMinor = touchMajor;
4156a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown                toolMinor = toolMajor;
41578d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
4158a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown
4159a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mCalibration.applySizeScaleAndBias(&touchMajor);
4160a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mCalibration.applySizeScaleAndBias(&touchMinor);
4161a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mCalibration.applySizeScaleAndBias(&toolMajor);
4162a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            mCalibration.applySizeScaleAndBias(&toolMinor);
4163a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            size *= mSizeScale;
4164ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            break;
4165ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        default:
4166a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            touchMajor = 0;
4167a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            touchMinor = 0;
4168ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            toolMajor = 0;
4169ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            toolMinor = 0;
4170a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            size = 0;
4171ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            break;
4172ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
4173ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4174ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Pressure
4175ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        float pressure;
4176ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        switch (mCalibration.pressureCalibration) {
4177ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
4178ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
4179a1f89ceec076392da409e9f389b33e62e1d92da6Jeff Brown            pressure = in.pressure * mPressureScale;
4180ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            break;
4181ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        default:
4182be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            pressure = in.isHovering ? 0 : 1;
4183ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            break;
4184ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
4185ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
418665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Tilt and Orientation
418765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        float tilt;
4188ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        float orientation;
418965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mHaveTilt) {
419065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            float tiltXAngle = (in.tiltX - mTiltXCenter) * mTiltXScale;
419165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            float tiltYAngle = (in.tiltY - mTiltYCenter) * mTiltYScale;
419265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            orientation = atan2f(-sinf(tiltXAngle), sinf(tiltYAngle));
419365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            tilt = acosf(cosf(tiltXAngle) * cosf(tiltYAngle));
419465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        } else {
419565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            tilt = 0;
419665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
419765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            switch (mCalibration.orientationCalibration) {
419865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
4199037f727f49ddf4f5575f6440799261bd1289eb6eJeff Brown                orientation = in.orientation * mOrientationScale;
420065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                break;
420165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            case Calibration::ORIENTATION_CALIBRATION_VECTOR: {
420265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                int32_t c1 = signExtendNybble((in.orientation & 0xf0) >> 4);
420365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                int32_t c2 = signExtendNybble(in.orientation & 0x0f);
420465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                if (c1 != 0 || c2 != 0) {
420565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    orientation = atan2f(c1, c2) * 0.5f;
420665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    float confidence = hypotf(c1, c2);
420765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    float scale = 1.0f + confidence / 16.0f;
420865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    touchMajor *= scale;
420965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    touchMinor /= scale;
421065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    toolMajor *= scale;
421165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    toolMinor /= scale;
421265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                } else {
421365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    orientation = 0;
421465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                }
421565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                break;
421665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            }
421765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            default:
4218ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                orientation = 0;
42198d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
4220ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
42218d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
422280fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        // Distance
422380fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        float distance;
422480fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        switch (mCalibration.distanceCalibration) {
422580fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        case Calibration::DISTANCE_CALIBRATION_SCALED:
4226be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            distance = in.distance * mDistanceScale;
422780fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            break;
422880fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        default:
422980fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            distance = 0;
423080fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        }
423180fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
42325e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright        // Coverage
42335e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright        int32_t rawLeft, rawTop, rawRight, rawBottom;
42345e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright        switch (mCalibration.coverageCalibration) {
42355e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright        case Calibration::COVERAGE_CALIBRATION_BOX:
42365e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            rawLeft = (in.toolMinor & 0xffff0000) >> 16;
42375e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            rawRight = in.toolMinor & 0x0000ffff;
42385e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            rawBottom = in.toolMajor & 0x0000ffff;
42395e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            rawTop = (in.toolMajor & 0xffff0000) >> 16;
42405e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            break;
42415e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright        default:
42425e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            rawLeft = rawTop = rawRight = rawBottom = 0;
42435e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            break;
42445e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright        }
42455e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright
42465e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright        // X, Y, and the bounding box for coverage information
4247ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Adjust coords for surface orientation.
42485e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright        float x, y, left, top, right, bottom;
4249be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        switch (mSurfaceOrientation) {
4250ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        case DISPLAY_ORIENTATION_90:
425183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            x = float(in.y - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
425283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            y = float(mRawPointerAxes.x.maxValue - in.x) * mXScale + mXTranslate;
42535e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            left = float(rawTop - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
42545e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            right = float(rawBottom- mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
42555e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            bottom = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
42565e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            top = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale + mXTranslate;
4257ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            orientation -= M_PI_2;
425870bca4cc8a37c34ec5cdb0405b2e7e2c2779630dJason Gerecke            if (orientation < mOrientedRanges.orientation.min) {
425970bca4cc8a37c34ec5cdb0405b2e7e2c2779630dJason Gerecke                orientation += (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
4260ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            }
4261ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            break;
4262ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        case DISPLAY_ORIENTATION_180:
426383d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            x = float(mRawPointerAxes.x.maxValue - in.x) * mXScale + mXTranslate;
426483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            y = float(mRawPointerAxes.y.maxValue - in.y) * mYScale + mYTranslate;
42655e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            left = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale + mXTranslate;
42665e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            right = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
42675e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            bottom = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
42685e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            top = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale + mYTranslate;
426970bca4cc8a37c34ec5cdb0405b2e7e2c2779630dJason Gerecke            orientation -= M_PI;
427070bca4cc8a37c34ec5cdb0405b2e7e2c2779630dJason Gerecke            if (orientation < mOrientedRanges.orientation.min) {
427170bca4cc8a37c34ec5cdb0405b2e7e2c2779630dJason Gerecke                orientation += (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
427270bca4cc8a37c34ec5cdb0405b2e7e2c2779630dJason Gerecke            }
4273ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            break;
4274ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        case DISPLAY_ORIENTATION_270:
427583d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            x = float(mRawPointerAxes.y.maxValue - in.y) * mYScale + mYTranslate;
427683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            y = float(in.x - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
42775e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            left = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale + mYTranslate;
42785e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            right = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
42795e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            bottom = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
42805e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            top = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
4281ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            orientation += M_PI_2;
428270bca4cc8a37c34ec5cdb0405b2e7e2c2779630dJason Gerecke            if (orientation > mOrientedRanges.orientation.max) {
428370bca4cc8a37c34ec5cdb0405b2e7e2c2779630dJason Gerecke                orientation -= (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
42848d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
4285ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            break;
4286ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        default:
428783d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            x = float(in.x - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
428883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            y = float(in.y - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
42895e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            left = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
42905e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            right = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
42915e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            bottom = float(rawBottom - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
42925e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            top = float(rawTop - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
4293ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            break;
4294ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
42958d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
4296ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Write output coords.
4297be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        PointerCoords& out = mCurrentCookedPointerData.pointerCoords[i];
4298ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        out.clear();
4299ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        out.setAxisValue(AMOTION_EVENT_AXIS_X, x);
4300ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        out.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
4301ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        out.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure);
4302ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        out.setAxisValue(AMOTION_EVENT_AXIS_SIZE, size);
4303ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, touchMajor);
4304ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, touchMinor);
4305ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, orientation);
430665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        out.setAxisValue(AMOTION_EVENT_AXIS_TILT, tilt);
4307be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        out.setAxisValue(AMOTION_EVENT_AXIS_DISTANCE, distance);
43085e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright        if (mCalibration.coverageCalibration == Calibration::COVERAGE_CALIBRATION_BOX) {
43095e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_1, left);
43105e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_2, top);
43115e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_3, right);
43125e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_4, bottom);
43135e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright        } else {
43145e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, toolMajor);
43155e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright            out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, toolMinor);
43165e025eb1dc151a158d2fd7b12bb3a1c891b25d81Michael Wright        }
4317fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
4318fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        // Write output properties.
4319be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        PointerProperties& properties = mCurrentCookedPointerData.pointerProperties[i];
4320be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        uint32_t id = in.id;
4321fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        properties.clear();
4322be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        properties.id = id;
4323be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        properties.toolType = in.toolType;
4324ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4325be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        // Write id index.
4326be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mCurrentCookedPointerData.idToIndex[id] = i;
4327be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
4328ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown}
4329ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
433065fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::dispatchPointerUsage(nsecs_t when, uint32_t policyFlags,
433165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        PointerUsage pointerUsage) {
433265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (pointerUsage != mPointerUsage) {
433365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        abortPointerUsage(when, policyFlags);
433465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerUsage = pointerUsage;
433565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
433665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
433765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    switch (mPointerUsage) {
433865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    case POINTER_USAGE_GESTURES:
433965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        dispatchPointerGestures(when, policyFlags, false /*isTimeout*/);
434065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        break;
434165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    case POINTER_USAGE_STYLUS:
434265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        dispatchPointerStylus(when, policyFlags);
434365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        break;
434465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    case POINTER_USAGE_MOUSE:
434565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        dispatchPointerMouse(when, policyFlags);
434665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        break;
434765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    default:
434865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        break;
434965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
435065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
435165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
435265fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::abortPointerUsage(nsecs_t when, uint32_t policyFlags) {
435365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    switch (mPointerUsage) {
435465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    case POINTER_USAGE_GESTURES:
435565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        abortPointerGestures(when, policyFlags);
435665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        break;
435765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    case POINTER_USAGE_STYLUS:
435865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        abortPointerStylus(when, policyFlags);
435965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        break;
436065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    case POINTER_USAGE_MOUSE:
436165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        abortPointerMouse(when, policyFlags);
436265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        break;
436365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    default:
436465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        break;
436565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
436665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
436765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerUsage = POINTER_USAGE_NONE;
436865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
436965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
437079ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brownvoid TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlags,
437179ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        bool isTimeout) {
4372ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Update current gesture coordinates.
4373ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    bool cancelPreviousGesture, finishPreviousGesture;
437479ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown    bool sendEvents = preparePointerGestures(when,
437579ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            &cancelPreviousGesture, &finishPreviousGesture, isTimeout);
437679ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown    if (!sendEvents) {
437779ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        return;
437879ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown    }
437919c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown    if (finishPreviousGesture) {
438019c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown        cancelPreviousGesture = false;
438119c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown    }
4382ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4383bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown    // Update the pointer presentation and spots.
4384bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown    if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
4385bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_SPOT);
4386bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        if (finishPreviousGesture || cancelPreviousGesture) {
4387bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            mPointerController->clearSpots();
4388bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        }
4389cb5ffcf0e41d2597401208221c61589547a00f3dJeff Brown        mPointerController->setSpots(mPointerGesture.currentGestureCoords,
4390cb5ffcf0e41d2597401208221c61589547a00f3dJeff Brown                mPointerGesture.currentGestureIdToIndex,
4391cb5ffcf0e41d2597401208221c61589547a00f3dJeff Brown                mPointerGesture.currentGestureIdBits);
4392bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown    } else {
4393bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
4394bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown    }
4395214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown
4396538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    // Show or hide the pointer if needed.
4397538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    switch (mPointerGesture.currentGestureMode) {
4398538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    case PointerGesture::NEUTRAL:
4399538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    case PointerGesture::QUIET:
4400538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS
4401538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown                && (mPointerGesture.lastGestureMode == PointerGesture::SWIPE
4402538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown                        || mPointerGesture.lastGestureMode == PointerGesture::FREEFORM)) {
4403538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown            // Remind the user of where the pointer is after finishing a gesture with spots.
4404538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown            mPointerController->unfade(PointerControllerInterface::TRANSITION_GRADUAL);
4405538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        }
4406538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        break;
4407538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    case PointerGesture::TAP:
4408538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    case PointerGesture::TAP_DRAG:
4409538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    case PointerGesture::BUTTON_CLICK_OR_DRAG:
4410538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    case PointerGesture::HOVER:
4411538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    case PointerGesture::PRESS:
4412538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        // Unfade the pointer when the current gesture manipulates the
4413538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        // area directly under the pointer.
4414538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
4415538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        break;
4416538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    case PointerGesture::SWIPE:
4417538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown    case PointerGesture::FREEFORM:
4418538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        // Fade the pointer when the current gesture manipulates a different
4419538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        // area and there are spots to guide the user experience.
4420538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
4421538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown            mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
4422538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        } else {
4423538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown            mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
4424538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        }
4425538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown        break;
44262352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    }
44272352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
4428ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Send events!
4429fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    int32_t metaState = getContext()->getGlobalMetaState();
4430be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t buttonState = mCurrentButtonState;
4431ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4432ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Update last coordinates of pointers that have moved so that we observe the new
4433ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // pointer positions at the same time as other pointers that have just gone up.
443479ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown    bool down = mPointerGesture.currentGestureMode == PointerGesture::TAP
443579ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            || mPointerGesture.currentGestureMode == PointerGesture::TAP_DRAG
443679ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            || mPointerGesture.currentGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG
44372352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            || mPointerGesture.currentGestureMode == PointerGesture::PRESS
4438ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            || mPointerGesture.currentGestureMode == PointerGesture::SWIPE
4439ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            || mPointerGesture.currentGestureMode == PointerGesture::FREEFORM;
4440ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    bool moveNeeded = false;
4441ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    if (down && !cancelPreviousGesture && !finishPreviousGesture
44422352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            && !mPointerGesture.lastGestureIdBits.isEmpty()
44432352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            && !mPointerGesture.currentGestureIdBits.isEmpty()) {
4444ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        BitSet32 movedGestureIdBits(mPointerGesture.currentGestureIdBits.value
4445ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                & mPointerGesture.lastGestureIdBits.value);
4446fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        moveNeeded = updateMovedPointers(mPointerGesture.currentGestureProperties,
4447ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
4448fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                mPointerGesture.lastGestureProperties,
4449ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
4450ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                movedGestureIdBits);
4451be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (buttonState != mLastButtonState) {
4452fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            moveNeeded = true;
4453fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        }
4454ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
4455ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4456ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Send motion events for all pointers that went up or were canceled.
4457ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    BitSet32 dispatchedGestureIdBits(mPointerGesture.lastGestureIdBits);
4458ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    if (!dispatchedGestureIdBits.isEmpty()) {
4459ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        if (cancelPreviousGesture) {
446065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            dispatchMotion(when, policyFlags, mSource,
4461fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    AMOTION_EVENT_ACTION_CANCEL, 0, metaState, buttonState,
4462fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    AMOTION_EVENT_EDGE_FLAG_NONE,
4463fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    mPointerGesture.lastGestureProperties,
4464ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
4465ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    dispatchedGestureIdBits, -1,
4466ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    0, 0, mPointerGesture.downTime);
4467ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4468ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            dispatchedGestureIdBits.clear();
4469ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        } else {
4470ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            BitSet32 upGestureIdBits;
4471ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            if (finishPreviousGesture) {
4472ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                upGestureIdBits = dispatchedGestureIdBits;
4473ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            } else {
4474ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                upGestureIdBits.value = dispatchedGestureIdBits.value
4475ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                        & ~mPointerGesture.currentGestureIdBits.value;
44768d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
4477ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            while (!upGestureIdBits.isEmpty()) {
4478be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                uint32_t id = upGestureIdBits.clearFirstMarkedBit();
4479ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
448065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                dispatchMotion(when, policyFlags, mSource,
4481ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                        AMOTION_EVENT_ACTION_POINTER_UP, 0,
4482fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                        metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
4483fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                        mPointerGesture.lastGestureProperties,
4484ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                        mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
4485ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                        dispatchedGestureIdBits, id,
4486ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                        0, 0, mPointerGesture.downTime);
4487ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4488ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                dispatchedGestureIdBits.clearBit(id);
4489ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            }
4490ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
4491ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
4492ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4493ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Send motion events for all pointers that moved.
4494ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    if (moveNeeded) {
449565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        dispatchMotion(when, policyFlags, mSource,
4496fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
4497fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                mPointerGesture.currentGestureProperties,
4498ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
4499ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                dispatchedGestureIdBits, -1,
4500ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                0, 0, mPointerGesture.downTime);
4501ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
45028d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
4503ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Send motion events for all pointers that went down.
4504ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    if (down) {
4505ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        BitSet32 downGestureIdBits(mPointerGesture.currentGestureIdBits.value
4506ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                & ~dispatchedGestureIdBits.value);
4507ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        while (!downGestureIdBits.isEmpty()) {
4508be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t id = downGestureIdBits.clearFirstMarkedBit();
4509ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            dispatchedGestureIdBits.markBit(id);
4510ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4511ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            if (dispatchedGestureIdBits.count() == 1) {
4512ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.downTime = when;
45138d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
4514ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
451565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            dispatchMotion(when, policyFlags, mSource,
4516a6111377e1edbc5d63fc2a7205d58b2d9c21d978Jeff Brown                    AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, 0,
4517fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    mPointerGesture.currentGestureProperties,
4518ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
4519ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    dispatchedGestureIdBits, id,
4520ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    0, 0, mPointerGesture.downTime);
4521ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
4522ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
4523ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4524ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Send motion events for hover.
4525ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    if (mPointerGesture.currentGestureMode == PointerGesture::HOVER) {
452665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        dispatchMotion(when, policyFlags, mSource,
4527fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
4528fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
4529fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                mPointerGesture.currentGestureProperties,
4530ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
4531ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.currentGestureIdBits, -1,
4532ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                0, 0, mPointerGesture.downTime);
45338134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    } else if (dispatchedGestureIdBits.isEmpty()
45348134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            && !mPointerGesture.lastGestureIdBits.isEmpty()) {
45358134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        // Synthesize a hover move event after all pointers go up to indicate that
45368134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        // the pointer is hovering again even if the user is not currently touching
45378134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        // the touch pad.  This ensures that a view will receive a fresh hover enter
45388134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        // event after a tap.
45398134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        float x, y;
45408134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        mPointerController->getPosition(&x, &y);
45418134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown
45428134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        PointerProperties pointerProperties;
45438134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        pointerProperties.clear();
45448134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        pointerProperties.id = 0;
454549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
45468134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown
45478134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        PointerCoords pointerCoords;
45488134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        pointerCoords.clear();
45498134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
45508134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
45518134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown
455265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
45538134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
45548134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
455583d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                mViewport.displayId, 1, &pointerProperties, &pointerCoords,
455683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                0, 0, mPointerGesture.downTime);
4557be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        getListener()->notifyMotion(&args);
4558ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
4559ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4560ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Update state.
4561ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    mPointerGesture.lastGestureMode = mPointerGesture.currentGestureMode;
4562ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    if (!down) {
4563ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.lastGestureIdBits.clear();
4564ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    } else {
4565ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.lastGestureIdBits = mPointerGesture.currentGestureIdBits;
4566ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        for (BitSet32 idBits(mPointerGesture.currentGestureIdBits); !idBits.isEmpty(); ) {
4567be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t id = idBits.clearFirstMarkedBit();
4568ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
4569fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            mPointerGesture.lastGestureProperties[index].copyFrom(
4570fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    mPointerGesture.currentGestureProperties[index]);
4571ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerGesture.lastGestureCoords[index].copyFrom(
4572ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.currentGestureCoords[index]);
4573ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerGesture.lastGestureIdToIndex[id] = index;
4574ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
4575ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
4576ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown}
4577ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
457865fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::abortPointerGestures(nsecs_t when, uint32_t policyFlags) {
457965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Cancel previously dispatches pointers.
458065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (!mPointerGesture.lastGestureIdBits.isEmpty()) {
458165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        int32_t metaState = getContext()->getGlobalMetaState();
458265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        int32_t buttonState = mCurrentButtonState;
458365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        dispatchMotion(when, policyFlags, mSource,
458465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                AMOTION_EVENT_ACTION_CANCEL, 0, metaState, buttonState,
458565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                AMOTION_EVENT_EDGE_FLAG_NONE,
458665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPointerGesture.lastGestureProperties,
458765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
458865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPointerGesture.lastGestureIdBits, -1,
458965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                0, 0, mPointerGesture.downTime);
459065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
459165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
459265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Reset the current pointer gesture.
459365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerGesture.reset();
459465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerVelocityControl.reset();
459565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
459665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Remove any current spots.
459765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mPointerController != NULL) {
459865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
459965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerController->clearSpots();
460065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
460165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
460265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
460379ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brownbool TouchInputMapper::preparePointerGestures(nsecs_t when,
460479ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        bool* outCancelPreviousGesture, bool* outFinishPreviousGesture, bool isTimeout) {
4605ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    *outCancelPreviousGesture = false;
4606ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    *outFinishPreviousGesture = false;
4607ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
460879ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown    // Handle TAP timeout.
460979ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown    if (isTimeout) {
461079ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown#if DEBUG_GESTURES
46115baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("Gestures: Processing timeout");
461279ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown#endif
461379ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown
461479ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        if (mPointerGesture.lastGestureMode == PointerGesture::TAP) {
4615474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) {
461679ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                // The tap/drag timeout has not yet expired.
4617214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown                getContext()->requestTimeoutAtTime(mPointerGesture.tapUpTime
4618474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                        + mConfig.pointerGestureTapDragInterval);
461979ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            } else {
462079ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                // The tap is finished.
462179ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown#if DEBUG_GESTURES
46225baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Gestures: TAP finished");
462379ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown#endif
462479ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                *outFinishPreviousGesture = true;
462579ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown
462679ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                mPointerGesture.activeGestureId = -1;
462779ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
462879ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                mPointerGesture.currentGestureIdBits.clear();
462979ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown
463065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPointerVelocityControl.reset();
463179ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                return true;
463279ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            }
463379ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        }
463479ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown
463579ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        // We did not handle this timeout.
463679ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        return false;
463779ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown    }
463879ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown
463965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    const uint32_t currentFingerCount = mCurrentFingerIdBits.count();
464065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    const uint32_t lastFingerCount = mLastFingerIdBits.count();
464165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
4642ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Update the velocity tracker.
4643ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    {
4644ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        VelocityTracker::Position positions[MAX_POINTERS];
4645ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        uint32_t count = 0;
464665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        for (BitSet32 idBits(mCurrentFingerIdBits); !idBits.isEmpty(); count++) {
4647be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t id = idBits.clearFirstMarkedBit();
4648be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
464965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            positions[count].x = pointer.x * mPointerXMovementScale;
465065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            positions[count].y = pointer.y * mPointerYMovementScale;
4651ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
4652be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mPointerGesture.velocityTracker.addMovement(when,
465365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mCurrentFingerIdBits, positions);
4654ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
4655ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4656398d309c616ee5e1661282d7fce38db4cfb24ee6Michael Wright    // If the gesture ever enters a mode other than TAP, HOVER or TAP_DRAG, without first returning
4657398d309c616ee5e1661282d7fce38db4cfb24ee6Michael Wright    // to NEUTRAL, then we should not generate tap event.
4658398d309c616ee5e1661282d7fce38db4cfb24ee6Michael Wright    if (mPointerGesture.lastGestureMode != PointerGesture::HOVER
4659398d309c616ee5e1661282d7fce38db4cfb24ee6Michael Wright            && mPointerGesture.lastGestureMode != PointerGesture::TAP
4660398d309c616ee5e1661282d7fce38db4cfb24ee6Michael Wright            && mPointerGesture.lastGestureMode != PointerGesture::TAP_DRAG) {
4661398d309c616ee5e1661282d7fce38db4cfb24ee6Michael Wright        mPointerGesture.resetTap();
4662398d309c616ee5e1661282d7fce38db4cfb24ee6Michael Wright    }
4663398d309c616ee5e1661282d7fce38db4cfb24ee6Michael Wright
4664ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Pick a new active touch id if needed.
4665ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Choose an arbitrary pointer that just went down, if there is one.
4666ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Otherwise choose an arbitrary remaining pointer.
4667ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // This guarantees we always have an active touch id when there is at least one pointer.
46682352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    // We keep the same active touch id for as long as possible.
46692352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    bool activeTouchChanged = false;
46702352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    int32_t lastActiveTouchId = mPointerGesture.activeTouchId;
46712352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    int32_t activeTouchId = lastActiveTouchId;
46722352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    if (activeTouchId < 0) {
467365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (!mCurrentFingerIdBits.isEmpty()) {
46742352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            activeTouchChanged = true;
4675be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            activeTouchId = mPointerGesture.activeTouchId =
467665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    mCurrentFingerIdBits.firstMarkedBit();
46772352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            mPointerGesture.firstTouchTime = when;
4678ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
467965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    } else if (!mCurrentFingerIdBits.hasBit(activeTouchId)) {
46802352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        activeTouchChanged = true;
468165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (!mCurrentFingerIdBits.isEmpty()) {
4682be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            activeTouchId = mPointerGesture.activeTouchId =
468365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    mCurrentFingerIdBits.firstMarkedBit();
46842352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        } else {
46852352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            activeTouchId = mPointerGesture.activeTouchId = -1;
4686ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
4687ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
4688ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4689ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Determine whether we are in quiet time.
46902352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    bool isQuietTime = false;
46912352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    if (activeTouchId < 0) {
46922352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        mPointerGesture.resetQuietTime();
46932352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown    } else {
4694474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        isQuietTime = when < mPointerGesture.quietTime + mConfig.pointerGestureQuietInterval;
46952352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        if (!isQuietTime) {
46962352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            if ((mPointerGesture.lastGestureMode == PointerGesture::PRESS
46972352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                    || mPointerGesture.lastGestureMode == PointerGesture::SWIPE
46982352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                    || mPointerGesture.lastGestureMode == PointerGesture::FREEFORM)
469965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    && currentFingerCount < 2) {
47002352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                // Enter quiet time when exiting swipe or freeform state.
47012352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                // This is to prevent accidentally entering the hover state and flinging the
47022352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                // pointer when finishing a swipe and there is still one pointer left onscreen.
47032352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                isQuietTime = true;
470479ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            } else if (mPointerGesture.lastGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG
470565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    && currentFingerCount >= 2
4706be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    && !isPointerDown(mCurrentButtonState)) {
47072352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                // Enter quiet time when releasing the button and there are still two or more
47082352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                // fingers down.  This may indicate that one finger was used to press the button
47092352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                // but it has not gone up yet.
47102352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                isQuietTime = true;
47112352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            }
47122352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            if (isQuietTime) {
47132352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                mPointerGesture.quietTime = when;
47142352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            }
4715ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
4716ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
4717ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4718ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    // Switch states based on button and pointer state.
4719ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    if (isQuietTime) {
4720ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Case 1: Quiet time. (QUIET)
4721ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
47225baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("Gestures: QUIET for next %0.3fms", (mPointerGesture.quietTime
4723474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                + mConfig.pointerGestureQuietInterval - when) * 0.000001f);
4724ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
4725bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        if (mPointerGesture.lastGestureMode != PointerGesture::QUIET) {
4726bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            *outFinishPreviousGesture = true;
4727bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        }
4728ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4729ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.activeGestureId = -1;
4730ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureMode = PointerGesture::QUIET;
4731ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureIdBits.clear();
47322352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
473365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerVelocityControl.reset();
4734be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    } else if (isPointerDown(mCurrentButtonState)) {
473579ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        // Case 2: Button is pressed. (BUTTON_CLICK_OR_DRAG)
4736ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // The pointer follows the active touch point.
4737ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Emit DOWN, MOVE, UP events at the pointer location.
4738ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        //
4739ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Only the active touch matters; other fingers are ignored.  This policy helps
4740ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // to handle the case where the user places a second finger on the touch pad
4741ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // to apply the necessary force to depress an integrated button below the surface.
4742ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // We don't want the second finger to be delivered to applications.
4743ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        //
4744ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // For this to work well, we need to make sure to track the pointer that is really
4745ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // active.  If the user first puts one finger down to click then adds another
4746ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // finger to drag then the active pointer should switch to the finger that is
4747ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // being dragged.
4748ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
47495baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("Gestures: BUTTON_CLICK_OR_DRAG activeTouchId=%d, "
475065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                "currentFingerCount=%d", activeTouchId, currentFingerCount);
4751ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
4752ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Reset state when just starting.
475379ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        if (mPointerGesture.lastGestureMode != PointerGesture::BUTTON_CLICK_OR_DRAG) {
4754ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            *outFinishPreviousGesture = true;
4755ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerGesture.activeGestureId = 0;
4756ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
4757ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4758ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Switch pointers if needed.
4759ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Find the fastest pointer and follow it.
476065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (activeTouchId >= 0 && currentFingerCount > 1) {
476119c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            int32_t bestId = -1;
4762474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            float bestSpeed = mConfig.pointerGestureDragMinSwitchSpeed;
476365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            for (BitSet32 idBits(mCurrentFingerIdBits); !idBits.isEmpty(); ) {
4764be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                uint32_t id = idBits.clearFirstMarkedBit();
476519c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown                float vx, vy;
476619c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown                if (mPointerGesture.velocityTracker.getVelocity(id, &vx, &vy)) {
476719c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown                    float speed = hypotf(vx, vy);
476819c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown                    if (speed > bestSpeed) {
476919c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown                        bestId = id;
477019c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown                        bestSpeed = speed;
4771ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    }
4772ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                }
477319c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            }
477419c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            if (bestId >= 0 && bestId != activeTouchId) {
477519c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown                mPointerGesture.activeTouchId = activeTouchId = bestId;
477619c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown                activeTouchChanged = true;
4777ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
47785baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Gestures: BUTTON_CLICK_OR_DRAG switched pointers, "
477919c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown                        "bestId=%d, bestSpeed=%0.3f", bestId, bestSpeed);
4780ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
47816328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            }
478219c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown        }
47839c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
478465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (activeTouchId >= 0 && mLastFingerIdBits.hasBit(activeTouchId)) {
4785be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const RawPointerData::Pointer& currentPointer =
4786be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentRawPointerData.pointerForId(activeTouchId);
4787be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const RawPointerData::Pointer& lastPointer =
4788be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mLastRawPointerData.pointerForId(activeTouchId);
478965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            float deltaX = (currentPointer.x - lastPointer.x) * mPointerXMovementScale;
479065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            float deltaY = (currentPointer.y - lastPointer.y) * mPointerYMovementScale;
479119c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown
4792be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
479365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerVelocityControl.move(when, &deltaX, &deltaY);
479419c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown
479519c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            // Move the pointer using a relative motion.
479619c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            // When using spots, the click will occur at the position of the anchor
479719c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            // spot and all other spots will move there.
479819c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            mPointerController->move(deltaX, deltaY);
479919c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown        } else {
480065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerVelocityControl.reset();
4801ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
4802ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4803ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        float x, y;
4804ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerController->getPosition(&x, &y);
4805ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
480679ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        mPointerGesture.currentGestureMode = PointerGesture::BUTTON_CLICK_OR_DRAG;
4807ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureIdBits.clear();
4808ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
4809ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
4810fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        mPointerGesture.currentGestureProperties[0].clear();
4811fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
481249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        mPointerGesture.currentGestureProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
4813ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureCoords[0].clear();
4814ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
4815ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
4816ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
481765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    } else if (currentFingerCount == 0) {
4818ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Case 3. No fingers down and button is not pressed. (NEUTRAL)
4819bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        if (mPointerGesture.lastGestureMode != PointerGesture::NEUTRAL) {
4820bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            *outFinishPreviousGesture = true;
4821bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        }
4822ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
482379ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        // Watch for taps coming out of HOVER or TAP_DRAG mode.
4824214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown        // Checking for taps after TAP_DRAG allows us to detect double-taps.
4825ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        bool tapped = false;
482679ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        if ((mPointerGesture.lastGestureMode == PointerGesture::HOVER
482779ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                || mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG)
482865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                && lastFingerCount == 1) {
4829474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            if (when <= mPointerGesture.tapDownTime + mConfig.pointerGestureTapInterval) {
4830ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                float x, y;
4831ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerController->getPosition(&x, &y);
4832474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop
4833474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                        && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) {
4834ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
48355baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                    ALOGD("Gestures: TAP");
4836ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
483779ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown
483879ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                    mPointerGesture.tapUpTime = when;
4839214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown                    getContext()->requestTimeoutAtTime(when
4840474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                            + mConfig.pointerGestureTapDragInterval);
484179ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown
4842ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.activeGestureId = 0;
4843ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.currentGestureMode = PointerGesture::TAP;
4844ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.currentGestureIdBits.clear();
4845ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.currentGestureIdBits.markBit(
4846ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                            mPointerGesture.activeGestureId);
4847ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.currentGestureIdToIndex[
4848ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                            mPointerGesture.activeGestureId] = 0;
4849fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    mPointerGesture.currentGestureProperties[0].clear();
4850fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    mPointerGesture.currentGestureProperties[0].id =
4851fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                            mPointerGesture.activeGestureId;
4852fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    mPointerGesture.currentGestureProperties[0].toolType =
485349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                            AMOTION_EVENT_TOOL_TYPE_FINGER;
4854ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.currentGestureCoords[0].clear();
4855ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.currentGestureCoords[0].setAxisValue(
48562352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                            AMOTION_EVENT_AXIS_X, mPointerGesture.tapX);
4857ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.currentGestureCoords[0].setAxisValue(
48582352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                            AMOTION_EVENT_AXIS_Y, mPointerGesture.tapY);
4859ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.currentGestureCoords[0].setAxisValue(
4860ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                            AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
48612352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
4862ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    tapped = true;
4863517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown                } else {
4864ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
48655baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                    ALOGD("Gestures: Not a TAP, deltaX=%f, deltaY=%f",
48662352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                            x - mPointerGesture.tapX,
48672352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                            y - mPointerGesture.tapY);
4868ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
4869517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown                }
4870ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            } else {
4871ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
4872398d309c616ee5e1661282d7fce38db4cfb24ee6Michael Wright                if (mPointerGesture.tapDownTime != LLONG_MIN) {
4873398d309c616ee5e1661282d7fce38db4cfb24ee6Michael Wright                    ALOGD("Gestures: Not a TAP, %0.3fms since down",
4874398d309c616ee5e1661282d7fce38db4cfb24ee6Michael Wright                            (when - mPointerGesture.tapDownTime) * 0.000001f);
4875398d309c616ee5e1661282d7fce38db4cfb24ee6Michael Wright                } else {
4876398d309c616ee5e1661282d7fce38db4cfb24ee6Michael Wright                    ALOGD("Gestures: Not a TAP, incompatible mode transitions");
4877398d309c616ee5e1661282d7fce38db4cfb24ee6Michael Wright                }
4878ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
4879517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown            }
4880ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
48812352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
488265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerVelocityControl.reset();
488319c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown
4884ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        if (!tapped) {
4885ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
48865baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Gestures: NEUTRAL");
4887ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
4888ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerGesture.activeGestureId = -1;
4889ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
4890ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerGesture.currentGestureIdBits.clear();
4891ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
489265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    } else if (currentFingerCount == 1) {
489379ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        // Case 4. Exactly one finger down, button is not pressed. (HOVER or TAP_DRAG)
4894ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // The pointer follows the active touch point.
489579ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        // When in HOVER, emit HOVER_MOVE events at the pointer location.
489679ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        // When in TAP_DRAG, emit MOVE events at the pointer location.
4897ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block        ALOG_ASSERT(activeTouchId >= 0);
4898ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
489979ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        mPointerGesture.currentGestureMode = PointerGesture::HOVER;
490079ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        if (mPointerGesture.lastGestureMode == PointerGesture::TAP) {
4901474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) {
490279ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                float x, y;
490379ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                mPointerController->getPosition(&x, &y);
4904474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop
4905474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                        && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) {
490679ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                    mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG;
490779ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                } else {
490879ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown#if DEBUG_GESTURES
49095baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                    ALOGD("Gestures: Not a TAP_DRAG, deltaX=%f, deltaY=%f",
491079ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                            x - mPointerGesture.tapX,
491179ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                            y - mPointerGesture.tapY);
491279ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown#endif
491379ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                }
491479ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            } else {
4915ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
49165baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Gestures: Not a TAP_DRAG, %0.3fms time since up",
491779ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                        (when - mPointerGesture.tapUpTime) * 0.000001f);
4918ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
491979ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            }
492079ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        } else if (mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG) {
492179ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG;
492279ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        }
4923ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
492465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mLastFingerIdBits.hasBit(activeTouchId)) {
4925be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const RawPointerData::Pointer& currentPointer =
4926be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentRawPointerData.pointerForId(activeTouchId);
4927be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const RawPointerData::Pointer& lastPointer =
4928be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mLastRawPointerData.pointerForId(activeTouchId);
4929ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            float deltaX = (currentPointer.x - lastPointer.x)
493065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    * mPointerXMovementScale;
4931ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            float deltaY = (currentPointer.y - lastPointer.y)
493265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    * mPointerYMovementScale;
49332352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
4934be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
493565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerVelocityControl.move(when, &deltaX, &deltaY);
493619c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown
49372352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            // Move the pointer using a relative motion.
493879ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            // When using spots, the hover or drag will occur at the position of the anchor spot.
4939ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerController->move(deltaX, deltaY);
494019c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown        } else {
494165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerVelocityControl.reset();
4942ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
4943ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
494479ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        bool down;
494579ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        if (mPointerGesture.currentGestureMode == PointerGesture::TAP_DRAG) {
494679ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown#if DEBUG_GESTURES
49475baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Gestures: TAP_DRAG");
494879ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown#endif
494979ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            down = true;
495079ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        } else {
495179ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown#if DEBUG_GESTURES
49525baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Gestures: HOVER");
495379ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown#endif
4954bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            if (mPointerGesture.lastGestureMode != PointerGesture::HOVER) {
4955bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                *outFinishPreviousGesture = true;
4956bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            }
495779ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            mPointerGesture.activeGestureId = 0;
495879ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            down = false;
495979ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        }
4960ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4961ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        float x, y;
4962ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerController->getPosition(&x, &y);
4963ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4964ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureIdBits.clear();
4965ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
4966ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
4967fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        mPointerGesture.currentGestureProperties[0].clear();
4968fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
4969fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        mPointerGesture.currentGestureProperties[0].toolType =
497049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                AMOTION_EVENT_TOOL_TYPE_FINGER;
4971ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureCoords[0].clear();
4972ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
4973ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
497479ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
497579ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown                down ? 1.0f : 0.0f);
497679ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown
497765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (lastFingerCount == 0 && currentFingerCount != 0) {
497879ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            mPointerGesture.resetTap();
497979ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown            mPointerGesture.tapDownTime = when;
49802352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            mPointerGesture.tapX = x;
49812352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            mPointerGesture.tapY = y;
49822352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        }
4983ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    } else {
49842352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        // Case 5. At least two fingers down, button is not pressed. (PRESS, SWIPE or FREEFORM)
49852352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        // We need to provide feedback for each finger that goes down so we cannot wait
49862352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        // for the fingers to move before deciding what to do.
4987ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        //
49882352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        // The ambiguous case is deciding what to do when there are two fingers down but they
49892352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        // have not moved enough to determine whether they are part of a drag or part of a
49902352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        // freeform gesture, or just a press or long-press at the pointer location.
49912352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        //
49922352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        // When there are two fingers we start with the PRESS hypothesis and we generate a
49932352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        // down at the pointer location.
49942352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        //
49952352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        // When the two fingers move enough or when additional fingers are added, we make
49962352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        // a decision to transition into SWIPE or FREEFORM mode accordingly.
4997ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block        ALOG_ASSERT(activeTouchId >= 0);
4998ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
4999214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown        bool settled = when >= mPointerGesture.firstTouchTime
5000474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                + mConfig.pointerGestureMultitouchSettleInterval;
50012352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        if (mPointerGesture.lastGestureMode != PointerGesture::PRESS
5002ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                && mPointerGesture.lastGestureMode != PointerGesture::SWIPE
5003ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                && mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) {
5004ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            *outFinishPreviousGesture = true;
500565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        } else if (!settled && currentFingerCount > lastFingerCount) {
500619c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            // Additional pointers have gone down but not yet settled.
500719c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            // Reset the gesture.
500819c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown#if DEBUG_GESTURES
50095baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Gestures: Resetting gesture since additional pointers went down for MULTITOUCH, "
5010bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                    "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime
5011474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                            + mConfig.pointerGestureMultitouchSettleInterval - when)
501219c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown                            * 0.000001f);
501319c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown#endif
501419c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            *outCancelPreviousGesture = true;
501519c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown        } else {
501619c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            // Continue previous gesture.
501719c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown            mPointerGesture.currentGestureMode = mPointerGesture.lastGestureMode;
501819c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown        }
501919c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown
502019c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown        if (*outFinishPreviousGesture || *outCancelPreviousGesture) {
50212352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            mPointerGesture.currentGestureMode = PointerGesture::PRESS;
50222352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            mPointerGesture.activeGestureId = 0;
5023538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown            mPointerGesture.referenceIdBits.clear();
502465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerVelocityControl.reset();
5025ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5026cb5ffcf0e41d2597401208221c61589547a00f3dJeff Brown            // Use the centroid and pointer location as the reference points for the gesture.
50272352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#if DEBUG_GESTURES
50285baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Gestures: Using centroid as reference for MULTITOUCH, "
5029cb5ffcf0e41d2597401208221c61589547a00f3dJeff Brown                    "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime
5030474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                            + mConfig.pointerGestureMultitouchSettleInterval - when)
5031cb5ffcf0e41d2597401208221c61589547a00f3dJeff Brown                            * 0.000001f);
50322352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#endif
5033be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mCurrentRawPointerData.getCentroidOfTouchingPointers(
5034be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    &mPointerGesture.referenceTouchX,
5035cb5ffcf0e41d2597401208221c61589547a00f3dJeff Brown                    &mPointerGesture.referenceTouchY);
5036cb5ffcf0e41d2597401208221c61589547a00f3dJeff Brown            mPointerController->getPosition(&mPointerGesture.referenceGestureX,
5037cb5ffcf0e41d2597401208221c61589547a00f3dJeff Brown                    &mPointerGesture.referenceGestureY);
50382352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        }
50396d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5040bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        // Clear the reference deltas for fingers not yet included in the reference calculation.
504165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        for (BitSet32 idBits(mCurrentFingerIdBits.value
5042be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                & ~mPointerGesture.referenceIdBits.value); !idBits.isEmpty(); ) {
5043be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t id = idBits.clearFirstMarkedBit();
5044bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            mPointerGesture.referenceDeltas[id].dx = 0;
5045bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            mPointerGesture.referenceDeltas[id].dy = 0;
5046bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        }
504765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerGesture.referenceIdBits = mCurrentFingerIdBits;
5048bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown
5049bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        // Add delta for all fingers and calculate a common movement delta.
5050bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        float commonDeltaX = 0, commonDeltaY = 0;
505165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        BitSet32 commonIdBits(mLastFingerIdBits.value
505265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                & mCurrentFingerIdBits.value);
5053bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        for (BitSet32 idBits(commonIdBits); !idBits.isEmpty(); ) {
5054bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            bool first = (idBits == commonIdBits);
5055be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t id = idBits.clearFirstMarkedBit();
5056be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const RawPointerData::Pointer& cpd = mCurrentRawPointerData.pointerForId(id);
5057be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const RawPointerData::Pointer& lpd = mLastRawPointerData.pointerForId(id);
5058bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
5059bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            delta.dx += cpd.x - lpd.x;
5060bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            delta.dy += cpd.y - lpd.y;
5061bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown
5062bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            if (first) {
5063bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                commonDeltaX = delta.dx;
5064bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                commonDeltaY = delta.dy;
5065bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            } else {
5066bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                commonDeltaX = calculateCommonVector(commonDeltaX, delta.dx);
5067bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                commonDeltaY = calculateCommonVector(commonDeltaY, delta.dy);
5068bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            }
5069bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        }
5070bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown
5071bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        // Consider transitions from PRESS to SWIPE or MULTITOUCH.
50722352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        if (mPointerGesture.currentGestureMode == PointerGesture::PRESS) {
5073bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            float dist[MAX_POINTER_ID + 1];
5074bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            int32_t distOverThreshold = 0;
5075bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
5076be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                uint32_t id = idBits.clearFirstMarkedBit();
5077bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
507865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                dist[id] = hypotf(delta.dx * mPointerXZoomScale,
507965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                        delta.dy * mPointerYZoomScale);
5080474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                if (dist[id] > mConfig.pointerGestureMultitouchMinDistance) {
5081bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                    distOverThreshold += 1;
5082bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                }
5083bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            }
5084bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown
5085bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            // Only transition when at least two pointers have moved further than
5086bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            // the minimum distance threshold.
5087bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            if (distOverThreshold >= 2) {
508865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                if (currentFingerCount > 2) {
5089bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                    // There are more than two pointers, switch to FREEFORM.
50902352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#if DEBUG_GESTURES
50915baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                    ALOGD("Gestures: PRESS transitioned to FREEFORM, number of pointers %d > 2",
509265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                            currentFingerCount);
50932352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#endif
5094bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                    *outCancelPreviousGesture = true;
5095bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                    mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
5096be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                } else {
5097be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    // There are exactly two pointers.
509865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    BitSet32 idBits(mCurrentFingerIdBits);
5099be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    uint32_t id1 = idBits.clearFirstMarkedBit();
5100be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    uint32_t id2 = idBits.firstMarkedBit();
5101be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    const RawPointerData::Pointer& p1 = mCurrentRawPointerData.pointerForId(id1);
5102be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    const RawPointerData::Pointer& p2 = mCurrentRawPointerData.pointerForId(id2);
5103be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    float mutualDistance = distance(p1.x, p1.y, p2.x, p2.y);
5104be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    if (mutualDistance > mPointerGestureMaxSwipeWidth) {
5105be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        // There are two pointers but they are too far apart for a SWIPE,
5106be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        // switch to FREEFORM.
51072352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#if DEBUG_GESTURES
51085baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                        ALOGD("Gestures: PRESS transitioned to FREEFORM, distance %0.3f > %0.3f",
5109be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                mutualDistance, mPointerGestureMaxSwipeWidth);
51102352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#endif
5111be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        *outCancelPreviousGesture = true;
5112be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
5113be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    } else {
5114be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        // There are two pointers.  Wait for both pointers to start moving
5115be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        // before deciding whether this is a SWIPE or FREEFORM gesture.
5116be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        float dist1 = dist[id1];
5117be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        float dist2 = dist[id2];
5118be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        if (dist1 >= mConfig.pointerGestureMultitouchMinDistance
5119be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                && dist2 >= mConfig.pointerGestureMultitouchMinDistance) {
5120be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            // Calculate the dot product of the displacement vectors.
5121be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            // When the vectors are oriented in approximately the same direction,
5122be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            // the angle betweeen them is near zero and the cosine of the angle
5123be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            // approches 1.0.  Recall that dot(v1, v2) = cos(angle) * mag(v1) * mag(v2).
5124be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            PointerGesture::Delta& delta1 = mPointerGesture.referenceDeltas[id1];
5125be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            PointerGesture::Delta& delta2 = mPointerGesture.referenceDeltas[id2];
512665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                            float dx1 = delta1.dx * mPointerXZoomScale;
512765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                            float dy1 = delta1.dy * mPointerYZoomScale;
512865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                            float dx2 = delta2.dx * mPointerXZoomScale;
512965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                            float dy2 = delta2.dy * mPointerYZoomScale;
5130be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            float dot = dx1 * dx2 + dy1 * dy2;
5131be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            float cosine = dot / (dist1 * dist2); // denominator always > 0
5132be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            if (cosine >= mConfig.pointerGestureSwipeTransitionAngleCosine) {
5133be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                // Pointers are moving in the same direction.  Switch to SWIPE.
51342352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#if DEBUG_GESTURES
51355baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                                ALOGD("Gestures: PRESS transitioned to SWIPE, "
5136be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                        "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
5137be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                        "cosine %0.3f >= %0.3f",
5138be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                        dist1, mConfig.pointerGestureMultitouchMinDistance,
5139be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                        dist2, mConfig.pointerGestureMultitouchMinDistance,
5140be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                        cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
51412352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#endif
5142be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                mPointerGesture.currentGestureMode = PointerGesture::SWIPE;
5143be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            } else {
5144be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                // Pointers are moving in different directions.  Switch to FREEFORM.
51452352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#if DEBUG_GESTURES
51465baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                                ALOGD("Gestures: PRESS transitioned to FREEFORM, "
5147be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                        "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
5148be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                        "cosine %0.3f < %0.3f",
5149be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                        dist1, mConfig.pointerGestureMultitouchMinDistance,
5150be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                        dist2, mConfig.pointerGestureMultitouchMinDistance,
5151be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                        cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
51522352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#endif
5153be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                *outCancelPreviousGesture = true;
5154be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
5155be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            }
5156bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                        }
5157ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    }
5158ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                }
5159ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            }
5160ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        } else if (mPointerGesture.currentGestureMode == PointerGesture::SWIPE) {
51612352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            // Switch from SWIPE to FREEFORM if additional pointers go down.
51622352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            // Cancel previous gesture.
516365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            if (currentFingerCount > 2) {
51642352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#if DEBUG_GESTURES
51655baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Gestures: SWIPE transitioned to FREEFORM, number of pointers %d > 2",
516665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                        currentFingerCount);
51672352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown#endif
5168ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                *outCancelPreviousGesture = true;
5169ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
51706328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            }
51716d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
51726328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
5173bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        // Move the reference points based on the overall group motion of the fingers
5174bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        // except in PRESS mode while waiting for a transition to occur.
5175bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown        if (mPointerGesture.currentGestureMode != PointerGesture::PRESS
5176bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                && (commonDeltaX || commonDeltaY)) {
5177bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
5178be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                uint32_t id = idBits.clearFirstMarkedBit();
5179538881e18323a0c983bd8809f8c3b1cdeeeab8a6Jeff Brown                PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
5180bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                delta.dx = 0;
5181bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown                delta.dy = 0;
51822352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            }
51832352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
5184bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            mPointerGesture.referenceTouchX += commonDeltaX;
5185bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            mPointerGesture.referenceTouchY += commonDeltaY;
518619c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown
518765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            commonDeltaX *= mPointerXMovementScale;
518865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            commonDeltaY *= mPointerYMovementScale;
5189612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown
5190be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            rotateDelta(mSurfaceOrientation, &commonDeltaX, &commonDeltaY);
519165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerVelocityControl.move(when, &commonDeltaX, &commonDeltaY);
519219c97d46fb57f87ff45d9e6ea7122b4eb21ede8cJeff Brown
5193bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            mPointerGesture.referenceGestureX += commonDeltaX;
5194bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown            mPointerGesture.referenceGestureY += commonDeltaY;
51952352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        }
51962352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown
51972352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        // Report gestures.
5198612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown        if (mPointerGesture.currentGestureMode == PointerGesture::PRESS
5199612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown                || mPointerGesture.currentGestureMode == PointerGesture::SWIPE) {
5200612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown            // PRESS or SWIPE mode.
5201ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
52025baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Gestures: PRESS or SWIPE activeTouchId=%d,"
5203ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    "activeGestureId=%d, currentTouchPointerCount=%d",
520465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    activeTouchId, mPointerGesture.activeGestureId, currentFingerCount);
5205ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
5206ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block            ALOG_ASSERT(mPointerGesture.activeGestureId >= 0);
5207ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5208ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerGesture.currentGestureIdBits.clear();
5209ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
5210ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
5211fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            mPointerGesture.currentGestureProperties[0].clear();
5212fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
5213fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            mPointerGesture.currentGestureProperties[0].toolType =
521449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                    AMOTION_EVENT_TOOL_TYPE_FINGER;
5215ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerGesture.currentGestureCoords[0].clear();
52162352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X,
52172352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                    mPointerGesture.referenceGestureX);
52182352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y,
52192352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown                    mPointerGesture.referenceGestureY);
5220ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
5221ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        } else if (mPointerGesture.currentGestureMode == PointerGesture::FREEFORM) {
5222ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            // FREEFORM mode.
5223ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
52245baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Gestures: FREEFORM activeTouchId=%d,"
5225ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    "activeGestureId=%d, currentTouchPointerCount=%d",
522665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    activeTouchId, mPointerGesture.activeGestureId, currentFingerCount);
5227ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
5228ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block            ALOG_ASSERT(mPointerGesture.activeGestureId >= 0);
5229ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5230ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            mPointerGesture.currentGestureIdBits.clear();
5231ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5232ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            BitSet32 mappedTouchIdBits;
5233ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            BitSet32 usedGestureIdBits;
5234ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            if (mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) {
5235ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                // Initially, assign the active gesture id to the active touch point
5236ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                // if there is one.  No other touch id bits are mapped yet.
5237ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                if (!*outCancelPreviousGesture) {
5238ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mappedTouchIdBits.markBit(activeTouchId);
5239ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    usedGestureIdBits.markBit(mPointerGesture.activeGestureId);
5240ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.freeformTouchToGestureIdMap[activeTouchId] =
5241ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                            mPointerGesture.activeGestureId;
5242ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                } else {
5243ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.activeGestureId = -1;
5244ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                }
5245ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            } else {
5246ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                // Otherwise, assume we mapped all touches from the previous frame.
5247ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                // Reuse all mappings that are still applicable.
524865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mappedTouchIdBits.value = mLastFingerIdBits.value
524965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                        & mCurrentFingerIdBits.value;
5250ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                usedGestureIdBits = mPointerGesture.lastGestureIdBits;
5251ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5252ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                // Check whether we need to choose a new active gesture id because the
5253ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                // current went went up.
525465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                for (BitSet32 upTouchIdBits(mLastFingerIdBits.value
525565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                        & ~mCurrentFingerIdBits.value);
5256ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                        !upTouchIdBits.isEmpty(); ) {
5257be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    uint32_t upTouchId = upTouchIdBits.clearFirstMarkedBit();
5258ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    uint32_t upGestureId = mPointerGesture.freeformTouchToGestureIdMap[upTouchId];
5259ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    if (upGestureId == uint32_t(mPointerGesture.activeGestureId)) {
5260ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                        mPointerGesture.activeGestureId = -1;
5261ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                        break;
5262ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    }
5263ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                }
5264ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            }
5265ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5266ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
52675baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Gestures: FREEFORM follow up "
5268ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    "mappedTouchIdBits=0x%08x, usedGestureIdBits=0x%08x, "
5269ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    "activeGestureId=%d",
5270ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mappedTouchIdBits.value, usedGestureIdBits.value,
5271ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.activeGestureId);
5272ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
527391c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
527465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            BitSet32 idBits(mCurrentFingerIdBits);
527565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            for (uint32_t i = 0; i < currentFingerCount; i++) {
5276be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                uint32_t touchId = idBits.clearFirstMarkedBit();
5277ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                uint32_t gestureId;
5278ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                if (!mappedTouchIdBits.hasBit(touchId)) {
5279be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    gestureId = usedGestureIdBits.markFirstUnmarkedBit();
5280ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    mPointerGesture.freeformTouchToGestureIdMap[touchId] = gestureId;
5281ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
52825baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                    ALOGD("Gestures: FREEFORM "
5283ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                            "new mapping for touch id %d -> gesture id %d",
5284ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                            touchId, gestureId);
5285ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
5286ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                } else {
5287ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    gestureId = mPointerGesture.freeformTouchToGestureIdMap[touchId];
5288ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
52895baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                    ALOGD("Gestures: FREEFORM "
5290ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                            "existing mapping for touch id %d -> gesture id %d",
5291ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                            touchId, gestureId);
5292ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
5293ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                }
5294ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.currentGestureIdBits.markBit(gestureId);
5295ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.currentGestureIdToIndex[gestureId] = i;
5296ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5297be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                const RawPointerData::Pointer& pointer =
5298be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        mCurrentRawPointerData.pointerForId(touchId);
5299be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                float deltaX = (pointer.x - mPointerGesture.referenceTouchX)
530065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                        * mPointerXZoomScale;
5301be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                float deltaY = (pointer.y - mPointerGesture.referenceTouchY)
530265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                        * mPointerYZoomScale;
5303be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
5304ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5305fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                mPointerGesture.currentGestureProperties[i].clear();
5306fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                mPointerGesture.currentGestureProperties[i].id = gestureId;
5307fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                mPointerGesture.currentGestureProperties[i].toolType =
530849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                        AMOTION_EVENT_TOOL_TYPE_FINGER;
5309ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.currentGestureCoords[i].clear();
5310ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.currentGestureCoords[i].setAxisValue(
5311612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown                        AMOTION_EVENT_AXIS_X, mPointerGesture.referenceGestureX + deltaX);
5312ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.currentGestureCoords[i].setAxisValue(
5313612891e07bf578a6c4e1b08200f21d8d861ab5ecJeff Brown                        AMOTION_EVENT_AXIS_Y, mPointerGesture.referenceGestureY + deltaY);
5314ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.currentGestureCoords[i].setAxisValue(
5315ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                        AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
53166328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            }
5317ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5318ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            if (mPointerGesture.activeGestureId < 0) {
5319ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                mPointerGesture.activeGestureId =
5320ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                        mPointerGesture.currentGestureIdBits.firstMarkedBit();
5321ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
53225baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Gestures: FREEFORM new "
5323ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                        "activeGestureId=%d", mPointerGesture.activeGestureId);
5324ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
53256328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            }
53262352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown        }
5327ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
53289c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
5329be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mPointerController->setButtonState(mCurrentButtonState);
5330fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
5331ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#if DEBUG_GESTURES
53325baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("Gestures: finishPreviousGesture=%s, cancelPreviousGesture=%s, "
53332352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            "currentGestureMode=%d, currentGestureIdBits=0x%08x, "
53342352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            "lastGestureMode=%d, lastGestureIdBits=0x%08x",
5335ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            toString(*outFinishPreviousGesture), toString(*outCancelPreviousGesture),
53362352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            mPointerGesture.currentGestureMode, mPointerGesture.currentGestureIdBits.value,
53372352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown            mPointerGesture.lastGestureMode, mPointerGesture.lastGestureIdBits.value);
5338ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    for (BitSet32 idBits = mPointerGesture.currentGestureIdBits; !idBits.isEmpty(); ) {
5339be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        uint32_t id = idBits.clearFirstMarkedBit();
5340ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
5341fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        const PointerProperties& properties = mPointerGesture.currentGestureProperties[index];
5342ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        const PointerCoords& coords = mPointerGesture.currentGestureCoords[index];
53435baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("  currentGesture[%d]: index=%d, toolType=%d, "
5344fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                "x=%0.3f, y=%0.3f, pressure=%0.3f",
5345fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                id, index, properties.toolType,
5346fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                coords.getAxisValue(AMOTION_EVENT_AXIS_X),
5347ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                coords.getAxisValue(AMOTION_EVENT_AXIS_Y),
5348ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
5349ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
5350ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    for (BitSet32 idBits = mPointerGesture.lastGestureIdBits; !idBits.isEmpty(); ) {
5351be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        uint32_t id = idBits.clearFirstMarkedBit();
5352ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        uint32_t index = mPointerGesture.lastGestureIdToIndex[id];
5353fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        const PointerProperties& properties = mPointerGesture.lastGestureProperties[index];
5354ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        const PointerCoords& coords = mPointerGesture.lastGestureCoords[index];
53555baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("  lastGesture[%d]: index=%d, toolType=%d, "
5356fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                "x=%0.3f, y=%0.3f, pressure=%0.3f",
5357fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                id, index, properties.toolType,
5358fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                coords.getAxisValue(AMOTION_EVENT_AXIS_X),
5359ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                coords.getAxisValue(AMOTION_EVENT_AXIS_Y),
5360ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
5361ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
5362ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown#endif
536379ac969d7a84b7198f9ed814cc0b2f0b7e11a662Jeff Brown    return true;
5364ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown}
5365ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
536665fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::dispatchPointerStylus(nsecs_t when, uint32_t policyFlags) {
536765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerSimple.currentCoords.clear();
536865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerSimple.currentProperties.clear();
536965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
537065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    bool down, hovering;
537165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (!mCurrentStylusIdBits.isEmpty()) {
537265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        uint32_t id = mCurrentStylusIdBits.firstMarkedBit();
537365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        uint32_t index = mCurrentCookedPointerData.idToIndex[id];
537465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        float x = mCurrentCookedPointerData.pointerCoords[index].getX();
537565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        float y = mCurrentCookedPointerData.pointerCoords[index].getY();
537665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerController->setPosition(x, y);
537765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
537865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        hovering = mCurrentCookedPointerData.hoveringIdBits.hasBit(id);
537965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        down = !hovering;
538065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
538165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerController->getPosition(&x, &y);
538265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.currentCoords.copyFrom(mCurrentCookedPointerData.pointerCoords[index]);
538365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
538465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
538565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.currentProperties.id = 0;
538665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.currentProperties.toolType =
538765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mCurrentCookedPointerData.pointerProperties[index].toolType;
538865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    } else {
538965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        down = false;
539065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        hovering = false;
539165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
539265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
539365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    dispatchPointerSimple(when, policyFlags, down, hovering);
539465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
539565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
539665fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::abortPointerStylus(nsecs_t when, uint32_t policyFlags) {
539765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    abortPointerSimple(when, policyFlags);
539865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
539965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
540065fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::dispatchPointerMouse(nsecs_t when, uint32_t policyFlags) {
540165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerSimple.currentCoords.clear();
540265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerSimple.currentProperties.clear();
540365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
540465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    bool down, hovering;
540565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (!mCurrentMouseIdBits.isEmpty()) {
540665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        uint32_t id = mCurrentMouseIdBits.firstMarkedBit();
540765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        uint32_t currentIndex = mCurrentRawPointerData.idToIndex[id];
540865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (mLastMouseIdBits.hasBit(id)) {
540965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            uint32_t lastIndex = mCurrentRawPointerData.idToIndex[id];
541065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            float deltaX = (mCurrentRawPointerData.pointers[currentIndex].x
541165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    - mLastRawPointerData.pointers[lastIndex].x)
541265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    * mPointerXMovementScale;
541365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            float deltaY = (mCurrentRawPointerData.pointers[currentIndex].y
541465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    - mLastRawPointerData.pointers[lastIndex].y)
541565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    * mPointerYMovementScale;
541665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
541765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
541865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerVelocityControl.move(when, &deltaX, &deltaY);
541965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
542065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerController->move(deltaX, deltaY);
542165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        } else {
542265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerVelocityControl.reset();
542365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
542465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
542565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        down = isPointerDown(mCurrentButtonState);
542665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        hovering = !down;
542765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
542865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        float x, y;
542965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerController->getPosition(&x, &y);
543065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.currentCoords.copyFrom(
543165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mCurrentCookedPointerData.pointerCoords[currentIndex]);
543265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
543365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
543465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
543565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                hovering ? 0.0f : 1.0f);
543665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.currentProperties.id = 0;
543765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.currentProperties.toolType =
543865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mCurrentCookedPointerData.pointerProperties[currentIndex].toolType;
543965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    } else {
544065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerVelocityControl.reset();
544165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
544265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        down = false;
544365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        hovering = false;
544465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
544565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
544665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    dispatchPointerSimple(when, policyFlags, down, hovering);
544765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
544865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
544965fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::abortPointerMouse(nsecs_t when, uint32_t policyFlags) {
545065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    abortPointerSimple(when, policyFlags);
545165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
545265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerVelocityControl.reset();
545365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
545465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
545565fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::dispatchPointerSimple(nsecs_t when, uint32_t policyFlags,
545665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        bool down, bool hovering) {
545765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    int32_t metaState = getContext()->getGlobalMetaState();
545865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
545965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mPointerController != NULL) {
546065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (down || hovering) {
546165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
546265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerController->clearSpots();
546365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerController->setButtonState(mCurrentButtonState);
546465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
546565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        } else if (!down && !hovering && (mPointerSimple.down || mPointerSimple.hovering)) {
546665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
546765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
546865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
546965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
547065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mPointerSimple.down && !down) {
547165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.down = false;
547265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
547365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Send up.
547465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
547565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                 AMOTION_EVENT_ACTION_UP, 0, metaState, mLastButtonState, 0,
547683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                 mViewport.displayId,
547765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                 1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
547865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                 mOrientedXPrecision, mOrientedYPrecision,
547965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                 mPointerSimple.downTime);
548065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        getListener()->notifyMotion(&args);
548165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
548265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
548365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mPointerSimple.hovering && !hovering) {
548465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.hovering = false;
548565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
548665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Send hover exit.
548765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
548865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                AMOTION_EVENT_ACTION_HOVER_EXIT, 0, metaState, mLastButtonState, 0,
548983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                mViewport.displayId,
549065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
549165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mOrientedXPrecision, mOrientedYPrecision,
549265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPointerSimple.downTime);
549365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        getListener()->notifyMotion(&args);
549465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
549565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
549665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (down) {
549765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (!mPointerSimple.down) {
549865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerSimple.down = true;
549965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerSimple.downTime = when;
550065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
550165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            // Send down.
550265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
550365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    AMOTION_EVENT_ACTION_DOWN, 0, metaState, mCurrentButtonState, 0,
550483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                    mViewport.displayId,
550565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
550665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    mOrientedXPrecision, mOrientedYPrecision,
550765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    mPointerSimple.downTime);
550865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            getListener()->notifyMotion(&args);
550965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
551065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
551165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Send move.
551265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
551365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                AMOTION_EVENT_ACTION_MOVE, 0, metaState, mCurrentButtonState, 0,
551483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                mViewport.displayId,
551565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
551665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mOrientedXPrecision, mOrientedYPrecision,
551765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPointerSimple.downTime);
551865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        getListener()->notifyMotion(&args);
551965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
552065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
552165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (hovering) {
552265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (!mPointerSimple.hovering) {
552365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            mPointerSimple.hovering = true;
552465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
552565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            // Send hover enter.
552665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
552765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    AMOTION_EVENT_ACTION_HOVER_ENTER, 0, metaState, mCurrentButtonState, 0,
552883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                    mViewport.displayId,
552965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
553065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    mOrientedXPrecision, mOrientedYPrecision,
553165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                    mPointerSimple.downTime);
553265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            getListener()->notifyMotion(&args);
553365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        }
553465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
553565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Send hover move.
553665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
553765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                AMOTION_EVENT_ACTION_HOVER_MOVE, 0, metaState, mCurrentButtonState, 0,
553883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                mViewport.displayId,
553965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
554065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mOrientedXPrecision, mOrientedYPrecision,
554165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPointerSimple.downTime);
554265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        getListener()->notifyMotion(&args);
554365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
554465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
554565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (mCurrentRawVScroll || mCurrentRawHScroll) {
554665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        float vscroll = mCurrentRawVScroll;
554765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        float hscroll = mCurrentRawHScroll;
554865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mWheelYVelocityControl.move(when, NULL, &vscroll);
554965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mWheelXVelocityControl.move(when, &hscroll, NULL);
555065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
555165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        // Send scroll.
555265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        PointerCoords pointerCoords;
555365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        pointerCoords.copyFrom(mPointerSimple.currentCoords);
555465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
555565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
555665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
555765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
555865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                AMOTION_EVENT_ACTION_SCROLL, 0, metaState, mCurrentButtonState, 0,
555983d616a9c7b9505153d258511eb5c16b552e268dJeff Brown                mViewport.displayId,
556065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                1, &mPointerSimple.currentProperties, &pointerCoords,
556165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mOrientedXPrecision, mOrientedYPrecision,
556265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                mPointerSimple.downTime);
556365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        getListener()->notifyMotion(&args);
556465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
556565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
556665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    // Save state.
556765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (down || hovering) {
556865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.lastCoords.copyFrom(mPointerSimple.currentCoords);
556965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.lastProperties.copyFrom(mPointerSimple.currentProperties);
557065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    } else {
557165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mPointerSimple.reset();
557265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
557365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
557465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
557565fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid TouchInputMapper::abortPointerSimple(nsecs_t when, uint32_t policyFlags) {
557665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerSimple.currentCoords.clear();
557765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerSimple.currentProperties.clear();
557865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
557965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    dispatchPointerSimple(when, policyFlags, false, false);
558065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
558165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
5582ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brownvoid TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source,
5583fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        int32_t action, int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags,
5584fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        const PointerProperties* properties, const PointerCoords* coords,
5585fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        const uint32_t* idToIndex, BitSet32 idBits,
5586ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        int32_t changedId, float xPrecision, float yPrecision, nsecs_t downTime) {
5587ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    PointerCoords pointerCoords[MAX_POINTERS];
5588fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    PointerProperties pointerProperties[MAX_POINTERS];
5589ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    uint32_t pointerCount = 0;
5590ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    while (!idBits.isEmpty()) {
5591be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        uint32_t id = idBits.clearFirstMarkedBit();
5592ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        uint32_t index = idToIndex[id];
5593fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        pointerProperties[pointerCount].copyFrom(properties[index]);
5594ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        pointerCoords[pointerCount].copyFrom(coords[index]);
5595ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5596ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        if (changedId >= 0 && id == uint32_t(changedId)) {
5597ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            action |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
5598ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
5599ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5600ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        pointerCount += 1;
5601ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
5602ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5603ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block    ALOG_ASSERT(pointerCount != 0);
5604ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5605ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    if (changedId >= 0 && pointerCount == 1) {
5606ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // Replace initial down and final up action.
5607ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // We can compare the action without masking off the changed pointer index
5608ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        // because we know the index is 0.
5609ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        if (action == AMOTION_EVENT_ACTION_POINTER_DOWN) {
5610ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            action = AMOTION_EVENT_ACTION_DOWN;
5611ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        } else if (action == AMOTION_EVENT_ACTION_POINTER_UP) {
5612ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            action = AMOTION_EVENT_ACTION_UP;
5613ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        } else {
5614ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            // Can't happen.
5615ec193dec4d9ca2cfc8295c4becfe950a906a15edSteve Block            ALOG_ASSERT(false);
5616ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
5617ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
5618ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5619be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    NotifyMotionArgs args(when, getDeviceId(), source, policyFlags,
5620fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            action, flags, metaState, buttonState, edgeFlags,
562183d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            mViewport.displayId, pointerCount, pointerProperties, pointerCoords,
562283d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            xPrecision, yPrecision, downTime);
5623be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getListener()->notifyMotion(&args);
5624ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown}
5625ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5626fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownbool TouchInputMapper::updateMovedPointers(const PointerProperties* inProperties,
5627ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        const PointerCoords* inCoords, const uint32_t* inIdToIndex,
5628fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        PointerProperties* outProperties, PointerCoords* outCoords, const uint32_t* outIdToIndex,
5629fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        BitSet32 idBits) const {
5630ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    bool changed = false;
5631ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    while (!idBits.isEmpty()) {
5632be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        uint32_t id = idBits.clearFirstMarkedBit();
5633ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        uint32_t inIndex = inIdToIndex[id];
5634ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        uint32_t outIndex = outIdToIndex[id];
5635fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
5636fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        const PointerProperties& curInProperties = inProperties[inIndex];
5637ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        const PointerCoords& curInCoords = inCoords[inIndex];
5638fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        PointerProperties& curOutProperties = outProperties[outIndex];
5639ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        PointerCoords& curOutCoords = outCoords[outIndex];
5640ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5641fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        if (curInProperties != curOutProperties) {
5642fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            curOutProperties.copyFrom(curInProperties);
5643fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            changed = true;
5644fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        }
5645fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
5646ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        if (curInCoords != curOutCoords) {
5647ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            curOutCoords.copyFrom(curInCoords);
5648ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            changed = true;
5649ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        }
5650ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    }
5651ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown    return changed;
5652ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown}
5653ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown
5654ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brownvoid TouchInputMapper::fadePointer() {
5655be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (mPointerController != NULL) {
5656be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
5657be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
56589c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown}
56599c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
5660be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownbool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) {
5661be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    return x >= mRawPointerAxes.x.minValue && x <= mRawPointerAxes.x.maxValue
5662be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            && y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue;
56639c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown}
56649c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
5665be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownconst TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHit(
56666328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        int32_t x, int32_t y) {
5667be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    size_t numVirtualKeys = mVirtualKeys.size();
56686328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    for (size_t i = 0; i < numVirtualKeys; i++) {
5669be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        const VirtualKey& virtualKey = mVirtualKeys[i];
56709c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
56716d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_VIRTUAL_KEYS
56725baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, "
56736d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                "left=%d, top=%d, right=%d, bottom=%d",
56746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                x, y,
56756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                virtualKey.keyCode, virtualKey.scanCode,
56766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                virtualKey.hitLeft, virtualKey.hitTop,
56776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                virtualKey.hitRight, virtualKey.hitBottom);
56786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
56796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
56806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (virtualKey.isHit(x, y)) {
56816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            return & virtualKey;
56829c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown        }
56836d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
56849c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
56856d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return NULL;
56869c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown}
56879c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
5688be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid TouchInputMapper::assignPointerIds() {
5689be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    uint32_t currentPointerCount = mCurrentRawPointerData.pointerCount;
5690be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    uint32_t lastPointerCount = mLastRawPointerData.pointerCount;
5691be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
5692be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mCurrentRawPointerData.clearIdBits();
56936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
56946d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (currentPointerCount == 0) {
56956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // No pointers to assign.
5696be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        return;
5697be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
5698be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
5699be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (lastPointerCount == 0) {
57006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // All pointers are new.
57016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        for (uint32_t i = 0; i < currentPointerCount; i++) {
5702be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t id = i;
5703be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mCurrentRawPointerData.pointers[i].id = id;
5704be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mCurrentRawPointerData.idToIndex[id] = i;
5705be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mCurrentRawPointerData.markIdBit(id, mCurrentRawPointerData.isHovering(i));
57066d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
5707be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        return;
5708be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
5709be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
5710be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (currentPointerCount == 1 && lastPointerCount == 1
5711be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            && mCurrentRawPointerData.pointers[0].toolType
5712be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    == mLastRawPointerData.pointers[0].toolType) {
57136d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // Only one pointer and no change in count so it must have the same id as before.
5714be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        uint32_t id = mLastRawPointerData.pointers[0].id;
5715be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mCurrentRawPointerData.pointers[0].id = id;
5716be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mCurrentRawPointerData.idToIndex[id] = 0;
5717be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mCurrentRawPointerData.markIdBit(id, mCurrentRawPointerData.isHovering(0));
5718be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        return;
5719be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
5720be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
5721be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // General case.
5722be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // We build a heap of squared euclidean distances between current and last pointers
5723be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // associated with the current and last pointer indices.  Then, we find the best
5724be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // match (by distance) for each current pointer.
5725be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // The pointers must have the same tool type but it is possible for them to
5726be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // transition from hovering to touching or vice-versa while retaining the same id.
5727be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    PointerDistanceHeapElement heap[MAX_POINTERS * MAX_POINTERS];
5728be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
5729be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    uint32_t heapSize = 0;
5730be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (uint32_t currentPointerIndex = 0; currentPointerIndex < currentPointerCount;
5731be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            currentPointerIndex++) {
5732be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        for (uint32_t lastPointerIndex = 0; lastPointerIndex < lastPointerCount;
5733be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                lastPointerIndex++) {
5734be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const RawPointerData::Pointer& currentPointer =
5735be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentRawPointerData.pointers[currentPointerIndex];
5736be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            const RawPointerData::Pointer& lastPointer =
5737be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mLastRawPointerData.pointers[lastPointerIndex];
5738be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (currentPointer.toolType == lastPointer.toolType) {
5739be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                int64_t deltaX = currentPointer.x - lastPointer.x;
5740be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                int64_t deltaY = currentPointer.y - lastPointer.y;
57416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
57426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY);
57436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
57446d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                // Insert new element into the heap (sift up).
57456d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                heap[heapSize].currentPointerIndex = currentPointerIndex;
57466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                heap[heapSize].lastPointerIndex = lastPointerIndex;
57476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                heap[heapSize].distance = distance;
57486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                heapSize += 1;
57496d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
57506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
5751be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
57529c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
5753be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // Heapify
5754be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (uint32_t startIndex = heapSize / 2; startIndex != 0; ) {
5755be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        startIndex -= 1;
5756be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        for (uint32_t parentIndex = startIndex; ;) {
5757be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t childIndex = parentIndex * 2 + 1;
5758be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (childIndex >= heapSize) {
5759be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                break;
5760be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            }
57616d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5762be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (childIndex + 1 < heapSize
5763be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    && heap[childIndex + 1].distance < heap[childIndex].distance) {
5764be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                childIndex += 1;
5765be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            }
57666d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5767be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (heap[parentIndex].distance <= heap[childIndex].distance) {
5768be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                break;
57696d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
5770be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
5771be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            swap(heap[parentIndex], heap[childIndex]);
5772be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            parentIndex = childIndex;
57739c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown        }
5774be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
57759c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
57766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_POINTER_ASSIGNMENT
57775baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("assignPointerIds - initial distance min-heap: size=%d", heapSize);
5778be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (size_t i = 0; i < heapSize; i++) {
57795baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("  heap[%d]: cur=%d, last=%d, distance=%lld",
5780be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
5781be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                heap[i].distance);
5782be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
57836d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
57849c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
5785be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // Pull matches out by increasing order of distance.
5786be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // To avoid reassigning pointers that have already been matched, the loop keeps track
5787be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // of which last and current pointers have been matched using the matchedXXXBits variables.
5788be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // It also tracks the used pointer id bits.
5789be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    BitSet32 matchedLastBits(0);
5790be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    BitSet32 matchedCurrentBits(0);
5791be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    BitSet32 usedIdBits(0);
5792be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    bool first = true;
5793be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (uint32_t i = min(currentPointerCount, lastPointerCount); heapSize > 0 && i > 0; i--) {
5794be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        while (heapSize > 0) {
5795be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (first) {
5796be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                // The first time through the loop, we just consume the root element of
5797be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                // the heap (the one with smallest distance).
5798be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                first = false;
5799be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            } else {
5800be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                // Previous iterations consumed the root element of the heap.
5801be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                // Pop root element off of the heap (sift down).
5802be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                heap[0] = heap[heapSize];
5803be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                for (uint32_t parentIndex = 0; ;) {
5804be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    uint32_t childIndex = parentIndex * 2 + 1;
5805be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    if (childIndex >= heapSize) {
5806be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        break;
5807be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    }
58086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5809be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    if (childIndex + 1 < heapSize
5810be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            && heap[childIndex + 1].distance < heap[childIndex].distance) {
5811be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        childIndex += 1;
5812be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    }
58136d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5814be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    if (heap[parentIndex].distance <= heap[childIndex].distance) {
5815be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        break;
58166d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    }
58176d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5818be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    swap(heap[parentIndex], heap[childIndex]);
5819be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    parentIndex = childIndex;
5820be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                }
5821be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
58226d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_POINTER_ASSIGNMENT
58235baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("assignPointerIds - reduced distance min-heap: size=%d", heapSize);
5824be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                for (size_t i = 0; i < heapSize; i++) {
58255baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                    ALOGD("  heap[%d]: cur=%d, last=%d, distance=%lld",
5826be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
5827be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            heap[i].distance);
58286d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
5829be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown#endif
5830be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            }
583146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5832be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            heapSize -= 1;
583346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5834be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t currentPointerIndex = heap[0].currentPointerIndex;
5835be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (matchedCurrentBits.hasBit(currentPointerIndex)) continue; // already matched
583646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5837be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t lastPointerIndex = heap[0].lastPointerIndex;
5838be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (matchedLastBits.hasBit(lastPointerIndex)) continue; // already matched
583946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5840be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            matchedCurrentBits.markBit(currentPointerIndex);
5841be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            matchedLastBits.markBit(lastPointerIndex);
5842be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
5843be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            uint32_t id = mLastRawPointerData.pointers[lastPointerIndex].id;
5844be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mCurrentRawPointerData.pointers[currentPointerIndex].id = id;
5845be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mCurrentRawPointerData.idToIndex[id] = currentPointerIndex;
5846be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            mCurrentRawPointerData.markIdBit(id,
5847be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    mCurrentRawPointerData.isHovering(currentPointerIndex));
5848be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            usedIdBits.markBit(id);
584946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
58506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_POINTER_ASSIGNMENT
58515baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("assignPointerIds - matched: cur=%d, last=%d, id=%d, distance=%lld",
5852be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    lastPointerIndex, currentPointerIndex, id, heap[0].distance);
58536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
5854be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            break;
58556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
5856be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
585746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5858be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    // Assign fresh ids to pointers that were not matched in the process.
5859be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (uint32_t i = currentPointerCount - matchedCurrentBits.count(); i != 0; i--) {
5860be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        uint32_t currentPointerIndex = matchedCurrentBits.markFirstUnmarkedBit();
5861be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        uint32_t id = usedIdBits.markFirstUnmarkedBit();
58626d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5863be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mCurrentRawPointerData.pointers[currentPointerIndex].id = id;
5864be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mCurrentRawPointerData.idToIndex[id] = currentPointerIndex;
5865be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mCurrentRawPointerData.markIdBit(id,
5866be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentRawPointerData.isHovering(currentPointerIndex));
58676d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
58686d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_POINTER_ASSIGNMENT
58695baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("assignPointerIds - assigned: cur=%d, id=%d",
5870be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                currentPointerIndex, id);
58716d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
58726d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
587346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
587446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
58756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
5876be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (mCurrentVirtualKey.down && mCurrentVirtualKey.keyCode == keyCode) {
5877be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        return AKEY_STATE_VIRTUAL;
5878be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
58796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5880be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    size_t numVirtualKeys = mVirtualKeys.size();
5881be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (size_t i = 0; i < numVirtualKeys; i++) {
5882be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        const VirtualKey& virtualKey = mVirtualKeys[i];
5883be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (virtualKey.keyCode == keyCode) {
5884be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            return AKEY_STATE_UP;
58856d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
5886be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
58876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
58886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return AKEY_STATE_UNKNOWN;
58896d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
58906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
58916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
5892be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (mCurrentVirtualKey.down && mCurrentVirtualKey.scanCode == scanCode) {
5893be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        return AKEY_STATE_VIRTUAL;
5894be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
58956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5896be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    size_t numVirtualKeys = mVirtualKeys.size();
5897be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (size_t i = 0; i < numVirtualKeys; i++) {
5898be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        const VirtualKey& virtualKey = mVirtualKeys[i];
5899be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (virtualKey.scanCode == scanCode) {
5900be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            return AKEY_STATE_UP;
59016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
5902be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
59036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
59046d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return AKEY_STATE_UNKNOWN;
59056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
59066d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
59076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownbool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
59086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        const int32_t* keyCodes, uint8_t* outFlags) {
5909be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    size_t numVirtualKeys = mVirtualKeys.size();
5910be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (size_t i = 0; i < numVirtualKeys; i++) {
5911be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        const VirtualKey& virtualKey = mVirtualKeys[i];
59126d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5913be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        for (size_t i = 0; i < numCodes; i++) {
5914be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            if (virtualKey.keyCode == keyCodes[i]) {
5915be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                outFlags[i] = 1;
59166d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
59176d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
5918be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
59196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
59206d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return true;
59216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
59226d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
59236d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
59246d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown// --- SingleTouchInputMapper ---
59256d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
592647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff BrownSingleTouchInputMapper::SingleTouchInputMapper(InputDevice* device) :
592747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        TouchInputMapper(device) {
59286d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
59296d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
59306d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownSingleTouchInputMapper::~SingleTouchInputMapper() {
59316d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
59326d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
593365fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid SingleTouchInputMapper::reset(nsecs_t when) {
593465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mSingleTouchMotionAccumulator.reset(getDevice());
59356d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
593665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    TouchInputMapper::reset(when);
593765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
59386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
59396d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid SingleTouchInputMapper::process(const RawEvent* rawEvent) {
594065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    TouchInputMapper::process(rawEvent);
59416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
594265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mSingleTouchMotionAccumulator.process(rawEvent);
59436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
59446d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
594565fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid SingleTouchInputMapper::syncTouch(nsecs_t when, bool* outHavePointerIds) {
5946d87c6d5fd5e620ecb1a7a401d2b31c6cf2e1a851Jeff Brown    if (mTouchButtonAccumulator.isToolActive()) {
5947be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mCurrentRawPointerData.pointerCount = 1;
5948be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mCurrentRawPointerData.idToIndex[0] = 0;
594949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
595065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        bool isHovering = mTouchButtonAccumulator.getToolType() != AMOTION_EVENT_TOOL_TYPE_MOUSE
595165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                && (mTouchButtonAccumulator.isHovering()
595265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                        || (mRawPointerAxes.pressure.valid
595365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                                && mSingleTouchMotionAccumulator.getAbsolutePressure() <= 0));
5954be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        mCurrentRawPointerData.markIdBit(0, isHovering);
595549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
5956be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        RawPointerData::Pointer& outPointer = mCurrentRawPointerData.pointers[0];
595749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.id = 0;
595849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.x = mSingleTouchMotionAccumulator.getAbsoluteX();
595949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.y = mSingleTouchMotionAccumulator.getAbsoluteY();
596049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.pressure = mSingleTouchMotionAccumulator.getAbsolutePressure();
596149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.touchMajor = 0;
596249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.touchMinor = 0;
596349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.toolMajor = mSingleTouchMotionAccumulator.getAbsoluteToolWidth();
596449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.toolMinor = mSingleTouchMotionAccumulator.getAbsoluteToolWidth();
596549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.orientation = 0;
596649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.distance = mSingleTouchMotionAccumulator.getAbsoluteDistance();
596765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        outPointer.tiltX = mSingleTouchMotionAccumulator.getAbsoluteTiltX();
596865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        outPointer.tiltY = mSingleTouchMotionAccumulator.getAbsoluteTiltY();
596949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.toolType = mTouchButtonAccumulator.getToolType();
597049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
597149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
597249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        }
597349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.isHovering = isHovering;
59746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
59756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
59766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5977be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid SingleTouchInputMapper::configureRawPointerAxes() {
5978be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    TouchInputMapper::configureRawPointerAxes();
59796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5980be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_X, &mRawPointerAxes.x);
5981be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_Y, &mRawPointerAxes.y);
5982be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_PRESSURE, &mRawPointerAxes.pressure);
5983be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_TOOL_WIDTH, &mRawPointerAxes.toolMajor);
5984be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_DISTANCE, &mRawPointerAxes.distance);
598565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    getAbsoluteAxisInfo(ABS_TILT_X, &mRawPointerAxes.tiltX);
598665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    getAbsoluteAxisInfo(ABS_TILT_Y, &mRawPointerAxes.tiltY);
59876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
59886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
598900710e906bdafd58386ee7f81fa84addd218122fJeff Brownbool SingleTouchInputMapper::hasStylus() const {
599000710e906bdafd58386ee7f81fa84addd218122fJeff Brown    return mTouchButtonAccumulator.hasStylus();
599100710e906bdafd58386ee7f81fa84addd218122fJeff Brown}
599200710e906bdafd58386ee7f81fa84addd218122fJeff Brown
59936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
59946d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown// --- MultiTouchInputMapper ---
59956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
599647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff BrownMultiTouchInputMapper::MultiTouchInputMapper(InputDevice* device) :
599749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        TouchInputMapper(device) {
59986d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
59996d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
60006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownMultiTouchInputMapper::~MultiTouchInputMapper() {
60016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
60026d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
600365fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid MultiTouchInputMapper::reset(nsecs_t when) {
600465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mMultiTouchMotionAccumulator.reset(getDevice());
60052717eff2ac04bed60e5fd577bcb8ec1ea7c2ccdeJeff Brown
600665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mPointerIdBits.clear();
60076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
600865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    TouchInputMapper::reset(when);
60096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
60106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
60116d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid MultiTouchInputMapper::process(const RawEvent* rawEvent) {
601265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    TouchInputMapper::process(rawEvent);
60136d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
601465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mMultiTouchMotionAccumulator.process(rawEvent);
60156d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
60166d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
601765fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid MultiTouchInputMapper::syncTouch(nsecs_t when, bool* outHavePointerIds) {
601849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown    size_t inCount = mMultiTouchMotionAccumulator.getSlotCount();
601980fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    size_t outCount = 0;
6020be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    BitSet32 newPointerIdBits;
60216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
602280fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    for (size_t inIndex = 0; inIndex < inCount; inIndex++) {
602349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        const MultiTouchMotionAccumulator::Slot* inSlot =
602449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                mMultiTouchMotionAccumulator.getSlot(inIndex);
602549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        if (!inSlot->isInUse()) {
60266d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            continue;
60276d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
60286d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
602980fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        if (outCount >= MAX_POINTERS) {
603080fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown#if DEBUG_POINTERS
60315baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("MultiTouch device %s emitted more than maximum of %d pointers; "
603280fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                    "ignoring the rest.",
603380fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                    getDeviceName().string(), MAX_POINTERS);
603480fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown#endif
603580fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown            break; // too many fingers!
603680fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        }
603780fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
6038be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        RawPointerData::Pointer& outPointer = mCurrentRawPointerData.pointers[outCount];
603949754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.x = inSlot->getX();
604049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.y = inSlot->getY();
604149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.pressure = inSlot->getPressure();
604249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.touchMajor = inSlot->getTouchMajor();
604349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.touchMinor = inSlot->getTouchMinor();
604449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.toolMajor = inSlot->getToolMajor();
604549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.toolMinor = inSlot->getToolMinor();
604649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.orientation = inSlot->getOrientation();
604749754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.distance = inSlot->getDistance();
604865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        outPointer.tiltX = 0;
604965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        outPointer.tiltY = 0;
605049754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown
605149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        outPointer.toolType = inSlot->getToolType();
605249754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
605349754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            outPointer.toolType = mTouchButtonAccumulator.getToolType();
605449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
605549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
605649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            }
605780fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        }
605880fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown
605965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        bool isHovering = mTouchButtonAccumulator.getToolType() != AMOTION_EVENT_TOOL_TYPE_MOUSE
606065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                && (mTouchButtonAccumulator.isHovering()
606165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                        || (mRawPointerAxes.pressure.valid && inSlot->getPressure() <= 0));
6062be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        outPointer.isHovering = isHovering;
6063fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
60648d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // Assign pointer id using tracking id if available.
606565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        if (*outHavePointerIds) {
606649754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            int32_t trackingId = inSlot->getTrackingId();
60676894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown            int32_t id = -1;
606849754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            if (trackingId >= 0) {
60696894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown                for (BitSet32 idBits(mPointerIdBits); !idBits.isEmpty(); ) {
6070be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    uint32_t n = idBits.clearFirstMarkedBit();
60716894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown                    if (mPointerTrackingIdMap[n] == trackingId) {
60726894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown                        id = n;
60736894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown                    }
60746894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown                }
60756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
60766894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown                if (id < 0 && !mPointerIdBits.isFull()) {
6077be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    id = mPointerIdBits.markFirstUnmarkedBit();
60786894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown                    mPointerTrackingIdMap[id] = trackingId;
60796894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown                }
60806894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown            }
60816894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown            if (id < 0) {
608265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                *outHavePointerIds = false;
6083be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentRawPointerData.clearIdBits();
6084be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                newPointerIdBits.clear();
60856894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown            } else {
608680fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                outPointer.id = id;
6087be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentRawPointerData.idToIndex[id] = outCount;
6088be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                mCurrentRawPointerData.markIdBit(id, isHovering);
6089be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                newPointerIdBits.markBit(id);
60906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
60916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
60926d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
60936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        outCount += 1;
60946d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
60956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
6096be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mCurrentRawPointerData.pointerCount = outCount;
6097be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mPointerIdBits = newPointerIdBits;
60986894a2947eb1f9d499fd7f1a1ec4e7098e07d25dJeff Brown
609965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    mMultiTouchMotionAccumulator.finishSync();
61006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
61016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
6102be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid MultiTouchInputMapper::configureRawPointerAxes() {
6103be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    TouchInputMapper::configureRawPointerAxes();
61042dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown
6105be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_MT_POSITION_X, &mRawPointerAxes.x);
6106be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_MT_POSITION_Y, &mRawPointerAxes.y);
6107be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_MT_TOUCH_MAJOR, &mRawPointerAxes.touchMajor);
6108be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_MT_TOUCH_MINOR, &mRawPointerAxes.touchMinor);
6109be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_MT_WIDTH_MAJOR, &mRawPointerAxes.toolMajor);
6110be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_MT_WIDTH_MINOR, &mRawPointerAxes.toolMinor);
6111be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_MT_ORIENTATION, &mRawPointerAxes.orientation);
6112be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_MT_PRESSURE, &mRawPointerAxes.pressure);
6113be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_MT_DISTANCE, &mRawPointerAxes.distance);
6114be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_MT_TRACKING_ID, &mRawPointerAxes.trackingId);
6115be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getAbsoluteAxisInfo(ABS_MT_SLOT, &mRawPointerAxes.slot);
6116be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown
6117be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (mRawPointerAxes.trackingId.valid
6118be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            && mRawPointerAxes.slot.valid
6119be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            && mRawPointerAxes.slot.minValue == 0 && mRawPointerAxes.slot.maxValue > 0) {
6120be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        size_t slotCount = mRawPointerAxes.slot.maxValue + 1;
612149754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown        if (slotCount > MAX_SLOTS) {
61228564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("MultiTouch Device %s reported %d slots but the framework "
612380fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown                    "only supports a maximum of %d slots at this time.",
612449754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown                    getDeviceName().string(), slotCount, MAX_SLOTS);
612549754db5a304d995c1cc108ff6f19e4ba4265572Jeff Brown            slotCount = MAX_SLOTS;
612680fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown        }
612700710e906bdafd58386ee7f81fa84addd218122fJeff Brown        mMultiTouchMotionAccumulator.configure(getDevice(),
612800710e906bdafd58386ee7f81fa84addd218122fJeff Brown                slotCount, true /*usingSlotsProtocol*/);
612980fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    } else {
613000710e906bdafd58386ee7f81fa84addd218122fJeff Brown        mMultiTouchMotionAccumulator.configure(getDevice(),
613100710e906bdafd58386ee7f81fa84addd218122fJeff Brown                MAX_POINTERS, false /*usingSlotsProtocol*/);
613280fd47ce75253dcdc2cfa85d7a3f42634b923a47Jeff Brown    }
61336d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
61346d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
613500710e906bdafd58386ee7f81fa84addd218122fJeff Brownbool MultiTouchInputMapper::hasStylus() const {
613600710e906bdafd58386ee7f81fa84addd218122fJeff Brown    return mMultiTouchMotionAccumulator.hasStylus()
613700710e906bdafd58386ee7f81fa84addd218122fJeff Brown            || mTouchButtonAccumulator.hasStylus();
613800710e906bdafd58386ee7f81fa84addd218122fJeff Brown}
613900710e906bdafd58386ee7f81fa84addd218122fJeff Brown
61406d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
6141cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown// --- JoystickInputMapper ---
6142cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
6143cb1404e45639d20439d7700b06d57ca1a1aad1faJeff BrownJoystickInputMapper::JoystickInputMapper(InputDevice* device) :
6144cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        InputMapper(device) {
6145cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
6146cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
6147cb1404e45639d20439d7700b06d57ca1a1aad1faJeff BrownJoystickInputMapper::~JoystickInputMapper() {
6148cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
6149cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
6150cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brownuint32_t JoystickInputMapper::getSources() {
6151cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    return AINPUT_SOURCE_JOYSTICK;
6152cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
6153cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
6154cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brownvoid JoystickInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
6155cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    InputMapper::populateDeviceInfo(info);
6156cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
61576f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    for (size_t i = 0; i < mAxes.size(); i++) {
61586f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        const Axis& axis = mAxes.valueAt(i);
61592b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright        addMotionRange(axis.axisInfo.axis, axis, info);
61602b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright
61618529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
61622b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright            addMotionRange(axis.axisInfo.highAxis, axis, info);
61632b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright
61648529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        }
6165cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
6166cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
6167cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
61682b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wrightvoid JoystickInputMapper::addMotionRange(int32_t axisId, const Axis& axis,
61692b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright        InputDeviceInfo* info) {
61702b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright    info->addMotionRange(axisId, AINPUT_SOURCE_JOYSTICK,
61712b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright            axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
61722b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright    /* In order to ease the transition for developers from using the old axes
61732b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright     * to the newer, more semantically correct axes, we'll continue to register
61742b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright     * the old axes as duplicates of their corresponding new ones.  */
61752b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright    int32_t compatAxis = getCompatAxis(axisId);
61762b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright    if (compatAxis >= 0) {
61772b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright        info->addMotionRange(compatAxis, AINPUT_SOURCE_JOYSTICK,
61782b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright                axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
61792b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright    }
61802b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright}
61812b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright
61822b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright/* A mapping from axes the joystick actually has to the axes that should be
61832b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright * artificially created for compatibility purposes.
61842b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright * Returns -1 if no compatibility axis is needed. */
61852b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wrightint32_t JoystickInputMapper::getCompatAxis(int32_t axis) {
61862b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright    switch(axis) {
61872b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright    case AMOTION_EVENT_AXIS_LTRIGGER:
61882b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright        return AMOTION_EVENT_AXIS_BRAKE;
61892b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright    case AMOTION_EVENT_AXIS_RTRIGGER:
61902b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright        return AMOTION_EVENT_AXIS_GAS;
61912b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright    }
61922b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright    return -1;
61932b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright}
61942b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright
6195cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brownvoid JoystickInputMapper::dump(String8& dump) {
6196cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    dump.append(INDENT2 "Joystick Input Mapper:\n");
6197cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
61986f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    dump.append(INDENT3 "Axes:\n");
61996f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    size_t numAxes = mAxes.size();
62006f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    for (size_t i = 0; i < numAxes; i++) {
62016f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        const Axis& axis = mAxes.valueAt(i);
62028529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        const char* label = getAxisLabel(axis.axisInfo.axis);
62036f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        if (label) {
62048529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            dump.appendFormat(INDENT4 "%s", label);
62056f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        } else {
62068529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            dump.appendFormat(INDENT4 "%d", axis.axisInfo.axis);
62078529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        }
62088529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
62098529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            label = getAxisLabel(axis.axisInfo.highAxis);
62108529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            if (label) {
62118529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                dump.appendFormat(" / %s (split at %d)", label, axis.axisInfo.splitValue);
62128529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            } else {
62138529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                dump.appendFormat(" / %d (split at %d)", axis.axisInfo.highAxis,
62148529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                        axis.axisInfo.splitValue);
62158529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            }
62168529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        } else if (axis.axisInfo.mode == AxisInfo::MODE_INVERT) {
62178529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            dump.append(" (invert)");
62186f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        }
62198529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown
6220c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright        dump.appendFormat(": min=%0.5f, max=%0.5f, flat=%0.5f, fuzz=%0.5f, resolution=%0.5f\n",
6221c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright                axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
62228529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        dump.appendFormat(INDENT4 "  scale=%0.5f, offset=%0.5f, "
62238529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                "highScale=%0.5f, highOffset=%0.5f\n",
62248529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                axis.scale, axis.offset, axis.highScale, axis.highOffset);
6225b3a2d1330716812784aee91b6d6275764b5e4210Jeff Brown        dump.appendFormat(INDENT4 "  rawAxis=%d, rawMin=%d, rawMax=%d, "
6226b3a2d1330716812784aee91b6d6275764b5e4210Jeff Brown                "rawFlat=%d, rawFuzz=%d, rawResolution=%d\n",
62276f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown                mAxes.keyAt(i), axis.rawAxisInfo.minValue, axis.rawAxisInfo.maxValue,
6228b3a2d1330716812784aee91b6d6275764b5e4210Jeff Brown                axis.rawAxisInfo.flat, axis.rawAxisInfo.fuzz, axis.rawAxisInfo.resolution);
6229cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
6230cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
6231cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
623265fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid JoystickInputMapper::configure(nsecs_t when,
623365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        const InputReaderConfiguration* config, uint32_t changes) {
623465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    InputMapper::configure(when, config, changes);
6235cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
6236474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown    if (!changes) { // first time only
6237474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        // Collect all axes.
6238474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        for (int32_t abs = 0; abs <= ABS_MAX; abs++) {
62399ee285afe740ff13d176c9d8430979dfd9575a23Jeff Brown            if (!(getAbsAxisUsage(abs, getDevice()->getClasses())
62409ee285afe740ff13d176c9d8430979dfd9575a23Jeff Brown                    & INPUT_DEVICE_CLASS_JOYSTICK)) {
62419ee285afe740ff13d176c9d8430979dfd9575a23Jeff Brown                continue; // axis must be claimed by a different device
62429ee285afe740ff13d176c9d8430979dfd9575a23Jeff Brown            }
62439ee285afe740ff13d176c9d8430979dfd9575a23Jeff Brown
6244474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            RawAbsoluteAxisInfo rawAxisInfo;
6245be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            getAbsoluteAxisInfo(abs, &rawAxisInfo);
6246474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            if (rawAxisInfo.valid) {
6247474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                // Map axis.
6248474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                AxisInfo axisInfo;
6249474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                bool explicitlyMapped = !getEventHub()->mapAxis(getDeviceId(), abs, &axisInfo);
6250474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                if (!explicitlyMapped) {
6251474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    // Axis is not explicitly mapped, will choose a generic axis later.
6252474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    axisInfo.mode = AxisInfo::MODE_NORMAL;
6253474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    axisInfo.axis = -1;
6254474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                }
62556f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
6256474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                // Apply flat override.
6257474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                int32_t rawFlat = axisInfo.flatOverride < 0
6258474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                        ? rawAxisInfo.flat : axisInfo.flatOverride;
6259474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown
6260474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                // Calculate scaling factors and limits.
6261474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                Axis axis;
6262474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                if (axisInfo.mode == AxisInfo::MODE_SPLIT) {
6263474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    float scale = 1.0f / (axisInfo.splitValue - rawAxisInfo.minValue);
6264474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    float highScale = 1.0f / (rawAxisInfo.maxValue - axisInfo.splitValue);
6265474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
6266474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                            scale, 0.0f, highScale, 0.0f,
6267c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright                            0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale,
6268c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright                            rawAxisInfo.resolution * scale);
6269474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                } else if (isCenteredAxis(axisInfo.axis)) {
6270474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    float scale = 2.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
6271474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    float offset = avg(rawAxisInfo.minValue, rawAxisInfo.maxValue) * -scale;
6272474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
6273474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                            scale, offset, scale, offset,
6274c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright                            -1.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale,
6275c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright                            rawAxisInfo.resolution * scale);
6276474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                } else {
6277474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    float scale = 1.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
6278474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
6279474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                            scale, 0.0f, scale, 0.0f,
6280c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright                            0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale,
6281c6091c64c90e9557ea58e0d7cf75915aea7c6c3eMichael Wright                            rawAxisInfo.resolution * scale);
6282474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                }
62836f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
6284474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                // To eliminate noise while the joystick is at rest, filter out small variations
6285474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                // in axis values up front.
6286474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                axis.filter = axis.flat * 0.25f;
62876f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
6288474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                mAxes.add(abs, axis);
6289474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            }
62906f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        }
6291cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
6292474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        // If there are too many axes, start dropping them.
6293474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        // Prefer to keep explicitly mapped axes.
6294474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        if (mAxes.size() > PointerCoords::MAX_AXES) {
62956215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block            ALOGI("Joystick '%s' has %d axes but the framework only supports a maximum of %d.",
6296474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    getDeviceName().string(), mAxes.size(), PointerCoords::MAX_AXES);
6297474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            pruneAxes(true);
6298474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            pruneAxes(false);
6299474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        }
6300474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown
6301474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        // Assign generic axis ids to remaining axes.
6302474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        int32_t nextGenericAxisId = AMOTION_EVENT_AXIS_GENERIC_1;
6303474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        size_t numAxes = mAxes.size();
6304474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown        for (size_t i = 0; i < numAxes; i++) {
6305474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            Axis& axis = mAxes.editValueAt(i);
6306474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown            if (axis.axisInfo.axis < 0) {
6307474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                while (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16
6308474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                        && haveAxis(nextGenericAxisId)) {
6309474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    nextGenericAxisId += 1;
6310474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                }
63116f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
6312474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                if (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16) {
6313474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    axis.axisInfo.axis = nextGenericAxisId;
6314474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    nextGenericAxisId += 1;
6315474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                } else {
63166215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block                    ALOGI("Ignoring joystick '%s' axis %d because all of the generic axis ids "
6317474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                            "have already been assigned to other axes.",
6318474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                            getDeviceName().string(), mAxes.keyAt(i));
6319474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    mAxes.removeItemsAt(i--);
6320474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                    numAxes -= 1;
6321474dcb5c3ddff737c4ac9fc44a1f7be569605e5fJeff Brown                }
63226f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            }
63236f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        }
63246f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
6325cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
6326cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
63278529745b27877d98a0c76692295a3fcac238b1e6Jeff Brownbool JoystickInputMapper::haveAxis(int32_t axisId) {
63286f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    size_t numAxes = mAxes.size();
63296f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    for (size_t i = 0; i < numAxes; i++) {
63308529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        const Axis& axis = mAxes.valueAt(i);
63318529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        if (axis.axisInfo.axis == axisId
63328529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                || (axis.axisInfo.mode == AxisInfo::MODE_SPLIT
63338529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                        && axis.axisInfo.highAxis == axisId)) {
63346f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            return true;
63356f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        }
63366f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
63376f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    return false;
63386f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown}
6339cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
63406f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brownvoid JoystickInputMapper::pruneAxes(bool ignoreExplicitlyMappedAxes) {
63416f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    size_t i = mAxes.size();
63426f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    while (mAxes.size() > PointerCoords::MAX_AXES && i-- > 0) {
63436f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        if (ignoreExplicitlyMappedAxes && mAxes.valueAt(i).explicitlyMapped) {
63446f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            continue;
63456f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        }
63466215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block        ALOGI("Discarding joystick '%s' axis %d because there are too many axes.",
63476f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown                getDeviceName().string(), mAxes.keyAt(i));
63486f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        mAxes.removeItemsAt(i);
63496f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
63506f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown}
63516f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
63526f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brownbool JoystickInputMapper::isCenteredAxis(int32_t axis) {
63536f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    switch (axis) {
63546f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_X:
63556f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_Y:
63566f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_Z:
63576f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_RX:
63586f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_RY:
63596f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_RZ:
63606f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_HAT_X:
63616f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_HAT_Y:
63626f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_ORIENTATION:
63638529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    case AMOTION_EVENT_AXIS_RUDDER:
63648529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    case AMOTION_EVENT_AXIS_WHEEL:
63656f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        return true;
63666f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    default:
63676f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        return false;
63686f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
6369cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
6370cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
637165fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid JoystickInputMapper::reset(nsecs_t when) {
6372cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    // Recenter all axes.
63736f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    size_t numAxes = mAxes.size();
63746f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    for (size_t i = 0; i < numAxes; i++) {
63756f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        Axis& axis = mAxes.editValueAt(i);
63768529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        axis.resetValue();
63776f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
63786f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
637965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    InputMapper::reset(when);
6380cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
6381cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
6382cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brownvoid JoystickInputMapper::process(const RawEvent* rawEvent) {
6383cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    switch (rawEvent->type) {
63846f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case EV_ABS: {
638549ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        ssize_t index = mAxes.indexOfKey(rawEvent->code);
63866f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        if (index >= 0) {
63876f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            Axis& axis = mAxes.editValueAt(index);
63888529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            float newValue, highNewValue;
63898529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            switch (axis.axisInfo.mode) {
63908529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            case AxisInfo::MODE_INVERT:
63918529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                newValue = (axis.rawAxisInfo.maxValue - rawEvent->value)
63928529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                        * axis.scale + axis.offset;
63938529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                highNewValue = 0.0f;
63948529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                break;
63958529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            case AxisInfo::MODE_SPLIT:
63968529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                if (rawEvent->value < axis.axisInfo.splitValue) {
63978529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                    newValue = (axis.axisInfo.splitValue - rawEvent->value)
63988529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                            * axis.scale + axis.offset;
63998529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                    highNewValue = 0.0f;
64008529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                } else if (rawEvent->value > axis.axisInfo.splitValue) {
64018529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                    newValue = 0.0f;
64028529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                    highNewValue = (rawEvent->value - axis.axisInfo.splitValue)
64038529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                            * axis.highScale + axis.highOffset;
64048529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                } else {
64058529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                    newValue = 0.0f;
64068529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                    highNewValue = 0.0f;
64078529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                }
64088529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                break;
64098529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            default:
64108529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                newValue = rawEvent->value * axis.scale + axis.offset;
64118529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                highNewValue = 0.0f;
64128529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                break;
64136f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            }
64148529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            axis.newValue = newValue;
64158529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            axis.highNewValue = highNewValue;
6416cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        }
6417cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        break;
64186f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
6419cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
6420cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    case EV_SYN:
642149ccac530b5a798e3c4a79b66b51b8546a0deed1Jeff Brown        switch (rawEvent->code) {
6422cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        case SYN_REPORT:
64236f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            sync(rawEvent->when, false /*force*/);
6424cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown            break;
6425cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        }
6426cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        break;
6427cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
6428cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
6429cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
64306f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brownvoid JoystickInputMapper::sync(nsecs_t when, bool force) {
64318529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    if (!filterAxes(force)) {
64326f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        return;
6433cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
6434cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
6435cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    int32_t metaState = mContext->getGlobalMetaState();
6436fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    int32_t buttonState = 0;
6437fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
6438fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    PointerProperties pointerProperties;
6439fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    pointerProperties.clear();
6440fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    pointerProperties.id = 0;
6441fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
6442cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
64436f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    PointerCoords pointerCoords;
64446f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    pointerCoords.clear();
6445cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
64466f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    size_t numAxes = mAxes.size();
64476f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    for (size_t i = 0; i < numAxes; i++) {
64488529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        const Axis& axis = mAxes.valueAt(i);
64492b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright        setPointerCoordsAxisValue(&pointerCoords, axis.axisInfo.axis, axis.currentValue);
64508529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
64512b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright            setPointerCoordsAxisValue(&pointerCoords, axis.axisInfo.highAxis,
64522b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright                    axis.highCurrentValue);
64538529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        }
6454cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
6455cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
645683d616a9c7b9505153d258511eb5c16b552e268dJeff Brown    // Moving a joystick axis should not wake the device because joysticks can
645756194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // be fairly noisy even when not in use.  On the other hand, pushing a gamepad
645856194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // button will likely wake the device.
645956194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // TODO: Use the input device configuration to control this behavior more finely.
646056194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    uint32_t policyFlags = 0;
646156194ebec6212e229f4ccdaa4b187166d20013efJeff Brown
6462be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    NotifyMotionArgs args(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, policyFlags,
6463fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
646483d616a9c7b9505153d258511eb5c16b552e268dJeff Brown            ADISPLAY_ID_NONE, 1, &pointerProperties, &pointerCoords, 0, 0, 0);
6465be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    getListener()->notifyMotion(&args);
6466cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
6467cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
64682b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wrightvoid JoystickInputMapper::setPointerCoordsAxisValue(PointerCoords* pointerCoords,
64692b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright        int32_t axis, float value) {
64702b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright    pointerCoords->setAxisValue(axis, value);
64712b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright    /* In order to ease the transition for developers from using the old axes
64722b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright     * to the newer, more semantically correct axes, we'll continue to produce
64732b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright     * values for the old axes as mirrors of the value of their corresponding
64742b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright     * new axes. */
64752b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright    int32_t compatAxis = getCompatAxis(axis);
64762b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright    if (compatAxis >= 0) {
64772b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright        pointerCoords->setAxisValue(compatAxis, value);
64782b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright    }
64792b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright}
64802b08c611c88bcb17cfb0861fed67cec6d009e83bMichael Wright
64818529745b27877d98a0c76692295a3fcac238b1e6Jeff Brownbool JoystickInputMapper::filterAxes(bool force) {
64828529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    bool atLeastOneSignificantChange = force;
64836f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    size_t numAxes = mAxes.size();
64846f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    for (size_t i = 0; i < numAxes; i++) {
64858529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        Axis& axis = mAxes.editValueAt(i);
64868529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        if (force || hasValueChangedSignificantly(axis.filter,
64878529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                axis.newValue, axis.currentValue, axis.min, axis.max)) {
64888529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            axis.currentValue = axis.newValue;
64898529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            atLeastOneSignificantChange = true;
64908529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        }
64918529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
64928529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            if (force || hasValueChangedSignificantly(axis.filter,
64938529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                    axis.highNewValue, axis.highCurrentValue, axis.min, axis.max)) {
64948529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                axis.highCurrentValue = axis.highNewValue;
64958529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                atLeastOneSignificantChange = true;
64968529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            }
64978529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        }
64988529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    }
64998529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    return atLeastOneSignificantChange;
65008529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown}
65018529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown
65028529745b27877d98a0c76692295a3fcac238b1e6Jeff Brownbool JoystickInputMapper::hasValueChangedSignificantly(
65038529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        float filter, float newValue, float currentValue, float min, float max) {
65048529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    if (newValue != currentValue) {
65058529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        // Filter out small changes in value unless the value is converging on the axis
65068529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        // bounds or center point.  This is intended to reduce the amount of information
65078529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        // sent to applications by particularly noisy joysticks (such as PS3).
65088529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        if (fabs(newValue - currentValue) > filter
65098529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, min)
65108529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, max)
65118529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, 0)) {
65128529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            return true;
65138529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        }
65148529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    }
65158529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    return false;
65168529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown}
65178529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown
65188529745b27877d98a0c76692295a3fcac238b1e6Jeff Brownbool JoystickInputMapper::hasMovedNearerToValueWithinFilteredRange(
65198529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        float filter, float newValue, float currentValue, float thresholdValue) {
65208529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    float newDistance = fabs(newValue - thresholdValue);
65218529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    if (newDistance < filter) {
65228529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        float oldDistance = fabs(currentValue - thresholdValue);
65238529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        if (newDistance < oldDistance) {
65246f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            return true;
65256f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        }
6526cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
65276f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    return false;
6528cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
6529cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
653046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} // namespace android
6531